Array constructor can be simplified by loading context from JSFunction.

BUG=
R=verwaest@chromium.org

Review URL: https://codereview.chromium.org/128683002

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@18518 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
mvstanton@chromium.org 2014-01-09 15:07:23 +00:00
parent 6cdcc43ab5
commit 380aa6dc8d
12 changed files with 50 additions and 100 deletions

View File

@ -5552,9 +5552,7 @@ template<class T>
static void CreateArrayDispatch(MacroAssembler* masm,
AllocationSiteOverrideMode mode) {
if (mode == DISABLE_ALLOCATION_SITES) {
T stub(GetInitialFastElementsKind(),
CONTEXT_CHECK_REQUIRED,
mode);
T stub(GetInitialFastElementsKind(), mode);
__ TailCallStub(&stub);
} else if (mode == DONT_OVERRIDE) {
int last_index = GetSequenceIndexFromFastElementsKind(
@ -5605,13 +5603,11 @@ static void CreateArrayDispatchOneArgument(MacroAssembler* masm,
ElementsKind holey_initial = GetHoleyElementsKind(initial);
ArraySingleArgumentConstructorStub stub_holey(holey_initial,
CONTEXT_CHECK_REQUIRED,
DISABLE_ALLOCATION_SITES);
__ TailCallStub(&stub_holey);
__ bind(&normal_sequence);
ArraySingleArgumentConstructorStub stub(initial,
CONTEXT_CHECK_REQUIRED,
DISABLE_ALLOCATION_SITES);
__ TailCallStub(&stub);
} else if (mode == DONT_OVERRIDE) {
@ -5662,7 +5658,7 @@ static void ArrayConstructorStubAheadOfTimeHelper(Isolate* isolate) {
T stub(kind);
stub.GetCode(isolate);
if (AllocationSite::GetMode(kind) != DONT_TRACK_ALLOCATION_SITE) {
T stub1(kind, CONTEXT_CHECK_REQUIRED, DISABLE_ALLOCATION_SITES);
T stub1(kind, DISABLE_ALLOCATION_SITES);
stub1.GetCode(isolate);
}
}

View File

@ -4054,10 +4054,9 @@ void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
(AllocationSite::GetMode(kind) == TRACK_ALLOCATION_SITE)
? DISABLE_ALLOCATION_SITES
: DONT_OVERRIDE;
ContextCheckMode context_mode = CONTEXT_CHECK_NOT_REQUIRED;
if (instr->arity() == 0) {
ArrayNoArgumentConstructorStub stub(kind, context_mode, override_mode);
ArrayNoArgumentConstructorStub stub(kind, override_mode);
CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
} else if (instr->arity() == 1) {
Label done;
@ -4070,18 +4069,17 @@ void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
__ b(eq, &packed_case);
ElementsKind holey_kind = GetHoleyElementsKind(kind);
ArraySingleArgumentConstructorStub stub(holey_kind, context_mode,
override_mode);
ArraySingleArgumentConstructorStub stub(holey_kind, override_mode);
CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
__ jmp(&done);
__ bind(&packed_case);
}
ArraySingleArgumentConstructorStub stub(kind, context_mode, override_mode);
ArraySingleArgumentConstructorStub stub(kind, override_mode);
CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
__ bind(&done);
} else {
ArrayNArgumentsConstructorStub stub(kind, context_mode, override_mode);
ArrayNArgumentsConstructorStub stub(kind, override_mode);
CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
}
}

View File

@ -81,24 +81,6 @@ class CodeStubGraphBuilderBase : public HGraphBuilder {
HContext* context() { return context_; }
Isolate* isolate() { return info_.isolate(); }
class ArrayContextChecker {
public:
ArrayContextChecker(HGraphBuilder* builder, HValue* constructor,
HValue* array_function)
: checker_(builder) {
checker_.If<HCompareObjectEqAndBranch, HValue*>(constructor,
array_function);
checker_.Then();
}
~ArrayContextChecker() {
checker_.ElseDeopt("Array constructor called from different context");
checker_.End();
}
private:
IfBuilder checker_;
};
enum ArgumentClass {
NONE,
SINGLE,
@ -106,7 +88,6 @@ class CodeStubGraphBuilderBase : public HGraphBuilder {
};
HValue* BuildArrayConstructor(ElementsKind kind,
ContextCheckMode context_mode,
AllocationSiteOverrideMode override_mode,
ArgumentClass argument_class);
HValue* BuildInternalArrayConstructor(ElementsKind kind,
@ -672,15 +653,9 @@ Handle<Code> TransitionElementsKindStub::GenerateCode(Isolate* isolate) {
HValue* CodeStubGraphBuilderBase::BuildArrayConstructor(
ElementsKind kind,
ContextCheckMode context_mode,
AllocationSiteOverrideMode override_mode,
ArgumentClass argument_class) {
HValue* constructor = GetParameter(ArrayConstructorStubBase::kConstructor);
if (context_mode == CONTEXT_CHECK_REQUIRED) {
HInstruction* array_function = BuildGetArrayFunction();
ArrayContextChecker checker(this, constructor, array_function);
}
HValue* property_cell = GetParameter(ArrayConstructorStubBase::kPropertyCell);
// Walk through the property cell to the AllocationSite
HValue* alloc_site = Add<HLoadNamedField>(property_cell,
@ -787,9 +762,8 @@ HValue* CodeStubGraphBuilderBase::BuildArrayNArgumentsConstructor(
template <>
HValue* CodeStubGraphBuilder<ArrayNoArgumentConstructorStub>::BuildCodeStub() {
ElementsKind kind = casted_stub()->elements_kind();
ContextCheckMode context_mode = casted_stub()->context_mode();
AllocationSiteOverrideMode override_mode = casted_stub()->override_mode();
return BuildArrayConstructor(kind, context_mode, override_mode, NONE);
return BuildArrayConstructor(kind, override_mode, NONE);
}
@ -802,9 +776,8 @@ template <>
HValue* CodeStubGraphBuilder<ArraySingleArgumentConstructorStub>::
BuildCodeStub() {
ElementsKind kind = casted_stub()->elements_kind();
ContextCheckMode context_mode = casted_stub()->context_mode();
AllocationSiteOverrideMode override_mode = casted_stub()->override_mode();
return BuildArrayConstructor(kind, context_mode, override_mode, SINGLE);
return BuildArrayConstructor(kind, override_mode, SINGLE);
}
@ -817,9 +790,8 @@ Handle<Code> ArraySingleArgumentConstructorStub::GenerateCode(
template <>
HValue* CodeStubGraphBuilder<ArrayNArgumentsConstructorStub>::BuildCodeStub() {
ElementsKind kind = casted_stub()->elements_kind();
ContextCheckMode context_mode = casted_stub()->context_mode();
AllocationSiteOverrideMode override_mode = casted_stub()->override_mode();
return BuildArrayConstructor(kind, context_mode, override_mode, MULTIPLE);
return BuildArrayConstructor(kind, override_mode, MULTIPLE);
}

View File

@ -1987,16 +1987,9 @@ class TransitionElementsKindStub : public HydrogenCodeStub {
};
enum ContextCheckMode {
CONTEXT_CHECK_REQUIRED,
CONTEXT_CHECK_NOT_REQUIRED,
LAST_CONTEXT_CHECK_MODE = CONTEXT_CHECK_NOT_REQUIRED
};
class ArrayConstructorStubBase : public HydrogenCodeStub {
public:
ArrayConstructorStubBase(ElementsKind kind, ContextCheckMode context_mode,
ArrayConstructorStubBase(ElementsKind kind,
AllocationSiteOverrideMode override_mode) {
// It only makes sense to override local allocation site behavior
// if there is a difference between the global allocation site policy
@ -2004,8 +1997,7 @@ class ArrayConstructorStubBase : public HydrogenCodeStub {
ASSERT(override_mode != DISABLE_ALLOCATION_SITES ||
AllocationSite::GetMode(kind) == TRACK_ALLOCATION_SITE);
bit_field_ = ElementsKindBits::encode(kind) |
AllocationSiteOverrideModeBits::encode(override_mode) |
ContextCheckModeBits::encode(context_mode);
AllocationSiteOverrideModeBits::encode(override_mode);
}
ElementsKind elements_kind() const {
@ -2016,10 +2008,6 @@ class ArrayConstructorStubBase : public HydrogenCodeStub {
return AllocationSiteOverrideModeBits::decode(bit_field_);
}
ContextCheckMode context_mode() const {
return ContextCheckModeBits::decode(bit_field_);
}
static void GenerateStubsAheadOfTime(Isolate* isolate);
static void InstallDescriptors(Isolate* isolate);
@ -2035,12 +2023,10 @@ class ArrayConstructorStubBase : public HydrogenCodeStub {
// Ensure data fits within available bits.
STATIC_ASSERT(LAST_ALLOCATION_SITE_OVERRIDE_MODE == 1);
STATIC_ASSERT(LAST_CONTEXT_CHECK_MODE == 1);
class ElementsKindBits: public BitField<ElementsKind, 0, 8> {};
class AllocationSiteOverrideModeBits: public
BitField<AllocationSiteOverrideMode, 8, 1> {}; // NOLINT
class ContextCheckModeBits: public BitField<ContextCheckMode, 9, 1> {};
uint32_t bit_field_;
DISALLOW_COPY_AND_ASSIGN(ArrayConstructorStubBase);
@ -2051,9 +2037,8 @@ class ArrayNoArgumentConstructorStub : public ArrayConstructorStubBase {
public:
ArrayNoArgumentConstructorStub(
ElementsKind kind,
ContextCheckMode context_mode = CONTEXT_CHECK_REQUIRED,
AllocationSiteOverrideMode override_mode = DONT_OVERRIDE)
: ArrayConstructorStubBase(kind, context_mode, override_mode) {
: ArrayConstructorStubBase(kind, override_mode) {
}
virtual Handle<Code> GenerateCode(Isolate* isolate);
@ -2077,9 +2062,8 @@ class ArraySingleArgumentConstructorStub : public ArrayConstructorStubBase {
public:
ArraySingleArgumentConstructorStub(
ElementsKind kind,
ContextCheckMode context_mode = CONTEXT_CHECK_REQUIRED,
AllocationSiteOverrideMode override_mode = DONT_OVERRIDE)
: ArrayConstructorStubBase(kind, context_mode, override_mode) {
: ArrayConstructorStubBase(kind, override_mode) {
}
virtual Handle<Code> GenerateCode(Isolate* isolate);
@ -2103,9 +2087,8 @@ class ArrayNArgumentsConstructorStub : public ArrayConstructorStubBase {
public:
ArrayNArgumentsConstructorStub(
ElementsKind kind,
ContextCheckMode context_mode = CONTEXT_CHECK_REQUIRED,
AllocationSiteOverrideMode override_mode = DONT_OVERRIDE)
: ArrayConstructorStubBase(kind, context_mode, override_mode) {
: ArrayConstructorStubBase(kind, override_mode) {
}
virtual Handle<Code> GenerateCode(Isolate* isolate);

View File

@ -2657,6 +2657,18 @@ void HGraphBuilder::BuildCreateAllocationMemento(
}
HInstruction* HGraphBuilder::BuildGetNativeContext(HValue* closure) {
// Get the global context, then the native context
HInstruction* context =
Add<HLoadNamedField>(closure, HObjectAccess::ForFunctionContextPointer());
HInstruction* global_object = Add<HLoadNamedField>(context,
HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX));
HObjectAccess access = HObjectAccess::ForJSObjectOffset(
GlobalObject::kNativeContextOffset);
return Add<HLoadNamedField>(global_object, access);
}
HInstruction* HGraphBuilder::BuildGetNativeContext() {
// Get the global context, then the native context
HInstruction* global_object = Add<HGlobalObject>();
@ -2716,7 +2728,12 @@ HValue* HGraphBuilder::JSArrayBuilder::EmitMapCode() {
return builder()->AddLoadNamedField(constructor_function_, access);
}
HInstruction* native_context = builder()->BuildGetNativeContext();
// TODO(mvstanton): we should always have a constructor function if we
// are creating a stub.
HInstruction* native_context = constructor_function_ != NULL
? builder()->BuildGetNativeContext(constructor_function_)
: builder()->BuildGetNativeContext();
HInstruction* index = builder()->Add<HConstant>(
static_cast<int32_t>(Context::JS_ARRAY_MAPS_INDEX));

View File

@ -1774,6 +1774,7 @@ class HGraphBuilder {
HInstruction* BuildCheckPrototypeMaps(Handle<JSObject> prototype,
Handle<JSObject> holder);
HInstruction* BuildGetNativeContext(HValue* closure);
HInstruction* BuildGetNativeContext();
HInstruction* BuildGetArrayFunction();

View File

@ -5409,7 +5409,6 @@ static void CreateArrayDispatch(MacroAssembler* masm,
AllocationSiteOverrideMode mode) {
if (mode == DISABLE_ALLOCATION_SITES) {
T stub(GetInitialFastElementsKind(),
CONTEXT_CHECK_REQUIRED,
mode);
__ TailCallStub(&stub);
} else if (mode == DONT_OVERRIDE) {
@ -5465,13 +5464,11 @@ static void CreateArrayDispatchOneArgument(MacroAssembler* masm,
ElementsKind holey_initial = GetHoleyElementsKind(initial);
ArraySingleArgumentConstructorStub stub_holey(holey_initial,
CONTEXT_CHECK_REQUIRED,
DISABLE_ALLOCATION_SITES);
__ TailCallStub(&stub_holey);
__ bind(&normal_sequence);
ArraySingleArgumentConstructorStub stub(initial,
CONTEXT_CHECK_REQUIRED,
DISABLE_ALLOCATION_SITES);
__ TailCallStub(&stub);
} else if (mode == DONT_OVERRIDE) {
@ -5523,7 +5520,7 @@ static void ArrayConstructorStubAheadOfTimeHelper(Isolate* isolate) {
T stub(kind);
stub.GetCode(isolate);
if (AllocationSite::GetMode(kind) != DONT_TRACK_ALLOCATION_SITE) {
T stub1(kind, CONTEXT_CHECK_REQUIRED, DISABLE_ALLOCATION_SITES);
T stub1(kind, DISABLE_ALLOCATION_SITES);
stub1.GetCode(isolate);
}
}

View File

@ -4302,10 +4302,9 @@ void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
(AllocationSite::GetMode(kind) == TRACK_ALLOCATION_SITE)
? DISABLE_ALLOCATION_SITES
: DONT_OVERRIDE;
ContextCheckMode context_mode = CONTEXT_CHECK_NOT_REQUIRED;
if (instr->arity() == 0) {
ArrayNoArgumentConstructorStub stub(kind, context_mode, override_mode);
ArrayNoArgumentConstructorStub stub(kind, override_mode);
CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
} else if (instr->arity() == 1) {
Label done;
@ -4318,18 +4317,17 @@ void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
__ j(zero, &packed_case, Label::kNear);
ElementsKind holey_kind = GetHoleyElementsKind(kind);
ArraySingleArgumentConstructorStub stub(holey_kind, context_mode,
override_mode);
ArraySingleArgumentConstructorStub stub(holey_kind, override_mode);
CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
__ jmp(&done, Label::kNear);
__ bind(&packed_case);
}
ArraySingleArgumentConstructorStub stub(kind, context_mode, override_mode);
ArraySingleArgumentConstructorStub stub(kind, override_mode);
CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
__ bind(&done);
} else {
ArrayNArgumentsConstructorStub stub(kind, context_mode, override_mode);
ArrayNArgumentsConstructorStub stub(kind, override_mode);
CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
}
}

View File

@ -5732,9 +5732,7 @@ template<class T>
static void CreateArrayDispatch(MacroAssembler* masm,
AllocationSiteOverrideMode mode) {
if (mode == DISABLE_ALLOCATION_SITES) {
T stub(GetInitialFastElementsKind(),
CONTEXT_CHECK_REQUIRED,
mode);
T stub(GetInitialFastElementsKind(), mode);
__ TailCallStub(&stub);
} else if (mode == DONT_OVERRIDE) {
int last_index = GetSequenceIndexFromFastElementsKind(
@ -5783,13 +5781,11 @@ static void CreateArrayDispatchOneArgument(MacroAssembler* masm,
ElementsKind holey_initial = GetHoleyElementsKind(initial);
ArraySingleArgumentConstructorStub stub_holey(holey_initial,
CONTEXT_CHECK_REQUIRED,
DISABLE_ALLOCATION_SITES);
__ TailCallStub(&stub_holey);
__ bind(&normal_sequence);
ArraySingleArgumentConstructorStub stub(initial,
CONTEXT_CHECK_REQUIRED,
DISABLE_ALLOCATION_SITES);
__ TailCallStub(&stub);
} else if (mode == DONT_OVERRIDE) {
@ -5840,7 +5836,7 @@ static void ArrayConstructorStubAheadOfTimeHelper(Isolate* isolate) {
T stub(kind);
stub.GetCode(isolate);
if (AllocationSite::GetMode(kind) != DONT_TRACK_ALLOCATION_SITE) {
T stub1(kind, CONTEXT_CHECK_REQUIRED, DISABLE_ALLOCATION_SITES);
T stub1(kind, DISABLE_ALLOCATION_SITES);
stub1.GetCode(isolate);
}
}

View File

@ -3976,10 +3976,9 @@ void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
(AllocationSite::GetMode(kind) == TRACK_ALLOCATION_SITE)
? DISABLE_ALLOCATION_SITES
: DONT_OVERRIDE;
ContextCheckMode context_mode = CONTEXT_CHECK_NOT_REQUIRED;
if (instr->arity() == 0) {
ArrayNoArgumentConstructorStub stub(kind, context_mode, override_mode);
ArrayNoArgumentConstructorStub stub(kind, override_mode);
CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
} else if (instr->arity() == 1) {
Label done;
@ -3991,18 +3990,17 @@ void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
__ Branch(&packed_case, eq, t1, Operand(zero_reg));
ElementsKind holey_kind = GetHoleyElementsKind(kind);
ArraySingleArgumentConstructorStub stub(holey_kind, context_mode,
override_mode);
ArraySingleArgumentConstructorStub stub(holey_kind, override_mode);
CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
__ jmp(&done);
__ bind(&packed_case);
}
ArraySingleArgumentConstructorStub stub(kind, context_mode, override_mode);
ArraySingleArgumentConstructorStub stub(kind, override_mode);
CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
__ bind(&done);
} else {
ArrayNArgumentsConstructorStub stub(kind, context_mode, override_mode);
ArrayNArgumentsConstructorStub stub(kind, override_mode);
CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
}
}

View File

@ -5208,9 +5208,7 @@ template<class T>
static void CreateArrayDispatch(MacroAssembler* masm,
AllocationSiteOverrideMode mode) {
if (mode == DISABLE_ALLOCATION_SITES) {
T stub(GetInitialFastElementsKind(),
CONTEXT_CHECK_REQUIRED,
mode);
T stub(GetInitialFastElementsKind(), mode);
__ TailCallStub(&stub);
} else if (mode == DONT_OVERRIDE) {
int last_index = GetSequenceIndexFromFastElementsKind(
@ -5270,13 +5268,11 @@ static void CreateArrayDispatchOneArgument(MacroAssembler* masm,
ElementsKind holey_initial = GetHoleyElementsKind(initial);
ArraySingleArgumentConstructorStub stub_holey(holey_initial,
CONTEXT_CHECK_REQUIRED,
DISABLE_ALLOCATION_SITES);
__ TailCallStub(&stub_holey);
__ bind(&normal_sequence);
ArraySingleArgumentConstructorStub stub(initial,
CONTEXT_CHECK_REQUIRED,
DISABLE_ALLOCATION_SITES);
__ TailCallStub(&stub);
} else if (mode == DONT_OVERRIDE) {
@ -5328,7 +5324,7 @@ static void ArrayConstructorStubAheadOfTimeHelper(Isolate* isolate) {
T stub(kind);
stub.GetCode(isolate);
if (AllocationSite::GetMode(kind) != DONT_TRACK_ALLOCATION_SITE) {
T stub1(kind, CONTEXT_CHECK_REQUIRED, DISABLE_ALLOCATION_SITES);
T stub1(kind, DISABLE_ALLOCATION_SITES);
stub1.GetCode(isolate);
}
}

View File

@ -3874,10 +3874,9 @@ void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
(AllocationSite::GetMode(kind) == TRACK_ALLOCATION_SITE)
? DISABLE_ALLOCATION_SITES
: DONT_OVERRIDE;
ContextCheckMode context_mode = CONTEXT_CHECK_NOT_REQUIRED;
if (instr->arity() == 0) {
ArrayNoArgumentConstructorStub stub(kind, context_mode, override_mode);
ArrayNoArgumentConstructorStub stub(kind, override_mode);
CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
} else if (instr->arity() == 1) {
Label done;
@ -3890,18 +3889,17 @@ void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
__ j(zero, &packed_case, Label::kNear);
ElementsKind holey_kind = GetHoleyElementsKind(kind);
ArraySingleArgumentConstructorStub stub(holey_kind, context_mode,
override_mode);
ArraySingleArgumentConstructorStub stub(holey_kind, override_mode);
CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
__ jmp(&done, Label::kNear);
__ bind(&packed_case);
}
ArraySingleArgumentConstructorStub stub(kind, context_mode, override_mode);
ArraySingleArgumentConstructorStub stub(kind, override_mode);
CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
__ bind(&done);
} else {
ArrayNArgumentsConstructorStub stub(kind, context_mode, override_mode);
ArrayNArgumentsConstructorStub stub(kind, override_mode);
CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
}
}