@@ -239,8 +239,10 @@ static jl_datatype_layout_t *jl_get_layout(uint32_t sz,
239239 flddesc -> flags .haspadding = haspadding ;
240240 flddesc -> flags .isbitsegal = isbitsegal ;
241241 flddesc -> flags .fielddesc_type = fielddesc_type ;
242- flddesc -> flags .arrayelem_isboxed = arrayelem == 1 ;
243- flddesc -> flags .arrayelem_isunion = arrayelem == 2 ;
242+ flddesc -> flags .arrayelem_isboxed = (arrayelem & 1 ) != 0 ;
243+ flddesc -> flags .arrayelem_isunion = (arrayelem & 2 ) != 0 ;
244+ flddesc -> flags .arrayelem_isatomic = (arrayelem & 4 ) != 0 ;
245+ flddesc -> flags .arrayelem_islocked = (arrayelem & 8 ) != 0 ;
244246 flddesc -> flags .padding = 0 ;
245247 flddesc -> npointers = npointers ;
246248 flddesc -> first_ptr = first_ptr ;
@@ -537,6 +539,7 @@ void jl_get_genericmemory_layout(jl_datatype_t *st)
537539 uint32_t * pointers = & first_ptr ;
538540 int needlock = 0 ;
539541
542+ const jl_datatype_layout_t * el_layout = NULL ;
540543 if (isunboxed ) {
541544 elsz = LLT_ALIGN (elsz , al );
542545 if (kind == (jl_value_t * )jl_atomic_sym ) {
@@ -551,12 +554,12 @@ void jl_get_genericmemory_layout(jl_datatype_t *st)
551554 else {
552555 assert (jl_is_datatype (eltype ));
553556 zi = ((jl_datatype_t * )eltype )-> zeroinit ;
554- const jl_datatype_layout_t * layout = ((jl_datatype_t * )eltype )-> layout ;
555- if (layout -> first_ptr >= 0 ) {
556- first_ptr = layout -> first_ptr ;
557- npointers = layout -> npointers ;
558- if (layout -> flags .fielddesc_type == 2 ) {
559- pointers = (uint32_t * )jl_dt_layout_ptrs (layout );
557+ el_layout = ((jl_datatype_t * )eltype )-> layout ;
558+ if (el_layout -> first_ptr >= 0 ) {
559+ first_ptr = el_layout -> first_ptr ;
560+ npointers = el_layout -> npointers ;
561+ if (el_layout -> flags .fielddesc_type == 2 && ! needlock ) {
562+ pointers = (uint32_t * )jl_dt_layout_ptrs (el_layout );
560563 }
561564 else {
562565 pointers = (uint32_t * )alloca (npointers * sizeof (uint32_t ));
@@ -568,10 +571,22 @@ void jl_get_genericmemory_layout(jl_datatype_t *st)
568571 }
569572 if (needlock ) {
570573 assert (al <= JL_SMALL_BYTE_ALIGNMENT );
571- size_t offset = LLT_ALIGN (sizeof (jl_mutex_t ), JL_SMALL_BYTE_ALIGNMENT );
572- elsz += offset ;
574+ size_t lock_offset = LLT_ALIGN (sizeof (jl_mutex_t ), JL_SMALL_BYTE_ALIGNMENT );
575+ elsz += lock_offset ;
576+ if (al < sizeof (void * )) {
577+ al = sizeof (void * );
578+ elsz = LLT_ALIGN (elsz , al );
579+ }
573580 haspadding = 1 ;
574581 zi = 1 ;
582+ // Adjust pointer offsets to account for the lock at the beginning
583+ if (first_ptr != -1 ) {
584+ uint32_t lock_offset_words = lock_offset / sizeof (void * );
585+ first_ptr += lock_offset_words ;
586+ for (int j = 0 ; j < npointers ; j ++ ) {
587+ pointers [j ] += lock_offset_words ;
588+ }
589+ }
575590 }
576591 }
577592 else {
@@ -580,13 +595,17 @@ void jl_get_genericmemory_layout(jl_datatype_t *st)
580595 zi = 1 ;
581596 }
582597
583- int arrayelem ;
598+ // arrayelem is a bitfield: 1=isboxed, 2=isunion, 4=isatomic, 8=islocked
599+ int arrayelem = 0 ;
584600 if (!isunboxed )
585- arrayelem = 1 ;
586- else if (isunion )
587- arrayelem = 2 ;
588- else
589- arrayelem = 0 ;
601+ arrayelem |= 1 ; // arrayelem_isboxed
602+ if (isunion )
603+ arrayelem |= 2 ; // arrayelem_isunion
604+ if (kind == (jl_value_t * )jl_atomic_sym ) {
605+ arrayelem |= 4 ; // arrayelem_isatomic
606+ if (needlock )
607+ arrayelem |= 8 ; // arrayelem_islocked
608+ }
590609 assert (!st -> layout );
591610 st -> layout = jl_get_layout (elsz , nfields , npointers , al , haspadding , isbitsegal , arrayelem , NULL , pointers );
592611 st -> zeroinit = zi ;
@@ -647,17 +666,17 @@ void jl_compute_field_offsets(jl_datatype_t *st)
647666 // if we have no fields, we can trivially skip the rest
648667 if (st == jl_symbol_type || st == jl_string_type ) {
649668 // opaque layout - heap-allocated blob
650- static const jl_datatype_layout_t opaque_byte_layout = {0 , 0 , 1 , -1 , 1 , { .haspadding = 0 , . fielddesc_type = 0 , . isbitsegal = 1 , . arrayelem_isboxed = 0 , . arrayelem_isunion = 0 }};
669+ static const jl_datatype_layout_t opaque_byte_layout = {0 , 0 , 1 , -1 , 1 , { .isbitsegal = 1 }};
651670 st -> layout = & opaque_byte_layout ;
652671 return ;
653672 }
654673 else if (st == jl_simplevector_type || st == jl_module_type ) {
655- static const jl_datatype_layout_t opaque_ptr_layout = {0 , 0 , 1 , -1 , sizeof (void * ), { .haspadding = 0 , . fielddesc_type = 0 , . isbitsegal = 1 , . arrayelem_isboxed = 0 , . arrayelem_isunion = 0 }};
674+ static const jl_datatype_layout_t opaque_ptr_layout = {0 , 0 , 1 , -1 , sizeof (void * ), { .isbitsegal = 1 }};
656675 st -> layout = & opaque_ptr_layout ;
657676 return ;
658677 }
659678 else {
660- static const jl_datatype_layout_t singleton_layout = {0 , 0 , 0 , -1 , 1 , { .haspadding = 0 , . fielddesc_type = 0 , . isbitsegal = 1 , . arrayelem_isboxed = 0 , . arrayelem_isunion = 0 }};
679+ static const jl_datatype_layout_t singleton_layout = {0 , 0 , 0 , -1 , 1 , { .isbitsegal = 1 }};
661680 st -> layout = & singleton_layout ;
662681 }
663682 }
@@ -1001,6 +1020,8 @@ JL_DLLEXPORT jl_datatype_t * jl_new_foreign_type(jl_sym_t *name,
10011020 layout -> flags .padding = 0 ;
10021021 layout -> flags .arrayelem_isboxed = 0 ;
10031022 layout -> flags .arrayelem_isunion = 0 ;
1023+ layout -> flags .arrayelem_isatomic = 0 ;
1024+ layout -> flags .arrayelem_islocked = 0 ;
10041025 jl_fielddescdyn_t * desc =
10051026 (jl_fielddescdyn_t * ) ((char * )layout + sizeof (* layout ));
10061027 desc -> markfunc = markfunc ;
0 commit comments