@@ -1921,8 +1921,21 @@ namespace Js
1921
1921
// And/or the old segment is not scanned by the recycler, so we need a new one to hold vars.
1922
1922
SparseArraySegment<Var> *newSeg =
1923
1923
SparseArraySegment<Var>::AllocateSegment (recycler, left, length, nextSeg);
1924
-
1925
1924
AnalysisAssert (newSeg);
1925
+
1926
+ // Fill the new segment with the overflow.
1927
+ for (i = 0 ; (uint)i < newSeg->length ; i++)
1928
+ {
1929
+ ival = ((SparseArraySegment<int32>*)seg)->elements [i];
1930
+ if (ival == JavascriptNativeIntArray::MissingItem)
1931
+ {
1932
+ continue ;
1933
+ }
1934
+ newSeg->elements [i] = JavascriptNumber::ToVar (ival, scriptContext);
1935
+ }
1936
+
1937
+ // seg elements are copied over, now it is safe to replace seg with newSeg.
1938
+ // seg could be GC collected if replaced by newSeg.
1926
1939
Assert ((prevSeg == nullptr ) == (seg == intArray->head ));
1927
1940
newSeg->next = nextSeg;
1928
1941
intArray->LinkSegments ((SparseArraySegment<Var>*)prevSeg, newSeg);
@@ -1937,17 +1950,6 @@ namespace Js
1937
1950
{
1938
1951
segmentMap->SwapSegment (left, seg, newSeg);
1939
1952
}
1940
-
1941
- // Fill the new segment with the overflow.
1942
- for (i = 0 ; (uint)i < newSeg->length ; i++)
1943
- {
1944
- ival = ((SparseArraySegment<int32>*)seg)->elements [i];
1945
- if (ival == JavascriptNativeIntArray::MissingItem)
1946
- {
1947
- continue ;
1948
- }
1949
- newSeg->elements [i] = JavascriptNumber::ToVar (ival, scriptContext);
1950
- }
1951
1953
}
1952
1954
else
1953
1955
{
@@ -2097,26 +2099,12 @@ namespace Js
2097
2099
}
2098
2100
uint32 left = seg->left ;
2099
2101
uint32 length = seg->length ;
2100
- SparseArraySegment<Var> *newSeg;
2102
+ SparseArraySegment<Var> *newSeg = nullptr ;
2101
2103
if (seg->next == nullptr && SparseArraySegmentBase::IsLeafSegment (seg, recycler))
2102
2104
{
2103
2105
// The old segment is not scanned by the recycler, so we need a new one to hold vars.
2104
2106
newSeg =
2105
2107
SparseArraySegment<Var>::AllocateSegment (recycler, left, length, nextSeg);
2106
- Assert ((prevSeg == nullptr ) == (seg == fArray ->head ));
2107
- newSeg->next = nextSeg;
2108
- fArray ->LinkSegments ((SparseArraySegment<Var>*)prevSeg, newSeg);
2109
- if (fArray ->GetLastUsedSegment () == seg)
2110
- {
2111
- fArray ->SetLastUsedSegment (newSeg);
2112
- }
2113
- prevSeg = newSeg;
2114
-
2115
- SegmentBTree * segmentMap = fArray ->GetSegmentMap ();
2116
- if (segmentMap)
2117
- {
2118
- segmentMap->SwapSegment (left, seg, newSeg);
2119
- }
2120
2108
}
2121
2109
else
2122
2110
{
@@ -2172,6 +2160,26 @@ namespace Js
2172
2160
// Fill the remaining slots.
2173
2161
newSeg->FillSegmentBuffer (i, seg->size );
2174
2162
}
2163
+
2164
+ // seg elements are copied over, now it is safe to replace seg with newSeg.
2165
+ // seg could be GC collected if replaced by newSeg.
2166
+ if (newSeg != seg)
2167
+ {
2168
+ Assert ((prevSeg == nullptr ) == (seg == fArray ->head ));
2169
+ newSeg->next = nextSeg;
2170
+ fArray ->LinkSegments ((SparseArraySegment<Var>*)prevSeg, newSeg);
2171
+ if (fArray ->GetLastUsedSegment () == seg)
2172
+ {
2173
+ fArray ->SetLastUsedSegment (newSeg);
2174
+ }
2175
+ prevSeg = newSeg;
2176
+
2177
+ SegmentBTree * segmentMap = fArray ->GetSegmentMap ();
2178
+ if (segmentMap)
2179
+ {
2180
+ segmentMap->SwapSegment (left, seg, newSeg);
2181
+ }
2182
+ }
2175
2183
}
2176
2184
2177
2185
if (fArray ->GetType () == scriptContext->GetLibrary ()->GetNativeFloatArrayType ())
@@ -3140,7 +3148,7 @@ namespace Js
3140
3148
JS_REENTRANT_NO_MUTATE (jsReentLock, CopyNativeIntArrayElementsToVar (pDestArray, BigIndex (idxDest).GetSmallIndex (), pIntItemArray));
3141
3149
idxDest = idxDest + pIntItemArray->length ;
3142
3150
}
3143
- else
3151
+ else
3144
3152
{
3145
3153
JavascriptNativeFloatArray *pFloatItemArray = JavascriptOperators::TryFromVar<JavascriptNativeFloatArray>(aItem);
3146
3154
if (pFloatItemArray)
@@ -3390,7 +3398,7 @@ namespace Js
3390
3398
3391
3399
idxDest = idxDest + pIntItemArray->length ;
3392
3400
}
3393
- else
3401
+ else
3394
3402
{
3395
3403
JavascriptNativeFloatArray * pFloatItemArray = JavascriptOperators::TryFromVar<JavascriptNativeFloatArray>(aItem);
3396
3404
if (pFloatItemArray && !isFillFromPrototypes)
@@ -5384,7 +5392,7 @@ namespace Js
5384
5392
{
5385
5393
RecyclableObject* protoObj = prototype;
5386
5394
5387
- if (!(DynamicObject::IsAnyArray (protoObj) || JavascriptOperators::IsObject (protoObj))
5395
+ if (!(DynamicObject::IsAnyArray (protoObj) || JavascriptOperators::IsObject (protoObj))
5388
5396
|| JavascriptProxy::Is (protoObj)
5389
5397
|| protoObj->IsExternal ())
5390
5398
{
@@ -6099,7 +6107,7 @@ namespace Js
6099
6107
*isIntArray = true ;
6100
6108
#endif
6101
6109
}
6102
- else
6110
+ else
6103
6111
{
6104
6112
JavascriptNativeFloatArray* nativeFloatArray = JavascriptOperators::TryFromVar<JavascriptNativeFloatArray>(this );
6105
6113
if (nativeFloatArray)
0 commit comments