瀏覽代碼

fixed hot reload wrt globals relocation

Nicolas Cannasse 5 年之前
父節點
當前提交
bc714bec20
共有 4 個文件被更改,包括 36 次插入18 次删除
  1. 3 5
      src/code.c
  2. 1 0
      src/hlmodule.h
  3. 31 12
      src/module.c
  4. 1 1
      src/std/obj.c

+ 3 - 5
src/code.c

@@ -994,10 +994,8 @@ void hl_code_hash_remap_globals( hl_code_hash *hnew, hl_code_hash *hold ) {
 
 	// new globals
 	for(i=0;i<count;i++)
-		if( remap[i] == -1 ) {
+		if( remap[i] == -1 )
 			remap[i] = count + extra++;
-			printf("GLOBAL %d->%d CHANGED\n",i,remap[i]);
-		}
 
 	hl_type **nglobals;
 	ALLOC(nglobals,hl_type*,count + extra);
@@ -1022,11 +1020,11 @@ void hl_code_hash_remap_globals( hl_code_hash *hnew, hl_code_hash *hold ) {
 		case HSTRUCT:
 		case HOBJ:
 			if( t->obj->global_value )
-				t->obj->global_value = (void*)(int_val)remap[(int)(int_val)t->obj->global_value - 1];
+				t->obj->global_value = (void*)(int_val)(remap[(int)(int_val)t->obj->global_value - 1] + 1);
 			break;
 		case HENUM:
 			if( t->tenum->global_value )
-				t->tenum->global_value = (void*)(int_val)remap[(int)(int_val)t->tenum->global_value - 1];
+				t->tenum->global_value = (void*)(int_val)(remap[(int)(int_val)t->tenum->global_value - 1] + 1);
 			break;
 		}
 	}

+ 1 - 0
src/hlmodule.h

@@ -118,6 +118,7 @@ typedef struct {
 typedef struct {
 	hl_code *code;
 	int codesize;
+	int globals_size;
 	int *globals_indexes;
 	unsigned char *globals_data;
 	void **functions_ptrs;

+ 31 - 12
src/module.c

@@ -31,6 +31,8 @@ EXTERN_C IMAGE_DOS_HEADER __ImageBase;
 #	include <dlfcn.h>
 #endif
 
+#define HOT_RELOAD_EXTRA_GLOBALS	4096
+
 static hl_module **cur_modules = NULL;
 static int modules_count = 0;
 
@@ -235,6 +237,7 @@ hl_module *hl_module_alloc( hl_code *c ) {
 		m->globals_indexes[i] = gsize;
 		gsize += hl_type_size(c->globals[i]);
 	}
+	m->globals_size = gsize;
 	m->globals_data = (unsigned char*)malloc(gsize);
 	if( m->globals_data == NULL ) {
 		hl_module_free(m);
@@ -477,6 +480,19 @@ static void hl_module_init_natives( hl_module *m ) {
 int hl_module_init( hl_module *m, h_bool hot_reload ) {
 	int i;
 	jit_ctx *ctx;
+	// expand globals
+	if( hot_reload ) {
+		int nsize = m->globals_size + HOT_RELOAD_EXTRA_GLOBALS * sizeof(void*);
+		int *nindexes = malloc(sizeof(int) * (m->code->nglobals + HOT_RELOAD_EXTRA_GLOBALS));
+		memcpy(nindexes,m->globals_indexes,sizeof(int)*m->code->nglobals);
+		memset(nindexes + m->code->nglobals,0xFF,HOT_RELOAD_EXTRA_GLOBALS * sizeof(int));
+		free(m->globals_indexes);
+		free(m->globals_data);
+		m->globals_indexes = nindexes;
+		m->globals_data = malloc(nsize);
+		memset(m->globals_data,0,m->globals_size);
+		memset(m->globals_data + m->globals_size,0xFF,HOT_RELOAD_EXTRA_GLOBALS * sizeof(void*));
+	}
 	// RESET globals
 	for(i=0;i<m->code->nglobals;i++) {
 		hl_type *t = m->code->globals[i];
@@ -582,6 +598,15 @@ h_bool hl_module_patch( hl_module *m1, hl_code *c ) {
 	hl_module *m2 = hl_module_alloc(c);
 	m2->hash = hl_code_hash_alloc(c);
 	hl_code_hash_remap_globals(m2->hash,m1->hash);
+
+	// share global data
+	// TODO : we should assign indexes for new globals
+	// and eventually init their value correctly
+	free(m2->globals_data);
+	free(m2->globals_indexes);
+	m2->globals_data = m1->globals_data;
+	m2->globals_indexes = m1->globals_indexes;
+	
 	hl_module_init_natives(m2);
 	hl_module_init_indexes(m2);
 	hl_jit_reset(ctx, m2);
@@ -599,11 +624,11 @@ h_bool hl_module_patch( hl_module *m1, hl_code *c ) {
 			if( sign1 == sign2 ) {
 				hl_function *f1 = m1->code->functions + i1;
 				if( (f1->obj != NULL) != (f2->obj != NULL) || !f1->field.name || !f2->field.name ) {
-					printf("Signature conflict\n");
+					printf("[HotReload] Signature conflict\n");
 					continue;
 				}
 				if( ucmp(fun_obj(f1)->name,fun_obj(f2)->name) != 0 || ucmp(fun_field_name(f1),fun_field_name(f2)) != 0 ) {
-					printf("Signature conflict\n");
+					printf("[HotReload] Signature conflict\n");
 					continue;
 				}
 
@@ -648,7 +673,7 @@ h_bool hl_module_patch( hl_module *m1, hl_code *c ) {
 		}
 	}
 	if( !has_changes ) {
-		printf("No changes found\n");
+		printf("[HotReload] No changes found\n");
 		fflush(stdout);
 		hl_jit_free(ctx, true);
 		return false;
@@ -663,15 +688,9 @@ h_bool hl_module_patch( hl_module *m1, hl_code *c ) {
 			if( p->kind != t->kind ) continue;
 			if( ucmp(p->obj->name,t->obj->name) != 0 ) continue;
 			if( hl_code_hash_type(m1->hash,p) == hl_code_hash_type(m2->hash,t)  ) {
-				if( p->obj->global_value && t->obj->global_value ) {
-					// set old global value
-					*t->obj->global_value = *p->obj->global_value;
-					// point to old value address
-					t->obj->global_value = p->obj->global_value; 
-				}
 				t->obj = p->obj; // alias the types ! they are different pointers but have the same layout
 			} else {
-				uprintf(USTR("Type %s has changed\n"),t->obj->name);
+				uprintf(USTR("[HotReload] Type %s has changed\n"),t->obj->name);
 				changes_count++;
 			}
 			break;
@@ -682,7 +701,7 @@ h_bool hl_module_patch( hl_module *m1, hl_code *c ) {
 	hl_jit_free(ctx,true);
 
 	if( m2->jit_code == NULL ) {
-		printf("Couldn't JIT result\n");
+		printf("[HotReload] Couldn't JIT result\n");
 		fflush(stdout);
 		return false;
 	}
@@ -706,7 +725,7 @@ h_bool hl_module_patch( hl_module *m1, hl_code *c ) {
 	}
 
 	if( changes_count > 0 ) {
-		printf("%d changes\n", changes_count);
+		printf("[HotReload] %d changes\n", changes_count);
 		fflush(stdout);
 	}
 

+ 1 - 1
src/std/obj.c

@@ -392,7 +392,7 @@ HL_API void hl_flush_proto( hl_type *ot ) {
 	hl_type_obj *o = ot->obj;
 	hl_runtime_obj *rt = ot->obj->rt;
 	hl_module_context *m = o->m;
-	if( !rt ) return;
+	if( !rt || !ot->vobj_proto ) return;
 	for(i=0;i<o->nbindings;i++) {
 		hl_runtime_binding *b = rt->bindings + i;
 		int mid = o->bindings[(i<<1)|1];