@@ -5192,6 +5192,42 @@ namespace Js
51925192 }
51935193 }
51945194
5195+ template <typename T>
5196+ void JavascriptArray::CopyHeadIfInlinedHeadSegment (JavascriptArray *array, Recycler *recycler)
5197+ {
5198+ SparseArraySegmentBase* inlineHeadSegment = nullptr ;
5199+ bool hasInlineSegment = false ;
5200+
5201+ if (JavascriptNativeArray::Is (array))
5202+ {
5203+ if (JavascriptNativeFloatArray::Is (array))
5204+ {
5205+ inlineHeadSegment = DetermineInlineHeadSegmentPointer<JavascriptNativeFloatArray, 0 , true >((JavascriptNativeFloatArray*)array);
5206+ }
5207+ else if (JavascriptNativeIntArray::Is (array))
5208+ {
5209+ inlineHeadSegment = DetermineInlineHeadSegmentPointer<JavascriptNativeIntArray, 0 , true >((JavascriptNativeIntArray*)array);
5210+ }
5211+ Assert (inlineHeadSegment);
5212+ hasInlineSegment = (array->head == (SparseArraySegment<T>*)inlineHeadSegment);
5213+ }
5214+ else
5215+ {
5216+ hasInlineSegment = HasInlineHeadSegment (array->head ->length );
5217+ }
5218+
5219+ if (hasInlineSegment)
5220+ {
5221+ SparseArraySegment<T>* headSeg = (SparseArraySegment<T>*)array->head ;
5222+
5223+ SparseArraySegment<T>* newHeadSeg = SparseArraySegment<T>::template AllocateSegmentImpl<false >(recycler,
5224+ headSeg->left , headSeg->length , headSeg->size , headSeg->next );
5225+
5226+ newHeadSeg = SparseArraySegment<T>::CopySegment (recycler, newHeadSeg, headSeg->left , headSeg, headSeg->left , headSeg->length );
5227+ newHeadSeg->next = headSeg->next ;
5228+ array->head = newHeadSeg;
5229+ }
5230+ }
51955231
51965232 Var JavascriptArray::EntryReverse (RecyclableObject* function, CallInfo callInfo, ...)
51975233 {
@@ -5289,7 +5325,6 @@ namespace Js
52895325 // Note : since we are reversing the whole segment below - the functionality is not spec compliant already.
52905326 length = pArr->length ;
52915327
5292- SparseArraySegmentBase* seg = pArr->head ;
52935328 SparseArraySegmentBase *prevSeg = nullptr ;
52945329 SparseArraySegmentBase *nextSeg = nullptr ;
52955330 SparseArraySegmentBase *pinPrevSeg = nullptr ;
@@ -5306,6 +5341,27 @@ namespace Js
53065341 isFloatArray = true ;
53075342 }
53085343
5344+ // During the loop below we are going to reverse the segments list. The head segment will become the last segment.
5345+ // We have to verify that the current head segment is not the inilined segement, otherwise due to shuffling below, the inlined segment will no longer
5346+ // be the head and that can create issue down the line. Create new segment if it is an inilined segment.
5347+ if (pArr->head && pArr->head ->next )
5348+ {
5349+ if (isIntArray)
5350+ {
5351+ CopyHeadIfInlinedHeadSegment<int32>(pArr, recycler);
5352+ }
5353+ else if (isFloatArray)
5354+ {
5355+ CopyHeadIfInlinedHeadSegment<double >(pArr, recycler);
5356+ }
5357+ else
5358+ {
5359+ CopyHeadIfInlinedHeadSegment<Var>(pArr, recycler);
5360+ }
5361+ }
5362+
5363+ SparseArraySegmentBase* seg = pArr->head ;
5364+
53095365 while (seg)
53105366 {
53115367 nextSeg = seg->next ;
0 commit comments