From 1e3e01698275139fff5b36b32c73f6252953bd2d Mon Sep 17 00:00:00 2001 From: Nicolas Cannasse Date: Thu, 16 May 2024 15:21:38 +0200 Subject: [PATCH] Change struct/obj alloc size (#682) --- libs/directx/dx/Dx12.hx | 2 +- src/gc.c | 7 ++----- src/hl.h | 2 ++ src/jit.c | 1 - src/std/array.c | 6 ++---- src/std/obj.c | 35 +++++++++++++++++++++++++---------- 6 files changed, 32 insertions(+), 21 deletions(-) diff --git a/libs/directx/dx/Dx12.hx b/libs/directx/dx/Dx12.hx index 8a420900b..5b6b6406d 100644 --- a/libs/directx/dx/Dx12.hx +++ b/libs/directx/dx/Dx12.hx @@ -1044,6 +1044,7 @@ enum abstract InputClassification(Int) { @:struct class InputLayoutDesc { public var inputElementDescs : hl.CArray; public var numElements : Int; + public var __padding : Int; // largest element public function new() { } } @@ -1094,7 +1095,6 @@ enum abstract PipelineStateFlags(Int) { @:packed public var rasterizerState(default,null) : RasterizerDesc; @:packed public var depthStencilDesc(default,null) : DepthStencilDesc; @:packed public var inputLayout(default,null) : InputLayoutDesc; - var __padding : Int; // ? public var ibStripCutValue : IndexBufferStripCutValue; public var primitiveTopologyType : PrimitiveTopologyType; public var numRenderTargets : Int; diff --git a/src/gc.c b/src/gc.c index c55bd63bc..3f8dfc80c 100644 --- a/src/gc.c +++ b/src/gc.c @@ -1271,16 +1271,13 @@ vdynamic *hl_alloc_dynbool( bool b ) { vdynamic *hl_alloc_obj( hl_type *t ) { vobj *o; - int size; int i; hl_runtime_obj *rt = t->obj->rt; if( rt == NULL || rt->methods == NULL ) rt = hl_get_obj_proto(t); - size = rt->size; - if( size & (HL_WSIZE-1) ) size += HL_WSIZE - (size & (HL_WSIZE-1)); if( t->kind == HSTRUCT ) { - o = (vobj*)hl_gc_alloc_gen(t, size, (rt->hasPtr ? MEM_KIND_RAW : MEM_KIND_NOPTR) | MEM_ZERO); + o = (vobj*)hl_gc_alloc_gen(t, rt->size, (rt->hasPtr ? MEM_KIND_RAW : MEM_KIND_NOPTR) | MEM_ZERO); } else { - o = (vobj*)hl_gc_alloc_gen(t, size, (rt->hasPtr ? MEM_KIND_DYNAMIC : MEM_KIND_NOPTR) | MEM_ZERO); + o = (vobj*)hl_gc_alloc_gen(t, rt->size, (rt->hasPtr ? MEM_KIND_DYNAMIC : MEM_KIND_NOPTR) | MEM_ZERO); o->t = t; } for(i=0;inbindings;i++) { diff --git a/src/hl.h b/src/hl.h index 30490dac0..c71b387ec 100644 --- a/src/hl.h +++ b/src/hl.h @@ -533,6 +533,8 @@ struct hl_runtime_obj { int size; int nmethods; int nbindings; + unsigned char pad_size; + unsigned char largest_field; bool hasPtr; void **methods; int *fields_indexes; diff --git a/src/jit.c b/src/jit.c index 91bea1b88..7a6077116 100644 --- a/src/jit.c +++ b/src/jit.c @@ -3822,7 +3822,6 @@ int hl_jit_function( jit_ctx *ctx, hl_module *m, hl_function *f ) { else { hl_runtime_obj *rt = hl_get_obj_rt(dst->t); osize = rt->size; - if( osize & (HL_WSIZE-1) ) osize += HL_WSIZE - (osize & (HL_WSIZE-1)); } preg *idx = alloc_cpu(ctx, rb, true); op64(ctx, IMUL, idx, pconst(&p,osize)); diff --git a/src/std/array.c b/src/std/array.c index 55ae5c235..3d82a922c 100644 --- a/src/std/array.c +++ b/src/std/array.c @@ -57,13 +57,11 @@ HL_PRIM void *hl_alloc_carray( hl_type *at, int size ) { hl_runtime_obj *rt = at->obj->rt; if( rt == NULL || rt->methods == NULL ) rt = hl_get_obj_proto(at); - int osize = rt->size; - if( osize & (HL_WSIZE-1) ) osize += HL_WSIZE - (osize & (HL_WSIZE-1)); - char *arr = hl_gc_alloc_gen(at, size * osize, (rt->hasPtr ? MEM_KIND_RAW : MEM_KIND_NOPTR) | MEM_ZERO); + char *arr = hl_gc_alloc_gen(at, size * rt->size, (rt->hasPtr ? MEM_KIND_RAW : MEM_KIND_NOPTR) | MEM_ZERO); if( at->kind == HOBJ || rt->nbindings ) { int i,k; for(k=0;ksize * k; if( at->kind == HOBJ ) ((vobj*)o)->t = at; for(i=0;inbindings;i++) { diff --git a/src/std/obj.c b/src/std/obj.c index 4c91d3d31..b50f40bf0 100644 --- a/src/std/obj.c +++ b/src/std/obj.c @@ -236,18 +236,21 @@ HL_PRIM hl_runtime_obj *hl_get_obj_rt( hl_type *ot ) { start = p->nfields; memcpy(t->fields_indexes, p->fields_indexes, sizeof(int)*p->nfields); } - size = p ? p->size : (ot->kind == HSTRUCT ? 0 : HL_WSIZE); // hl_type* + size = p ? p->size - p->pad_size : (ot->kind == HSTRUCT ? 0 : HL_WSIZE); // hl_type* nlookup = 0; + int largest_field = p ? p->largest_field : size; for(i=0;infields;i++) { hl_type *ft = o->fields[i].t; - hl_type *pad = ft; - while( pad->kind == HPACKED ) { - // align on first field - pad = pad->tparam; - while( pad->obj->super && hl_get_obj_rt(pad->obj->super)->nfields ) pad = pad->obj->super; - pad = pad->obj->fields[0].t; - } - size += hl_pad_struct(size,pad); + if( ft->kind == HPACKED ) { + // align on packed largest field + int large = hl_get_obj_rt(ft->tparam)->largest_field; + int pad = size % large; + if( pad != 0 ) + size += large - pad; + if( large > largest_field ) + largest_field = large; + } else + size += hl_pad_struct(size,ft); t->fields_indexes[i+start] = size; if( *o->fields[i].name ) hl_lookup_insert(t->lookup,nlookup++,o->fields[i].hashed_name,o->fields[i].t,size); @@ -259,10 +262,22 @@ HL_PRIM hl_runtime_obj *hl_get_obj_rt( hl_type *ot ) { if( rts->hasPtr ) t->hasPtr = true; continue; } - size += hl_type_size(ft); + int sz = hl_type_size(ft); + size += sz; + if( sz > largest_field ) largest_field = sz; if( !t->hasPtr && hl_is_ptr(ft) ) t->hasPtr = true; } t->size = size; + t->pad_size = 0; + // align size on largest field size to match C, so arr[i].field is always aligned + if( largest_field > 0 ) { + int pad = size % largest_field; + if( pad != 0 ) { + t->pad_size = largest_field - pad; + t->size += t->pad_size; + } + } + t->largest_field = largest_field; t->nmethods = p ? p->nmethods : o->nproto; t->methods = NULL; o->rt = t;