@@ -27,12 +27,6 @@ char *jl_array_typetagdata(jl_array_t *a) JL_NOTSAFEPOINT
27
27
return ((char * )jl_array_data (a )) + ((jl_array_ndims (a ) == 1 ? (a -> maxsize - a -> offset ) : jl_array_len (a )) * a -> elsize ) + a -> offset ;
28
28
}
29
29
30
- JL_DLLEXPORT int jl_array_store_unboxed (jl_value_t * eltype ) JL_NOTSAFEPOINT
31
- {
32
- size_t fsz = 0 , al = 0 ;
33
- return jl_islayout_inline (eltype , & fsz , & al );
34
- }
35
-
36
30
STATIC_INLINE jl_value_t * jl_array_owner (jl_array_t * a JL_PROPAGATES_ROOT ) JL_NOTSAFEPOINT
37
31
{
38
32
if (a -> flags .how == 3 ) {
@@ -53,7 +47,7 @@ size_t jl_arr_xtralloc_limit = 0;
53
47
#define MAXINTVAL (((size_t)-1)>>1)
54
48
55
49
static jl_array_t * _new_array_ (jl_value_t * atype , uint32_t ndims , size_t * dims ,
56
- int isunboxed , int isunion , int elsz )
50
+ int isunboxed , int hasptr , int isunion , int elsz )
57
51
{
58
52
jl_ptls_t ptls = jl_get_ptls_states ();
59
53
size_t i , tot , nel = 1 ;
@@ -101,7 +95,7 @@ static jl_array_t *_new_array_(jl_value_t *atype, uint32_t ndims, size_t *dims,
101
95
// No allocation or safepoint allowed after this
102
96
a -> flags .how = 0 ;
103
97
data = (char * )a + doffs ;
104
- if (( tot > 0 && !isunboxed ) || isunion )
98
+ if (tot > 0 && ( !isunboxed || hasptr || isunion )) // TODO: check for zeroinit
105
99
memset (data , 0 , tot );
106
100
}
107
101
else {
@@ -113,7 +107,7 @@ static jl_array_t *_new_array_(jl_value_t *atype, uint32_t ndims, size_t *dims,
113
107
// No allocation or safepoint allowed after this
114
108
a -> flags .how = 2 ;
115
109
jl_gc_track_malloced_array (ptls , a );
116
- if (!isunboxed || isunion )
110
+ if (tot > 0 && ( !isunboxed || hasptr || isunion )) // TODO: check for zeroinit
117
111
// need to zero out isbits union array selector bytes to ensure a valid type index
118
112
memset (data , 0 , tot );
119
113
}
@@ -127,6 +121,7 @@ static jl_array_t *_new_array_(jl_value_t *atype, uint32_t ndims, size_t *dims,
127
121
#endif
128
122
a -> flags .ndims = ndims ;
129
123
a -> flags .ptrarray = !isunboxed ;
124
+ a -> flags .hasptr = hasptr ;
130
125
a -> elsize = elsz ;
131
126
a -> flags .isshared = 0 ;
132
127
a -> flags .isaligned = 1 ;
@@ -135,9 +130,12 @@ static jl_array_t *_new_array_(jl_value_t *atype, uint32_t ndims, size_t *dims,
135
130
a -> nrows = nel ;
136
131
a -> maxsize = nel ;
137
132
}
133
+ else if (a -> flags .ndims != ndims ) {
134
+ jl_exceptionf (jl_argumenterror_type , "invalid Array dimensions" );
135
+ }
138
136
else {
139
137
size_t * adims = & a -> nrows ;
140
- for ( i = 0 ; i < ndims ; i ++ )
138
+ for ( i = 0 ; i < ndims ; i ++ )
141
139
adims [i ] = dims [i ];
142
140
}
143
141
@@ -152,6 +150,7 @@ static inline jl_array_t *_new_array(jl_value_t *atype, uint32_t ndims, size_t *
152
150
jl_type_error_rt ("Array" , "element type" , (jl_value_t * )jl_type_type , eltype );
153
151
int isunboxed = jl_islayout_inline (eltype , & elsz , & al );
154
152
int isunion = jl_is_uniontype (eltype );
153
+ int hasptr = isunboxed && (jl_is_datatype (eltype ) && ((jl_datatype_t * )eltype )-> layout -> npointers > 0 );
155
154
if (!isunboxed ) {
156
155
elsz = sizeof (void * );
157
156
al = elsz ;
@@ -160,13 +159,13 @@ static inline jl_array_t *_new_array(jl_value_t *atype, uint32_t ndims, size_t *
160
159
elsz = LLT_ALIGN (elsz , al );
161
160
}
162
161
163
- return _new_array_ (atype , ndims , dims , isunboxed , isunion , elsz );
162
+ return _new_array_ (atype , ndims , dims , isunboxed , hasptr , isunion , elsz );
164
163
}
165
164
166
165
jl_array_t * jl_new_array_for_deserialization (jl_value_t * atype , uint32_t ndims , size_t * dims ,
167
- int isunboxed , int isunion , int elsz )
166
+ int isunboxed , int hasptr , int isunion , int elsz )
168
167
{
169
- return _new_array_ (atype , ndims , dims , isunboxed , isunion , elsz );
168
+ return _new_array_ (atype , ndims , dims , isunboxed , hasptr , isunion , elsz );
170
169
}
171
170
172
171
#ifndef JL_NDEBUG
@@ -224,10 +223,12 @@ JL_DLLEXPORT jl_array_t *jl_reshape_array(jl_value_t *atype, jl_array_t *data,
224
223
"reinterpret from alignment %d bytes to alignment %d bytes not allowed" ,
225
224
(int ) oldalign , (int ) align );
226
225
a -> flags .ptrarray = 0 ;
226
+ a -> flags .hasptr = data -> flags .hasptr ;
227
227
}
228
228
else {
229
229
a -> elsize = sizeof (void * );
230
230
a -> flags .ptrarray = 1 ;
231
+ a -> flags .hasptr = 0 ;
231
232
}
232
233
233
234
// if data is itself a shared wrapper,
@@ -247,6 +248,9 @@ JL_DLLEXPORT jl_array_t *jl_reshape_array(jl_value_t *atype, jl_array_t *data,
247
248
a -> nrows = l ;
248
249
a -> maxsize = l ;
249
250
}
251
+ else if (a -> flags .ndims != ndims ) {
252
+ jl_exceptionf (jl_argumenterror_type , "invalid Array dimensions" );
253
+ }
250
254
else {
251
255
size_t * adims = & a -> nrows ;
252
256
size_t l = 1 ;
@@ -281,6 +285,7 @@ JL_DLLEXPORT jl_array_t *jl_string_to_array(jl_value_t *str)
281
285
a -> flags .isaligned = 0 ;
282
286
a -> elsize = 1 ;
283
287
a -> flags .ptrarray = 0 ;
288
+ a -> flags .hasptr = 0 ;
284
289
jl_array_data_owner (a ) = str ;
285
290
a -> flags .how = 3 ;
286
291
a -> flags .isshared = 1 ;
@@ -300,12 +305,12 @@ JL_DLLEXPORT jl_array_t *jl_ptr_to_array_1d(jl_value_t *atype, void *data,
300
305
jl_array_t * a ;
301
306
jl_value_t * eltype = jl_tparam0 (atype );
302
307
303
- int isunboxed = jl_array_store_unboxed (eltype );
304
- size_t elsz ;
305
- unsigned align ;
308
+ int isunboxed = jl_stored_inline (eltype );
306
309
if (isunboxed && jl_is_uniontype (eltype ))
307
310
jl_exceptionf (jl_argumenterror_type ,
308
311
"unsafe_wrap: unspecified layout for union element type" );
312
+ size_t elsz ;
313
+ unsigned align ;
309
314
if (isunboxed ) {
310
315
elsz = jl_datatype_size (eltype );
311
316
align = jl_datatype_align (eltype );
@@ -328,6 +333,7 @@ JL_DLLEXPORT jl_array_t *jl_ptr_to_array_1d(jl_value_t *atype, void *data,
328
333
#endif
329
334
a -> elsize = LLT_ALIGN (elsz , align );
330
335
a -> flags .ptrarray = !isunboxed ;
336
+ a -> flags .hasptr = isunboxed && (jl_is_datatype (eltype ) && ((jl_datatype_t * )eltype )-> layout -> npointers > 0 );
331
337
a -> flags .ndims = 1 ;
332
338
a -> flags .isshared = 1 ;
333
339
a -> flags .isaligned = 0 ; // TODO: allow passing memalign'd buffers
@@ -366,12 +372,12 @@ JL_DLLEXPORT jl_array_t *jl_ptr_to_array(jl_value_t *atype, void *data,
366
372
return jl_ptr_to_array_1d (atype , data , nel , own_buffer );
367
373
jl_value_t * eltype = jl_tparam0 (atype );
368
374
369
- int isunboxed = jl_array_store_unboxed (eltype );
370
- size_t elsz ;
371
- unsigned align ;
375
+ int isunboxed = jl_stored_inline (eltype );
372
376
if (isunboxed && jl_is_uniontype (eltype ))
373
377
jl_exceptionf (jl_argumenterror_type ,
374
378
"unsafe_wrap: unspecified layout for union element type" );
379
+ size_t elsz ;
380
+ unsigned align ;
375
381
if (isunboxed ) {
376
382
elsz = jl_datatype_size (eltype );
377
383
align = jl_datatype_align (eltype );
@@ -394,6 +400,7 @@ JL_DLLEXPORT jl_array_t *jl_ptr_to_array(jl_value_t *atype, void *data,
394
400
#endif
395
401
a -> elsize = LLT_ALIGN (elsz , align );
396
402
a -> flags .ptrarray = !isunboxed ;
403
+ a -> flags .hasptr = isunboxed && (jl_is_datatype (eltype ) && ((jl_datatype_t * )eltype )-> layout -> npointers > 0 );
397
404
a -> flags .ndims = ndims ;
398
405
a -> offset = 0 ;
399
406
a -> flags .isshared = 1 ;
@@ -408,6 +415,8 @@ JL_DLLEXPORT jl_array_t *jl_ptr_to_array(jl_value_t *atype, void *data,
408
415
}
409
416
410
417
assert (ndims != 1 ); // handled above
418
+ if (a -> flags .ndims != ndims )
419
+ jl_exceptionf (jl_argumenterror_type , "invalid Array dimensions" );
411
420
memcpy (& a -> nrows , dims , ndims * sizeof (size_t ));
412
421
return a ;
413
422
}
@@ -559,8 +568,16 @@ JL_DLLEXPORT jl_value_t *jl_arrayref(jl_array_t *a, size_t i)
559
568
560
569
JL_DLLEXPORT int jl_array_isassigned (jl_array_t * a , size_t i )
561
570
{
562
- if (a -> flags .ptrarray )
571
+ if (a -> flags .ptrarray ) {
563
572
return ((jl_value_t * * )jl_array_data (a ))[i ] != NULL ;
573
+ }
574
+ else if (a -> flags .hasptr ) {
575
+ jl_datatype_t * eltype = (jl_datatype_t * )jl_tparam0 (jl_typeof (a ));
576
+ assert (eltype -> layout -> first_ptr >= 0 );
577
+ jl_value_t * * slot =
578
+ (jl_value_t * * )(& ((char * )a -> data )[i * a -> elsize ] + eltype -> layout -> first_ptr );
579
+ return * slot != NULL ;
580
+ }
564
581
return 1 ;
565
582
}
566
583
@@ -585,6 +602,8 @@ JL_DLLEXPORT void jl_arrayset(jl_array_t *a JL_ROOTING_ARGUMENT, jl_value_t *rhs
585
602
return ;
586
603
}
587
604
jl_assign_bits (& ((char * )a -> data )[i * a -> elsize ], rhs );
605
+ if (a -> flags .hasptr )
606
+ jl_gc_multi_wb (jl_array_owner (a ), rhs );
588
607
}
589
608
else {
590
609
((jl_value_t * * )a -> data )[i ] = rhs ;
@@ -598,6 +617,11 @@ JL_DLLEXPORT void jl_arrayunset(jl_array_t *a, size_t i)
598
617
jl_bounds_error_int ((jl_value_t * )a , i + 1 );
599
618
if (a -> flags .ptrarray )
600
619
((jl_value_t * * )a -> data )[i ] = NULL ;
620
+ else if (a -> flags .hasptr ) {
621
+ size_t elsize = a -> elsize ;
622
+ jl_assume (elsize >= sizeof (void * ) && elsize % sizeof (void * ) == 0 );
623
+ memset (& ((jl_value_t * * )a -> data )[i ], 0 , elsize );
624
+ }
601
625
}
602
626
603
627
// at this size and bigger, allocate resized array data with malloc directly
@@ -809,7 +833,7 @@ STATIC_INLINE void jl_array_grow_at_beg(jl_array_t *a, size_t idx, size_t inc,
809
833
#endif
810
834
a -> nrows = newnrows ;
811
835
a -> data = newdata ;
812
- if (a -> flags .ptrarray ) {
836
+ if (a -> flags .ptrarray || a -> flags . hasptr ) { // TODO: check for zeroinit
813
837
memset (newdata + idx * elsz , 0 , nbinc );
814
838
}
815
839
else if (isbitsunion ) {
@@ -890,7 +914,7 @@ STATIC_INLINE void jl_array_grow_at_end(jl_array_t *a, size_t idx,
890
914
a -> length = newnrows ;
891
915
#endif
892
916
a -> nrows = newnrows ;
893
- if (a -> flags .ptrarray ) {
917
+ if (a -> flags .ptrarray || a -> flags . hasptr ) { // TODO: check for zeroinit
894
918
memset (data + idx * elsz , 0 , inc * elsz );
895
919
}
896
920
}
@@ -1129,7 +1153,7 @@ JL_DLLEXPORT jl_array_t *jl_array_copy(jl_array_t *ary)
1129
1153
int isunion = jl_is_uniontype (jl_tparam0 (jl_typeof (ary )));
1130
1154
jl_array_t * new_ary = _new_array_ (jl_typeof (ary ), jl_array_ndims (ary ),
1131
1155
& ary -> nrows , !ary -> flags .ptrarray ,
1132
- isunion , elsz );
1156
+ ary -> flags . hasptr , isunion , elsz );
1133
1157
memcpy (new_ary -> data , ary -> data , len * elsz );
1134
1158
// ensure isbits union arrays copy their selector bytes correctly
1135
1159
if (jl_array_isbitsunion (ary ))
0 commit comments