[builtins] Remove InternalArray and reduce InternalPackedArray constructors.

InternalPackedArray now only has one constructor variant that expects no
arguments (Chrome's only usage of InternalPackedArray). As such, these TFC
builtins are no longer used and were removed:
- InternalArrayNoArgumentConstructor_Holey
- InternalArraySingleArgumentConstructor_Packed
- InternalArraySingleArgumentConstructor_Holey

On x64.release, this reduces builtins size by ~1.2KB.

Bug: v8:7624
Change-Id: I7316608dc02b1e09e9e414ee1aeb1fb08410c6f6
Reviewed-on: https://chromium-review.googlesource.com/c/1372772
Commit-Queue: Peter Wong <peter.wm.wong@gmail.com>
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#58193}
This commit is contained in:
peterwmwong 2018-12-12 09:15:13 -06:00 committed by Commit Bot
parent 2aaf34a23b
commit 640d3adf5f
19 changed files with 144 additions and 653 deletions

View File

@ -26,8 +26,8 @@ namespace internal {
V(kInputStringTooLong, "Input string too long") \
V(kInvalidBytecode, "Invalid bytecode") \
V(kInvalidBytecodeAdvance, "Cannot advance current bytecode, ") \
V(kInvalidElementsKindForInternalArrayOrInternalPackedArray, \
"Invalid ElementsKind for InternalArray or InternalPackedArray") \
V(kInvalidElementsKindForInternalPackedArray, \
"Invalid ElementsKind for InternalPackedArray") \
V(kInvalidHandleScopeLevel, "Invalid HandleScope level") \
V(kInvalidJumpTableIndex, "Invalid jump table index") \
V(kInvalidParametersAndRegistersInGenerator, \
@ -86,6 +86,8 @@ namespace internal {
"Wrong number of arguments for intrinsic") \
V(kWrongFunctionCodeStart, "Wrong value in code start register passed") \
V(kWrongFunctionContext, "Wrong context passed to function") \
V(kWrongNumberOfArgumentsForInternalPackedArray, \
"Wrong number of arguments for InternalPackedArray") \
V(kUnexpectedThreadInWasmSet, "thread_in_wasm flag was already set") \
V(kUnexpectedThreadInWasmUnset, "thread_in_wasm flag was not set")

View File

@ -5017,20 +5017,6 @@ bool Genesis::InstallNatives() {
native_context()->set_opaque_reference_function(*opaque_reference_fun);
}
// InternalArrays should not use Smi-Only array optimizations. There are too
// many places in the C++ runtime code (e.g. RegEx) that assume that
// elements in InternalArrays can be set to non-Smi values without going
// through a common bottleneck that would make the SMI_ONLY -> FAST_ELEMENT
// transition easy to trap. Moreover, they rarely are smi-only.
{
HandleScope scope(isolate());
Handle<JSObject> utils =
Handle<JSObject>::cast(isolate()->natives_utils_object());
Handle<JSFunction> array_function =
InstallInternalArray(utils, "InternalArray", HOLEY_ELEMENTS);
native_context()->set_internal_array_function(*array_function);
}
// Run the rest of the native scripts.
while (builtin_index < Natives::GetBuiltinsCount()) {
if (!Bootstrapper::CompileBuiltin(isolate(), builtin_index++)) return false;
@ -5135,16 +5121,6 @@ bool Genesis::InstallNatives() {
proto->set_elements(ReadOnlyRoots(heap()).empty_fixed_array());
}
// Install InternalArray.prototype.concat
{
Handle<JSFunction> array_constructor(
native_context()->internal_array_function(), isolate());
Handle<JSObject> proto(JSObject::cast(array_constructor->prototype()),
isolate());
SimpleInstallFunction(isolate(), proto, "concat", Builtins::kArrayConcat, 1,
false);
}
InstallBuiltinFunctionIds();
// Create a map for accessor property descriptors (a variant of JSObject

View File

@ -2763,43 +2763,6 @@ void Builtins::Generate_MathPowInternal(MacroAssembler* masm) {
__ Ret();
}
namespace {
void GenerateInternalArrayConstructorCase(MacroAssembler* masm,
ElementsKind kind) {
// Load undefined into the allocation site parameter as required by
// ArrayNArgumentsConstructor.
__ LoadRoot(kJavaScriptCallExtraArg1Register, RootIndex::kUndefinedValue);
__ cmp(r0, Operand(1));
__ Jump(CodeFactory::InternalArrayNoArgumentConstructor(masm->isolate(), kind)
.code(),
RelocInfo::CODE_TARGET, lo);
Handle<Code> code = BUILTIN_CODE(masm->isolate(), ArrayNArgumentsConstructor);
__ Jump(code, RelocInfo::CODE_TARGET, hi);
if (IsFastPackedElementsKind(kind)) {
// We might need to create a holey array
// look at the first argument
__ ldr(r3, MemOperand(sp, 0));
__ cmp(r3, Operand::Zero());
__ Jump(CodeFactory::InternalArraySingleArgumentConstructor(
masm->isolate(), GetHoleyElementsKind(kind))
.code(),
RelocInfo::CODE_TARGET, ne);
}
__ Jump(
CodeFactory::InternalArraySingleArgumentConstructor(masm->isolate(), kind)
.code(),
RelocInfo::CODE_TARGET);
}
} // namespace
void Builtins::Generate_InternalArrayConstructorImpl(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- r0 : argc
@ -2819,34 +2782,27 @@ void Builtins::Generate_InternalArrayConstructorImpl(MacroAssembler* masm) {
__ Assert(ne, AbortReason::kUnexpectedInitialMapForArrayFunction);
__ CompareObjectType(r3, r3, r4, MAP_TYPE);
__ Assert(eq, AbortReason::kUnexpectedInitialMapForArrayFunction);
}
// Figure out the right elements kind
__ ldr(r3, FieldMemOperand(r1, JSFunction::kPrototypeOrInitialMapOffset));
// Load the map's "bit field 2" into |result|. We only need the first byte,
// but the following bit field extraction takes care of that anyway.
__ ldr(r3, FieldMemOperand(r3, Map::kBitField2Offset));
// Retrieve elements_kind from bit field 2.
__ DecodeField<Map::ElementsKindBits>(r3);
// Figure out the right elements kind
__ ldr(r3, FieldMemOperand(r1, JSFunction::kPrototypeOrInitialMapOffset));
// Load the map's "bit field 2" into |result|. We only need the first byte,
// but the following bit field extraction takes care of that anyway.
__ ldr(r3, FieldMemOperand(r3, Map::kBitField2Offset));
// Retrieve elements_kind from bit field 2.
__ DecodeField<Map::ElementsKindBits>(r3);
if (FLAG_debug_code) {
Label done;
// Initial elements kind should be packed elements.
__ cmp(r3, Operand(PACKED_ELEMENTS));
__ b(eq, &done);
__ cmp(r3, Operand(HOLEY_ELEMENTS));
__ Assert(
eq,
AbortReason::kInvalidElementsKindForInternalArrayOrInternalPackedArray);
__ bind(&done);
__ Assert(eq, AbortReason::kInvalidElementsKindForInternalPackedArray);
// No arguments should be passed.
__ cmp(r0, Operand(0));
__ Assert(eq, AbortReason::kWrongNumberOfArgumentsForInternalPackedArray);
}
Label fast_elements_case;
__ cmp(r3, Operand(PACKED_ELEMENTS));
__ b(eq, &fast_elements_case);
GenerateInternalArrayConstructorCase(masm, HOLEY_ELEMENTS);
__ bind(&fast_elements_case);
GenerateInternalArrayConstructorCase(masm, PACKED_ELEMENTS);
__ Jump(
BUILTIN_CODE(masm->isolate(), InternalArrayNoArgumentConstructor_Packed),
RelocInfo::CODE_TARGET);
}
namespace {

View File

@ -3322,54 +3322,6 @@ void Builtins::Generate_MathPowInternal(MacroAssembler* masm) {
__ Ret();
}
namespace {
void GenerateInternalArrayConstructorCase(MacroAssembler* masm,
ElementsKind kind) {
Label zero_case, n_case;
Register argc = x0;
__ Cbz(argc, &zero_case);
__ CompareAndBranch(argc, 1, ne, &n_case);
// One argument.
if (IsFastPackedElementsKind(kind)) {
Label packed_case;
// We might need to create a holey array; look at the first argument.
__ Peek(x10, 0);
__ Cbz(x10, &packed_case);
__ Jump(CodeFactory::InternalArraySingleArgumentConstructor(
masm->isolate(), GetHoleyElementsKind(kind))
.code(),
RelocInfo::CODE_TARGET);
__ Bind(&packed_case);
}
__ Jump(
CodeFactory::InternalArraySingleArgumentConstructor(masm->isolate(), kind)
.code(),
RelocInfo::CODE_TARGET);
__ Bind(&zero_case);
// No arguments.
__ Jump(CodeFactory::InternalArrayNoArgumentConstructor(masm->isolate(), kind)
.code(),
RelocInfo::CODE_TARGET);
__ Bind(&n_case);
// N arguments.
// Load undefined into the allocation site parameter as required by
// ArrayNArgumentsConstructor.
__ LoadRoot(kJavaScriptCallExtraArg1Register, RootIndex::kUndefinedValue);
Handle<Code> code = BUILTIN_CODE(masm->isolate(), ArrayNArgumentsConstructor);
__ Jump(code, RelocInfo::CODE_TARGET);
}
} // namespace
void Builtins::Generate_InternalArrayConstructorImpl(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- x0 : argc
@ -3394,31 +3346,27 @@ void Builtins::Generate_InternalArrayConstructorImpl(MacroAssembler* masm) {
__ Bind(&unexpected_map);
__ Abort(AbortReason::kUnexpectedInitialMapForArrayFunction);
__ Bind(&map_ok);
Register kind = w3;
// Figure out the right elements kind
__ Ldr(x10, FieldMemOperand(constructor,
JSFunction::kPrototypeOrInitialMapOffset));
// Retrieve elements_kind from map.
__ LoadElementsKindFromMap(kind, x10);
// Initial elements kind should be packed elements.
__ Cmp(kind, PACKED_ELEMENTS);
__ Assert(eq, AbortReason::kInvalidElementsKindForInternalPackedArray);
// No arguments should be passed.
__ Cmp(x0, 0);
__ Assert(eq, AbortReason::kWrongNumberOfArgumentsForInternalPackedArray);
}
Register kind = w3;
// Figure out the right elements kind
__ Ldr(x10, FieldMemOperand(constructor,
JSFunction::kPrototypeOrInitialMapOffset));
// Retrieve elements_kind from map.
__ LoadElementsKindFromMap(kind, x10);
if (FLAG_debug_code) {
Label done;
__ Cmp(x3, PACKED_ELEMENTS);
__ Ccmp(x3, HOLEY_ELEMENTS, ZFlag, ne);
__ Assert(
eq,
AbortReason::kInvalidElementsKindForInternalArrayOrInternalPackedArray);
}
Label fast_elements_case;
__ CompareAndBranch(kind, PACKED_ELEMENTS, eq, &fast_elements_case);
GenerateInternalArrayConstructorCase(masm, HOLEY_ELEMENTS);
__ Bind(&fast_elements_case);
GenerateInternalArrayConstructorCase(masm, PACKED_ELEMENTS);
__ Jump(
BUILTIN_CODE(masm->isolate(), InternalArrayNoArgumentConstructor_Packed),
RelocInfo::CODE_TARGET);
}
namespace {

View File

@ -3822,32 +3822,6 @@ TF_BUILTIN(ArrayNArgumentsConstructor, ArrayBuiltinsAssembler) {
maybe_allocation_site);
}
void ArrayBuiltinsAssembler::GenerateInternalArrayNoArgumentConstructor(
ElementsKind kind) {
typedef ArrayNoArgumentConstructorDescriptor Descriptor;
TNode<Map> array_map =
CAST(LoadObjectField(Parameter(Descriptor::kFunction),
JSFunction::kPrototypeOrInitialMapOffset));
TNode<JSArray> array = AllocateJSArray(
kind, array_map, IntPtrConstant(JSArray::kPreallocatedArrayElements),
SmiConstant(0));
Return(array);
}
void ArrayBuiltinsAssembler::GenerateInternalArraySingleArgumentConstructor(
ElementsKind kind) {
typedef ArraySingleArgumentConstructorDescriptor Descriptor;
Node* context = Parameter(Descriptor::kContext);
Node* function = Parameter(Descriptor::kFunction);
Node* array_map =
LoadObjectField(function, JSFunction::kPrototypeOrInitialMapOffset);
Node* array_size = Parameter(Descriptor::kArraySizeSmiParameter);
Node* allocation_site = UndefinedConstant();
GenerateConstructor(context, function, array_map, array_size, allocation_site,
kind, DONT_TRACK_ALLOCATION_SITE);
}
#define GENERATE_ARRAY_CTOR(name, kind_camel, kind_caps, mode_camel, \
mode_caps) \
TF_BUILTIN(Array##name##Constructor_##kind_camel##_##mode_camel, \
@ -3893,18 +3867,16 @@ GENERATE_ARRAY_CTOR(SingleArgument, HoleyDouble, HOLEY_DOUBLE_ELEMENTS,
#undef GENERATE_ARRAY_CTOR
#define GENERATE_INTERNAL_ARRAY_CTOR(name, kind_camel, kind_caps) \
TF_BUILTIN(InternalArray##name##Constructor_##kind_camel, \
ArrayBuiltinsAssembler) { \
GenerateInternalArray##name##Constructor(kind_caps); \
}
GENERATE_INTERNAL_ARRAY_CTOR(NoArgument, Packed, PACKED_ELEMENTS);
GENERATE_INTERNAL_ARRAY_CTOR(NoArgument, Holey, HOLEY_ELEMENTS);
GENERATE_INTERNAL_ARRAY_CTOR(SingleArgument, Packed, PACKED_ELEMENTS);
GENERATE_INTERNAL_ARRAY_CTOR(SingleArgument, Holey, HOLEY_ELEMENTS);
#undef GENERATE_INTERNAL_ARRAY_CTOR
TF_BUILTIN(InternalArrayNoArgumentConstructor_Packed, ArrayBuiltinsAssembler) {
typedef ArrayNoArgumentConstructorDescriptor Descriptor;
TNode<Map> array_map =
CAST(LoadObjectField(Parameter(Descriptor::kFunction),
JSFunction::kPrototypeOrInitialMapOffset));
TNode<JSArray> array = AllocateJSArray(
PACKED_ELEMENTS, array_map,
IntPtrConstant(JSArray::kPreallocatedArrayElements), SmiConstant(0));
Return(array);
}
} // namespace internal
} // namespace v8

View File

@ -159,9 +159,6 @@ class ArrayBuiltinsAssembler : public CodeStubAssembler {
TNode<Object> new_target, TNode<Int32T> argc,
TNode<HeapObject> maybe_allocation_site);
void GenerateInternalArrayNoArgumentConstructor(ElementsKind kind);
void GenerateInternalArraySingleArgumentConstructor(ElementsKind kind);
private:
static ElementsKind ElementsKindForInstanceType(InstanceType type);

View File

@ -305,11 +305,6 @@ namespace internal {
ASM(InternalArrayConstructorImpl) \
TFC(InternalArrayNoArgumentConstructor_Packed, ArrayNoArgumentConstructor, \
1) \
TFC(InternalArrayNoArgumentConstructor_Holey, ArrayNoArgumentConstructor, 1) \
TFC(InternalArraySingleArgumentConstructor_Packed, \
ArraySingleArgumentConstructor, 1) \
TFC(InternalArraySingleArgumentConstructor_Holey, \
ArraySingleArgumentConstructor, 1) \
CPP(ArrayConcat) \
/* ES6 #sec-array.isarray */ \
TFJ(ArrayIsArray, 1, kReceiver, kArg) \

View File

@ -3006,52 +3006,6 @@ void Builtins::Generate_MathPowInternal(MacroAssembler* masm) {
__ ret(0);
}
namespace {
void GenerateInternalArrayConstructorCase(MacroAssembler* masm,
ElementsKind kind) {
Label not_zero_case, not_one_case;
Label normal_sequence;
__ test(eax, eax);
__ j(not_zero, &not_zero_case);
__ Jump(CodeFactory::InternalArrayNoArgumentConstructor(masm->isolate(), kind)
.code(),
RelocInfo::CODE_TARGET);
__ bind(&not_zero_case);
__ cmp(eax, 1);
__ j(greater, &not_one_case);
if (IsFastPackedElementsKind(kind)) {
// We might need to create a holey array
// look at the first argument
__ mov(ecx, Operand(esp, kPointerSize));
__ test(ecx, ecx);
__ j(zero, &normal_sequence);
__ Jump(CodeFactory::InternalArraySingleArgumentConstructor(
masm->isolate(), GetHoleyElementsKind(kind))
.code(),
RelocInfo::CODE_TARGET);
}
__ bind(&normal_sequence);
__ Jump(
CodeFactory::InternalArraySingleArgumentConstructor(masm->isolate(), kind)
.code(),
RelocInfo::CODE_TARGET);
__ bind(&not_one_case);
// Load undefined into the allocation site parameter as required by
// ArrayNArgumentsConstructor.
__ LoadRoot(kJavaScriptCallExtraArg1Register, RootIndex::kUndefinedValue);
Handle<Code> code = BUILTIN_CODE(masm->isolate(), ArrayNArgumentsConstructor);
__ Jump(code, RelocInfo::CODE_TARGET);
}
} // namespace
void Builtins::Generate_InternalArrayConstructorImpl(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- eax : argc
@ -3071,35 +3025,28 @@ void Builtins::Generate_InternalArrayConstructorImpl(MacroAssembler* masm) {
__ Assert(not_zero, AbortReason::kUnexpectedInitialMapForArrayFunction);
__ CmpObjectType(ecx, MAP_TYPE, ecx);
__ Assert(equal, AbortReason::kUnexpectedInitialMapForArrayFunction);
}
// Figure out the right elements kind
__ mov(ecx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset));
// Figure out the right elements kind
__ mov(ecx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset));
// Load the map's "bit field 2" into |result|. We only need the first byte,
// but the following masking takes care of that anyway.
__ mov(ecx, FieldOperand(ecx, Map::kBitField2Offset));
// Retrieve elements_kind from bit field 2.
__ DecodeField<Map::ElementsKindBits>(ecx);
// Load the map's "bit field 2" into |result|. We only need the first byte,
// but the following masking takes care of that anyway.
__ mov(ecx, FieldOperand(ecx, Map::kBitField2Offset));
// Retrieve elements_kind from bit field 2.
__ DecodeField<Map::ElementsKindBits>(ecx);
if (FLAG_debug_code) {
Label done;
// Initial elements kind should be packed elements.
__ cmp(ecx, Immediate(PACKED_ELEMENTS));
__ j(equal, &done);
__ cmp(ecx, Immediate(HOLEY_ELEMENTS));
__ Assert(
equal,
AbortReason::kInvalidElementsKindForInternalArrayOrInternalPackedArray);
__ bind(&done);
__ Assert(equal, AbortReason::kInvalidElementsKindForInternalPackedArray);
// No arguments should be passed.
__ test(eax, eax);
__ Assert(zero, AbortReason::kWrongNumberOfArgumentsForInternalPackedArray);
}
Label fast_elements_case;
__ cmp(ecx, Immediate(PACKED_ELEMENTS));
__ j(equal, &fast_elements_case);
GenerateInternalArrayConstructorCase(masm, HOLEY_ELEMENTS);
__ bind(&fast_elements_case);
GenerateInternalArrayConstructorCase(masm, PACKED_ELEMENTS);
__ Jump(
BUILTIN_CODE(masm->isolate(), InternalArrayNoArgumentConstructor_Packed),
RelocInfo::CODE_TARGET);
}
namespace {

View File

@ -2845,40 +2845,6 @@ void Builtins::Generate_MathPowInternal(MacroAssembler* masm) {
__ Ret();
}
namespace {
void GenerateInternalArrayConstructorCase(MacroAssembler* masm,
ElementsKind kind) {
// Load undefined into the allocation site parameter as required by
// ArrayNArgumentsConstructor.
__ LoadRoot(kJavaScriptCallExtraArg1Register, RootIndex::kUndefinedValue);
__ Jump(CodeFactory::InternalArrayNoArgumentConstructor(masm->isolate(), kind)
.code(),
RelocInfo::CODE_TARGET, lo, a0, Operand(1));
__ Jump(BUILTIN_CODE(masm->isolate(), ArrayNArgumentsConstructor),
RelocInfo::CODE_TARGET, hi, a0, Operand(1));
if (IsFastPackedElementsKind(kind)) {
// We might need to create a holey array
// look at the first argument.
__ lw(kScratchReg, MemOperand(sp, 0));
__ Jump(CodeFactory::InternalArraySingleArgumentConstructor(
masm->isolate(), GetHoleyElementsKind(kind))
.code(),
RelocInfo::CODE_TARGET, ne, kScratchReg, Operand(zero_reg));
}
__ Jump(
CodeFactory::InternalArraySingleArgumentConstructor(masm->isolate(), kind)
.code(),
RelocInfo::CODE_TARGET);
}
} // namespace
void Builtins::Generate_InternalArrayConstructorImpl(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- a0 : argc
@ -2900,33 +2866,28 @@ void Builtins::Generate_InternalArrayConstructorImpl(MacroAssembler* masm) {
__ GetObjectType(a3, a3, t0);
__ Assert(eq, AbortReason::kUnexpectedInitialMapForArrayFunction, t0,
Operand(MAP_TYPE));
// Figure out the right elements kind.
__ lw(a3, FieldMemOperand(a1, JSFunction::kPrototypeOrInitialMapOffset));
// Load the map's "bit field 2" into a3. We only need the first byte,
// but the following bit field extraction takes care of that anyway.
__ lbu(a3, FieldMemOperand(a3, Map::kBitField2Offset));
// Retrieve elements_kind from bit field 2.
__ DecodeField<Map::ElementsKindBits>(a3);
// Initial elements kind should be packed elements.
__ Assert(eq, AbortReason::kInvalidElementsKindForInternalPackedArray, a3,
Operand(PACKED_ELEMENTS));
// No arguments should be passed.
__ Assert(eq, AbortReason::kWrongNumberOfArgumentsForInternalPackedArray,
a0, Operand(0));
}
// Figure out the right elements kind.
__ lw(a3, FieldMemOperand(a1, JSFunction::kPrototypeOrInitialMapOffset));
// Load the map's "bit field 2" into a3. We only need the first byte,
// but the following bit field extraction takes care of that anyway.
__ lbu(a3, FieldMemOperand(a3, Map::kBitField2Offset));
// Retrieve elements_kind from bit field 2.
__ DecodeField<Map::ElementsKindBits>(a3);
if (FLAG_debug_code) {
Label done;
__ Branch(&done, eq, a3, Operand(PACKED_ELEMENTS));
__ Assert(
eq,
AbortReason::kInvalidElementsKindForInternalArrayOrInternalPackedArray,
a3, Operand(HOLEY_ELEMENTS));
__ bind(&done);
}
Label fast_elements_case;
__ Branch(&fast_elements_case, eq, a3, Operand(PACKED_ELEMENTS));
GenerateInternalArrayConstructorCase(masm, HOLEY_ELEMENTS);
__ bind(&fast_elements_case);
GenerateInternalArrayConstructorCase(masm, PACKED_ELEMENTS);
__ Jump(
BUILTIN_CODE(masm->isolate(), InternalArrayNoArgumentConstructor_Packed),
RelocInfo::CODE_TARGET);
}
namespace {

View File

@ -2859,40 +2859,6 @@ void Builtins::Generate_MathPowInternal(MacroAssembler* masm) {
__ Ret();
}
namespace {
void GenerateInternalArrayConstructorCase(MacroAssembler* masm,
ElementsKind kind) {
// Load undefined into the allocation site parameter as required by
// ArrayNArgumentsConstructor.
__ LoadRoot(kJavaScriptCallExtraArg1Register, RootIndex::kUndefinedValue);
__ Jump(CodeFactory::InternalArrayNoArgumentConstructor(masm->isolate(), kind)
.code(),
RelocInfo::CODE_TARGET, lo, a0, Operand(1));
__ Jump(BUILTIN_CODE(masm->isolate(), ArrayNArgumentsConstructor),
RelocInfo::CODE_TARGET, hi, a0, Operand(1));
if (IsFastPackedElementsKind(kind)) {
// We might need to create a holey array
// look at the first argument.
__ Ld(kScratchReg, MemOperand(sp, 0));
__ Jump(CodeFactory::InternalArraySingleArgumentConstructor(
masm->isolate(), GetHoleyElementsKind(kind))
.code(),
RelocInfo::CODE_TARGET, ne, kScratchReg, Operand(zero_reg));
}
__ Jump(
CodeFactory::InternalArraySingleArgumentConstructor(masm->isolate(), kind)
.code(),
RelocInfo::CODE_TARGET);
}
} // namespace
void Builtins::Generate_InternalArrayConstructorImpl(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- a0 : argc
@ -2914,33 +2880,28 @@ void Builtins::Generate_InternalArrayConstructorImpl(MacroAssembler* masm) {
__ GetObjectType(a3, a3, a4);
__ Assert(eq, AbortReason::kUnexpectedInitialMapForArrayFunction, a4,
Operand(MAP_TYPE));
// Figure out the right elements kind.
__ Ld(a3, FieldMemOperand(a1, JSFunction::kPrototypeOrInitialMapOffset));
// Load the map's "bit field 2" into a3. We only need the first byte,
// but the following bit field extraction takes care of that anyway.
__ Lbu(a3, FieldMemOperand(a3, Map::kBitField2Offset));
// Retrieve elements_kind from bit field 2.
__ DecodeField<Map::ElementsKindBits>(a3);
// Initial elements kind should be packed elements.
__ Assert(eq, AbortReason::kInvalidElementsKindForInternalPackedArray, a3,
Operand(PACKED_ELEMENTS));
// No arguments should be passed.
__ Assert(eq, AbortReason::kWrongNumberOfArgumentsForInternalPackedArray,
a0, Operand(0));
}
// Figure out the right elements kind.
__ Ld(a3, FieldMemOperand(a1, JSFunction::kPrototypeOrInitialMapOffset));
// Load the map's "bit field 2" into a3. We only need the first byte,
// but the following bit field extraction takes care of that anyway.
__ Lbu(a3, FieldMemOperand(a3, Map::kBitField2Offset));
// Retrieve elements_kind from bit field 2.
__ DecodeField<Map::ElementsKindBits>(a3);
if (FLAG_debug_code) {
Label done;
__ Branch(&done, eq, a3, Operand(PACKED_ELEMENTS));
__ Assert(
eq,
AbortReason::kInvalidElementsKindForInternalArrayOrInternalPackedArray,
a3, Operand(HOLEY_ELEMENTS));
__ bind(&done);
}
Label fast_elements_case;
__ Branch(&fast_elements_case, eq, a3, Operand(PACKED_ELEMENTS));
GenerateInternalArrayConstructorCase(masm, HOLEY_ELEMENTS);
__ bind(&fast_elements_case);
GenerateInternalArrayConstructorCase(masm, PACKED_ELEMENTS);
__ Jump(
BUILTIN_CODE(masm->isolate(), InternalArrayNoArgumentConstructor_Packed),
RelocInfo::CODE_TARGET);
}
namespace {

View File

@ -2718,43 +2718,6 @@ void Builtins::Generate_MathPowInternal(MacroAssembler* masm) {
__ Ret();
}
namespace {
void GenerateInternalArrayConstructorCase(MacroAssembler* masm,
ElementsKind kind) {
// Load undefined into the allocation site parameter as required by
// ArrayNArgumentsConstructor.
__ LoadRoot(kJavaScriptCallExtraArg1Register, RootIndex::kUndefinedValue);
__ cmpli(r3, Operand(1));
__ Jump(CodeFactory::InternalArrayNoArgumentConstructor(masm->isolate(), kind)
.code(),
RelocInfo::CODE_TARGET, lt);
__ Jump(BUILTIN_CODE(masm->isolate(), ArrayNArgumentsConstructor),
RelocInfo::CODE_TARGET, gt);
if (IsFastPackedElementsKind(kind)) {
// We might need to create a holey array
// look at the first argument
__ LoadP(r6, MemOperand(sp, 0));
__ cmpi(r6, Operand::Zero());
__ Jump(CodeFactory::InternalArraySingleArgumentConstructor(
masm->isolate(), GetHoleyElementsKind(kind))
.code(),
RelocInfo::CODE_TARGET, ne);
}
__ Jump(
CodeFactory::InternalArraySingleArgumentConstructor(masm->isolate(), kind)
.code(),
RelocInfo::CODE_TARGET);
}
} // namespace
void Builtins::Generate_InternalArrayConstructorImpl(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- r3 : argc
@ -2774,33 +2737,26 @@ void Builtins::Generate_InternalArrayConstructorImpl(MacroAssembler* masm) {
__ Assert(ne, AbortReason::kUnexpectedInitialMapForArrayFunction, cr0);
__ CompareObjectType(r6, r6, r7, MAP_TYPE);
__ Assert(eq, AbortReason::kUnexpectedInitialMapForArrayFunction);
}
// Figure out the right elements kind
__ LoadP(r6, FieldMemOperand(r4, JSFunction::kPrototypeOrInitialMapOffset));
// Load the map's "bit field 2" into |result|.
__ lbz(r6, FieldMemOperand(r6, Map::kBitField2Offset));
// Retrieve elements_kind from bit field 2.
__ DecodeField<Map::ElementsKindBits>(r6);
// Figure out the right elements kind
__ LoadP(r6, FieldMemOperand(r4, JSFunction::kPrototypeOrInitialMapOffset));
// Load the map's "bit field 2" into |result|.
__ lbz(r6, FieldMemOperand(r6, Map::kBitField2Offset));
// Retrieve elements_kind from bit field 2.
__ DecodeField<Map::ElementsKindBits>(r6);
if (FLAG_debug_code) {
Label done;
// Initial elements kind should be packed elements.
__ cmpi(r6, Operand(PACKED_ELEMENTS));
__ beq(&done);
__ cmpi(r6, Operand(HOLEY_ELEMENTS));
__ Assert(
eq,
AbortReason::kInvalidElementsKindForInternalArrayOrInternalPackedArray);
__ bind(&done);
__ Assert(eq, AbortReason::kInvalidElementsKindForInternalPackedArray);
// No arguments should be passed.
__ cmpi(r3, Operand(0));
__ Assert(eq, AbortReason::kWrongNumberOfArgumentsForInternalPackedArray);
}
Label fast_elements_case;
__ cmpi(r6, Operand(PACKED_ELEMENTS));
__ beq(&fast_elements_case);
GenerateInternalArrayConstructorCase(masm, HOLEY_ELEMENTS);
__ bind(&fast_elements_case);
GenerateInternalArrayConstructorCase(masm, PACKED_ELEMENTS);
__ Jump(
BUILTIN_CODE(masm->isolate(), InternalArrayNoArgumentConstructor_Packed),
RelocInfo::CODE_TARGET);
}
namespace {

View File

@ -2706,37 +2706,13 @@ void Builtins::Generate_MathPowInternal(MacroAssembler* masm) {
namespace {
void GenerateInternalArrayConstructorCase(MacroAssembler* masm,
ElementsKind kind) {
// Load undefined into the allocation site parameter as required by
// ArrayNArgumentsConstructor.
__ LoadRoot(kJavaScriptCallExtraArg1Register, RootIndex::kUndefinedValue);
__ CmpLogicalP(r2, Operand(1));
__ Jump(CodeFactory::InternalArrayNoArgumentConstructor(masm->isolate(), kind)
.code(),
RelocInfo::CODE_TARGET, lt);
__ Jump(BUILTIN_CODE(masm->isolate(), ArrayNArgumentsConstructor),
RelocInfo::CODE_TARGET, gt);
if (IsFastPackedElementsKind(kind)) {
// We might need to create a holey array
// look at the first argument
__ LoadP(r5, MemOperand(sp, 0));
__ CmpP(r5, Operand::Zero());
__ Jump(CodeFactory::InternalArraySingleArgumentConstructor(
masm->isolate(), GetHoleyElementsKind(kind))
.code(),
RelocInfo::CODE_TARGET, ne);
}
void GenerateInternalArrayConstructorCase(MacroAssembler* masm) {
__ CmpP(r2, Operand(0));
__ Assert(eq, AbortReason::kWrongNumberOfArgumentsForInternalPackedArray);
__ Jump(
CodeFactory::InternalArraySingleArgumentConstructor(masm->isolate(), kind)
.code(),
RelocInfo::CODE_TARGET);
BUILTIN_CODE(masm->isolate(), InternalArrayNoArgumentConstructor_Packed),
RelocInfo::CODE_TARGET, lt);
}
} // namespace
@ -2770,23 +2746,11 @@ void Builtins::Generate_InternalArrayConstructorImpl(MacroAssembler* masm) {
__ DecodeField<Map::ElementsKindBits>(r5);
if (FLAG_debug_code) {
Label done;
__ CmpP(r5, Operand(PACKED_ELEMENTS));
__ beq(&done);
__ CmpP(r5, Operand(HOLEY_ELEMENTS));
__ Assert(
eq,
AbortReason::kInvalidElementsKindForInternalArrayOrInternalPackedArray);
__ bind(&done);
__ Assert(eq, AbortReason::kInvalidElementsKindForInternalPackedArray);
}
Label fast_elements_case;
__ CmpP(r5, Operand(PACKED_ELEMENTS));
__ beq(&fast_elements_case);
GenerateInternalArrayConstructorCase(masm, HOLEY_ELEMENTS);
__ bind(&fast_elements_case);
GenerateInternalArrayConstructorCase(masm, PACKED_ELEMENTS);
GenerateInternalArrayConstructorCase(masm);
}
namespace {

View File

@ -2939,53 +2939,6 @@ void Builtins::Generate_MathPowInternal(MacroAssembler* masm) {
__ ret(0);
}
namespace {
void GenerateInternalArrayConstructorCase(MacroAssembler* masm,
ElementsKind kind) {
Label not_zero_case, not_one_case;
Label normal_sequence;
__ testp(rax, rax);
__ j(not_zero, &not_zero_case);
__ Jump(CodeFactory::InternalArrayNoArgumentConstructor(masm->isolate(), kind)
.code(),
RelocInfo::CODE_TARGET);
__ bind(&not_zero_case);
__ cmpl(rax, Immediate(1));
__ j(greater, &not_one_case);
if (IsFastPackedElementsKind(kind)) {
// We might need to create a holey array
// look at the first argument
StackArgumentsAccessor args(rsp, 1, ARGUMENTS_DONT_CONTAIN_RECEIVER);
__ movp(rcx, args.GetArgumentOperand(0));
__ testp(rcx, rcx);
__ j(zero, &normal_sequence);
__ Jump(CodeFactory::InternalArraySingleArgumentConstructor(
masm->isolate(), GetHoleyElementsKind(kind))
.code(),
RelocInfo::CODE_TARGET);
}
__ bind(&normal_sequence);
__ Jump(
CodeFactory::InternalArraySingleArgumentConstructor(masm->isolate(), kind)
.code(),
RelocInfo::CODE_TARGET);
__ bind(&not_one_case);
// Load undefined into the allocation site parameter as required by
// ArrayNArgumentsConstructor.
__ LoadRoot(kJavaScriptCallExtraArg1Register, RootIndex::kUndefinedValue);
Handle<Code> code = BUILTIN_CODE(masm->isolate(), ArrayNArgumentsConstructor);
__ Jump(code, RelocInfo::CODE_TARGET);
}
} // namespace
void Builtins::Generate_InternalArrayConstructorImpl(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- rax : argc
@ -3006,35 +2959,28 @@ void Builtins::Generate_InternalArrayConstructorImpl(MacroAssembler* masm) {
__ Check(not_smi, AbortReason::kUnexpectedInitialMapForArrayFunction);
__ CmpObjectType(rcx, MAP_TYPE, rcx);
__ Check(equal, AbortReason::kUnexpectedInitialMapForArrayFunction);
}
// Figure out the right elements kind
__ movp(rcx, FieldOperand(rdi, JSFunction::kPrototypeOrInitialMapOffset));
// Figure out the right elements kind
__ movp(rcx, FieldOperand(rdi, JSFunction::kPrototypeOrInitialMapOffset));
// Load the map's "bit field 2" into |result|. We only need the first byte,
// but the following masking takes care of that anyway.
__ movzxbp(rcx, FieldOperand(rcx, Map::kBitField2Offset));
// Retrieve elements_kind from bit field 2.
__ DecodeField<Map::ElementsKindBits>(rcx);
// Load the map's "bit field 2" into |result|. We only need the first byte,
// but the following masking takes care of that anyway.
__ movzxbp(rcx, FieldOperand(rcx, Map::kBitField2Offset));
// Retrieve elements_kind from bit field 2.
__ DecodeField<Map::ElementsKindBits>(rcx);
if (FLAG_debug_code) {
Label done;
// Initial elements kind should be packed elements.
__ cmpl(rcx, Immediate(PACKED_ELEMENTS));
__ j(equal, &done);
__ cmpl(rcx, Immediate(HOLEY_ELEMENTS));
__ Assert(
equal,
AbortReason::kInvalidElementsKindForInternalArrayOrInternalPackedArray);
__ bind(&done);
__ Assert(equal, AbortReason::kInvalidElementsKindForInternalPackedArray);
// No arguments should be passed.
__ testp(rax, rax);
__ Assert(zero, AbortReason::kWrongNumberOfArgumentsForInternalPackedArray);
}
Label fast_elements_case;
__ cmpl(rcx, Immediate(PACKED_ELEMENTS));
__ j(equal, &fast_elements_case);
GenerateInternalArrayConstructorCase(masm, HOLEY_ELEMENTS);
__ bind(&fast_elements_case);
GenerateInternalArrayConstructorCase(masm, PACKED_ELEMENTS);
__ Jump(
BUILTIN_CODE(masm->isolate(), InternalArrayNoArgumentConstructor_Packed),
RelocInfo::CODE_TARGET);
}
namespace {

View File

@ -488,39 +488,5 @@ Callable CodeFactory::ArraySingleArgumentConstructor(
#undef CASE
}
// static
Callable CodeFactory::InternalArrayNoArgumentConstructor(Isolate* isolate,
ElementsKind kind) {
switch (kind) {
case PACKED_ELEMENTS:
return Callable(
BUILTIN_CODE(isolate, InternalArrayNoArgumentConstructor_Packed),
ArrayNoArgumentConstructorDescriptor{});
case HOLEY_ELEMENTS:
return Callable(
BUILTIN_CODE(isolate, InternalArrayNoArgumentConstructor_Holey),
ArrayNoArgumentConstructorDescriptor{});
default:
UNREACHABLE();
}
}
// static
Callable CodeFactory::InternalArraySingleArgumentConstructor(
Isolate* isolate, ElementsKind kind) {
switch (kind) {
case PACKED_ELEMENTS:
return Callable(
BUILTIN_CODE(isolate, InternalArraySingleArgumentConstructor_Packed),
ArraySingleArgumentConstructorDescriptor{});
case HOLEY_ELEMENTS:
return Callable(
BUILTIN_CODE(isolate, InternalArraySingleArgumentConstructor_Holey),
ArraySingleArgumentConstructorDescriptor{});
default:
UNREACHABLE();
}
}
} // namespace internal
} // namespace v8

View File

@ -103,11 +103,6 @@ class V8_EXPORT_PRIVATE CodeFactory final {
static Callable ArraySingleArgumentConstructor(
Isolate* isolate, ElementsKind kind,
AllocationSiteOverrideMode override_mode);
static Callable InternalArrayNoArgumentConstructor(Isolate* isolate,
ElementsKind kind);
static Callable InternalArraySingleArgumentConstructor(Isolate* isolate,
ElementsKind kind);
};
} // namespace internal

View File

@ -205,7 +205,6 @@ enum ContextLookupFlags {
V(INT16_ARRAY_FUN_INDEX, JSFunction, int16_array_fun) \
V(INT32_ARRAY_FUN_INDEX, JSFunction, int32_array_fun) \
V(INT8_ARRAY_FUN_INDEX, JSFunction, int8_array_fun) \
V(INTERNAL_ARRAY_FUNCTION_INDEX, JSFunction, internal_array_function) \
V(INTL_COLLATOR_FUNCTION_INDEX, JSFunction, intl_collator_function) \
V(INTL_DATE_TIME_FORMAT_FUNCTION_INDEX, JSFunction, \
intl_date_time_format_function) \

View File

@ -69,7 +69,6 @@ function SetUpLockedPrototype(
}
var GlobalArray = global.Array;
var InternalArray;
// -----------------------------------------------------------------------
// To be called by bootstrapper
@ -80,7 +79,6 @@ function PostNatives(utils) {
// -------------------------------------------------------------------
// Array
InternalArray = utils.InternalArray;
var iteratorSymbol = ImportNow("iterator_symbol");
var unscopablesSymbol = ImportNow("unscopables_symbol");
@ -101,13 +99,10 @@ function PostNatives(utils) {
%AddNamedProperty(GlobalArray.prototype, unscopablesSymbol, unscopables,
DONT_ENUM | READ_ONLY);
var ArrayIndexOf = GlobalArray.prototype.indexOf;
var ArrayJoin = GlobalArray.prototype.join;
var ArrayPop = GlobalArray.prototype.pop;
var ArrayPush = GlobalArray.prototype.push;
var ArraySlice = GlobalArray.prototype.slice;
var ArrayShift = GlobalArray.prototype.shift;
var ArraySort = GlobalArray.prototype.sort;
var ArraySplice = GlobalArray.prototype.splice;
var ArrayUnshift = GlobalArray.prototype.unshift;
@ -118,20 +113,6 @@ function PostNatives(utils) {
var ArrayKeys = GlobalArray.prototype.keys;
var ArrayValues = GlobalArray.prototype[iteratorSymbol];
// 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.
SetUpLockedPrototype(InternalArray, GlobalArray(), [
"indexOf", ArrayIndexOf,
"join", ArrayJoin,
"pop", ArrayPop,
"push", ArrayPush,
"shift", ArrayShift,
"sort", ArraySort,
"splice", ArraySplice
]);
// V8 extras get a separate copy of InternalPackedArray. We give them the basic
// manipulation methods.
SetUpLockedPrototype(extrasUtils.InternalPackedArray, GlobalArray(), [

View File

@ -5026,37 +5026,6 @@ TEST(BootstrappingExports) {
}
TEST(Regress1878) {
FLAG_allow_natives_syntax = true;
CcTest::InitializeVM();
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
v8::Local<v8::Function> constructor = v8::Utils::CallableToLocal(
CcTest::i_isolate()->internal_array_function());
LocalContext env;
CHECK(CcTest::global()
->Set(env.local(), v8_str("InternalArray"), constructor)
.FromJust());
v8::TryCatch try_catch(isolate);
CompileRun(
"var a = Array();"
"for (var i = 0; i < 1000; i++) {"
" var ai = new InternalArray(10000);"
" if (%HaveSameMap(ai, a)) throw Error();"
" if (!%HasObjectElements(ai)) throw Error();"
"}"
"for (var i = 0; i < 1000; i++) {"
" var ai = new InternalArray(10000);"
" if (%HaveSameMap(ai, a)) throw Error();"
" if (!%HasObjectElements(ai)) throw Error();"
"}");
CHECK(!try_catch.HasCaught());
}
void AllocateInSpace(Isolate* isolate, size_t bytes, AllocationSpace space) {
CHECK_LE(FixedArray::kHeaderSize, bytes);
CHECK_EQ(0, bytes % kPointerSize);

View File

@ -80,7 +80,7 @@
const rejectedPromise = v8.createPromise();
v8.rejectPromise(rejectedPromise, apply(function (arg1, arg2) {
return (arg1 === arg2 && arg2 === 'x') ? 3 : -1;
}, null, new v8.InternalPackedArray('x', 'x')));
}, null, ['x', 'x']));
const rejectedButHandledPromise = v8.createPromise();
v8.rejectPromise(rejectedButHandledPromise, 4);