Explorar o código

fixed concurrent usage of allocator on first object allocation

Nicolas Cannasse %!s(int64=2) %!d(string=hai) anos
pai
achega
76ca98fee1
Modificáronse 4 ficheiros con 30 adicións e 1 borrados
  1. 9 0
      src/gc.c
  2. 2 0
      src/hl.h
  3. 1 1
      src/std/fun.c
  4. 18 0
      src/std/obj.c

+ 9 - 0
src/gc.c

@@ -240,6 +240,13 @@ static void gc_global_lock( bool lock ) {
 }
 #endif
 
+HL_PRIM void hl_global_lock( bool lock ) {
+	if( lock )
+		hl_mutex_acquire(gc_threads.exclusive_lock);
+	else
+		hl_mutex_release(gc_threads.exclusive_lock);
+}
+
 HL_PRIM void hl_add_root( void *r ) {
 	gc_global_lock(true);
 	if( gc_roots_count == gc_roots_max ) {
@@ -764,8 +771,10 @@ static void hl_gc_init() {
 	gc_stats.mark_bytes = 4; // prevent reading out of bmp
 	memset(&gc_threads,0,sizeof(gc_threads));
 	gc_threads.global_lock = hl_mutex_alloc(false);
+	gc_threads.exclusive_lock = hl_mutex_alloc(false);
 #	ifdef HL_THREADS
 	hl_add_root(&gc_threads.global_lock);
+	hl_add_root(&gc_threads.exclusive_lock);
 #	endif
 }
 

+ 2 - 0
src/hl.h

@@ -766,6 +766,7 @@ HL_API void hl_free( hl_alloc *a );
 
 HL_API void hl_global_init( void );
 HL_API void hl_global_free( void );
+HL_API void hl_global_lock( bool lock );
 
 HL_API void *hl_alloc_executable_memory( int size );
 HL_API void hl_free_executable_memory( void *ptr, int size );
@@ -928,6 +929,7 @@ typedef struct {
 	bool stopping_world;
 	hl_thread_info **threads;
 	hl_mutex *global_lock;
+	hl_mutex *exclusive_lock;
 } hl_threads_info;
 
 HL_API hl_thread_info *hl_get_thread();

+ 1 - 1
src/std/fun.c

@@ -464,7 +464,7 @@ HL_PRIM vdynamic *hl_dyn_call_safe( vclosure *c, vdynamic **args, int nargs, boo
 	ULONG size = 32<<10;
 	SetThreadStackGuarantee(&size);
 	static bool first = true;
-	if( first ) {
+	if( first && !hl_detect_debugger() ) {
 		first = false;
 		AddVectoredExceptionHandler(1,global_handler);
 	}

+ 18 - 0
src/std/obj.c

@@ -178,6 +178,13 @@ HL_PRIM hl_runtime_obj *hl_get_obj_rt( hl_type *ot ) {
 	int i, size, start, nlookup, compareHash;
 	if( o->rt ) return o->rt;
 	if( o->super ) p = hl_get_obj_rt(o->super);
+
+	hl_global_lock(true);
+	if( o->rt ) {
+		hl_global_lock(false);
+		return o->rt;
+	}
+
 	t = (hl_runtime_obj*)hl_malloc(alloc,sizeof(hl_runtime_obj));
 	t->t = ot;
 	t->nfields = o->nfields + (p ? p->nfields : 0);
@@ -300,6 +307,8 @@ HL_PRIM hl_runtime_obj *hl_get_obj_rt( hl_type *ot ) {
 			}
 		}
 	}
+
+	hl_global_lock(false);
 	return t;
 }
 
@@ -318,6 +327,13 @@ HL_API hl_runtime_obj *hl_get_obj_proto( hl_type *ot ) {
 	if( ot->vobj_proto ) return t;
 	if( o->super ) p = hl_get_obj_proto(o->super);
 
+	hl_global_lock(true);
+
+	if( ot->vobj_proto ) {
+		hl_global_lock(false);
+		return t;
+	}
+
 	if( t->nproto ) {
 		void **fptr = (void**)hl_malloc(alloc, sizeof(void*) * t->nproto);
 		ot->vobj_proto = fptr;
@@ -417,6 +433,8 @@ HL_API hl_runtime_obj *hl_get_obj_proto( hl_type *ot ) {
 	t->getFieldFun = getField ? t->methods[-(getField->field_index+1)] : NULL;
 	if( p && !t->getFieldFun ) t->getFieldFun = p->getFieldFun;
 
+	hl_global_lock(false);
+
 	return t;
 }