Always run our fast array builtins.
Before, we carefully turned on fast array builtins only if flag --enable-fast-array-builtins was true (though it was implied true if --turbo was on). Now, the set of Array.prototype.{some, forEach, every, reduce} is good enough to always turn them on. This means we can remove the JavaScript implementations. The flag is renamed to --experimental-fast-array-builtins, which is off. In the next days we'll add more non-javascript implementations here for testing. BUG= R=danno@chromium.org Review-Url: https://codereview.chromium.org/2761783002 Cr-Commit-Position: refs/heads/master@{#44026}
This commit is contained in:
parent
8f033c2d0b
commit
1fe5f0e3ad
@ -218,7 +218,7 @@ class Genesis BASE_EMBEDDED {
|
||||
|
||||
void InstallOneBuiltinFunction(const char* object, const char* method,
|
||||
Builtins::Name name);
|
||||
void InitializeGlobal_enable_fast_array_builtins();
|
||||
void InitializeGlobal_experimental_fast_array_builtins();
|
||||
|
||||
Handle<JSFunction> InstallArrayBuffer(Handle<JSObject> target,
|
||||
const char* name, Builtins::Name call,
|
||||
@ -433,6 +433,24 @@ Handle<JSFunction> SimpleCreateFunction(Isolate* isolate, Handle<String> name,
|
||||
return fun;
|
||||
}
|
||||
|
||||
Handle<JSFunction> InstallArrayBuiltinFunction(Handle<JSObject> base,
|
||||
const char* name,
|
||||
Builtins::Name call,
|
||||
int argument_count) {
|
||||
Isolate* isolate = base->GetIsolate();
|
||||
Handle<String> str_name = isolate->factory()->InternalizeUtf8String(name);
|
||||
Handle<JSFunction> fun =
|
||||
CreateFunction(isolate, str_name, JS_OBJECT_TYPE, JSObject::kHeaderSize,
|
||||
MaybeHandle<JSObject>(), call, true);
|
||||
fun->shared()->set_internal_formal_parameter_count(argument_count);
|
||||
|
||||
// Set the length to 1 to satisfy ECMA-262.
|
||||
fun->shared()->set_length(1);
|
||||
fun->shared()->set_language_mode(STRICT);
|
||||
InstallFunction(base, fun, str_name);
|
||||
return fun;
|
||||
}
|
||||
|
||||
Handle<JSFunction> SimpleInstallFunction(Handle<JSObject> base,
|
||||
Handle<String> name,
|
||||
Builtins::Name call, int len,
|
||||
@ -3066,10 +3084,9 @@ void Genesis::InitializeExperimentalGlobal() {
|
||||
HARMONY_SHIPPING(FEATURE_INITIALIZE_GLOBAL)
|
||||
#undef FEATURE_INITIALIZE_GLOBAL
|
||||
|
||||
InitializeGlobal_enable_fast_array_builtins();
|
||||
InitializeGlobal_experimental_fast_array_builtins();
|
||||
}
|
||||
|
||||
|
||||
bool Bootstrapper::CompileBuiltin(Isolate* isolate, int index) {
|
||||
Vector<const char> name = Natives::GetScriptName(index);
|
||||
Handle<String> source_code =
|
||||
@ -3689,17 +3706,11 @@ void Genesis::InstallOneBuiltinFunction(const char* object_name,
|
||||
isolate->builtins()->builtin(builtin_name));
|
||||
}
|
||||
|
||||
void Genesis::InitializeGlobal_enable_fast_array_builtins() {
|
||||
if (!FLAG_enable_fast_array_builtins) return;
|
||||
void Genesis::InitializeGlobal_experimental_fast_array_builtins() {
|
||||
if (!FLAG_experimental_fast_array_builtins) return;
|
||||
|
||||
InstallOneBuiltinFunction("Array", "forEach", Builtins::kArrayForEach);
|
||||
InstallOneBuiltinFunction("Array", "every", Builtins::kArrayEvery);
|
||||
InstallOneBuiltinFunction("Array", "some", Builtins::kArraySome);
|
||||
InstallOneBuiltinFunction("Array", "reduce", Builtins::kArrayReduce);
|
||||
|
||||
if (FLAG_experimental_array_builtins) {
|
||||
InstallOneBuiltinFunction("Array", "filter", Builtins::kArrayFilter);
|
||||
}
|
||||
// Insert experimental fast array builtins here.
|
||||
InstallOneBuiltinFunction("Array", "filter", Builtins::kArrayFilter);
|
||||
}
|
||||
|
||||
void Genesis::InitializeGlobal_harmony_sharedarraybuffer() {
|
||||
@ -4143,10 +4154,21 @@ bool Genesis::InstallNatives(GlobalContextType context_type) {
|
||||
SimpleInstallFunction(global_object, "isNaN", Builtins::kGlobalIsNaN, 1, true,
|
||||
kGlobalIsNaN);
|
||||
|
||||
// Install Array.prototype.concat
|
||||
// Install Array builtin functions.
|
||||
{
|
||||
Handle<JSFunction> array_constructor(native_context()->array_function());
|
||||
Handle<JSObject> proto(JSObject::cast(array_constructor->prototype()));
|
||||
Handle<JSArray> proto(JSArray::cast(array_constructor->prototype()));
|
||||
|
||||
// Verification of important array prototype properties.
|
||||
Object* length = proto->length();
|
||||
CHECK(length->IsSmi());
|
||||
CHECK(Smi::cast(length)->value() == 0);
|
||||
CHECK(proto->HasFastSmiOrObjectElements());
|
||||
// This is necessary to enable fast checks for absence of elements
|
||||
// on Array.prototype and below.
|
||||
proto->set_elements(heap()->empty_fixed_array());
|
||||
|
||||
// Install Array.prototype.concat
|
||||
Handle<JSFunction> concat =
|
||||
InstallFunction(proto, "concat", JS_OBJECT_TYPE, JSObject::kHeaderSize,
|
||||
MaybeHandle<JSObject>(), Builtins::kArrayConcat);
|
||||
@ -4158,6 +4180,21 @@ bool Genesis::InstallNatives(GlobalContextType context_type) {
|
||||
DCHECK(concat->is_compiled());
|
||||
// Set the lengths for the functions to satisfy ECMA-262.
|
||||
concat->shared()->set_length(1);
|
||||
|
||||
// Install Array.prototype.forEach
|
||||
Handle<JSFunction> forEach = InstallArrayBuiltinFunction(
|
||||
proto, "forEach", Builtins::kArrayForEach, 2);
|
||||
// Add forEach to the context.
|
||||
native_context()->set_array_for_each_iterator(*forEach);
|
||||
|
||||
// Install Array.prototype.every
|
||||
InstallArrayBuiltinFunction(proto, "every", Builtins::kArrayEvery, 2);
|
||||
|
||||
// Install Array.prototype.some
|
||||
InstallArrayBuiltinFunction(proto, "some", Builtins::kArraySome, 2);
|
||||
|
||||
// Install Array.prototype.reduce
|
||||
InstallArrayBuiltinFunction(proto, "reduce", Builtins::kArrayReduce, 2);
|
||||
}
|
||||
|
||||
// Install InternalArray.prototype.concat
|
||||
|
@ -269,7 +269,6 @@ DEFINE_BOOL(future, FUTURE_BOOL,
|
||||
DEFINE_IMPLICATION(future, turbo)
|
||||
|
||||
DEFINE_DUAL_IMPLICATION(turbo, ignition)
|
||||
DEFINE_DUAL_IMPLICATION(turbo, enable_fast_array_builtins)
|
||||
DEFINE_DUAL_IMPLICATION(turbo, thin_strings)
|
||||
|
||||
// Flags for experimental implementation features.
|
||||
@ -772,9 +771,8 @@ DEFINE_BOOL(builtins_in_stack_traces, false,
|
||||
"show built-in functions in stack traces")
|
||||
|
||||
// builtins.cc
|
||||
DEFINE_BOOL(enable_fast_array_builtins, false, "use optimized builtins")
|
||||
DEFINE_BOOL(experimental_array_builtins, false,
|
||||
"Experimental versions of array builtins")
|
||||
DEFINE_BOOL(experimental_fast_array_builtins, false,
|
||||
"use experimental array builtins")
|
||||
DEFINE_BOOL(allow_unsafe_function_constructor, false,
|
||||
"allow invoking the function constructor without security checks")
|
||||
|
||||
|
136
src/js/array.js
136
src/js/array.js
@ -1033,88 +1033,6 @@ function ArrayFilter(f, receiver) {
|
||||
return InnerArrayFilter(f, receiver, array, length, result);
|
||||
}
|
||||
|
||||
|
||||
function InnerArrayForEach(f, receiver, array, length) {
|
||||
if (!IS_CALLABLE(f)) throw %make_type_error(kCalledNonCallable, f);
|
||||
|
||||
if (IS_UNDEFINED(receiver)) {
|
||||
for (var i = 0; i < length; i++) {
|
||||
if (i in array) {
|
||||
var element = array[i];
|
||||
f(element, i, array);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (var i = 0; i < length; i++) {
|
||||
if (i in array) {
|
||||
var element = array[i];
|
||||
%_Call(f, receiver, element, i, array);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function ArrayForEach(f, receiver) {
|
||||
CHECK_OBJECT_COERCIBLE(this, "Array.prototype.forEach");
|
||||
|
||||
// Pull out the length so that modifications to the length in the
|
||||
// loop will not affect the looping and side effects are visible.
|
||||
var array = TO_OBJECT(this);
|
||||
var length = TO_LENGTH(array.length);
|
||||
InnerArrayForEach(f, receiver, array, length);
|
||||
}
|
||||
|
||||
|
||||
function InnerArraySome(f, receiver, array, length) {
|
||||
if (!IS_CALLABLE(f)) throw %make_type_error(kCalledNonCallable, f);
|
||||
|
||||
for (var i = 0; i < length; i++) {
|
||||
if (i in array) {
|
||||
var element = array[i];
|
||||
if (%_Call(f, receiver, element, i, array)) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Executes the function once for each element present in the
|
||||
// array until it finds one where callback returns true.
|
||||
function ArraySome(f, receiver) {
|
||||
CHECK_OBJECT_COERCIBLE(this, "Array.prototype.some");
|
||||
|
||||
// Pull out the length so that modifications to the length in the
|
||||
// loop will not affect the looping and side effects are visible.
|
||||
var array = TO_OBJECT(this);
|
||||
var length = TO_LENGTH(array.length);
|
||||
return InnerArraySome(f, receiver, array, length);
|
||||
}
|
||||
|
||||
|
||||
function InnerArrayEvery(f, receiver, array, length) {
|
||||
if (!IS_CALLABLE(f)) throw %make_type_error(kCalledNonCallable, f);
|
||||
|
||||
for (var i = 0; i < length; i++) {
|
||||
if (i in array) {
|
||||
var element = array[i];
|
||||
if (!%_Call(f, receiver, element, i, array)) return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function ArrayEvery(f, receiver) {
|
||||
CHECK_OBJECT_COERCIBLE(this, "Array.prototype.every");
|
||||
|
||||
// Pull out the length so that modifications to the length in the
|
||||
// loop will not affect the looping and side effects are visible.
|
||||
var array = TO_OBJECT(this);
|
||||
var length = TO_LENGTH(array.length);
|
||||
return InnerArrayEvery(f, receiver, array, length);
|
||||
}
|
||||
|
||||
|
||||
function ArrayMap(f, receiver) {
|
||||
CHECK_OBJECT_COERCIBLE(this, "Array.prototype.map");
|
||||
|
||||
@ -1188,45 +1106,6 @@ function ArrayLastIndexOf(element, index) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
function InnerArrayReduce(callback, current, array, length, argumentsLength) {
|
||||
if (!IS_CALLABLE(callback)) {
|
||||
throw %make_type_error(kCalledNonCallable, callback);
|
||||
}
|
||||
|
||||
var i = 0;
|
||||
find_initial: if (argumentsLength < 2) {
|
||||
for (; i < length; i++) {
|
||||
if (i in array) {
|
||||
current = array[i++];
|
||||
break find_initial;
|
||||
}
|
||||
}
|
||||
throw %make_type_error(kReduceNoInitial);
|
||||
}
|
||||
|
||||
for (; i < length; i++) {
|
||||
if (i in array) {
|
||||
var element = array[i];
|
||||
current = callback(current, element, i, array);
|
||||
}
|
||||
}
|
||||
return current;
|
||||
}
|
||||
|
||||
|
||||
function ArrayReduce(callback, current) {
|
||||
CHECK_OBJECT_COERCIBLE(this, "Array.prototype.reduce");
|
||||
|
||||
// Pull out the length so that modifications to the length in the
|
||||
// loop will not affect the looping and side effects are visible.
|
||||
var array = TO_OBJECT(this);
|
||||
var length = TO_LENGTH(array.length);
|
||||
return InnerArrayReduce(callback, current, array, length,
|
||||
arguments.length);
|
||||
}
|
||||
|
||||
|
||||
function InnerArrayReduceRight(callback, current, array, length,
|
||||
argumentsLength) {
|
||||
if (!IS_CALLABLE(callback)) {
|
||||
@ -1522,7 +1401,6 @@ function getFunction(name, jsBuiltin, len) {
|
||||
// public API via Template::SetIntrinsicDataProperty().
|
||||
var IteratorFunctions = {
|
||||
"entries": getFunction("entries", null, 0),
|
||||
"forEach": getFunction("forEach", ArrayForEach, 1),
|
||||
"keys": getFunction("keys", null, 0),
|
||||
"values": getFunction("values", null, 0)
|
||||
}
|
||||
@ -1544,12 +1422,9 @@ utils.InstallFunctions(GlobalArray.prototype, DONT_ENUM, [
|
||||
"splice", getFunction("splice", ArraySplice, 2),
|
||||
"sort", getFunction("sort", ArraySort),
|
||||
"filter", getFunction("filter", ArrayFilter, 1),
|
||||
"some", getFunction("some", ArraySome, 1),
|
||||
"every", getFunction("every", ArrayEvery, 1),
|
||||
"map", getFunction("map", ArrayMap, 1),
|
||||
"indexOf", getFunction("indexOf", null, 1),
|
||||
"lastIndexOf", getFunction("lastIndexOf", ArrayLastIndexOf, 1),
|
||||
"reduce", getFunction("reduce", ArrayReduce, 1),
|
||||
"reduceRight", getFunction("reduceRight", ArrayReduceRight, 1),
|
||||
"copyWithin", getFunction("copyWithin", ArrayCopyWithin, 2),
|
||||
"find", getFunction("find", ArrayFind, 1),
|
||||
@ -1557,20 +1432,14 @@ utils.InstallFunctions(GlobalArray.prototype, DONT_ENUM, [
|
||||
"fill", getFunction("fill", ArrayFill, 1),
|
||||
"includes", getFunction("includes", null, 1),
|
||||
"entries", IteratorFunctions.entries,
|
||||
"forEach", IteratorFunctions.forEach,
|
||||
"keys", IteratorFunctions.keys,
|
||||
iteratorSymbol, IteratorFunctions.values
|
||||
]);
|
||||
|
||||
utils.ForEachFunction = GlobalArray.prototype.forEach;
|
||||
|
||||
%FunctionSetName(IteratorFunctions.entries, "entries");
|
||||
%FunctionSetName(IteratorFunctions.forEach, "forEach");
|
||||
%FunctionSetName(IteratorFunctions.keys, "keys");
|
||||
%FunctionSetName(IteratorFunctions.values, "values");
|
||||
|
||||
%FinishArrayPrototypeSetup(GlobalArray.prototype);
|
||||
|
||||
// The internal Array prototype doesn't need to be fancy, since it's never
|
||||
// exposed to user code.
|
||||
// Adding only the functions that are actually used.
|
||||
@ -1611,15 +1480,11 @@ utils.Export(function(to) {
|
||||
to.ArrayPush = ArrayPush;
|
||||
to.ArrayToString = ArrayToString;
|
||||
to.ArrayValues = IteratorFunctions.values,
|
||||
to.InnerArrayEvery = InnerArrayEvery;
|
||||
to.InnerArrayFilter = InnerArrayFilter;
|
||||
to.InnerArrayFind = InnerArrayFind;
|
||||
to.InnerArrayFindIndex = InnerArrayFindIndex;
|
||||
to.InnerArrayForEach = InnerArrayForEach;
|
||||
to.InnerArrayJoin = InnerArrayJoin;
|
||||
to.InnerArrayReduce = InnerArrayReduce;
|
||||
to.InnerArrayReduceRight = InnerArrayReduceRight;
|
||||
to.InnerArraySome = InnerArraySome;
|
||||
to.InnerArraySort = InnerArraySort;
|
||||
to.InnerArrayToLocaleString = InnerArrayToLocaleString;
|
||||
to.PackedArrayReverse = PackedArrayReverse;
|
||||
@ -1627,7 +1492,6 @@ utils.Export(function(to) {
|
||||
|
||||
%InstallToContext([
|
||||
"array_entries_iterator", IteratorFunctions.entries,
|
||||
"array_for_each_iterator", IteratorFunctions.forEach,
|
||||
"array_keys_iterator", IteratorFunctions.keys,
|
||||
"array_pop", ArrayPop,
|
||||
"array_push", ArrayPush,
|
||||
|
@ -20,15 +20,11 @@ var GlobalArray = global.Array;
|
||||
var GlobalArrayBuffer = global.ArrayBuffer;
|
||||
var GlobalArrayBufferPrototype = GlobalArrayBuffer.prototype;
|
||||
var GlobalObject = global.Object;
|
||||
var InnerArrayEvery;
|
||||
var InnerArrayFilter;
|
||||
var InnerArrayFind;
|
||||
var InnerArrayFindIndex;
|
||||
var InnerArrayForEach;
|
||||
var InnerArrayJoin;
|
||||
var InnerArrayReduce;
|
||||
var InnerArrayReduceRight;
|
||||
var InnerArraySome;
|
||||
var InnerArraySort;
|
||||
var InnerArrayToLocaleString;
|
||||
var InternalArray = utils.InternalArray;
|
||||
@ -66,15 +62,11 @@ utils.Import(function(from) {
|
||||
ArrayValues = from.ArrayValues;
|
||||
GetIterator = from.GetIterator;
|
||||
GetMethod = from.GetMethod;
|
||||
InnerArrayEvery = from.InnerArrayEvery;
|
||||
InnerArrayFilter = from.InnerArrayFilter;
|
||||
InnerArrayFind = from.InnerArrayFind;
|
||||
InnerArrayFindIndex = from.InnerArrayFindIndex;
|
||||
InnerArrayForEach = from.InnerArrayForEach;
|
||||
InnerArrayJoin = from.InnerArrayJoin;
|
||||
InnerArrayReduce = from.InnerArrayReduce;
|
||||
InnerArrayReduceRight = from.InnerArrayReduceRight;
|
||||
InnerArraySome = from.InnerArraySome;
|
||||
InnerArraySort = from.InnerArraySort;
|
||||
InnerArrayToLocaleString = from.InnerArrayToLocaleString;
|
||||
MaxSimple = from.MaxSimple;
|
||||
@ -371,6 +363,17 @@ function TypedArrayGetToStringTag() {
|
||||
return name;
|
||||
}
|
||||
|
||||
function InnerTypedArrayEvery(f, receiver, array, length) {
|
||||
if (!IS_CALLABLE(f)) throw %make_type_error(kCalledNonCallable, f);
|
||||
|
||||
for (var i = 0; i < length; i++) {
|
||||
if (i in array) {
|
||||
var element = array[i];
|
||||
if (!%_Call(f, receiver, element, i, array)) return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// ES6 draft 05-05-15, section 22.2.3.7
|
||||
function TypedArrayEvery(f, receiver) {
|
||||
@ -378,10 +381,29 @@ function TypedArrayEvery(f, receiver) {
|
||||
|
||||
var length = %_TypedArrayGetLength(this);
|
||||
|
||||
return InnerArrayEvery(f, receiver, this, length);
|
||||
return InnerTypedArrayEvery(f, receiver, this, length);
|
||||
}
|
||||
%FunctionSetLength(TypedArrayEvery, 1);
|
||||
|
||||
function InnerTypedArrayForEach(f, receiver, array, length) {
|
||||
if (!IS_CALLABLE(f)) throw %make_type_error(kCalledNonCallable, f);
|
||||
|
||||
if (IS_UNDEFINED(receiver)) {
|
||||
for (var i = 0; i < length; i++) {
|
||||
if (i in array) {
|
||||
var element = array[i];
|
||||
f(element, i, array);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (var i = 0; i < length; i++) {
|
||||
if (i in array) {
|
||||
var element = array[i];
|
||||
%_Call(f, receiver, element, i, array);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ES6 draft 08-24-14, section 22.2.3.12
|
||||
function TypedArrayForEach(f, receiver) {
|
||||
@ -389,7 +411,7 @@ function TypedArrayForEach(f, receiver) {
|
||||
|
||||
var length = %_TypedArrayGetLength(this);
|
||||
|
||||
InnerArrayForEach(f, receiver, this, length);
|
||||
InnerTypedArrayForEach(f, receiver, this, length);
|
||||
}
|
||||
%FunctionSetLength(TypedArrayForEach, 1);
|
||||
|
||||
@ -472,6 +494,17 @@ function TypedArrayMap(f, thisArg) {
|
||||
}
|
||||
%FunctionSetLength(TypedArrayMap, 1);
|
||||
|
||||
function InnerTypedArraySome(f, receiver, array, length) {
|
||||
if (!IS_CALLABLE(f)) throw %make_type_error(kCalledNonCallable, f);
|
||||
|
||||
for (var i = 0; i < length; i++) {
|
||||
if (i in array) {
|
||||
var element = array[i];
|
||||
if (%_Call(f, receiver, element, i, array)) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// ES6 draft 05-05-15, section 22.2.3.24
|
||||
function TypedArraySome(f, receiver) {
|
||||
@ -479,7 +512,7 @@ function TypedArraySome(f, receiver) {
|
||||
|
||||
var length = %_TypedArrayGetLength(this);
|
||||
|
||||
return InnerArraySome(f, receiver, this, length);
|
||||
return InnerTypedArraySome(f, receiver, this, length);
|
||||
}
|
||||
%FunctionSetLength(TypedArraySome, 1);
|
||||
|
||||
@ -503,14 +536,39 @@ function TypedArrayJoin(separator) {
|
||||
return InnerArrayJoin(separator, this, length);
|
||||
}
|
||||
|
||||
function InnerTypedArrayReduce(
|
||||
callback, current, array, length, argumentsLength) {
|
||||
if (!IS_CALLABLE(callback)) {
|
||||
throw %make_type_error(kCalledNonCallable, callback);
|
||||
}
|
||||
|
||||
var i = 0;
|
||||
find_initial: if (argumentsLength < 2) {
|
||||
for (; i < length; i++) {
|
||||
if (i in array) {
|
||||
current = array[i++];
|
||||
break find_initial;
|
||||
}
|
||||
}
|
||||
throw %make_type_error(kReduceNoInitial);
|
||||
}
|
||||
|
||||
for (; i < length; i++) {
|
||||
if (i in array) {
|
||||
var element = array[i];
|
||||
current = callback(current, element, i, array);
|
||||
}
|
||||
}
|
||||
return current;
|
||||
}
|
||||
|
||||
// ES6 draft 07-15-13, section 22.2.3.19
|
||||
function TypedArrayReduce(callback, current) {
|
||||
if (!IS_TYPEDARRAY(this)) throw %make_type_error(kNotTypedArray);
|
||||
|
||||
var length = %_TypedArrayGetLength(this);
|
||||
return InnerArrayReduce(callback, current, this, length,
|
||||
arguments.length);
|
||||
return InnerTypedArrayReduce(
|
||||
callback, current, this, length, arguments.length);
|
||||
}
|
||||
%FunctionSetLength(TypedArrayReduce, 1);
|
||||
|
||||
|
@ -17,20 +17,6 @@
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_FinishArrayPrototypeSetup) {
|
||||
HandleScope scope(isolate);
|
||||
DCHECK_EQ(1, args.length());
|
||||
CONVERT_ARG_HANDLE_CHECKED(JSArray, prototype, 0);
|
||||
Object* length = prototype->length();
|
||||
CHECK(length->IsSmi());
|
||||
CHECK(Smi::cast(length)->value() == 0);
|
||||
CHECK(prototype->HasFastSmiOrObjectElements());
|
||||
// This is necessary to enable fast checks for absence of elements
|
||||
// on Array.prototype and below.
|
||||
prototype->set_elements(isolate->heap()->empty_fixed_array());
|
||||
return Smi::kZero;
|
||||
}
|
||||
|
||||
static void InstallCode(
|
||||
Isolate* isolate, Handle<JSObject> holder, const char* name,
|
||||
Handle<Code> code, int argc = -1,
|
||||
|
@ -37,7 +37,6 @@ namespace internal {
|
||||
// are specified by inline comments
|
||||
|
||||
#define FOR_EACH_INTRINSIC_ARRAY(F) \
|
||||
F(FinishArrayPrototypeSetup, 1, 1) \
|
||||
F(SpecialArrayFunctions, 0, 1) \
|
||||
F(TransitionElementsKind, 2, 1) \
|
||||
F(RemoveArrayHoles, 2, 1) \
|
||||
|
Loading…
Reference in New Issue
Block a user