Skip to content

Commit ef3eda5

Browse files
committed
change struct/obj alloc size based on largest field size alignment (match C spec)
1 parent 63763dc commit ef3eda5

File tree

5 files changed

+27
-12
lines changed

5 files changed

+27
-12
lines changed

src/gc.c

+2-5
Original file line numberDiff line numberDiff line change
@@ -1271,16 +1271,13 @@ vdynamic *hl_alloc_dynbool( bool b ) {
12711271

12721272
vdynamic *hl_alloc_obj( hl_type *t ) {
12731273
vobj *o;
1274-
int size;
12751274
int i;
12761275
hl_runtime_obj *rt = t->obj->rt;
12771276
if( rt == NULL || rt->methods == NULL ) rt = hl_get_obj_proto(t);
1278-
size = rt->size;
1279-
if( size & (HL_WSIZE-1) ) size += HL_WSIZE - (size & (HL_WSIZE-1));
12801277
if( t->kind == HSTRUCT ) {
1281-
o = (vobj*)hl_gc_alloc_gen(t, size, (rt->hasPtr ? MEM_KIND_RAW : MEM_KIND_NOPTR) | MEM_ZERO);
1278+
o = (vobj*)hl_gc_alloc_gen(t, rt->size, (rt->hasPtr ? MEM_KIND_RAW : MEM_KIND_NOPTR) | MEM_ZERO);
12821279
} else {
1283-
o = (vobj*)hl_gc_alloc_gen(t, size, (rt->hasPtr ? MEM_KIND_DYNAMIC : MEM_KIND_NOPTR) | MEM_ZERO);
1280+
o = (vobj*)hl_gc_alloc_gen(t, rt->size, (rt->hasPtr ? MEM_KIND_DYNAMIC : MEM_KIND_NOPTR) | MEM_ZERO);
12841281
o->t = t;
12851282
}
12861283
for(i=0;i<rt->nbindings;i++) {

src/hl.h

+2
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,8 @@ struct hl_runtime_obj {
533533
int size;
534534
int nmethods;
535535
int nbindings;
536+
unsigned char pad_size;
537+
unsigned char largest_field;
536538
bool hasPtr;
537539
void **methods;
538540
int *fields_indexes;

src/jit.c

-1
Original file line numberDiff line numberDiff line change
@@ -3822,7 +3822,6 @@ int hl_jit_function( jit_ctx *ctx, hl_module *m, hl_function *f ) {
38223822
else {
38233823
hl_runtime_obj *rt = hl_get_obj_rt(dst->t);
38243824
osize = rt->size;
3825-
if( osize & (HL_WSIZE-1) ) osize += HL_WSIZE - (osize & (HL_WSIZE-1));
38263825
}
38273826
preg *idx = alloc_cpu(ctx, rb, true);
38283827
op64(ctx, IMUL, idx, pconst(&p,osize));

src/std/array.c

+2-4
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,11 @@ HL_PRIM void *hl_alloc_carray( hl_type *at, int size ) {
5757

5858
hl_runtime_obj *rt = at->obj->rt;
5959
if( rt == NULL || rt->methods == NULL ) rt = hl_get_obj_proto(at);
60-
int osize = rt->size;
61-
if( osize & (HL_WSIZE-1) ) osize += HL_WSIZE - (osize & (HL_WSIZE-1));
62-
char *arr = hl_gc_alloc_gen(at, size * osize, (rt->hasPtr ? MEM_KIND_RAW : MEM_KIND_NOPTR) | MEM_ZERO);
60+
char *arr = hl_gc_alloc_gen(at, size * rt->size, (rt->hasPtr ? MEM_KIND_RAW : MEM_KIND_NOPTR) | MEM_ZERO);
6361
if( at->kind == HOBJ || rt->nbindings ) {
6462
int i,k;
6563
for(k=0;k<size;k++) {
66-
char *o = arr + osize * k;
64+
char *o = arr + rt->size * k;
6765
if( at->kind == HOBJ )
6866
((vobj*)o)->t = at;
6967
for(i=0;i<rt->nbindings;i++) {

src/std/obj.c

+21-2
Original file line numberDiff line numberDiff line change
@@ -236,8 +236,9 @@ HL_PRIM hl_runtime_obj *hl_get_obj_rt( hl_type *ot ) {
236236
start = p->nfields;
237237
memcpy(t->fields_indexes, p->fields_indexes, sizeof(int)*p->nfields);
238238
}
239-
size = p ? p->size : (ot->kind == HSTRUCT ? 0 : HL_WSIZE); // hl_type*
239+
size = p ? p->size - p->pad_size : (ot->kind == HSTRUCT ? 0 : HL_WSIZE); // hl_type*
240240
nlookup = 0;
241+
int largest_field = p ? p->largest_field : size;
241242
for(i=0;i<o->nfields;i++) {
242243
hl_type *ft = o->fields[i].t;
243244
hl_type *pad = ft;
@@ -259,10 +260,28 @@ HL_PRIM hl_runtime_obj *hl_get_obj_rt( hl_type *ot ) {
259260
if( rts->hasPtr ) t->hasPtr = true;
260261
continue;
261262
}
262-
size += hl_type_size(ft);
263+
int sz = hl_type_size(ft);
264+
size += sz;
265+
if( sz > largest_field ) largest_field = sz;
263266
if( !t->hasPtr && hl_is_ptr(ft) ) t->hasPtr = true;
264267
}
265268
t->size = size;
269+
t->pad_size = 0;
270+
// align size on largest field size to match C, so arr[i].field is always aligned
271+
if( largest_field > 0 ) {
272+
int pad = size % largest_field;
273+
if( pad != 0 ) {
274+
t->pad_size = largest_field - pad;
275+
t->size += t->pad_size;
276+
}
277+
}
278+
{
279+
int sz2 = size;
280+
if( sz2 & (HL_WSIZE-1) ) sz2 += HL_WSIZE - (sz2 & (HL_WSIZE-1));
281+
if( sz2 != t->size )
282+
uprintf(USTR("%s(%d --> %d)\n"), o->name, sz2, t->size);
283+
}
284+
t->largest_field = largest_field;
266285
t->nmethods = p ? p->nmethods : o->nproto;
267286
t->methods = NULL;
268287
o->rt = t;

0 commit comments

Comments
 (0)