Reviewers: ulan,
Message:
PTAL
Description:
Elide unnecessary context reload in generated stubs.
Please review this at https://codereview.chromium.org/11550005/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files:
M src/arm/lithium-arm.cc
M src/arm/lithium-codegen-arm.cc
M src/code-stubs-hydrogen.cc
M src/hydrogen-instructions.h
M src/hydrogen.cc
M src/ia32/lithium-codegen-ia32.cc
M src/ia32/lithium-ia32.h
M src/ia32/lithium-ia32.cc
M src/lithium-allocator-inl.h
M src/lithium-allocator.cc
M src/x64/lithium-codegen-x64.cc
M src/x64/lithium-x64.cc
Index: src/arm/lithium-arm.cc
diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc
index
f44ca98aad059da26ffb7bfeb6aa320d9247e5ca..fd55e2460fcbfa2242057be35b096dabec5b3725
100644
--- a/src/arm/lithium-arm.cc
+++ b/src/arm/lithium-arm.cc
@@ -999,7 +999,14 @@ LInstruction*
LChunkBuilder::DoThisFunction(HThisFunction* instr) {
LInstruction* LChunkBuilder::DoContext(HContext* instr) {
- return instr->HasNoUses() ? NULL : DefineAsRegister(new(zone())
LContext);
+ // If there is a non-return use, the context must be allocated in a
register.
+ for (HUseIterator it(instr->uses()); !it.Done(); it.Advance()) {
+ if (!it.value()->IsReturn()) {
+ return DefineAsRegister(new(zone()) LContext);
+ }
+ }
+
+ return NULL;
}
Index: src/arm/lithium-codegen-arm.cc
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
index
53d99814bb5d56cc10cb7c1aaed206f730ce1c3d..aedd48584320031919050edb3f5e72b99c3467f9
100644
--- a/src/arm/lithium-codegen-arm.cc
+++ b/src/arm/lithium-codegen-arm.cc
@@ -2765,9 +2765,6 @@ void LCodeGen::DoReturn(LReturn* instr) {
__ ldm(ia_w, sp, fp.bit() | lr.bit());
__ add(sp, sp, Operand(sp_delta));
}
- if (info()->IsStub()) {
- __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
- }
__ Jump(lr);
}
Index: src/code-stubs-hydrogen.cc
diff --git a/src/code-stubs-hydrogen.cc b/src/code-stubs-hydrogen.cc
index
74bd93f8805b768fbcb9806d2da04f754c80dfff..58e17f43f2adf7f98883e97db94b7297710949cb
100644
--- a/src/code-stubs-hydrogen.cc
+++ b/src/code-stubs-hydrogen.cc
@@ -51,17 +51,19 @@ Handle<Code> HydrogenCodeStub::CodeFromGraph(HGraph*
graph) {
class CodeStubGraphBuilderBase : public HGraphBuilder {
public:
CodeStubGraphBuilderBase(Isolate* isolate, HydrogenCodeStub* stub)
- : HGraphBuilder(&info_), info_(stub, isolate) {}
+ : HGraphBuilder(&info_), info_(stub, isolate), context_(NULL) {}
virtual bool BuildGraph();
protected:
virtual void BuildCodeStub() = 0;
HParameter* GetParameter(int parameter) { return parameters_[parameter];
}
HydrogenCodeStub* stub() { return info_.code_stub(); }
+ HContext* context() { return context_; }
private:
SmartArrayPointer<HParameter*> parameters_;
CompilationInfoWithZone info_;
+ HContext* context_;
};
@@ -77,6 +79,9 @@ bool CodeStubGraphBuilderBase::BuildGraph() {
graph()->entry_block()->Finish(jump);
set_current_block(next_block);
+ context_ = new(zone()) HContext();
+ AddInstruction(context_);
+
int major_key = stub()->MajorKey();
CodeStubInterfaceDescriptor* descriptor =
info_.isolate()->code_stub_interface_descriptor(major_key);
@@ -121,7 +126,7 @@ void
CodeStubGraphBuilder<KeyedLoadFastElementStub>::BuildCodeStub() {
casted_stub()->is_js_array(), casted_stub()->elements_kind(), false);
AddInstruction(load);
- HReturn* ret = new(zone) HReturn(load);
+ HReturn* ret = new(zone) HReturn(load, context());
current_block()->Finish(ret);
}
Index: src/hydrogen-instructions.h
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
index
d8f5dec0f7d90b4bc93c9da0da0e604dd0e65050..ee3fd9ba16818b30144d67b18c80425fa7515e73
100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
@@ -1171,10 +1171,11 @@ class HCompareMap: public HUnaryControlInstruction {
};
-class HReturn: public HTemplateControlInstruction<0, 1> {
+class HReturn: public HTemplateControlInstruction<0, 2> {
public:
- explicit HReturn(HValue* value) {
+ HReturn(HValue* value, HValue* context) {
SetOperandAt(0, value);
+ SetOperandAt(1, context);
}
virtual Representation RequiredInputRepresentation(int index) {
@@ -1184,6 +1185,7 @@ class HReturn: public HTemplateControlInstruction<0,
1> {
virtual void PrintDataTo(StringStream* stream);
HValue* value() { return OperandAt(0); }
+ HValue* context() { return OperandAt(1); }
DECLARE_CONCRETE_INSTRUCTION(Return)
};
Index: src/hydrogen.cc
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index
7100d3a97ab930e57f7b5d5cd2c186201a31da41..97489a97c0742d2ec94bba60598106cb027a3813
100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -3399,7 +3399,8 @@ bool HOptimizedGraphBuilder::BuildGraph() {
if (HasStackOverflow()) return false;
if (current_block() != NULL) {
- HReturn* instr = new(zone()) HReturn(graph()->GetConstantUndefined());
+ HReturn* instr = new(zone()) HReturn(graph()->GetConstantUndefined(),
+ context);
current_block()->FinishExit(instr);
set_current_block(NULL);
}
@@ -4215,7 +4216,9 @@ void
HOptimizedGraphBuilder::VisitReturnStatement(ReturnStatement* stmt) {
// Not an inlined return, so an actual one.
CHECK_ALIVE(VisitForValue(stmt->expression()));
HValue* result = environment()->Pop();
- current_block()->FinishExit(new(zone()) HReturn(result));
+ current_block()->FinishExit(new(zone()) HReturn(
+ result,
+ environment()->LookupContext()));
} else if (state->inlining_kind() == CONSTRUCT_CALL_RETURN) {
// Return from an inlined construct call. In a test context the return
value
// will always evaluate to true, in a value context the return value
needs
Index: src/ia32/lithium-codegen-ia32.cc
diff --git a/src/ia32/lithium-codegen-ia32.cc
b/src/ia32/lithium-codegen-ia32.cc
index
b2ce5203c511d096b7f300c290100aea80418d26..7e2f6ee7b1eb5c9d3074b9574df771c679be9012
100644
--- a/src/ia32/lithium-codegen-ia32.cc
+++ b/src/ia32/lithium-codegen-ia32.cc
@@ -804,7 +804,7 @@ void LCodeGen::DeoptimizeIf(Condition cc, LEnvironment*
environment) {
ASSERT(environment->HasBeenRegistered());
int id = environment->deoptimization_index();
ASSERT(info()->IsOptimizing() || info()->IsStub());
- Deoptimizer::BailoutType bailout_type = frame_is_built_
+ Deoptimizer::BailoutType bailout_type = info()->IsOptimizing()
? Deoptimizer::EAGER
: Deoptimizer::LAZY;
Address entry = Deoptimizer::GetDeoptimizationEntry(id, bailout_type);
@@ -2640,7 +2640,6 @@ void LCodeGen::DoReturn(LReturn* instr) {
__ bind(&no_padding);
}
if (info()->IsStub()) {
- __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
__ Ret();
} else {
__ Ret((GetParameterCount() + 1) * kPointerSize, ecx);
@@ -3375,7 +3374,12 @@ void LCodeGen::DoThisFunction(LThisFunction* instr) {
void LCodeGen::DoContext(LContext* instr) {
Register result = ToRegister(instr->result());
- __ mov(result, Operand(ebp, StandardFrameConstants::kContextOffset));
+ if (info()->IsOptimizing()) {
+ __ mov(result, Operand(ebp, StandardFrameConstants::kContextOffset));
+ } else {
+ // If there is no frame, the context must be in esi.
+ ASSERT(result.is(esi));
+ }
}
Index: src/ia32/lithium-ia32.cc
diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc
index
6e075937977f83461a7ab19be17c061a4be23a49..46d8f408823c0d20cc66693b26469b5f75dd8a93
100644
--- a/src/ia32/lithium-ia32.cc
+++ b/src/ia32/lithium-ia32.cc
@@ -1055,7 +1055,13 @@ LInstruction*
LChunkBuilder::DoThisFunction(HThisFunction* instr) {
LInstruction* LChunkBuilder::DoContext(HContext* instr) {
- return instr->HasNoUses() ? NULL : DefineAsRegister(new(zone())
LContext);
+ if (instr->HasNoUses()) return NULL;
+
+ if (info()->IsStub()) {
+ return DefineFixed(new(zone()) LContext, esi);
+ }
+
+ return DefineAsRegister(new(zone()) LContext);
}
@@ -1865,7 +1871,10 @@ LInstruction*
LChunkBuilder::DoClampToUint8(HClampToUint8* instr) {
LInstruction* LChunkBuilder::DoReturn(HReturn* instr) {
- return new(zone()) LReturn(UseFixed(instr->value(), eax));
+ LOperand* context = info()->IsStub()
+ ? UseFixed(instr->context(), esi)
+ : NULL;
+ return new(zone()) LReturn(UseFixed(instr->value(), eax), context);
}
Index: src/ia32/lithium-ia32.h
diff --git a/src/ia32/lithium-ia32.h b/src/ia32/lithium-ia32.h
index
f4056c10d9115b8652b713f8a66c13ba526b6030..59b23d429c1e8f79c953d1d409bd1174793f16ef
100644
--- a/src/ia32/lithium-ia32.h
+++ b/src/ia32/lithium-ia32.h
@@ -1342,10 +1342,11 @@ class LArithmeticT: public LTemplateInstruction<1,
3, 0> {
};
-class LReturn: public LTemplateInstruction<0, 1, 0> {
+class LReturn: public LTemplateInstruction<0, 2, 0> {
public:
- explicit LReturn(LOperand* value) {
+ explicit LReturn(LOperand* value, LOperand* context) {
inputs_[0] = value;
+ inputs_[1] = context;
}
DECLARE_CONCRETE_INSTRUCTION(Return, "return")
Index: src/lithium-allocator-inl.h
diff --git a/src/lithium-allocator-inl.h b/src/lithium-allocator-inl.h
index
8f660ce0e00373bdd5521b183527e972fc68c75c..29b81848ceb33fc188b897da526ec9a56235d7bf
100644
--- a/src/lithium-allocator-inl.h
+++ b/src/lithium-allocator-inl.h
@@ -110,7 +110,10 @@ void InputIterator::Advance() {
void InputIterator::SkipUninteresting() {
- while (current_ < limit_ &&
instr_->InputAt(current_)->IsConstantOperand()) {
+ LOperand* current;
+ while (current_ < limit_ &&
+ (current = instr_->InputAt(current_)) != NULL &&
+ current->IsConstantOperand()) {
++current_;
}
}
Index: src/lithium-allocator.cc
diff --git a/src/lithium-allocator.cc b/src/lithium-allocator.cc
index
b23c86766a6fb71e86927aebefdd1b2034aab359..dcaa91e8662860ea21619ff27fa93e66a76c1e4c
100644
--- a/src/lithium-allocator.cc
+++ b/src/lithium-allocator.cc
@@ -830,6 +830,7 @@ void LAllocator::MeetConstraintsBetween(LInstruction*
first,
// Handle fixed input operands of second instruction.
if (second != NULL) {
for (UseIterator it(second); !it.Done(); it.Advance()) {
+ if (it.Current() == NULL) continue;
LUnallocated* cur_input = LUnallocated::cast(it.Current());
if (cur_input->HasFixedPolicy()) {
LUnallocated* input_copy = cur_input->CopyUnconstrained(zone());
@@ -973,6 +974,7 @@ void LAllocator::ProcessInstructions(HBasicBlock*
block, BitVector* live) {
for (UseIterator it(instr); !it.Done(); it.Advance()) {
LOperand* input = it.Current();
+ if (input == NULL) continue;
LifetimePosition use_pos;
if (input->IsUnallocated() &&
Index: src/x64/lithium-codegen-x64.cc
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
index
2a10a87ac71e3868e344c9cc2a004cf0ef89a372..ad5469ecb1bc323253c6c73b4be9d0d9b8f52452
100644
--- a/src/x64/lithium-codegen-x64.cc
+++ b/src/x64/lithium-codegen-x64.cc
@@ -2441,7 +2441,6 @@ void LCodeGen::DoReturn(LReturn* instr) {
__ pop(rbp);
}
if (info()->IsStub()) {
- __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
__ Ret(0, r10);
} else {
__ Ret((GetParameterCount() + 1) * kPointerSize, rcx);
Index: src/x64/lithium-x64.cc
diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc
index
574970c6994e701cab44a590ac58d0f6aa121479..11c8a32d2693d6f28ad39271c84eb9715e20c48e
100644
--- a/src/x64/lithium-x64.cc
+++ b/src/x64/lithium-x64.cc
@@ -1006,7 +1006,14 @@ LInstruction*
LChunkBuilder::DoThisFunction(HThisFunction* instr) {
LInstruction* LChunkBuilder::DoContext(HContext* instr) {
- return instr->HasNoUses() ? NULL : DefineAsRegister(new(zone())
LContext);
+ // If there is a non-return use, the context must be allocated in a
register.
+ for (HUseIterator it(instr->uses()); !it.Done(); it.Advance()) {
+ if (!it.value()->IsReturn()) {
+ return DefineAsRegister(new(zone()) LContext);
+ }
+ }
+
+ return NULL;
}
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev