Commit 0b2fa277 authored by Simon Zünd's avatar Simon Zünd Committed by Commit Bot

[cleanup] Remove usage of 'ReloadElements' from Array#sort

This CL is mostly a mechanical change. Loading either the receiver,
the backing store or the temp array from the sort state is pushed down
into each respective Load/Store builtin. This eliminates the need
for reloading the elements pointer after each compare function call.

R=jgruber@chromium.org, tebbi@chromium.org

Bug: v8:8562
Change-Id: I453e98635f9d891da58cf7b2a86c5c58f4a4069c
Reviewed-on: https://chromium-review.googlesource.com/c/1449613Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Commit-Queue: Simon Zünd <szuend@chromium.org>
Cr-Commit-Position: refs/heads/master@{#59291}
parent 30c1199f
...@@ -112,8 +112,8 @@ namespace array { ...@@ -112,8 +112,8 @@ namespace array {
// it is first requested, but it has always at least this size. // it is first requested, but it has always at least this size.
const kSortStateTempSize: Smi = 32; const kSortStateTempSize: Smi = 32;
type LoadFn = builtin(Context, FixedArray, HeapObject, Smi) => Object; type LoadFn = builtin(Context, FixedArray, Smi) => Object;
type StoreFn = builtin(Context, FixedArray, HeapObject, Smi, Object) => Smi; type StoreFn = builtin(Context, FixedArray, Smi, Object) => Smi;
type CanUseSameAccessorFn = builtin(Context, JSReceiver, Object, Number) => type CanUseSameAccessorFn = builtin(Context, JSReceiver, Object, Number) =>
Boolean; Boolean;
type CompareBuiltinFn = builtin(Context, Object, Object, Object) => Number; type CompareBuiltinFn = builtin(Context, Object, Object, Object) => Number;
...@@ -125,23 +125,25 @@ namespace array { ...@@ -125,23 +125,25 @@ namespace array {
// through a hole. // through a hole.
transitioning builtin Load<ElementsAccessor: type>( transitioning builtin Load<ElementsAccessor: type>(
context: Context, sortState: FixedArray, elements: HeapObject, context: Context, sortState: FixedArray, index: Smi): Object {
index: Smi): Object { const receiver = GetReceiver(sortState);
return GetProperty(elements, index); return GetProperty(receiver, index);
} }
Load<FastPackedSmiElements>( Load<FastPackedSmiElements>(
context: Context, sortState: FixedArray, elements: HeapObject, context: Context, sortState: FixedArray, index: Smi): Object {
index: Smi): Object { const receiver = GetReceiver(sortState);
const elems: FixedArray = UnsafeCast<FixedArray>(elements); const object = UnsafeCast<JSObject>(receiver);
return elems[index]; const elements = UnsafeCast<FixedArray>(object.elements);
return elements[index];
} }
Load<FastSmiOrObjectElements>( Load<FastSmiOrObjectElements>(
context: Context, sortState: FixedArray, elements: HeapObject, context: Context, sortState: FixedArray, index: Smi): Object {
index: Smi): Object { const receiver = GetReceiver(sortState);
const elems: FixedArray = UnsafeCast<FixedArray>(elements); const object = UnsafeCast<JSObject>(receiver);
const result: Object = elems[index]; const elements = UnsafeCast<FixedArray>(object.elements);
const result: Object = elements[index];
if (IsTheHole(result)) { if (IsTheHole(result)) {
// The pre-processing step removed all holes by compacting all elements // The pre-processing step removed all holes by compacting all elements
// at the start of the array. Finding a hole means the cmp function or // at the start of the array. Finding a hole means the cmp function or
...@@ -151,13 +153,13 @@ namespace array { ...@@ -151,13 +153,13 @@ namespace array {
return result; return result;
} }
Load<FastDoubleElements>( Load<FastDoubleElements>(context: Context, sortState: FixedArray, index: Smi):
context: Context, sortState: FixedArray, elements: HeapObject, Object {
index: Smi): Object {
try { try {
const elems: FixedDoubleArray = UnsafeCast<FixedDoubleArray>(elements); const receiver = GetReceiver(sortState);
const value: float64 = const object = UnsafeCast<JSObject>(receiver);
LoadDoubleWithHoleCheck(elems, index) otherwise Bailout; const elements = UnsafeCast<FixedDoubleArray>(object.elements);
const value = LoadDoubleWithHoleCheck(elements, index) otherwise Bailout;
return AllocateHeapNumberWithValue(value); return AllocateHeapNumberWithValue(value);
} }
label Bailout { label Bailout {
...@@ -168,70 +170,71 @@ namespace array { ...@@ -168,70 +170,71 @@ namespace array {
} }
} }
Load<DictionaryElements>( Load<DictionaryElements>(context: Context, sortState: FixedArray, index: Smi):
context: Context, sortState: FixedArray, elements: HeapObject, Object {
index: Smi): Object {
try { try {
const dictionary: NumberDictionary = const receiver = GetReceiver(sortState);
UnsafeCast<NumberDictionary>(elements); const object = UnsafeCast<JSObject>(receiver);
const intptrIndex: intptr = Convert<intptr>(index); const dictionary = UnsafeCast<NumberDictionary>(object.elements);
const value: Object = const intptrIndex = Convert<intptr>(index);
BasicLoadNumberDictionaryElement(dictionary, intptrIndex) return BasicLoadNumberDictionaryElement(dictionary, intptrIndex)
otherwise Bailout, Bailout; otherwise Bailout, Bailout;
return value;
} }
label Bailout { label Bailout {
return Failure(sortState); return Failure(sortState);
} }
} }
Load<TempArrayElements>( Load<TempArrayElements>(context: Context, sortState: FixedArray, index: Smi):
context: Context, sortState: FixedArray, elements: HeapObject, Object {
index: Smi): Object { const elements = GetTempArray(sortState);
assert(IsFixedArray(elements)); assert(IsFixedArray(elements));
const elems: FixedArray = UnsafeCast<FixedArray>(elements); return elements[index];
return elems[index];
} }
transitioning builtin Store<ElementsAccessor: type>( transitioning builtin Store<ElementsAccessor: type>(
context: Context, sortState: FixedArray, elements: HeapObject, index: Smi, context: Context, sortState: FixedArray, index: Smi, value: Object): Smi {
value: Object): Smi { const receiver = GetReceiver(sortState);
SetProperty(elements, index, value); SetProperty(receiver, index, value);
return kSuccess; return kSuccess;
} }
Store<FastPackedSmiElements>( Store<FastPackedSmiElements>(
context: Context, sortState: FixedArray, elements: HeapObject, index: Smi, context: Context, sortState: FixedArray, index: Smi, value: Object): Smi {
value: Object): Smi { const receiver = GetReceiver(sortState);
const elems: FixedArray = UnsafeCast<FixedArray>(elements); const object = UnsafeCast<JSObject>(receiver);
StoreFixedArrayElementSmi(elems, index, value, SKIP_WRITE_BARRIER); const elements = UnsafeCast<FixedArray>(object.elements);
StoreFixedArrayElementSmi(elements, index, value, SKIP_WRITE_BARRIER);
return kSuccess; return kSuccess;
} }
Store<FastSmiOrObjectElements>( Store<FastSmiOrObjectElements>(
context: Context, sortState: FixedArray, elements: HeapObject, index: Smi, context: Context, sortState: FixedArray, index: Smi, value: Object): Smi {
value: Object): Smi { const receiver = GetReceiver(sortState);
const elems: FixedArray = UnsafeCast<FixedArray>(elements); const object = UnsafeCast<JSObject>(receiver);
elems[index] = value; const elements = UnsafeCast<FixedArray>(object.elements);
elements[index] = value;
return kSuccess; return kSuccess;
} }
Store<FastDoubleElements>( Store<FastDoubleElements>(
context: Context, sortState: FixedArray, elements: HeapObject, index: Smi, context: Context, sortState: FixedArray, index: Smi, value: Object): Smi {
value: Object): Smi { const receiver = GetReceiver(sortState);
const elems: FixedDoubleArray = UnsafeCast<FixedDoubleArray>(elements); const object = UnsafeCast<JSObject>(receiver);
const heapVal: HeapNumber = UnsafeCast<HeapNumber>(value); const elements = UnsafeCast<FixedDoubleArray>(object.elements);
const heapVal = UnsafeCast<HeapNumber>(value);
// Make sure we do not store signalling NaNs into double arrays. // Make sure we do not store signalling NaNs into double arrays.
const val: float64 = Float64SilenceNaN(Convert<float64>(heapVal)); const val = Float64SilenceNaN(Convert<float64>(heapVal));
StoreFixedDoubleArrayElementWithSmiIndex(elems, index, val); StoreFixedDoubleArrayElementWithSmiIndex(elements, index, val);
return kSuccess; return kSuccess;
} }
Store<DictionaryElements>( Store<DictionaryElements>(
context: Context, sortState: FixedArray, elements: HeapObject, index: Smi, context: Context, sortState: FixedArray, index: Smi, value: Object): Smi {
value: Object): Smi { const receiver = GetReceiver(sortState);
const dictionary: NumberDictionary = UnsafeCast<NumberDictionary>(elements); const object = UnsafeCast<JSObject>(receiver);
const intptrIndex: intptr = Convert<intptr>(index); const dictionary = UnsafeCast<NumberDictionary>(object.elements);
const intptrIndex = Convert<intptr>(index);
try { try {
BasicStoreNumberDictionaryElement(dictionary, intptrIndex, value) BasicStoreNumberDictionaryElement(dictionary, intptrIndex, value)
otherwise Fail, Fail, ReadOnly; otherwise Fail, Fail, ReadOnly;
...@@ -240,7 +243,7 @@ namespace array { ...@@ -240,7 +243,7 @@ namespace array {
label ReadOnly { label ReadOnly {
// We cannot write to read-only data properties. Throw the same TypeError // We cannot write to read-only data properties. Throw the same TypeError
// as SetProperty would. // as SetProperty would.
const receiver: JSReceiver = GetReceiver(sortState); const receiver = GetReceiver(sortState);
ThrowTypeError( ThrowTypeError(
context, kStrictReadOnlyProperty, index, Typeof(receiver), receiver); context, kStrictReadOnlyProperty, index, Typeof(receiver), receiver);
} }
...@@ -250,10 +253,9 @@ namespace array { ...@@ -250,10 +253,9 @@ namespace array {
} }
Store<TempArrayElements>( Store<TempArrayElements>(
context: Context, sortState: FixedArray, elements: HeapObject, index: Smi, context: Context, sortState: FixedArray, index: Smi, value: Object): Smi {
value: Object): Smi { const elements = GetTempArray(sortState);
const elems: FixedArray = UnsafeCast<FixedArray>(elements); elements[index] = value;
elems[index] = value;
return kSuccess; return kSuccess;
} }
...@@ -281,10 +283,10 @@ namespace array { ...@@ -281,10 +283,10 @@ namespace array {
} }
// 5. Let xString be ? ToString(x). // 5. Let xString be ? ToString(x).
const xString: String = ToString_Inline(context, x); const xString = ToString_Inline(context, x);
// 6. Let yString be ? ToString(y). // 6. Let yString be ? ToString(y).
const yString: String = ToString_Inline(context, y); const yString = ToString_Inline(context, y);
// 7. Let xSmaller be the result of performing // 7. Let xSmaller be the result of performing
// Abstract Relational Comparison xString < yString. // Abstract Relational Comparison xString < yString.
...@@ -303,11 +305,10 @@ namespace array { ...@@ -303,11 +305,10 @@ namespace array {
transitioning builtin SortCompareUserFn( transitioning builtin SortCompareUserFn(
context: Context, comparefn: Object, x: Object, y: Object): Number { context: Context, comparefn: Object, x: Object, y: Object): Number {
assert(comparefn != Undefined); assert(comparefn != Undefined);
const cmpfn: Callable = UnsafeCast<Callable>(comparefn); const cmpfn = UnsafeCast<Callable>(comparefn);
// a. Let v be ? ToNumber(? Call(comparefn, undefined, x, y)). // a. Let v be ? ToNumber(? Call(comparefn, undefined, x, y)).
const v: Number = const v = ToNumber_Inline(context, Call(context, cmpfn, Undefined, x, y));
ToNumber_Inline(context, Call(context, cmpfn, Undefined, x, y));
// b. If v is NaN, return +0. // b. If v is NaN, return +0.
if (NumberIsNaN(v)) return 0; if (NumberIsNaN(v)) return 0;
...@@ -365,19 +366,6 @@ namespace array { ...@@ -365,19 +366,6 @@ namespace array {
return result; return result;
} }
// Reloading elements after returning from JS is needed since left-trimming
// might have occurred. This means we cannot leave any pointer to the elements
// backing store on the stack (since it would point to the filler object).
// TODO(v8:7995): Remove reloading once left-trimming is removed.
macro ReloadElements(implicit context: Context)(sortState: FixedArray):
HeapObject {
const receiver: JSReceiver = GetReceiver(sortState);
if (sortState[kAccessorIdx] == kGenericElementsAccessorId) return receiver;
const object: JSObject = UnsafeCast<JSObject>(receiver);
return object.elements;
}
macro GetInitialReceiverLength(implicit context: macro GetInitialReceiverLength(implicit context:
Context)(sortState: FixedArray): Number { Context)(sortState: FixedArray): Number {
return UnsafeCast<Number>(sortState[kInitialReceiverLengthIdx]); return UnsafeCast<Number>(sortState[kInitialReceiverLengthIdx]);
...@@ -492,54 +480,52 @@ namespace array { ...@@ -492,54 +480,52 @@ namespace array {
// or the return value. // or the return value.
macro CallLoad( macro CallLoad(
context: Context, sortState: FixedArray, load: LoadFn, context: Context, sortState: FixedArray, load: LoadFn, index: Smi): Object
elements: HeapObject, index: Smi): Object
labels Bailout { labels Bailout {
const result: Object = load(context, sortState, elements, index); const result: Object = load(context, sortState, index);
EnsureSuccess(sortState) otherwise Bailout; EnsureSuccess(sortState) otherwise Bailout;
return result; return result;
} }
macro CallStore( macro CallStore(
context: Context, sortState: FixedArray, store: StoreFn, context: Context, sortState: FixedArray, store: StoreFn, index: Smi,
elements: HeapObject, index: Smi, value: Object) labels Bailout { value: Object) labels Bailout {
store(context, sortState, elements, index, value); store(context, sortState, index, value);
EnsureSuccess(sortState) otherwise Bailout; EnsureSuccess(sortState) otherwise Bailout;
} }
transitioning macro CallCopyFromTempArray( transitioning macro CallCopyFromTempArray(
context: Context, sortState: FixedArray, dstElements: HeapObject, context: Context, sortState: FixedArray, dstPos: Smi, srcPos: Smi,
dstPos: Smi, tempArray: FixedArray, srcPos: Smi, length: Smi) length: Smi)
labels Bailout { labels Bailout {
CopyFromTempArray( CopyFromTempArray(context, sortState, dstPos, srcPos, length);
context, sortState, dstElements, dstPos, tempArray, srcPos, length);
EnsureSuccess(sortState) otherwise Bailout; EnsureSuccess(sortState) otherwise Bailout;
} }
transitioning macro CallCopyWithinSortArray( transitioning macro CallCopyWithinSortArray(
context: Context, sortState: FixedArray, elements: HeapObject, context: Context, sortState: FixedArray, srcPos: Smi, dstPos: Smi,
srcPos: Smi, dstPos: Smi, length: Smi) length: Smi)
labels Bailout { labels Bailout {
CopyWithinSortArray(context, sortState, elements, srcPos, dstPos, length); CopyWithinSortArray(context, sortState, srcPos, dstPos, length);
EnsureSuccess(sortState) otherwise Bailout; EnsureSuccess(sortState) otherwise Bailout;
} }
macro CallGallopRight( macro CallGallopRight(
context: Context, sortState: FixedArray, load: LoadFn, key: Object, context: Context, sortState: FixedArray, load: LoadFn, key: Object,
base: Smi, length: Smi, hint: Smi, useTempArray: Boolean): Smi base: Smi, length: Smi, hint: Smi): Smi
labels Bailout { labels Bailout {
const result: Smi = GallopRight( const result: Smi =
context, sortState, load, key, base, length, hint, useTempArray); GallopRight(context, sortState, load, key, base, length, hint);
EnsureSuccess(sortState) otherwise Bailout; EnsureSuccess(sortState) otherwise Bailout;
return result; return result;
} }
macro CallGallopLeft( macro CallGallopLeft(
context: Context, sortState: FixedArray, load: LoadFn, key: Object, context: Context, sortState: FixedArray, load: LoadFn, key: Object,
base: Smi, length: Smi, hint: Smi, useTempArray: Boolean): Smi base: Smi, length: Smi, hint: Smi): Smi
labels Bailout { labels Bailout {
const result: Smi = GallopLeft( const result: Smi =
context, sortState, load, key, base, length, hint, useTempArray); GallopLeft(context, sortState, load, key, base, length, hint);
EnsureSuccess(sortState) otherwise Bailout; EnsureSuccess(sortState) otherwise Bailout;
return result; return result;
} }
...@@ -552,9 +538,8 @@ namespace array { ...@@ -552,9 +538,8 @@ namespace array {
} }
transitioning macro CopyToTempArray( transitioning macro CopyToTempArray(
context: Context, sortState: FixedArray, load: LoadFn, context: Context, sortState: FixedArray, load: LoadFn, srcPos: Smi,
srcElements: HeapObject, srcPos: Smi, tempArray: FixedArray, dstPos: Smi, tempArray: FixedArray, dstPos: Smi, length: Smi)
length: Smi)
labels Bailout { labels Bailout {
assert(srcPos >= 0); assert(srcPos >= 0);
assert(dstPos >= 0); assert(dstPos >= 0);
...@@ -566,16 +551,16 @@ namespace array { ...@@ -566,16 +551,16 @@ namespace array {
let to: Smi = srcPos + length; let to: Smi = srcPos + length;
while (srcIdx < to) { while (srcIdx < to) {
let element: Object = let element: Object = CallLoad(context, sortState, load, srcIdx++)
CallLoad(context, sortState, load, srcElements, srcIdx++)
otherwise Bailout; otherwise Bailout;
tempArray[dstIdx++] = element; tempArray[dstIdx++] = element;
} }
} }
transitioning builtin CopyFromTempArray( transitioning builtin CopyFromTempArray(
context: Context, sortState: FixedArray, dstElements: HeapObject, context: Context, sortState: FixedArray, dstPos: Smi, srcPos: Smi,
dstPos: Smi, tempArray: FixedArray, srcPos: Smi, length: Smi): Smi { length: Smi): Smi {
const tempArray = GetTempArray(sortState);
assert(srcPos >= 0); assert(srcPos >= 0);
assert(dstPos >= 0); assert(dstPos >= 0);
assert(srcPos <= tempArray.length - length); assert(srcPos <= tempArray.length - length);
...@@ -588,9 +573,7 @@ namespace array { ...@@ -588,9 +573,7 @@ namespace array {
let to: Smi = srcPos + length; let to: Smi = srcPos + length;
try { try {
while (srcIdx < to) { while (srcIdx < to) {
CallStore( CallStore(context, sortState, store, dstIdx++, tempArray[srcIdx++])
context, sortState, store, dstElements, dstIdx++,
tempArray[srcIdx++])
otherwise Bailout; otherwise Bailout;
} }
return kSuccess; return kSuccess;
...@@ -601,8 +584,8 @@ namespace array { ...@@ -601,8 +584,8 @@ namespace array {
} }
transitioning builtin CopyWithinSortArray( transitioning builtin CopyWithinSortArray(
context: Context, sortState: FixedArray, elements: HeapObject, context: Context, sortState: FixedArray, srcPos: Smi, dstPos: Smi,
srcPos: Smi, dstPos: Smi, length: Smi): Smi { length: Smi): Smi {
assert(srcPos >= 0); assert(srcPos >= 0);
assert(dstPos >= 0); assert(dstPos >= 0);
assert(srcPos <= GetInitialReceiverLength(sortState) - length); assert(srcPos <= GetInitialReceiverLength(sortState) - length);
...@@ -616,8 +599,7 @@ namespace array { ...@@ -616,8 +599,7 @@ namespace array {
let srcIdx: Smi = srcPos + length - 1; let srcIdx: Smi = srcPos + length - 1;
let dstIdx: Smi = dstPos + length - 1; let dstIdx: Smi = dstPos + length - 1;
while (srcIdx >= srcPos) { while (srcIdx >= srcPos) {
CopyElement( CopyElement(context, sortState, load, store, srcIdx--, dstIdx--)
context, sortState, load, store, elements, srcIdx--, dstIdx--)
otherwise Bailout; otherwise Bailout;
} }
} else { } else {
...@@ -625,8 +607,7 @@ namespace array { ...@@ -625,8 +607,7 @@ namespace array {
let dstIdx: Smi = dstPos; let dstIdx: Smi = dstPos;
let to: Smi = srcPos + length; let to: Smi = srcPos + length;
while (srcIdx < to) { while (srcIdx < to) {
CopyElement( CopyElement(context, sortState, load, store, srcIdx++, dstIdx++)
context, sortState, load, store, elements, srcIdx++, dstIdx++)
otherwise Bailout; otherwise Bailout;
} }
} }
...@@ -653,8 +634,6 @@ namespace array { ...@@ -653,8 +634,6 @@ namespace array {
assert(low <= startArg && startArg <= high); assert(low <= startArg && startArg <= high);
try { try {
let elements: HeapObject = ReloadElements(sortState);
const load: LoadFn = GetLoadFn(sortState); const load: LoadFn = GetLoadFn(sortState);
const store: StoreFn = GetStoreFn(sortState); const store: StoreFn = GetStoreFn(sortState);
...@@ -665,8 +644,7 @@ namespace array { ...@@ -665,8 +644,7 @@ namespace array {
let left: Smi = low; let left: Smi = low;
let right: Smi = start; let right: Smi = start;
const pivot: Object = const pivot: Object = CallLoad(context, sortState, load, right)
CallLoad(context, sortState, load, elements, right)
otherwise Bailout; otherwise Bailout;
// Invariants: // Invariants:
...@@ -677,13 +655,11 @@ namespace array { ...@@ -677,13 +655,11 @@ namespace array {
// Find pivot insertion point. // Find pivot insertion point.
while (left < right) { while (left < right) {
const mid: Smi = left + ((right - left) >> 1); const mid: Smi = left + ((right - left) >> 1);
const midElement: Object = const midElement: Object = CallLoad(context, sortState, load, mid)
CallLoad(context, sortState, load, elements, mid)
otherwise Bailout; otherwise Bailout;
const order: Number = const order: Number =
CallCompareFn(context, sortState, pivot, midElement) CallCompareFn(context, sortState, pivot, midElement)
otherwise Bailout; otherwise Bailout;
elements = ReloadElements(sortState);
if (order < 0) { if (order < 0) {
right = mid; right = mid;
...@@ -702,10 +678,10 @@ namespace array { ...@@ -702,10 +678,10 @@ namespace array {
// sort is stable. // sort is stable.
// Slide over to make room. // Slide over to make room.
for (let p: Smi = start; p > left; --p) { for (let p: Smi = start; p > left; --p) {
CopyElement(context, sortState, load, store, elements, p - 1, p) CopyElement(context, sortState, load, store, p - 1, p)
otherwise Bailout; otherwise Bailout;
} }
CallStore(context, sortState, store, elements, left, pivot) CallStore(context, sortState, store, left, pivot)
otherwise Bailout; otherwise Bailout;
} }
return kSuccess; return kSuccess;
...@@ -737,7 +713,6 @@ namespace array { ...@@ -737,7 +713,6 @@ namespace array {
labels Bailout { labels Bailout {
assert(lowArg < high); assert(lowArg < high);
let elements: HeapObject = ReloadElements(sortState);
const load: LoadFn = GetLoadFn(sortState); const load: LoadFn = GetLoadFn(sortState);
const store: StoreFn = GetStoreFn(sortState); const store: StoreFn = GetStoreFn(sortState);
...@@ -747,13 +722,12 @@ namespace array { ...@@ -747,13 +722,12 @@ namespace array {
let runLength: Smi = 2; let runLength: Smi = 2;
const elementLow: Object = const elementLow: Object =
CallLoad(context, sortState, load, elements, low) otherwise Bailout; CallLoad(context, sortState, load, low) otherwise Bailout;
const elementLowPred: Object = const elementLowPred: Object =
CallLoad(context, sortState, load, elements, low - 1) otherwise Bailout; CallLoad(context, sortState, load, low - 1) otherwise Bailout;
let order: Number = let order: Number =
CallCompareFn(context, sortState, elementLow, elementLowPred) CallCompareFn(context, sortState, elementLow, elementLowPred)
otherwise Bailout; otherwise Bailout;
elements = ReloadElements(sortState);
// TODO(szuend): Replace with "order < 0" once Torque supports it. // TODO(szuend): Replace with "order < 0" once Torque supports it.
// Currently the operator<(Number, Number) has return type // Currently the operator<(Number, Number) has return type
...@@ -763,10 +737,9 @@ namespace array { ...@@ -763,10 +737,9 @@ namespace array {
let previousElement: Object = elementLow; let previousElement: Object = elementLow;
for (let idx: Smi = low + 1; idx < high; ++idx) { for (let idx: Smi = low + 1; idx < high; ++idx) {
const currentElement: Object = const currentElement: Object =
CallLoad(context, sortState, load, elements, idx) otherwise Bailout; CallLoad(context, sortState, load, idx) otherwise Bailout;
order = CallCompareFn(context, sortState, currentElement, previousElement) order = CallCompareFn(context, sortState, currentElement, previousElement)
otherwise Bailout; otherwise Bailout;
elements = ReloadElements(sortState);
if (isDescending) { if (isDescending) {
if (order >= 0) break; if (order >= 0) break;
...@@ -779,8 +752,7 @@ namespace array { ...@@ -779,8 +752,7 @@ namespace array {
} }
if (isDescending) { if (isDescending) {
ReverseRange( ReverseRange(context, sortState, load, store, lowArg, lowArg + runLength)
context, sortState, load, store, elements, lowArg, lowArg + runLength)
otherwise Bailout; otherwise Bailout;
} }
...@@ -789,19 +761,19 @@ namespace array { ...@@ -789,19 +761,19 @@ namespace array {
macro ReverseRange( macro ReverseRange(
context: Context, sortState: FixedArray, load: LoadFn, store: StoreFn, context: Context, sortState: FixedArray, load: LoadFn, store: StoreFn,
elements: HeapObject, from: Smi, to: Smi) from: Smi, to: Smi)
labels Bailout { labels Bailout {
let low: Smi = from; let low: Smi = from;
let high: Smi = to - 1; let high: Smi = to - 1;
while (low < high) { while (low < high) {
const elementLow: Object = const elementLow: Object =
CallLoad(context, sortState, load, elements, low) otherwise Bailout; CallLoad(context, sortState, load, low) otherwise Bailout;
const elementHigh: Object = const elementHigh: Object =
CallLoad(context, sortState, load, elements, high) otherwise Bailout; CallLoad(context, sortState, load, high) otherwise Bailout;
CallStore(context, sortState, store, elements, low++, elementHigh) CallStore(context, sortState, store, low++, elementHigh)
otherwise Bailout; otherwise Bailout;
CallStore(context, sortState, store, elements, high--, elementLow) CallStore(context, sortState, store, high--, elementLow)
otherwise Bailout; otherwise Bailout;
} }
} }
...@@ -818,7 +790,6 @@ namespace array { ...@@ -818,7 +790,6 @@ namespace array {
assert(i >= 0); assert(i >= 0);
assert(i == stackSize - 2 || i == stackSize - 3); assert(i == stackSize - 2 || i == stackSize - 3);
let elements: HeapObject = ReloadElements(sortState);
const load: LoadFn = GetLoadFn(sortState); const load: LoadFn = GetLoadFn(sortState);
const pendingRuns: FixedArray = const pendingRuns: FixedArray =
...@@ -845,13 +816,11 @@ namespace array { ...@@ -845,13 +816,11 @@ namespace array {
try { try {
// Where does b start in a? Elements in a before that can be ignored, // Where does b start in a? Elements in a before that can be ignored,
// because they are already in place. // because they are already in place.
const keyRight: Object = const keyRight: Object = CallLoad(context, sortState, load, baseB)
CallLoad(context, sortState, load, elements, baseB)
otherwise Bailout; otherwise Bailout;
const k: Smi = CallGallopRight( const k: Smi =
context, sortState, load, keyRight, baseA, lengthA, 0, False) CallGallopRight(context, sortState, load, keyRight, baseA, lengthA, 0)
otherwise Bailout; otherwise Bailout;
elements = ReloadElements(sortState);
assert(k >= 0); assert(k >= 0);
baseA = baseA + k; baseA = baseA + k;
...@@ -862,12 +831,11 @@ namespace array { ...@@ -862,12 +831,11 @@ namespace array {
// Where does a end in b? Elements in b after that can be ignored, // Where does a end in b? Elements in b after that can be ignored,
// because they are already in place. // because they are already in place.
let keyLeft: Object = let keyLeft: Object =
CallLoad(context, sortState, load, elements, baseA + lengthA - 1) CallLoad(context, sortState, load, baseA + lengthA - 1)
otherwise Bailout; otherwise Bailout;
lengthB = CallGallopLeft( lengthB = CallGallopLeft(
context, sortState, load, keyLeft, baseB, lengthB, lengthB - 1, False) context, sortState, load, keyLeft, baseB, lengthB, lengthB - 1)
otherwise Bailout; otherwise Bailout;
elements = ReloadElements(sortState);
assert(lengthB >= 0); assert(lengthB >= 0);
if (lengthB == 0) return kSuccess; if (lengthB == 0) return kSuccess;
...@@ -887,12 +855,6 @@ namespace array { ...@@ -887,12 +855,6 @@ namespace array {
} }
} }
macro LoadElementsOrTempArray(implicit context: Context)(
useTempArray: Boolean, sortState: FixedArray): HeapObject {
return useTempArray == True ? GetTempArray(sortState) :
ReloadElements(sortState);
}
// Locates the proper position of key in a sorted array; if the array contains // Locates the proper position of key in a sorted array; if the array contains
// an element equal to key, return the position immediately to the left of // an element equal to key, return the position immediately to the left of
// the leftmost equal element. (GallopRight does the same except returns the // the leftmost equal element. (GallopRight does the same except returns the
...@@ -912,7 +874,7 @@ namespace array { ...@@ -912,7 +874,7 @@ namespace array {
// is plus infinity. In other words, key belongs at index base + k. // is plus infinity. In other words, key belongs at index base + k.
builtin GallopLeft( builtin GallopLeft(
context: Context, sortState: FixedArray, load: LoadFn, key: Object, context: Context, sortState: FixedArray, load: LoadFn, key: Object,
base: Smi, length: Smi, hint: Smi, useTempArray: Boolean): Smi { base: Smi, length: Smi, hint: Smi): Smi {
assert(length > 0 && base >= 0); assert(length > 0 && base >= 0);
assert(0 <= hint && hint < length); assert(0 <= hint && hint < length);
...@@ -920,9 +882,8 @@ namespace array { ...@@ -920,9 +882,8 @@ namespace array {
let offset: Smi = 1; let offset: Smi = 1;
try { try {
const baseHintElement: Object = CallLoad( const baseHintElement: Object =
context, sortState, load, CallLoad(context, sortState, load, base + hint)
LoadElementsOrTempArray(useTempArray, sortState), base + hint)
otherwise Bailout; otherwise Bailout;
let order: Number = let order: Number =
CallCompareFn(context, sortState, baseHintElement, key) CallCompareFn(context, sortState, baseHintElement, key)
...@@ -935,10 +896,8 @@ namespace array { ...@@ -935,10 +896,8 @@ namespace array {
// a[base + length - 1] is highest. // a[base + length - 1] is highest.
let maxOfs: Smi = length - hint; let maxOfs: Smi = length - hint;
while (offset < maxOfs) { while (offset < maxOfs) {
const offsetElement: Object = CallLoad( const offsetElement: Object =
context, sortState, load, CallLoad(context, sortState, load, base + hint + offset)
LoadElementsOrTempArray(useTempArray, sortState),
base + hint + offset)
otherwise Bailout; otherwise Bailout;
order = CallCompareFn(context, sortState, offsetElement, key) order = CallCompareFn(context, sortState, offsetElement, key)
otherwise Bailout; otherwise Bailout;
...@@ -966,10 +925,8 @@ namespace array { ...@@ -966,10 +925,8 @@ namespace array {
// a[base + hint] is lowest. // a[base + hint] is lowest.
let maxOfs: Smi = hint + 1; let maxOfs: Smi = hint + 1;
while (offset < maxOfs) { while (offset < maxOfs) {
const offsetElement: Object = CallLoad( const offsetElement: Object =
context, sortState, load, CallLoad(context, sortState, load, base + hint - offset)
LoadElementsOrTempArray(useTempArray, sortState),
base + hint - offset)
otherwise Bailout; otherwise Bailout;
order = CallCompareFn(context, sortState, offsetElement, key) order = CallCompareFn(context, sortState, offsetElement, key)
otherwise Bailout; otherwise Bailout;
...@@ -1001,9 +958,8 @@ namespace array { ...@@ -1001,9 +958,8 @@ namespace array {
while (lastOfs < offset) { while (lastOfs < offset) {
const m: Smi = lastOfs + ((offset - lastOfs) >> 1); const m: Smi = lastOfs + ((offset - lastOfs) >> 1);
const baseMElement: Object = CallLoad( const baseMElement: Object =
context, sortState, load, CallLoad(context, sortState, load, base + m)
LoadElementsOrTempArray(useTempArray, sortState), base + m)
otherwise Bailout; otherwise Bailout;
order = CallCompareFn(context, sortState, baseMElement, key) order = CallCompareFn(context, sortState, baseMElement, key)
otherwise Bailout; otherwise Bailout;
...@@ -1035,7 +991,7 @@ namespace array { ...@@ -1035,7 +991,7 @@ namespace array {
// or kFailure on error. // or kFailure on error.
builtin GallopRight( builtin GallopRight(
context: Context, sortState: FixedArray, load: LoadFn, key: Object, context: Context, sortState: FixedArray, load: LoadFn, key: Object,
base: Smi, length: Smi, hint: Smi, useTempArray: Boolean): Smi { base: Smi, length: Smi, hint: Smi): Smi {
assert(length > 0 && base >= 0); assert(length > 0 && base >= 0);
assert(0 <= hint && hint < length); assert(0 <= hint && hint < length);
...@@ -1043,9 +999,8 @@ namespace array { ...@@ -1043,9 +999,8 @@ namespace array {
let offset: Smi = 1; let offset: Smi = 1;
try { try {
const baseHintElement: Object = CallLoad( const baseHintElement: Object =
context, sortState, load, CallLoad(context, sortState, load, base + hint)
LoadElementsOrTempArray(useTempArray, sortState), base + hint)
otherwise Bailout; otherwise Bailout;
let order: Number = let order: Number =
CallCompareFn(context, sortState, key, baseHintElement) CallCompareFn(context, sortState, key, baseHintElement)
...@@ -1058,10 +1013,8 @@ namespace array { ...@@ -1058,10 +1013,8 @@ namespace array {
// a[base + hint] is lowest. // a[base + hint] is lowest.
let maxOfs: Smi = hint + 1; let maxOfs: Smi = hint + 1;
while (offset < maxOfs) { while (offset < maxOfs) {
const offsetElement: Object = CallLoad( const offsetElement: Object =
context, sortState, load, CallLoad(context, sortState, load, base + hint - offset)
LoadElementsOrTempArray(useTempArray, sortState),
base + hint - offset)
otherwise Bailout; otherwise Bailout;
order = CallCompareFn(context, sortState, key, offsetElement) order = CallCompareFn(context, sortState, key, offsetElement)
otherwise Bailout; otherwise Bailout;
...@@ -1088,10 +1041,8 @@ namespace array { ...@@ -1088,10 +1041,8 @@ namespace array {
// a[base + length - 1] is highest. // a[base + length - 1] is highest.
let maxOfs: Smi = length - hint; let maxOfs: Smi = length - hint;
while (offset < maxOfs) { while (offset < maxOfs) {
const offsetElement: Object = CallLoad( const offsetElement: Object =
context, sortState, load, CallLoad(context, sortState, load, base + hint + offset)
LoadElementsOrTempArray(useTempArray, sortState),
base + hint + offset)
otherwise Bailout; otherwise Bailout;
order = CallCompareFn(context, sortState, key, offsetElement) order = CallCompareFn(context, sortState, key, offsetElement)
otherwise Bailout; otherwise Bailout;
...@@ -1122,9 +1073,8 @@ namespace array { ...@@ -1122,9 +1073,8 @@ namespace array {
while (lastOfs < offset) { while (lastOfs < offset) {
const m: Smi = lastOfs + ((offset - lastOfs) >> 1); const m: Smi = lastOfs + ((offset - lastOfs) >> 1);
const baseMElement: Object = CallLoad( const baseMElement: Object =
context, sortState, load, CallLoad(context, sortState, load, base + m)
LoadElementsOrTempArray(useTempArray, sortState), base + m)
otherwise Bailout; otherwise Bailout;
order = CallCompareFn(context, sortState, key, baseMElement) order = CallCompareFn(context, sortState, key, baseMElement)
otherwise Bailout; otherwise Bailout;
...@@ -1148,11 +1098,11 @@ namespace array { ...@@ -1148,11 +1098,11 @@ namespace array {
// Copies a single element inside the array/object (NOT the tempArray). // Copies a single element inside the array/object (NOT the tempArray).
macro CopyElement( macro CopyElement(
context: Context, sortState: FixedArray, load: LoadFn, store: StoreFn, context: Context, sortState: FixedArray, load: LoadFn, store: StoreFn,
elements: HeapObject, from: Smi, to: Smi) from: Smi, to: Smi)
labels Bailout { labels Bailout {
const element: Object = CallLoad(context, sortState, load, elements, from) const element: Object = CallLoad(context, sortState, load, from)
otherwise Bailout; otherwise Bailout;
CallStore(context, sortState, store, elements, to, element) CallStore(context, sortState, store, to, element)
otherwise Bailout; otherwise Bailout;
} }
...@@ -1173,20 +1123,18 @@ namespace array { ...@@ -1173,20 +1123,18 @@ namespace array {
let lengthA: Smi = lengthAArg; let lengthA: Smi = lengthAArg;
let lengthB: Smi = lengthBArg; let lengthB: Smi = lengthBArg;
let elements: HeapObject = ReloadElements(sortState);
const load: LoadFn = GetLoadFn(sortState); const load: LoadFn = GetLoadFn(sortState);
const store: StoreFn = GetStoreFn(sortState); const store: StoreFn = GetStoreFn(sortState);
const tempArray: FixedArray = GetTempArray(sortState, lengthA); const tempArray: FixedArray = GetTempArray(sortState, lengthA);
CopyToTempArray( CopyToTempArray(context, sortState, load, baseA, tempArray, 0, lengthA)
context, sortState, load, elements, baseA, tempArray, 0, lengthA)
otherwise Bailout; otherwise Bailout;
let dest: Smi = baseA; let dest: Smi = baseA;
let cursorTemp: Smi = 0; let cursorTemp: Smi = 0;
let cursorB: Smi = baseB; let cursorB: Smi = baseB;
CopyElement(context, sortState, load, store, elements, cursorB++, dest++) CopyElement(context, sortState, load, store, cursorB++, dest++)
otherwise Bailout; otherwise Bailout;
try { try {
...@@ -1207,17 +1155,14 @@ namespace array { ...@@ -1207,17 +1155,14 @@ namespace array {
while (Int32TrueConstant()) { while (Int32TrueConstant()) {
assert(lengthA > 1 && lengthB > 0); assert(lengthA > 1 && lengthB > 0);
let elementB: Object = let elementB: Object = CallLoad(context, sortState, load, cursorB)
CallLoad(context, sortState, load, elements, cursorB)
otherwise Bailout; otherwise Bailout;
let order: Number = let order: Number =
CallCompareFn(context, sortState, elementB, tempArray[cursorTemp]) CallCompareFn(context, sortState, elementB, tempArray[cursorTemp])
otherwise Bailout; otherwise Bailout;
elements = ReloadElements(sortState);
if (order < 0) { if (order < 0) {
CopyElement( CopyElement(context, sortState, load, store, cursorB, dest)
context, sortState, load, store, elements, cursorB, dest)
otherwise Bailout; otherwise Bailout;
++cursorB; ++cursorB;
...@@ -1229,9 +1174,7 @@ namespace array { ...@@ -1229,9 +1174,7 @@ namespace array {
if (lengthB == 0) goto Succeed; if (lengthB == 0) goto Succeed;
if (nofWinsB >= minGallop) break; if (nofWinsB >= minGallop) break;
} else { } else {
CallStore( CallStore(context, sortState, store, dest, tempArray[cursorTemp])
context, sortState, store, elements, dest,
tempArray[cursorTemp])
otherwise Bailout; otherwise Bailout;
++cursorTemp; ++cursorTemp;
...@@ -1258,19 +1201,17 @@ namespace array { ...@@ -1258,19 +1201,17 @@ namespace array {
minGallop = SmiMax(1, minGallop - 1); minGallop = SmiMax(1, minGallop - 1);
sortState[kMinGallopIdx] = minGallop; sortState[kMinGallopIdx] = minGallop;
let keyRight: Object = let keyRight: Object = CallLoad(context, sortState, load, cursorB)
CallLoad(context, sortState, load, elements, cursorB)
otherwise Bailout; otherwise Bailout;
nofWinsA = CallGallopRight( nofWinsA = CallGallopRight(
context, sortState, Load<TempArrayElements>, keyRight, cursorTemp, context, sortState, Load<TempArrayElements>, keyRight, cursorTemp,
lengthA, 0, True) otherwise Bailout; lengthA, 0) otherwise Bailout;
elements = ReloadElements(sortState);
assert(nofWinsA >= 0); assert(nofWinsA >= 0);
if (nofWinsA > 0) { if (nofWinsA > 0) {
CallCopyFromTempArray( CallCopyFromTempArray(
context, sortState, elements, dest, tempArray, cursorTemp, context, sortState, dest, cursorTemp, nofWinsA)
nofWinsA) otherwise Bailout; otherwise Bailout;
dest = dest + nofWinsA; dest = dest + nofWinsA;
cursorTemp = cursorTemp + nofWinsA; cursorTemp = cursorTemp + nofWinsA;
lengthA = lengthA - nofWinsA; lengthA = lengthA - nofWinsA;
...@@ -1281,20 +1222,17 @@ namespace array { ...@@ -1281,20 +1222,17 @@ namespace array {
// consistent, but we can't assume that it is. // consistent, but we can't assume that it is.
if (lengthA == 0) goto Succeed; if (lengthA == 0) goto Succeed;
} }
CopyElement( CopyElement(context, sortState, load, store, cursorB++, dest++)
context, sortState, load, store, elements, cursorB++, dest++)
otherwise Bailout; otherwise Bailout;
if (--lengthB == 0) goto Succeed; if (--lengthB == 0) goto Succeed;
nofWinsB = CallGallopLeft( nofWinsB = CallGallopLeft(
context, sortState, load, tempArray[cursorTemp], cursorB, lengthB, context, sortState, load, tempArray[cursorTemp], cursorB, lengthB,
0, False) 0)
otherwise Bailout; otherwise Bailout;
elements = ReloadElements(sortState);
assert(nofWinsB >= 0); assert(nofWinsB >= 0);
if (nofWinsB > 0) { if (nofWinsB > 0) {
CallCopyWithinSortArray( CallCopyWithinSortArray(context, sortState, cursorB, dest, nofWinsB)
context, sortState, elements, cursorB, dest, nofWinsB)
otherwise Bailout; otherwise Bailout;
dest = dest + nofWinsB; dest = dest + nofWinsB;
...@@ -1303,9 +1241,7 @@ namespace array { ...@@ -1303,9 +1241,7 @@ namespace array {
if (lengthB == 0) goto Succeed; if (lengthB == 0) goto Succeed;
} }
CallStore( CallStore(context, sortState, store, dest++, tempArray[cursorTemp++])
context, sortState, store, elements, dest++,
tempArray[cursorTemp++])
otherwise Bailout; otherwise Bailout;
if (--lengthA == 1) goto CopyB; if (--lengthA == 1) goto CopyB;
} }
...@@ -1315,20 +1251,17 @@ namespace array { ...@@ -1315,20 +1251,17 @@ namespace array {
} }
label Succeed { label Succeed {
if (lengthA > 0) { if (lengthA > 0) {
CallCopyFromTempArray( CallCopyFromTempArray(context, sortState, dest, cursorTemp, lengthA)
context, sortState, elements, dest, tempArray, cursorTemp, lengthA)
otherwise Bailout; otherwise Bailout;
} }
} }
label CopyB { label CopyB {
assert(lengthA == 1 && lengthB > 0); assert(lengthA == 1 && lengthB > 0);
// The last element of run A belongs at the end of the merge. // The last element of run A belongs at the end of the merge.
CallCopyWithinSortArray( CallCopyWithinSortArray(context, sortState, cursorB, dest, lengthB)
context, sortState, elements, cursorB, dest, lengthB)
otherwise Bailout; otherwise Bailout;
CallStore( CallStore(
context, sortState, store, elements, dest + lengthB, context, sortState, store, dest + lengthB, tempArray[cursorTemp])
tempArray[cursorTemp])
otherwise Bailout; otherwise Bailout;
} }
} }
...@@ -1348,13 +1281,11 @@ namespace array { ...@@ -1348,13 +1281,11 @@ namespace array {
let lengthA: Smi = lengthAArg; let lengthA: Smi = lengthAArg;
let lengthB: Smi = lengthBArg; let lengthB: Smi = lengthBArg;
let elements: HeapObject = ReloadElements(sortState);
const load: LoadFn = GetLoadFn(sortState); const load: LoadFn = GetLoadFn(sortState);
const store: StoreFn = GetStoreFn(sortState); const store: StoreFn = GetStoreFn(sortState);
const tempArray: FixedArray = GetTempArray(sortState, lengthB); const tempArray: FixedArray = GetTempArray(sortState, lengthB);
CopyToTempArray( CopyToTempArray(context, sortState, load, baseB, tempArray, 0, lengthB)
context, sortState, load, elements, baseB, tempArray, 0, lengthB)
otherwise Bailout; otherwise Bailout;
// MergeHigh merges the two runs backwards. // MergeHigh merges the two runs backwards.
...@@ -1362,7 +1293,7 @@ namespace array { ...@@ -1362,7 +1293,7 @@ namespace array {
let cursorTemp: Smi = lengthB - 1; let cursorTemp: Smi = lengthB - 1;
let cursorA: Smi = baseA + lengthA - 1; let cursorA: Smi = baseA + lengthA - 1;
CopyElement(context, sortState, load, store, elements, cursorA--, dest--) CopyElement(context, sortState, load, store, cursorA--, dest--)
otherwise Bailout; otherwise Bailout;
try { try {
...@@ -1383,17 +1314,14 @@ namespace array { ...@@ -1383,17 +1314,14 @@ namespace array {
while (Int32TrueConstant()) { while (Int32TrueConstant()) {
assert(lengthA > 0 && lengthB > 1); assert(lengthA > 0 && lengthB > 1);
let elementA: Object = let elementA: Object = CallLoad(context, sortState, load, cursorA)
CallLoad(context, sortState, load, elements, cursorA)
otherwise Bailout; otherwise Bailout;
let order: Number = let order: Number =
CallCompareFn(context, sortState, tempArray[cursorTemp], elementA) CallCompareFn(context, sortState, tempArray[cursorTemp], elementA)
otherwise Bailout; otherwise Bailout;
elements = ReloadElements(sortState);
if (order < 0) { if (order < 0) {
CopyElement( CopyElement(context, sortState, load, store, cursorA, dest)
context, sortState, load, store, elements, cursorA, dest)
otherwise Bailout; otherwise Bailout;
--cursorA; --cursorA;
...@@ -1405,9 +1333,7 @@ namespace array { ...@@ -1405,9 +1333,7 @@ namespace array {
if (lengthA == 0) goto Succeed; if (lengthA == 0) goto Succeed;
if (nofWinsA >= minGallop) break; if (nofWinsA >= minGallop) break;
} else { } else {
CallStore( CallStore(context, sortState, store, dest, tempArray[cursorTemp])
context, sortState, store, elements, dest,
tempArray[cursorTemp])
otherwise Bailout; otherwise Bailout;
--cursorTemp; --cursorTemp;
...@@ -1437,9 +1363,8 @@ namespace array { ...@@ -1437,9 +1363,8 @@ namespace array {
let k: Smi = CallGallopRight( let k: Smi = CallGallopRight(
context, sortState, load, tempArray[cursorTemp], baseA, lengthA, context, sortState, load, tempArray[cursorTemp], baseA, lengthA,
lengthA - 1, False) lengthA - 1)
otherwise Bailout; otherwise Bailout;
elements = ReloadElements(sortState);
assert(k >= 0); assert(k >= 0);
nofWinsA = lengthA - k; nofWinsA = lengthA - k;
...@@ -1447,25 +1372,21 @@ namespace array { ...@@ -1447,25 +1372,21 @@ namespace array {
dest = dest - nofWinsA; dest = dest - nofWinsA;
cursorA = cursorA - nofWinsA; cursorA = cursorA - nofWinsA;
CallCopyWithinSortArray( CallCopyWithinSortArray(
context, sortState, elements, cursorA + 1, dest + 1, nofWinsA) context, sortState, cursorA + 1, dest + 1, nofWinsA)
otherwise Bailout; otherwise Bailout;
lengthA = lengthA - nofWinsA; lengthA = lengthA - nofWinsA;
if (lengthA == 0) goto Succeed; if (lengthA == 0) goto Succeed;
} }
CallStore( CallStore(context, sortState, store, dest--, tempArray[cursorTemp--])
context, sortState, store, elements, dest--,
tempArray[cursorTemp--])
otherwise Bailout; otherwise Bailout;
if (--lengthB == 1) goto CopyA; if (--lengthB == 1) goto CopyA;
let key: Object = let key: Object = CallLoad(context, sortState, load, cursorA)
CallLoad(context, sortState, load, elements, cursorA)
otherwise Bailout; otherwise Bailout;
k = CallGallopLeft( k = CallGallopLeft(
context, sortState, Load<TempArrayElements>, key, 0, lengthB, context, sortState, Load<TempArrayElements>, key, 0, lengthB,
lengthB - 1, True) otherwise Bailout; lengthB - 1) otherwise Bailout;
elements = ReloadElements(sortState);
assert(k >= 0); assert(k >= 0);
nofWinsB = lengthB - k; nofWinsB = lengthB - k;
...@@ -1473,8 +1394,8 @@ namespace array { ...@@ -1473,8 +1394,8 @@ namespace array {
dest = dest - nofWinsB; dest = dest - nofWinsB;
cursorTemp = cursorTemp - nofWinsB; cursorTemp = cursorTemp - nofWinsB;
CallCopyFromTempArray( CallCopyFromTempArray(
context, sortState, elements, dest + 1, tempArray, context, sortState, dest + 1, cursorTemp + 1, nofWinsB)
cursorTemp + 1, nofWinsB) otherwise Bailout; otherwise Bailout;
lengthB = lengthB - nofWinsB; lengthB = lengthB - nofWinsB;
if (lengthB == 1) goto CopyA; if (lengthB == 1) goto CopyA;
...@@ -1483,8 +1404,7 @@ namespace array { ...@@ -1483,8 +1404,7 @@ namespace array {
// consistent, but we can't assume that it is. // consistent, but we can't assume that it is.
if (lengthB == 0) goto Succeed; if (lengthB == 0) goto Succeed;
} }
CopyElement( CopyElement(context, sortState, load, store, cursorA--, dest--)
context, sortState, load, store, elements, cursorA--, dest--)
otherwise Bailout; otherwise Bailout;
if (--lengthA == 0) goto Succeed; if (--lengthA == 0) goto Succeed;
} }
...@@ -1496,8 +1416,8 @@ namespace array { ...@@ -1496,8 +1416,8 @@ namespace array {
if (lengthB > 0) { if (lengthB > 0) {
assert(lengthA == 0); assert(lengthA == 0);
CallCopyFromTempArray( CallCopyFromTempArray(
context, sortState, elements, dest - (lengthB - 1), tempArray, 0, context, sortState, dest - (lengthB - 1), 0, lengthB)
lengthB) otherwise Bailout; otherwise Bailout;
} }
} }
label CopyA { label CopyA {
...@@ -1507,10 +1427,9 @@ namespace array { ...@@ -1507,10 +1427,9 @@ namespace array {
dest = dest - lengthA; dest = dest - lengthA;
cursorA = cursorA - lengthA; cursorA = cursorA - lengthA;
CallCopyWithinSortArray( CallCopyWithinSortArray(
context, sortState, elements, cursorA + 1, dest + 1, lengthA) context, sortState, cursorA + 1, dest + 1, lengthA)
otherwise Bailout; otherwise Bailout;
CallStore( CallStore(context, sortState, store, dest, tempArray[cursorTemp])
context, sortState, store, elements, dest, tempArray[cursorTemp])
otherwise Bailout; otherwise Bailout;
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment