Sfoglia il codice sorgente

jit for trap, set(virtual), dynset

Nicolas Cannasse 9 anni fa
parent
commit
4ffcf1c93b
9 ha cambiato i file con 123 aggiunte e 91 eliminazioni
  1. 7 1
      src/alloc.c
  2. 12 0
      src/hl.h
  3. 0 15
      src/hlc.h
  4. 1 1
      src/hlc_main.c
  5. 85 72
      src/jit.c
  6. 3 1
      src/main.c
  7. 3 0
      src/module.c
  8. 1 1
      src/std/error.c
  9. 11 0
      src/std/obj.c

+ 7 - 1
src/alloc.c

@@ -82,10 +82,13 @@ struct _gc_pheader {
 	int free_blocks;
 	unsigned char *sizes;
 	unsigned char *bmp;
+	gc_pheader *next_page;
 #ifdef HL_TRACK_ALLOC
 	int *alloc_hashes;
 #endif
-	gc_pheader *next_page;
+#ifdef HL_DEBUG
+	int page_id;
+#endif
 };
 
 #define GC_PARTITIONS	9
@@ -185,6 +188,8 @@ static void gc_flush_empty_pages() {
 	}
 }
 
+static int PAGE_ID = 0;
+
 static gc_pheader *gc_alloc_new_page( int block, int size, bool varsize ) {
 	int m, i;
 	unsigned char *base;
@@ -200,6 +205,7 @@ static gc_pheader *gc_alloc_new_page( int block, int size, bool varsize ) {
 	}
 #	ifdef HL_DEBUG
 	memset(base,0xDD,size);
+	p->page_id = PAGE_ID++;
 #	endif
 	if( ((int_val)base) & ((1<<GC_MASK_BITS) - 1) )
 		hl_fatal("Page memory is not correctly aligned");

+ 12 - 0
src/hl.h

@@ -431,6 +431,7 @@ HL_API char *hl_to_utf8( uchar *bytes );
 HL_API vdynamic *hl_virtual_make_value( vvirtual *v );
 
 HL_API int hl_hash( vbyte *name );
+HL_API int hl_hash_utf8( const char *str ); // no cache
 HL_API int hl_hash_gen( const uchar *name, bool cache_name );
 HL_API const uchar *hl_field_name( int hash );
 
@@ -581,4 +582,15 @@ HL_API void *hl_fatal_error( const char *msg, const char *file, int line );
 HL_API void hl_fatal_fmt( const char *file, int line, const char *fmt, ...);
 HL_API void hl_sys_init(void **args, int nargs);
 
+#include <setjmp.h>
+typedef struct _hl_trap_ctx hl_trap_ctx;
+struct _hl_trap_ctx {
+	jmp_buf buf;
+	hl_trap_ctx *prev;
+};
+HL_API hl_trap_ctx *hl_current_trap;
+HL_API vdynamic *hl_current_exc;
+#define hl_trap(ctx,r,label) { ctx.prev = hl_current_trap; hl_current_trap = &ctx; if( setjmp(ctx.buf) ) { r = hl_current_exc; goto label; } }
+#define hl_endtrap(ctx)	hl_current_trap = ctx.prev
+
 #endif

+ 0 - 15
src/hlc.h

@@ -117,21 +117,6 @@ static vdynamic *hlc_dyn_call_obj( vdynamic *o, int hfield, vdynamic **args, int
 
 #endif
 
-#include <setjmp.h>
-
-typedef struct _hl_trap_ctx hl_trap_ctx;
-
-struct _hl_trap_ctx {
-	jmp_buf buf;
-	hl_trap_ctx *prev;
-};
-
-HL_API hl_trap_ctx *hl_current_trap;
-HL_API vdynamic *hl_current_exc;
-
-#define hlc_trap(ctx,r,label) { ctx.prev = hl_current_trap; hl_current_trap = &ctx; if( setjmp(ctx.buf) ) { r = hl_current_exc; goto label; } }
-#define hlc_endtrap(ctx) hl_current_trap = ctx.prev
-
 extern void *hlc_static_call(void *fun, hl_type *t, void **args, vdynamic *out);
 extern void *hlc_get_wrapper(hl_type *t);
 HL_API void hlc_setup(void *sc, void *gw);

+ 1 - 1
src/hlc_main.c

@@ -43,7 +43,7 @@ int main(int argc, char *argv[]) {
 //	disable crt debug since it will prevent reusing our address space
 //	_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_DELAY_FREE_MEM_DF /*| _CRTDBG_LEAK_CHECK_DF | _CRTDBG_CHECK_ALWAYS_DF*/ );
 #	endif
-	hlc_trap(ctx, exc, on_exception);
+	hl_trap(ctx, exc, on_exception);
 	hl_entry_point();
 	hl_global_free();
 	return 0;

+ 85 - 72
src/jit.c

@@ -1693,6 +1693,22 @@ static void *get_dyncast( hl_type *t ) {
 	}
 }
 
+static void *get_dynset( hl_type *t ) {
+	switch( t->kind ) {
+	case HF32:
+		return hl_dyn_setf;
+	case HF64:
+		return hl_dyn_setd;
+	case HI32:
+	case HI16:
+	case HI8:
+	case HBOOL:
+		return hl_dyn_seti;
+	default:
+		return hl_dyn_setp;
+	}
+} 
+
 int hl_jit_function( jit_ctx *ctx, hl_module *m, hl_function *f ) {
 	int i, size = 0, opCount;
 	int codePos = BUF_POS();
@@ -2071,28 +2087,7 @@ int hl_jit_function( jit_ctx *ctx, hl_module *m, hl_function *f ) {
 					}
 					break;
 				case HVIRTUAL:
-					{
-						jit_error("TODO");
-/*
-						preg *rr = alloc_cpu(ctx,ra,true);
-						preg *ridx = alloc_reg(ctx, RCPU);
-						preg *ridx2 = IS_64 ? alloc_reg(ctx,RCPU) : ridx;
-						preg *rtmp = alloc_reg(ctx, RCPU);
-						// fetch index table
-						op64(ctx, MOV, ridx, pmem(&p, rr->id, 0));
-						// fetch index itself
-#						ifdef HL_64
-						op64(ctx, XOR, ridx2, ridx2);
-#						endif
-						op32(ctx, MOV, ridx2, pmem(&p, ridx->id, o->p3 * sizeof(int) + HL_WSIZE));
-						// fetch fields table
-						op64(ctx, MOV, rtmp, pmem(&p, rr->id, HL_WSIZE*2));
-						// add index
-						op64(ctx, ADD, rtmp, ridx2);
-						RUNLOCK(ridx);
-						// fetch field data
-						copy_to(ctx,dst, pmem(&p, rtmp->id, 0));*/
-					}
+					jit_error("TODO");
 					break;
 				default:
 					ASSERT(ra->t->kind);
@@ -2111,26 +2106,20 @@ int hl_jit_function( jit_ctx *ctx, hl_module *m, hl_function *f ) {
 					}
 					break;
 				case HVIRTUAL:
+					// ASM for --> if( hl_vfields(o)[f] ) *hl_vfields(o)[f] = v; else hl_dyn_set(o,hash(field),vt,v)
 					{
-						preg *rr = alloc_cpu(ctx,dst,true);
-						preg *ridx = alloc_reg(ctx, RCPU);
-						preg *ridx2 = IS_64 ? alloc_reg(ctx,RCPU) : ridx;
-						preg *rtmp = alloc_reg(ctx, RCPU);
-						// fetch index table
-						op64(ctx, MOV, ridx, pmem(&p, rr->id, 0));
-						// fetch index itself
-#						ifdef HL_64
-						op64(ctx, XOR, ridx2, ridx2);
-#						endif
-						op32(ctx, MOV, ridx2, pmem(&p, ridx->id, o->p2 * sizeof(int) + HL_WSIZE));
-						// fetch fields table
-						op64(ctx, MOV, rtmp, pmem(&p, rr->id, HL_WSIZE*2));
-						// add index
-						op64(ctx, ADD, rtmp, ridx2);
-						RUNLOCK(ridx);
-						// fetch field data
-						copy_from(ctx,pmem(&p, rtmp->id, 0), rb);
-					}
+						int jhasfield, jend;
+						preg *v = alloc_cpu(ctx,dst,true);
+						preg *r = alloc_reg(ctx,RCPU);
+						op64(ctx,MOV,r,pmem(&p,v->id,sizeof(vvirtual)+HL_WSIZE*o->p2));
+						op64(ctx,TEST,r,r);
+						XJump_small(JNotZero,jhasfield);
+						jit_error("TODO");
+						XJump_small(JAlways,jend);
+						patch_jump(ctx,jhasfield);
+						copy_from(ctx, pmem(&p,(CpuReg)r->id,0), rb);
+						patch_jump(ctx,jend);
+					}	
 					break;
 				default:
 					ASSERT(dst->t->kind);
@@ -2323,36 +2312,7 @@ int hl_jit_function( jit_ctx *ctx, hl_module *m, hl_function *f ) {
 				}
 			}
 			break;
-		case ODynSet:
-			{
-				int hfield = hl_hash(m->code->strings[o->p2],true);
-#				ifdef HL_64
-				int size = pad_stack(ctx, 0);
-				op64(ctx,MOV,REG_AT(CALL_REGS[0]),fetch(dst));
-				scratch(REG_AT(CALL_REGS[0]));
-				op64(ctx,MOV,REG_AT(CALL_REGS[3]),fetch(rb));
-				op64(ctx,MOV,REG_AT(CALL_REGS[1]),pconst(&p,hfield));
-				op64(ctx,MOV,REG_AT(CALL_REGS[2]),pconst64(&p,(int_val)rb->t));
-#				else
-				int size = pad_stack(ctx, HL_WSIZE*3 + rb->size);
-				if( rb->size == 8 ) {
-					BREAK();
-					//op32(ctx,PUSH,fetch(rb),UNUSED);
-				} else {
-					op32(ctx,PUSH,fetch(rb),UNUSED);
-				}
-				op32(ctx,PUSH,pconst(&p,(int)rb->t), UNUSED);
-				op32(ctx,PUSH,pconst(&p,hfield),UNUSED);
-				op32(ctx,PUSH,fetch(dst),UNUSED);
-#				endif
-				if( rb->size == 8 )
-					call_native(ctx,hl_dyn_set64,size);
-				else
-					call_native(ctx,hl_dyn_set32,size);
-			}
-			break;
-*/		
-		case OMakeEnum:
+*/		case OMakeEnum:
 			{
 				hl_enum_construct *c = &dst->t->tenum->constructs[o->p2];
 				int_val args[] = { c->size, c->hasptr?MEM_KIND_RAW:MEM_KIND_NOPTR };
@@ -2382,7 +2342,7 @@ int hl_jit_function( jit_ctx *ctx, hl_module *m, hl_function *f ) {
 			{
 				int size;
 #				ifdef HL_64
-
+				jit_error("TODO");
 #				else
 				switch( dst->t->kind ) {
 				case HF32:
@@ -2403,6 +2363,59 @@ int hl_jit_function( jit_ctx *ctx, hl_module *m, hl_function *f ) {
 #				endif
 			}
 			break;
+		case ODynSet:
+			{
+				int size;
+#				ifdef HL_64
+				jit_error("TODO");
+#				else
+				switch( dst->t->kind ) {
+				case HF32:
+				case HF64:
+					jit_error("TODO");
+					break;
+				default:
+					size = pad_stack(ctx, HL_WSIZE*4);
+					scratch(PEAX);
+					op32(ctx,MOV,PEAX,REG_AT(Ebp));
+					op32(ctx,ADD,PEAX,pconst(&p,rb->stackPos));
+					op32(ctx,PUSH,PEAX,UNUSED);
+					op32(ctx,PUSH,pconst64(&p,(int_val)rb->t),UNUSED);
+					op32(ctx,PUSH,pconst64(&p,hl_hash_utf8(m->code->strings[o->p2])),UNUSED);
+					op32(ctx,PUSH,fetch(dst),UNUSED);
+					call_native(ctx,get_dynset(rb->t),size);
+					break;
+				}
+#				endif
+			}
+			break;
+		case OTrap:
+			{
+				int size, jenter, jtrap;
+				int trap_size = (sizeof(hl_trap_ctx) + 15) & 0xFFF0;
+				// trap pad
+				op64(ctx,SUB,PESP,pconst(&p,trap_size - sizeof(hl_trap_ctx)));
+				op64(ctx,MOV,PEAX,paddr(&p,&hl_current_trap));
+				op64(ctx,PUSH,PEAX,UNUSED);
+				op64(ctx,SUB,PESP,pconst(&p,sizeof(hl_trap_ctx) - HL_WSIZE));
+				op64(ctx,MOV,PEAX,PESP);
+				op64(ctx,MOV,paddr(&p,&hl_current_trap),PEAX);
+				size = pad_stack(ctx, HL_WSIZE);
+				op64(ctx,PUSH,PEAX,UNUSED);
+				call_native(ctx,setjmp,size);
+				op64(ctx,TEST,PEAX,PEAX);
+				XJump_small(JZero,jenter);
+				op64(ctx,ADD,PESP,pconst(&p,trap_size));
+				op64(ctx,MOV,PEAX,paddr(&p,&hl_current_exc));
+				store(ctx,dst,PEAX,false);
+				jtrap = do_jump(ctx,OJAlways,false);
+				register_jump(ctx,jtrap,(opCount + 1) + o->p2);
+				patch_jump(ctx,jenter);
+			}
+			break;
+		case OEndTrap:
+			jit_error("TODO");
+			break;
 		default:
 			{
 				static bool TRACES[OLast] = {false};

+ 3 - 1
src/main.c

@@ -77,6 +77,7 @@ int main(int argc, char *argv[]) {
 		hl_module *m;
 		vdynamic *exc;
 	} ctx;
+	hl_trap_ctx trap;
 	if( argc == 1 ) {
 		printf("HLVM %d.%d.%d (c)2015-2016 Haxe Foundation\n  Usage : hl <file>\n",HL_VERSION/100,(HL_VERSION/10)%10,HL_VERSION%10);
 		return 1;
@@ -95,12 +96,13 @@ int main(int argc, char *argv[]) {
 		return 2;
 	if( !hl_module_init(ctx.m) )
 		return 3;
+	hl_trap(trap, ctx.exc, on_exception);
 	hl_callback(ctx.m->functions_ptrs[ctx.m->code->entrypoint],0,NULL);
 	hl_module_free(ctx.m);
 	hl_free(&ctx.code->alloc);
 	hl_global_free();
 	return 0;
-//on_exception:
+on_exception:
 	{
 		varray *a = hl_exception_stack();
 		int i;

+ 3 - 0
src/module.c

@@ -186,6 +186,9 @@ int hl_module_init( hl_module *m ) {
 		case HENUM:
 			hl_init_enum(t->tenum);
 			break;
+		case HVIRTUAL:
+			hl_init_virtual(t,&m->ctx);
+			break;
 		}
 	}
 	// JIT

+ 1 - 1
src/std/error.c

@@ -19,7 +19,7 @@
  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  * DEALINGS IN THE SOFTWARE.
  */
-#include <hlc.h>
+#include <hl.h>
 #include <stdarg.h>
 #include <string.h>
 

+ 11 - 0
src/std/obj.c

@@ -79,6 +79,17 @@ HL_PRIM int hl_hash( vbyte *b ) {
 	return hl_hash_gen((uchar*)b,true);
 }
 
+HL_PRIM int hl_hash_utf8( const char *name ) {
+	int h = 0;
+	// ASCII should be enough
+	while( *name ) {
+		h = 223 * h + (unsigned)*name;
+		name++;
+	}
+	h %= 0x1FFFFF7B;
+	return h;
+}
+
 HL_PRIM int hl_hash_gen( const uchar *name, bool cache_name ) {
 	int h = 0;
 	const uchar *oname = name;