From b46a770869089fb92c4c452d9f6102ec5cb4c3e3 Mon Sep 17 00:00:00 2001 From: Elijah Taylor Date: Thu, 31 Jan 2013 12:48:49 -0800 Subject: [PATCH] NaCl GC improvements - inline managed code implementation (add x86 test mem imm8 codegen macro for this as well) - clean up libgc NaCl code - centralize mono_nacl_gc into mini.c --- libgc/pthread_stop_world.c | 37 ++++++++++++++++++------------------- libgc/pthread_support.c | 8 ++++---- mono/arch/x86/x86-codegen.h | 8 ++++++++ mono/mini/mini-amd64.c | 24 ++++++++++++------------ mono/mini/mini-x86.c | 24 +++++++++++------------- mono/mini/mini.c | 8 ++++++++ 6 files changed, 61 insertions(+), 48 deletions(-) diff --git a/libgc/pthread_stop_world.c b/libgc/pthread_stop_world.c index e6ac64b62a8..05e897fb739 100644 --- a/libgc/pthread_stop_world.c +++ b/libgc/pthread_stop_world.c @@ -27,10 +27,10 @@ int nacl_park_threads_now = 0; pthread_t nacl_thread_parker = -1; -int nacl_thread_parked[MAX_NACL_GC_THREADS]; -int nacl_thread_used[MAX_NACL_GC_THREADS]; -int nacl_thread_parking_inited = 0; -int nacl_num_gc_threads = 0; +volatile int nacl_thread_parked[MAX_NACL_GC_THREADS]; +volatile int nacl_thread_used[MAX_NACL_GC_THREADS]; +volatile int nacl_thread_parking_inited = 0; +volatile int nacl_num_gc_threads = 0; pthread_mutex_t nacl_thread_alloc_lock = PTHREAD_MUTEX_INITIALIZER; __thread int nacl_thread_idx = -1; __thread GC_thread nacl_gc_thread_self = NULL; @@ -513,29 +513,28 @@ static void pthread_stop_world() #define NACL_STORE_REGS() \ do { \ - asm("push %rbx");\ - asm("push %rbp");\ - asm("push %r12");\ - asm("push %r13");\ - asm("push %r14");\ - asm("push %r15");\ - asm("mov %%esp, %0" : "=m" (nacl_gc_thread_self->stop_info.stack_ptr));\ + __asm__ __volatile__ ("push %rbx");\ + __asm__ __volatile__ ("push %rbp");\ + __asm__ __volatile__ ("push %r12");\ + __asm__ __volatile__ ("push %r13");\ + __asm__ __volatile__ ("push %r14");\ + __asm__ __volatile__ ("push %r15");\ + __asm__ __volatile__ ("mov %%esp, %0" : "=m" (nacl_gc_thread_self->stop_info.stack_ptr));\ memcpy(nacl_gc_thread_self->stop_info.reg_storage, nacl_gc_thread_self->stop_info.stack_ptr, NACL_GC_REG_STORAGE_SIZE * sizeof(ptr_t));\ - asm("add $48, %esp");\ - asm("add %r15, %rsp");\ + __asm__ __volatile__ ("naclasp $48, %r15");\ } while (0) #elif __i386__ #define NACL_STORE_REGS() \ do { \ - asm("push %ebx");\ - asm("push %ebp");\ - asm("push %esi");\ - asm("push %edi");\ - asm("mov %%esp, %0" : "=m" (nacl_gc_thread_self->stop_info.stack_ptr));\ + __asm__ __volatile__ ("push %ebx");\ + __asm__ __volatile__ ("push %ebp");\ + __asm__ __volatile__ ("push %esi");\ + __asm__ __volatile__ ("push %edi");\ + __asm__ __volatile__ ("mov %%esp, %0" : "=m" (nacl_gc_thread_self->stop_info.stack_ptr));\ memcpy(nacl_gc_thread_self->stop_info.reg_storage, nacl_gc_thread_self->stop_info.stack_ptr, NACL_GC_REG_STORAGE_SIZE * sizeof(ptr_t));\ - asm("add $16, %esp");\ + __asm__ __volatile__ ("add $16, %esp");\ } while (0) #endif diff --git a/libgc/pthread_support.c b/libgc/pthread_support.c index ccafb3b1169..50241e44bf8 100644 --- a/libgc/pthread_support.c +++ b/libgc/pthread_support.c @@ -687,10 +687,10 @@ void GC_mark_thread_local_free_lists(void) static struct GC_Thread_Rep first_thread; #ifdef NACL -extern int nacl_thread_parked[MAX_NACL_GC_THREADS]; -extern int nacl_thread_used[MAX_NACL_GC_THREADS]; -extern int nacl_thread_parking_inited; -extern int nacl_num_gc_threads; +extern volatile int nacl_thread_parked[MAX_NACL_GC_THREADS]; +extern volatile int nacl_thread_used[MAX_NACL_GC_THREADS]; +extern volatile int nacl_thread_parking_inited; +extern volatile int nacl_num_gc_threads; extern pthread_mutex_t nacl_thread_alloc_lock; extern __thread int nacl_thread_idx; extern __thread GC_thread nacl_gc_thread_self; diff --git a/mono/arch/x86/x86-codegen.h b/mono/arch/x86/x86-codegen.h index fd2c528c862..ced466eaf14 100644 --- a/mono/arch/x86/x86-codegen.h +++ b/mono/arch/x86/x86-codegen.h @@ -814,6 +814,14 @@ typedef union { x86_imm_emit32 ((inst), (imm)); \ } while (0) +#define x86_test_mem_imm8(inst,mem,imm) \ + do { \ + x86_codegen_pre(&(inst), 7); \ + *(inst)++ = (unsigned char)0xf6; \ + x86_mem_emit ((inst), 0, (mem)); \ + x86_imm_emit8 ((inst), (imm)); \ + } while (0) + #define x86_test_mem_imm(inst,mem,imm) \ do { \ x86_codegen_pre(&(inst), 10); \ diff --git a/mono/mini/mini-amd64.c b/mono/mini/mini-amd64.c index 0ffbde808da..656129c3331 100644 --- a/mono/mini/mini-amd64.c +++ b/mono/mini/mini-amd64.c @@ -3838,16 +3838,6 @@ amd64_pop_reg (code, AMD64_RAX); #define bb_is_loop_start(bb) ((bb)->loop_body_start && (bb)->nesting) #ifndef DISABLE_JIT - -#if defined(__native_client__) || defined(__native_client_codegen__) -void mono_nacl_gc() -{ -#ifdef __native_client_gc__ - __nacl_suspend_thread_if_needed(); -#endif -} -#endif - void mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) { @@ -6394,8 +6384,18 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) break; } case OP_NACL_GC_SAFE_POINT: { -#if defined(__native_client_codegen__) - code = emit_call (cfg, code, MONO_PATCH_INFO_ABS, (gpointer)mono_nacl_gc, TRUE); +#if defined(__native_client_codegen__) && defined(__native_client_gc__) + if (cfg->compile_aot) + code = emit_call (cfg, code, MONO_PATCH_INFO_ABS, (gpointer)mono_nacl_gc, TRUE); + else { + guint8 *br [1]; + + amd64_mov_reg_imm_size (code, AMD64_R11, (gpointer)&__nacl_thread_suspension_needed, 4); + amd64_test_membase_imm_size (code, AMD64_R11, 0, 0xFFFFFFFF, 4); + br[0] = code; x86_branch8 (code, X86_CC_EQ, 0, FALSE); + code = emit_call (cfg, code, MONO_PATCH_INFO_ABS, (gpointer)mono_nacl_gc, TRUE); + amd64_patch (br[0], code); + } #endif break; } diff --git a/mono/mini/mini-x86.c b/mono/mini/mini-x86.c index e7dd64909af..3db3ec3f4dc 100644 --- a/mono/mini/mini-x86.c +++ b/mono/mini/mini-x86.c @@ -2450,17 +2450,6 @@ x86_pop_reg (code, X86_EAX); #define bb_is_loop_start(bb) ((bb)->loop_body_start && (bb)->nesting) #ifndef DISABLE_JIT - -#if defined(__native_client__) || defined(__native_client_codegen__) -void -mono_nacl_gc() -{ -#ifdef __native_client_gc__ - __nacl_suspend_thread_if_needed(); -#endif -} -#endif - void mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) { @@ -4886,8 +4875,17 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) break; } case OP_NACL_GC_SAFE_POINT: { -#if defined(__native_client_codegen__) - code = emit_call (cfg, code, MONO_PATCH_INFO_ABS, (gpointer)mono_nacl_gc); +#if defined(__native_client_codegen__) && defined(__native_client_gc__) + if (cfg->compile_aot) + code = emit_call (cfg, code, MONO_PATCH_INFO_ABS, (gpointer)mono_nacl_gc); + else { + guint8 *br [1]; + + x86_test_mem_imm8 (code, (gpointer)&__nacl_thread_suspension_needed, 0xFFFFFFFF); + br[0] = code; x86_branch8 (code, X86_CC_EQ, 0, FALSE); + code = emit_call (cfg, code, MONO_PATCH_INFO_ABS, (gpointer)mono_nacl_gc); + x86_patch (br[0], code); + } #endif break; } diff --git a/mono/mini/mini.c b/mono/mini/mini.c index 28b66be959f..1d75429d558 100644 --- a/mono/mini/mini.c +++ b/mono/mini/mini.c @@ -462,6 +462,14 @@ void *mono_global_codeman_reserve (int size) } #if defined(__native_client_codegen__) && defined(__native_client__) +void +mono_nacl_gc() +{ +#ifdef __native_client_gc__ + __nacl_suspend_thread_if_needed(); +#endif +} + /* Given the temporary buffer (allocated by mono_global_codeman_reserve) into * which we are generating code, return a pointer to the destination in the * dynamic code segment into which the code will be copied when -- 2.25.1