@@ -337,7 +337,7 @@ static FORCE_INLINE void stackChangeFrameRefCnt(Fiber *fiber, HeapPages *pages,
337
337
}
338
338
339
339
340
- static FORCE_INLINE void * chunkAlloc (HeapPages * pages , int64_t size , Type * type , ExternFunc onFree , Error * error )
340
+ static FORCE_INLINE void * chunkAlloc (HeapPages * pages , int64_t size , Type * type , ExternFunc onFree , bool isStack , Error * error )
341
341
{
342
342
// Page layout: header, data, footer (char), padding, header, data, footer (char), padding...
343
343
int64_t chunkSize = align (sizeof (HeapChunkHeader ) + align (size + 1 , sizeof (int64_t )), VM_MIN_HEAP_CHUNK );
@@ -365,6 +365,7 @@ static FORCE_INLINE void *chunkAlloc(HeapPages *pages, int64_t size, Type *type,
365
365
chunk -> type = type ;
366
366
chunk -> onFree = onFree ;
367
367
chunk -> ip = pages -> fiber -> ip ;
368
+ chunk -> isStack = isStack ;
368
369
369
370
page -> numOccupiedChunks ++ ;
370
371
page -> refCnt ++ ;
@@ -538,7 +539,7 @@ void vmInit(VM *vm, int stackSize, bool fileSystemEnabled, Error *error)
538
539
539
540
pageInit (& vm -> pages , vm -> fiber , & vm -> strLenCache , error );
540
541
541
- vm -> fiber -> stack = chunkAlloc (& vm -> pages , stackSize * sizeof (Slot ), NULL , NULL , error );
542
+ vm -> fiber -> stack = chunkAlloc (& vm -> pages , stackSize * sizeof (Slot ), NULL , NULL , true, error );
542
543
vm -> fiber -> stackSize = stackSize ;
543
544
544
545
candidateInit (& vm -> refCntChangeCandidates );
@@ -910,7 +911,7 @@ static FORCE_INLINE void doAllocDynArray(HeapPages *pages, DynArray *array, Type
910
911
911
912
DynArrayDimensions dims = {.len = len , .capacity = 2 * (len + 1 )};
912
913
913
- char * dimsAndData = chunkAlloc (pages , sizeof (DynArrayDimensions ) + dims .capacity * array -> itemSize , array -> type , NULL , error );
914
+ char * dimsAndData = chunkAlloc (pages , sizeof (DynArrayDimensions ) + dims .capacity * array -> itemSize , array -> type , NULL , false, error );
914
915
* (DynArrayDimensions * )dimsAndData = dims ;
915
916
916
917
array -> data = dimsAndData + sizeof (DynArrayDimensions );
@@ -930,7 +931,7 @@ static FORCE_INLINE void doGetEmptyDynArray(DynArray *array, Type *type)
930
931
static FORCE_INLINE void doAllocMap (HeapPages * pages , Map * map , Type * type , Error * error )
931
932
{
932
933
map -> type = type ;
933
- map -> root = chunkAlloc (pages , typeSizeNoCheck (type -> base ), type -> base , NULL , error );
934
+ map -> root = chunkAlloc (pages , typeSizeNoCheck (type -> base ), type -> base , NULL , false, error );
934
935
map -> root -> len = 0 ;
935
936
}
936
937
@@ -1013,7 +1014,7 @@ static FORCE_INLINE MapNode *doGetMapNode(Map *map, Slot key, bool createMissing
1013
1014
return NULL ;
1014
1015
1015
1016
Type * nodeType = map -> type -> base ;
1016
- * child = (MapNode * )chunkAlloc (pages , typeSizeNoCheck (nodeType ), nodeType , NULL , error );
1017
+ * child = (MapNode * )chunkAlloc (pages , typeSizeNoCheck (nodeType ), nodeType , NULL , false, error );
1017
1018
}
1018
1019
1019
1020
if (nodePtrInParent )
@@ -1032,7 +1033,7 @@ static MapNode *doCopyMapNode(Map *map, MapNode *node, Fiber *fiber, HeapPages *
1032
1033
return NULL ;
1033
1034
1034
1035
Type * nodeType = map -> type -> base ;
1035
- MapNode * result = (MapNode * )chunkAlloc (pages , typeSizeNoCheck (nodeType ), nodeType , NULL , error );
1036
+ MapNode * result = (MapNode * )chunkAlloc (pages , typeSizeNoCheck (nodeType ), nodeType , NULL , false, error );
1036
1037
1037
1038
result -> len = node -> len ;
1038
1039
@@ -1045,7 +1046,7 @@ static MapNode *doCopyMapNode(Map *map, MapNode *node, Fiber *fiber, HeapPages *
1045
1046
doBasicDeref (& srcKey , keyType -> kind , error );
1046
1047
1047
1048
// When allocating dynamic arrays, we mark with type the data chunk, not the header chunk
1048
- result -> key = chunkAlloc (pages , typeSizeNoCheck (keyType ), keyType -> kind == TYPE_DYNARRAY ? NULL : keyType , NULL , error );
1049
+ result -> key = chunkAlloc (pages , typeSizeNoCheck (keyType ), keyType -> kind == TYPE_DYNARRAY ? NULL : keyType , NULL , false, error );
1049
1050
1050
1051
if (typeGarbageCollected (keyType ))
1051
1052
doBasicChangeRefCnt (fiber , pages , srcKey .ptrVal , keyType , TOK_PLUSPLUS );
@@ -1062,7 +1063,7 @@ static MapNode *doCopyMapNode(Map *map, MapNode *node, Fiber *fiber, HeapPages *
1062
1063
doBasicDeref (& srcItem , itemType -> kind , error );
1063
1064
1064
1065
// When allocating dynamic arrays, we mark with type the data chunk, not the header chunk
1065
- result -> data = chunkAlloc (pages , typeSizeNoCheck (itemType ), itemType -> kind == TYPE_DYNARRAY ? NULL : itemType , NULL , error );
1066
+ result -> data = chunkAlloc (pages , typeSizeNoCheck (itemType ), itemType -> kind == TYPE_DYNARRAY ? NULL : itemType , NULL , false, error );
1066
1067
1067
1068
if (typeGarbageCollected (itemType ))
1068
1069
doBasicChangeRefCnt (fiber , pages , srcItem .ptrVal , itemType , TOK_PLUSPLUS );
@@ -1473,7 +1474,7 @@ static FORCE_INLINE void doBuiltinPrintf(Fiber *fiber, HeapPages *pages, bool co
1473
1474
1474
1475
if (needRealloc )
1475
1476
{
1476
- char * newStream = chunkAlloc (pages , 2 * (prevLen + len ) + 1 , NULL , NULL , error );
1477
+ char * newStream = chunkAlloc (pages , 2 * (prevLen + len ) + 1 , NULL , NULL , false, error );
1477
1478
if (stream )
1478
1479
memcpy (newStream , stream , prevLen );
1479
1480
newStream [prevLen ] = 0 ;
@@ -1550,7 +1551,7 @@ static FORCE_INLINE void doBuiltinScanf(Fiber *fiber, HeapPages *pages, bool con
1550
1551
doBasicChangeRefCnt (fiber , pages , * dest , & destType , TOK_MINUSMINUS );
1551
1552
1552
1553
// Allocate new string
1553
- * dest = chunkAlloc (pages , strlen (src ) + 1 , NULL , NULL , error );
1554
+ * dest = chunkAlloc (pages , strlen (src ) + 1 , NULL , NULL , false, error );
1554
1555
strcpy (* dest , src );
1555
1556
free (src );
1556
1557
@@ -1580,7 +1581,7 @@ static FORCE_INLINE void doBuiltinNew(Fiber *fiber, HeapPages *pages, Error *err
1580
1581
if (type && type -> kind == TYPE_DYNARRAY )
1581
1582
type = NULL ;
1582
1583
1583
- void * result = chunkAlloc (pages , size , type , NULL , error );
1584
+ void * result = chunkAlloc (pages , size , type , NULL , false, error );
1584
1585
1585
1586
(-- fiber -> top )-> ptrVal = result ;
1586
1587
}
@@ -1676,7 +1677,7 @@ static FORCE_INLINE void doBuiltinMaketostr(Fiber *fiber, HeapPages *pages, Erro
1676
1677
1677
1678
if (src -> data )
1678
1679
{
1679
- dest = chunkAlloc (pages , getDims (src )-> len + 1 , NULL , NULL , error );
1680
+ dest = chunkAlloc (pages , getDims (src )-> len + 1 , NULL , NULL , false, error );
1680
1681
memcpy (dest , src -> data , getDims (src )-> len );
1681
1682
dest [getDims (src )-> len ] = 0 ;
1682
1683
}
@@ -1984,7 +1985,7 @@ static FORCE_INLINE void doBuiltinSlice(Fiber *fiber, HeapPages *pages, Error *e
1984
1985
else
1985
1986
{
1986
1987
// String
1987
- char * substr = chunkAlloc (pages , endIndex - startIndex + 1 , NULL , NULL , error );
1988
+ char * substr = chunkAlloc (pages , endIndex - startIndex + 1 , NULL , NULL , false, error );
1988
1989
memcpy (substr , & str [startIndex ], endIndex - startIndex );
1989
1990
substr [endIndex - startIndex ] = 0 ;
1990
1991
@@ -2174,10 +2175,10 @@ static FORCE_INLINE void doBuiltinFiberspawn(Fiber *fiber, HeapPages *pages, Err
2174
2175
int childEntryOffset = (fiber -> top ++ )-> intVal ;
2175
2176
2176
2177
// Copy whole fiber context
2177
- Fiber * child = chunkAlloc (pages , sizeof (Fiber ), NULL , NULL , error );
2178
+ Fiber * child = chunkAlloc (pages , sizeof (Fiber ), NULL , NULL , false, error );
2178
2179
2179
2180
* child = * fiber ;
2180
- child -> stack = chunkAlloc (pages , child -> stackSize * sizeof (Slot ), NULL , NULL , error );
2181
+ child -> stack = chunkAlloc (pages , child -> stackSize * sizeof (Slot ), NULL , NULL , true, error );
2181
2182
child -> top = child -> base = child -> stack + child -> stackSize - 1 ;
2182
2183
2183
2184
// Call child fiber function
@@ -2220,7 +2221,7 @@ static FORCE_INLINE void doBuiltinRepr(Fiber *fiber, HeapPages *pages, Error *er
2220
2221
enum {MAX_REPR_DEPTH = 20 };
2221
2222
2222
2223
int len = doFillReprBuf (val , type , NULL , 0 , MAX_REPR_DEPTH , fiber -> strLenCache , error ); // Predict buffer length
2223
- char * buf = chunkAlloc (pages , len + 1 , NULL , NULL , error ); // Allocate buffer
2224
+ char * buf = chunkAlloc (pages , len + 1 , NULL , NULL , false, error ); // Allocate buffer
2224
2225
doFillReprBuf (val , type , buf , INT_MAX , MAX_REPR_DEPTH , fiber -> strLenCache , error ); // Fill buffer
2225
2226
2226
2227
fiber -> top -> ptrVal = buf ;
@@ -2488,7 +2489,7 @@ static FORCE_INLINE void doBinary(Fiber *fiber, HeapPages *pages, Error *error)
2488
2489
}
2489
2490
else
2490
2491
{
2491
- buf = chunkAlloc (pages , 2 * (lhsLen + rhsLen ) + 1 , NULL , NULL , error );
2492
+ buf = chunkAlloc (pages , 2 * (lhsLen + rhsLen ) + 1 , NULL , NULL , false, error );
2492
2493
memmove (buf , lhsStr , lhsLen );
2493
2494
}
2494
2495
@@ -2707,8 +2708,8 @@ static FORCE_INLINE void doGetMapPtr(Fiber *fiber, HeapPages *pages, Error *erro
2707
2708
if (!node -> data )
2708
2709
{
2709
2710
// When allocating dynamic arrays, we mark with type the data chunk, not the header chunk
2710
- node -> key = chunkAlloc (pages , typeSizeNoCheck (keyType ), keyType -> kind == TYPE_DYNARRAY ? NULL : keyType , NULL , error );
2711
- node -> data = chunkAlloc (pages , typeSizeNoCheck (itemType ), itemType -> kind == TYPE_DYNARRAY ? NULL : itemType , NULL , error );
2711
+ node -> key = chunkAlloc (pages , typeSizeNoCheck (keyType ), keyType -> kind == TYPE_DYNARRAY ? NULL : keyType , NULL , false, error );
2712
+ node -> data = chunkAlloc (pages , typeSizeNoCheck (itemType ), itemType -> kind == TYPE_DYNARRAY ? NULL : itemType , NULL , false, error );
2712
2713
2713
2714
// Increase key ref count
2714
2715
if (typeGarbageCollected (keyType ))
@@ -2772,11 +2773,15 @@ static FORCE_INLINE void doWeakenPtr(Fiber *fiber, HeapPages *pages)
2772
2773
uint64_t weakPtr = 0 ;
2773
2774
2774
2775
HeapPage * page = pageFind (pages , ptr , false);
2775
- if (page && pageGetChunkHeader ( page , ptr ) -> refCnt > 0 )
2776
+ if (page )
2776
2777
{
2777
- int pageId = page -> id ;
2778
- int pageOffset = (char * )ptr - (char * )page -> ptr ;
2779
- weakPtr = ((uint64_t )pageId << 32 ) | pageOffset ;
2778
+ HeapChunkHeader * chunk = pageGetChunkHeader (page , ptr );
2779
+ if (chunk -> refCnt > 0 && !chunk -> isStack )
2780
+ {
2781
+ int pageId = page -> id ;
2782
+ int pageOffset = (char * )ptr - (char * )page -> ptr ;
2783
+ weakPtr = ((uint64_t )pageId << 32 ) | pageOffset ;
2784
+ }
2780
2785
}
2781
2786
2782
2787
fiber -> top -> weakPtrVal = weakPtr ;
@@ -2796,7 +2801,8 @@ static FORCE_INLINE void doStrengthenPtr(Fiber *fiber, HeapPages *pages)
2796
2801
int pageOffset = weakPtr & 0x7FFFFFFF ;
2797
2802
ptr = (char * )page -> ptr + pageOffset ;
2798
2803
2799
- if (pageGetChunkHeader (page , ptr )-> refCnt == 0 )
2804
+ HeapChunkHeader * chunk = pageGetChunkHeader (page , ptr );
2805
+ if (chunk -> refCnt == 0 || chunk -> isStack )
2800
2806
ptr = NULL ;
2801
2807
}
2802
2808
@@ -3224,7 +3230,7 @@ void vmSetHook(VM *vm, HookEvent event, HookFunc hook)
3224
3230
3225
3231
void * vmAllocData (VM * vm , int size , ExternFunc onFree )
3226
3232
{
3227
- return chunkAlloc (& vm -> pages , size , NULL , onFree , vm -> error );
3233
+ return chunkAlloc (& vm -> pages , size , NULL , onFree , false, vm -> error );
3228
3234
}
3229
3235
3230
3236
0 commit comments