@@ -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