@@ -236,18 +236,21 @@ HL_PRIM hl_runtime_obj *hl_get_obj_rt( hl_type *ot ) {
236
236
start = p -> nfields ;
237
237
memcpy (t -> fields_indexes , p -> fields_indexes , sizeof (int )* p -> nfields );
238
238
}
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*
240
240
nlookup = 0 ;
241
+ int largest_field = p ? p -> largest_field : size ;
241
242
for (i = 0 ;i < o -> nfields ;i ++ ) {
242
243
hl_type * ft = o -> fields [i ].t ;
243
- hl_type * pad = ft ;
244
- while ( pad -> kind == HPACKED ) {
245
- // align on first field
246
- pad = pad -> tparam ;
247
- while ( pad -> obj -> super && hl_get_obj_rt (pad -> obj -> super )-> nfields ) pad = pad -> obj -> super ;
248
- pad = pad -> obj -> fields [0 ].t ;
249
- }
250
- size += hl_pad_struct (size ,pad );
244
+ if ( ft -> kind == HPACKED ) {
245
+ // align on packed largest field
246
+ int large = hl_get_obj_rt (ft -> tparam )-> largest_field ;
247
+ int pad = size % large ;
248
+ if ( pad != 0 )
249
+ size += large - pad ;
250
+ if ( large > largest_field )
251
+ largest_field = large ;
252
+ } else
253
+ size += hl_pad_struct (size ,ft );
251
254
t -> fields_indexes [i + start ] = size ;
252
255
if ( * o -> fields [i ].name )
253
256
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 ) {
259
262
if ( rts -> hasPtr ) t -> hasPtr = true;
260
263
continue ;
261
264
}
262
- size += hl_type_size (ft );
265
+ int sz = hl_type_size (ft );
266
+ size += sz ;
267
+ if ( sz > largest_field ) largest_field = sz ;
263
268
if ( !t -> hasPtr && hl_is_ptr (ft ) ) t -> hasPtr = true;
264
269
}
265
270
t -> size = size ;
271
+ t -> pad_size = 0 ;
272
+ // align size on largest field size to match C, so arr[i].field is always aligned
273
+ if ( largest_field > 0 ) {
274
+ int pad = size % largest_field ;
275
+ if ( pad != 0 ) {
276
+ t -> pad_size = largest_field - pad ;
277
+ t -> size += t -> pad_size ;
278
+ }
279
+ }
280
+ t -> largest_field = largest_field ;
266
281
t -> nmethods = p ? p -> nmethods : o -> nproto ;
267
282
t -> methods = NULL ;
268
283
o -> rt = t ;
0 commit comments