зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1364346
part 1 - Optimize Array.prototype.unshift fast path and use it more. r=anba
This commit is contained in:
Родитель
a24f22ae22
Коммит
b37455bce0
|
@ -2485,41 +2485,41 @@ js::array_unshift(JSContext* cx, unsigned argc, Value* vp)
|
||||||
|
|
||||||
// Steps 3-4.
|
// Steps 3-4.
|
||||||
if (args.length() > 0) {
|
if (args.length() > 0) {
|
||||||
/* Slide up the array to make room for all args at the bottom. */
|
// Only include a fast path for native objects. Unboxed arrays can't
|
||||||
if (length > 0) {
|
// be optimized here because unshifting temporarily places holes at
|
||||||
// Only include a fast path for boxed arrays. Unboxed arrays can't
|
// the start of the array.
|
||||||
// be optimized here because unshifting temporarily places holes at
|
// TODO: Implement unboxed array optimization similar to the one in
|
||||||
// the start of the array.
|
// array_splice_impl(), unshift() is a special version of splice():
|
||||||
// TODO: Implement unboxed array optimization similar to the one in
|
// arr.unshift(...values) ~= arr.splice(0, 0, ...values).
|
||||||
// array_splice_impl(), unshift() is a special version of splice():
|
bool optimized = false;
|
||||||
// arr.unshift(...values) ~= arr.splice(0, 0, ...values).
|
do {
|
||||||
bool optimized = false;
|
if (length > UINT32_MAX)
|
||||||
do {
|
break;
|
||||||
if (length > UINT32_MAX)
|
if (!obj->isNative())
|
||||||
break;
|
break;
|
||||||
if (!obj->is<ArrayObject>())
|
if (ObjectMayHaveExtraIndexedProperties(obj))
|
||||||
break;
|
break;
|
||||||
if (ObjectMayHaveExtraIndexedProperties(obj))
|
if (MaybeInIteration(obj, cx))
|
||||||
break;
|
break;
|
||||||
if (MaybeInIteration(obj, cx))
|
NativeObject* nobj = &obj->as<NativeObject>();
|
||||||
break;
|
if (nobj->is<ArrayObject>() && !nobj->as<ArrayObject>().lengthIsWritable())
|
||||||
ArrayObject* aobj = &obj->as<ArrayObject>();
|
break;
|
||||||
if (!aobj->lengthIsWritable())
|
DenseElementResult result = nobj->ensureDenseElements(cx, uint32_t(length), args.length());
|
||||||
break;
|
if (result != DenseElementResult::Success) {
|
||||||
DenseElementResult result = aobj->ensureDenseElements(cx, uint32_t(length), args.length());
|
if (result == DenseElementResult::Failure)
|
||||||
if (result != DenseElementResult::Success) {
|
return false;
|
||||||
if (result == DenseElementResult::Failure)
|
MOZ_ASSERT(result == DenseElementResult::Incomplete);
|
||||||
return false;
|
break;
|
||||||
MOZ_ASSERT(result == DenseElementResult::Incomplete);
|
}
|
||||||
break;
|
if (length > 0)
|
||||||
}
|
nobj->moveDenseElements(args.length(), 0, uint32_t(length));
|
||||||
aobj->moveDenseElements(args.length(), 0, uint32_t(length));
|
for (uint32_t i = 0; i < args.length(); i++)
|
||||||
for (uint32_t i = 0; i < args.length(); i++)
|
nobj->setDenseElementWithType(cx, i, args[i]);
|
||||||
aobj->setDenseElement(i, MagicValue(JS_ELEMENTS_HOLE));
|
optimized = true;
|
||||||
optimized = true;
|
} while (false);
|
||||||
} while (false);
|
|
||||||
|
|
||||||
if (!optimized) {
|
if (!optimized) {
|
||||||
|
if (length > 0) {
|
||||||
uint64_t last = length;
|
uint64_t last = length;
|
||||||
uint64_t upperIndex = last + args.length();
|
uint64_t upperIndex = last + args.length();
|
||||||
|
|
||||||
|
@ -2547,12 +2547,12 @@ js::array_unshift(JSContext* cx, unsigned argc, Value* vp)
|
||||||
}
|
}
|
||||||
} while (last != 0);
|
} while (last != 0);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Steps 4.d-f.
|
// Steps 4.d-f.
|
||||||
/* Copy from args to the bottom of the array. */
|
/* Copy from args to the bottom of the array. */
|
||||||
if (!SetArrayElements(cx, obj, 0, args.length(), args.array()))
|
if (!SetArrayElements(cx, obj, 0, args.length(), args.array()))
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 5.
|
// Step 5.
|
||||||
|
|
Загрузка…
Ссылка в новой задаче