Commit f32878dc authored by Junliang Yan's avatar Junliang Yan Committed by Commit Bot

PPC/s390: [builtins] Move InternalArrayConstructorStub to builtin

Port 7d161e4d

Original Commit Message:

    Calls from embedded builtins to stubs are expensive due to the
    indirection through the builtins constants table. This moves
    the InternalArrayConstructorStub to a builtin.

R=jgruber@chromium.org, joransiu@ca.ibm.com, michael_dawson@ca.ibm.com
BUG=
LOG=N

Change-Id: Id16d4a5dc49d6832d5976aace17c33807270e50f
Reviewed-on: https://chromium-review.googlesource.com/1074558Reviewed-by: 's avatarJoran Siu <joransiu@ca.ibm.com>
Commit-Queue: Junliang Yan <jyan@ca.ibm.com>
Cr-Commit-Position: refs/heads/master@{#53390}
parent 7a45af14
......@@ -105,8 +105,8 @@ void Builtins::Generate_InternalArrayConstructor(MacroAssembler* masm) {
// function.
// tail call a stub
__ LoadRoot(r5, Heap::kUndefinedValueRootIndex);
InternalArrayConstructorStub stub(masm->isolate());
__ TailCallStub(&stub);
__ Jump(BUILTIN_CODE(masm->isolate(), InternalArrayConstructorImpl),
RelocInfo::CODE_TARGET);
}
void Builtins::Generate_ArrayConstructor(MacroAssembler* masm) {
......@@ -3236,6 +3236,83 @@ void Builtins::Generate_ArrayConstructorImpl(MacroAssembler* masm) {
__ JumpToExternalReference(ExternalReference::Create(Runtime::kNewArray));
}
namespace {
void GenerateInternalArrayConstructorCase(MacroAssembler* masm,
ElementsKind kind) {
__ cmpli(r3, Operand(1));
InternalArrayNoArgumentConstructorStub stub0(masm->isolate(), kind);
__ TailCallStub(&stub0, 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());
InternalArraySingleArgumentConstructorStub stub1_holey(
masm->isolate(), GetHoleyElementsKind(kind));
__ TailCallStub(&stub1_holey, ne);
}
InternalArraySingleArgumentConstructorStub stub1(masm->isolate(), kind);
__ TailCallStub(&stub1);
}
} // namespace
void Builtins::Generate_InternalArrayConstructorImpl(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- r3 : argc
// -- r4 : constructor
// -- sp[0] : return address
// -- sp[4] : last argument
// -----------------------------------
if (FLAG_debug_code) {
// The array construct code is only set for the global and natives
// builtin Array functions which always have maps.
// Initial map for the builtin Array function should be a map.
__ LoadP(r6, FieldMemOperand(r4, JSFunction::kPrototypeOrInitialMapOffset));
// Will both indicate a nullptr and a Smi.
__ TestIfSmi(r6, r0);
__ 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);
if (FLAG_debug_code) {
Label done;
__ cmpi(r6, Operand(PACKED_ELEMENTS));
__ beq(&done);
__ cmpi(r6, Operand(HOLEY_ELEMENTS));
__ Assert(
eq,
AbortReason::kInvalidElementsKindForInternalArrayOrInternalPackedArray);
__ bind(&done);
}
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);
}
void Builtins::Generate_ArrayNArgumentsConstructor(MacroAssembler* masm) {
__ ShiftLeftImm(r0, r3, Operand(kPointerSizeLog2));
__ StorePX(r4, MemOperand(sp, r0));
......
......@@ -111,8 +111,8 @@ void Builtins::Generate_InternalArrayConstructor(MacroAssembler* masm) {
// function.
// tail call a stub
__ LoadRoot(r4, Heap::kUndefinedValueRootIndex);
InternalArrayConstructorStub stub(masm->isolate());
__ TailCallStub(&stub);
__ Jump(BUILTIN_CODE(masm->isolate(), InternalArrayConstructorImpl),
RelocInfo::CODE_TARGET);
}
void Builtins::Generate_ArrayConstructor(MacroAssembler* masm) {
......@@ -3235,6 +3235,83 @@ void Builtins::Generate_ArrayConstructorImpl(MacroAssembler* masm) {
__ JumpToExternalReference(ExternalReference::Create(Runtime::kNewArray));
}
namespace {
void GenerateInternalArrayConstructorCase(MacroAssembler* masm,
ElementsKind kind) {
__ CmpLogicalP(r2, Operand(1));
InternalArrayNoArgumentConstructorStub stub0(masm->isolate(), kind);
__ TailCallStub(&stub0, 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());
InternalArraySingleArgumentConstructorStub stub1_holey(
masm->isolate(), GetHoleyElementsKind(kind));
__ TailCallStub(&stub1_holey, ne);
}
InternalArraySingleArgumentConstructorStub stub1(masm->isolate(), kind);
__ TailCallStub(&stub1);
}
} // namespace
void Builtins::Generate_InternalArrayConstructorImpl(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- r2 : argc
// -- r3 : constructor
// -- sp[0] : return address
// -- sp[4] : last argument
// -----------------------------------
if (FLAG_debug_code) {
// The array construct code is only set for the global and natives
// builtin Array functions which always have maps.
// Initial map for the builtin Array function should be a map.
__ LoadP(r5, FieldMemOperand(r3, JSFunction::kPrototypeOrInitialMapOffset));
// Will both indicate a nullptr and a Smi.
__ TestIfSmi(r5);
__ Assert(ne, AbortReason::kUnexpectedInitialMapForArrayFunction, cr0);
__ CompareObjectType(r5, r5, r6, MAP_TYPE);
__ Assert(eq, AbortReason::kUnexpectedInitialMapForArrayFunction);
}
// Figure out the right elements kind
__ LoadP(r5, FieldMemOperand(r3, JSFunction::kPrototypeOrInitialMapOffset));
// Load the map's "bit field 2" into |result|.
__ LoadlB(r5, FieldMemOperand(r5, Map::kBitField2Offset));
// Retrieve elements_kind from bit field 2.
__ 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);
}
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);
}
#undef __
} // namespace internal
......
......@@ -357,80 +357,6 @@ void CommonArrayConstructorStub::GenerateStubsAheadOfTime(Isolate* isolate) {
}
}
void InternalArrayConstructorStub::GenerateCase(MacroAssembler* masm,
ElementsKind kind) {
__ cmpli(r3, Operand(1));
InternalArrayNoArgumentConstructorStub stub0(isolate(), kind);
__ TailCallStub(&stub0, 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());
InternalArraySingleArgumentConstructorStub stub1_holey(
isolate(), GetHoleyElementsKind(kind));
__ TailCallStub(&stub1_holey, ne);
}
InternalArraySingleArgumentConstructorStub stub1(isolate(), kind);
__ TailCallStub(&stub1);
}
void InternalArrayConstructorStub::Generate(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- r3 : argc
// -- r4 : constructor
// -- sp[0] : return address
// -- sp[4] : last argument
// -----------------------------------
if (FLAG_debug_code) {
// The array construct code is only set for the global and natives
// builtin Array functions which always have maps.
// Initial map for the builtin Array function should be a map.
__ LoadP(r6, FieldMemOperand(r4, JSFunction::kPrototypeOrInitialMapOffset));
// Will both indicate a nullptr and a Smi.
__ TestIfSmi(r6, r0);
__ 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);
if (FLAG_debug_code) {
Label done;
__ cmpi(r6, Operand(PACKED_ELEMENTS));
__ beq(&done);
__ cmpi(r6, Operand(HOLEY_ELEMENTS));
__ Assert(
eq,
AbortReason::kInvalidElementsKindForInternalArrayOrInternalPackedArray);
__ bind(&done);
}
Label fast_elements_case;
__ cmpi(r6, Operand(PACKED_ELEMENTS));
__ beq(&fast_elements_case);
GenerateCase(masm, HOLEY_ELEMENTS);
__ bind(&fast_elements_case);
GenerateCase(masm, PACKED_ELEMENTS);
}
static int AddressOffset(ExternalReference ref0, ExternalReference ref1) {
return ref0.address() - ref1.address();
}
......
......@@ -398,79 +398,6 @@ void CommonArrayConstructorStub::GenerateStubsAheadOfTime(Isolate* isolate) {
}
}
void InternalArrayConstructorStub::GenerateCase(MacroAssembler* masm,
ElementsKind kind) {
__ CmpLogicalP(r2, Operand(1));
InternalArrayNoArgumentConstructorStub stub0(isolate(), kind);
__ TailCallStub(&stub0, 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());
InternalArraySingleArgumentConstructorStub stub1_holey(
isolate(), GetHoleyElementsKind(kind));
__ TailCallStub(&stub1_holey, ne);
}
InternalArraySingleArgumentConstructorStub stub1(isolate(), kind);
__ TailCallStub(&stub1);
}
void InternalArrayConstructorStub::Generate(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- r2 : argc
// -- r3 : constructor
// -- sp[0] : return address
// -- sp[4] : last argument
// -----------------------------------
if (FLAG_debug_code) {
// The array construct code is only set for the global and natives
// builtin Array functions which always have maps.
// Initial map for the builtin Array function should be a map.
__ LoadP(r5, FieldMemOperand(r3, JSFunction::kPrototypeOrInitialMapOffset));
// Will both indicate a nullptr and a Smi.
__ TestIfSmi(r5);
__ Assert(ne, AbortReason::kUnexpectedInitialMapForArrayFunction, cr0);
__ CompareObjectType(r5, r5, r6, MAP_TYPE);
__ Assert(eq, AbortReason::kUnexpectedInitialMapForArrayFunction);
}
// Figure out the right elements kind
__ LoadP(r5, FieldMemOperand(r3, JSFunction::kPrototypeOrInitialMapOffset));
// Load the map's "bit field 2" into |result|.
__ LoadlB(r5, FieldMemOperand(r5, Map::kBitField2Offset));
// Retrieve elements_kind from bit field 2.
__ 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);
}
Label fast_elements_case;
__ CmpP(r5, Operand(PACKED_ELEMENTS));
__ beq(&fast_elements_case);
GenerateCase(masm, HOLEY_ELEMENTS);
__ bind(&fast_elements_case);
GenerateCase(masm, PACKED_ELEMENTS);
}
static int AddressOffset(ExternalReference ref0, ExternalReference ref1) {
return ref0.address() - ref1.address();
}
......
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