@@ -99,29 +99,22 @@ jl_datatype_t *jl_new_uninitialized_datatype(void)
9999}
100100
101101static jl_datatype_layout_t * jl_get_layout (uint32_t nfields ,
102+ uint32_t npointers ,
102103 uint32_t alignment ,
103104 int haspadding ,
104- jl_fielddesc32_t desc []) JL_NOTSAFEPOINT
105+ jl_fielddesc32_t desc [],
106+ uint32_t pointers []) JL_NOTSAFEPOINT
105107{
106108 // compute the smallest fielddesc type that can hold the layout description
107109 int fielddesc_type = 0 ;
108- uint32_t npointers = 0 ;
109- // First pointer field
110- uint32_t first_ptr = (uint32_t )-1 ;
111- // Last pointer field
112- uint32_t last_ptr = 0 ;
113110 if (nfields > 0 ) {
114111 uint32_t max_size = 0 ;
115112 uint32_t max_offset = desc [nfields - 1 ].offset ;
113+ if (npointers > 0 && pointers [npointers - 1 ] > max_offset )
114+ max_offset = pointers [npointers - 1 ];
116115 for (size_t i = 0 ; i < nfields ; i ++ ) {
117116 if (desc [i ].size > max_size )
118117 max_size = desc [i ].size ;
119- if (desc [i ].isptr ) {
120- npointers ++ ;
121- if (first_ptr == (uint32_t )-1 )
122- first_ptr = i ;
123- last_ptr = i ;
124- }
125118 }
126119 jl_fielddesc8_t maxdesc8 = { 0 , max_size , max_offset };
127120 jl_fielddesc16_t maxdesc16 = { 0 , max_size , max_offset };
@@ -140,24 +133,14 @@ static jl_datatype_layout_t *jl_get_layout(uint32_t nfields,
140133 // allocate a new descriptor
141134 // TODO: lots of these are the same--take advantage of the fact these are immutable to combine them
142135 uint32_t fielddesc_size = jl_fielddesc_size (fielddesc_type );
143- int has_padding = nfields && npointers ;
144- jl_datatype_layout_t * flddesc =
145- (jl_datatype_layout_t * )jl_gc_perm_alloc (sizeof (jl_datatype_layout_t ) +
146- nfields * fielddesc_size +
147- (has_padding ? sizeof (uint32_t ) : 0 ), 0 , 4 , 0 );
148- if (has_padding ) {
149- if (first_ptr > UINT16_MAX )
150- first_ptr = UINT16_MAX ;
151- last_ptr = nfields - last_ptr - 1 ;
152- if (last_ptr > UINT16_MAX )
153- last_ptr = UINT16_MAX ;
154- flddesc = (jl_datatype_layout_t * )(((char * )flddesc ) + sizeof (uint32_t ));
155- jl_datatype_layout_n_nonptr (flddesc ) = (first_ptr << 16 ) | last_ptr ;
156- }
136+ jl_datatype_layout_t * flddesc = (jl_datatype_layout_t * )jl_gc_perm_alloc (
137+ sizeof (jl_datatype_layout_t ) + nfields * fielddesc_size + (npointers << fielddesc_type ),
138+ 0 , 4 , 0 );
157139 flddesc -> nfields = nfields ;
158140 flddesc -> alignment = alignment ;
159141 flddesc -> haspadding = haspadding ;
160142 flddesc -> fielddesc_type = fielddesc_type ;
143+ flddesc -> npointers = npointers ;
161144
162145 // fill out the fields of the new descriptor
163146 jl_fielddesc8_t * desc8 = (jl_fielddesc8_t * )jl_dt_layout_fields (flddesc );
@@ -180,12 +163,20 @@ static jl_datatype_layout_t *jl_get_layout(uint32_t nfields,
180163 desc32 [i ].isptr = desc [i ].isptr ;
181164 }
182165 }
183- uint32_t nexp = 0 ;
184- while (npointers >= 0x10000 ) {
185- nexp ++ ;
186- npointers = npointers >> 1 ;
166+ uint8_t * ptrs8 = (uint8_t * )jl_dt_layout_ptrs (flddesc );
167+ uint16_t * ptrs16 = (uint16_t * )jl_dt_layout_ptrs (flddesc );
168+ uint32_t * ptrs32 = (uint32_t * )jl_dt_layout_ptrs (flddesc );
169+ for (size_t i = 0 ; i < npointers ; i ++ ) {
170+ if (fielddesc_type == 0 ) {
171+ ptrs8 [i ] = pointers [i ];
172+ }
173+ else if (fielddesc_type == 1 ) {
174+ ptrs16 [i ] = pointers [i ];
175+ }
176+ else {
177+ ptrs32 [i ] = pointers [i ];
178+ }
187179 }
188- flddesc -> npointers = npointers | (nexp << 16 );
189180 return flddesc ;
190181}
191182
@@ -340,18 +331,18 @@ void jl_compute_field_offsets(jl_datatype_t *st)
340331 // if we have no fields, we can trivially skip the rest
341332 if (st == jl_symbol_type || st == jl_string_type ) {
342333 // opaque layout - heap-allocated blob
343- static const jl_datatype_layout_t opaque_byte_layout = {0 , 1 , 0 , 1 , 0 };
334+ static const jl_datatype_layout_t opaque_byte_layout = {0 , 1 , 1 , 0 , 0 };
344335 st -> layout = & opaque_byte_layout ;
345336 return ;
346337 }
347338 else if (st == jl_simplevector_type || st -> name == jl_array_typename ) {
348- static const jl_datatype_layout_t opaque_ptr_layout = {0 , sizeof (void * ), 0 , 1 , 0 };
339+ static const jl_datatype_layout_t opaque_ptr_layout = {0 , 1 , sizeof (void * ), 0 , 0 };
349340 st -> layout = & opaque_ptr_layout ;
350341 return ;
351342 }
352343 else {
353344 // reuse the same layout for all singletons
354- static const jl_datatype_layout_t singleton_layout = {0 , 1 , 0 , 0 , 0 };
345+ static const jl_datatype_layout_t singleton_layout = {0 , 0 , 1 , 0 , 0 };
355346 st -> layout = & singleton_layout ;
356347 }
357348 }
@@ -396,6 +387,7 @@ void jl_compute_field_offsets(jl_datatype_t *st)
396387 if (st -> layout == NULL ) {
397388 size_t descsz = nfields * sizeof (jl_fielddesc32_t );
398389 jl_fielddesc32_t * desc ;
390+ uint32_t * pointers ;
399391 int should_malloc = descsz >= jl_page_size ;
400392 if (should_malloc )
401393 desc = (jl_fielddesc32_t * )malloc_s (descsz );
@@ -406,6 +398,7 @@ void jl_compute_field_offsets(jl_datatype_t *st)
406398 int zeroinit = 0 ;
407399 int haspadding = 0 ;
408400 int homogeneous = 1 ;
401+ uint32_t npointers = 0 ;
409402 jl_value_t * firstty = jl_field_type (st , 0 );
410403 for (i = 0 ; i < nfields ; i ++ ) {
411404 jl_value_t * fld = jl_field_type (st , i );
@@ -434,6 +427,7 @@ void jl_compute_field_offsets(jl_datatype_t *st)
434427 al = fsz ;
435428 desc [i ].isptr = 1 ;
436429 zeroinit = 1 ;
430+ npointers ++ ;
437431 }
438432 assert (al <= JL_HEAP_ALIGNMENT && (JL_HEAP_ALIGNMENT % al ) == 0 );
439433 if (al != 0 ) {
@@ -464,9 +458,22 @@ void jl_compute_field_offsets(jl_datatype_t *st)
464458 st -> size = LLT_ALIGN (sz , alignm );
465459 if (st -> size > sz )
466460 haspadding = 1 ;
467- st -> layout = jl_get_layout (nfields , alignm , haspadding , desc );
468- if (should_malloc )
461+ if (should_malloc && npointers )
462+ pointers = (uint32_t * )malloc_s (npointers * sizeof (uint32_t ));
463+ else
464+ pointers = (uint32_t * )alloca (npointers * sizeof (uint32_t ));
465+ size_t ptr_i = 0 ;
466+ for (i = 0 ; i < nfields ; i ++ ) {
467+ if (desc [i ].isptr )
468+ pointers [ptr_i ++ ] = desc [i ].offset / sizeof (jl_value_t * * );
469+ }
470+ assert (ptr_i == npointers );
471+ st -> layout = jl_get_layout (nfields , npointers , alignm , haspadding , desc , pointers );
472+ if (should_malloc ) {
469473 free (desc );
474+ if (npointers )
475+ free (pointers );
476+ }
470477 }
471478 // now finish deciding if this instantiation qualifies for special properties
472479 assert (!isbitstype || st -> layout -> npointers == 0 ); // the definition of isbits
@@ -577,7 +584,7 @@ JL_DLLEXPORT jl_datatype_t *jl_new_primitivetype(jl_value_t *name, jl_module_t *
577584 alignm = MAX_ALIGN ;
578585 bt -> isbitstype = bt -> isinlinealloc = (parameters == jl_emptysvec );
579586 bt -> size = nbytes ;
580- bt -> layout = jl_get_layout (0 , alignm , 0 , NULL );
587+ bt -> layout = jl_get_layout (0 , 0 , alignm , 0 , NULL , NULL );
581588 bt -> instance = NULL ;
582589 return bt ;
583590}
0 commit comments