Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(38)

Unified Diff: src/arm/codegen-arm.cc

Issue 2249002: Fix jump targets on ARM to merge virtual frames (really this time).... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/arm/codegen-arm.h ('k') | src/arm/ic-arm.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/arm/codegen-arm.cc
===================================================================
--- src/arm/codegen-arm.cc (revision 4738)
+++ src/arm/codegen-arm.cc (working copy)
@@ -66,50 +66,16 @@
static bool IsEasyToMultiplyBy(int x);
-#define __ ACCESS_MASM(masm)
-
-// -------------------------------------------------------------------------
-// Platform-specific FrameRegisterState functions.
-
-void FrameRegisterState::Save(MacroAssembler* masm) const {
- for (int i = 0; i < RegisterAllocator::kNumRegisters; i++) {
- int action = registers_[i];
- if (action == kPush) {
- __ push(RegisterAllocator::ToRegister(i));
- } else if (action != kIgnore && (action & kSyncedFlag) == 0) {
- __ str(RegisterAllocator::ToRegister(i), MemOperand(fp, action));
- }
- }
-}
-
-
-void FrameRegisterState::Restore(MacroAssembler* masm) const {
- // Restore registers in reverse order due to the stack.
- for (int i = RegisterAllocator::kNumRegisters - 1; i >= 0; i--) {
- int action = registers_[i];
- if (action == kPush) {
- __ pop(RegisterAllocator::ToRegister(i));
- } else if (action != kIgnore) {
- action &= ~kSyncedFlag;
- __ ldr(RegisterAllocator::ToRegister(i), MemOperand(fp, action));
- }
- }
-}
-
-
-#undef __
#define __ ACCESS_MASM(masm_)
// -------------------------------------------------------------------------
// Platform-specific DeferredCode functions.
void DeferredCode::SaveRegisters() {
- frame_state_.Save(masm_);
}
void DeferredCode::RestoreRegisters() {
- frame_state_.Restore(masm_);
}
@@ -117,16 +83,16 @@
// Platform-specific RuntimeCallHelper functions.
void VirtualFrameRuntimeCallHelper::BeforeCall(MacroAssembler* masm) const {
- frame_state_->Save(masm);
+ frame_state_.frame()->AssertIsSpilled();
}
void VirtualFrameRuntimeCallHelper::AfterCall(MacroAssembler* masm) const {
- frame_state_->Restore(masm);
}
void ICRuntimeCallHelper::BeforeCall(MacroAssembler* masm) const {
+ frame_state_.frame()->AssertIsSpilled();
masm->EnterInternalFrame();
}
@@ -3457,7 +3423,6 @@
frame_->Dup();
}
EmitNamedLoad(name, var != NULL);
- frame_->EmitPush(r0);
// Perform the binary operation.
Literal* literal = node->value()->AsLiteral();
@@ -5614,11 +5579,19 @@
};
+// Convention for this is that on entry the receiver is in a register that
+// is not used by the stack. On exit the answer is found in that same
+// register and the stack has the same height.
void DeferredReferenceGetNamedValue::Generate() {
- ASSERT(receiver_.is(r0) || receiver_.is(r1));
+#ifdef DEBUG
+ int expected_height = frame_state()->frame()->height();
+#endif
+ VirtualFrame copied_frame(*frame_state()->frame());
+ copied_frame.SpillAll();
Register scratch1 = VirtualFrame::scratch0();
Register scratch2 = VirtualFrame::scratch1();
+ ASSERT(!receiver_.is(scratch1) && !receiver_.is(scratch2));
__ DecrementCounter(&Counters::named_load_inline, 1, scratch1, scratch2);
__ IncrementCounter(&Counters::named_load_inline_miss, 1, scratch1, scratch2);
@@ -5634,11 +5607,23 @@
// in-object has been inlined.
__ nop(PROPERTY_ACCESS_INLINED);
+ // At this point the answer is in r0. We move it to the expected register
+ // if necessary.
+ __ Move(receiver_, r0);
+
+ // Now go back to the frame that we entered with. This will not overwrite
+ // the receiver register since that register was not in use when we came
+ // in. The instructions emitted by this merge are skipped over by the
+ // inline load patching mechanism when looking for the branch instruction
+ // that tells it where the code to patch is.
+ copied_frame.MergeTo(frame_state()->frame());
+
// Block the constant pool for one more instruction after leaving this
// constant pool block scope to include the branch instruction ending the
// deferred code.
__ BlockConstPoolFor(1);
}
+ ASSERT_EQ(expected_height, frame_state()->frame()->height());
}
@@ -5739,6 +5724,7 @@
}
+// Consumes the top of stack (the receiver) and pushes the result instead.
void CodeGenerator::EmitNamedLoad(Handle<String> name, bool is_contextual) {
if (is_contextual || scope()->is_global_scope() || loop_nesting() == 0) {
Comment cmnt(masm(), "[ Load from named Property");
@@ -5747,6 +5733,7 @@
is_contextual
? RelocInfo::CODE_TARGET_CONTEXT
: RelocInfo::CODE_TARGET);
+ frame_->EmitPush(r0); // Push answer.
} else {
// Inline the in-object property case.
Comment cmnt(masm(), "[ Inlined named property load");
@@ -5763,7 +5750,6 @@
// Load the receiver from the stack.
Register receiver = frame_->PopToRegister();
- VirtualFrame::SpilledScope spilled(frame_);
DeferredReferenceGetNamedValue* deferred =
new DeferredReferenceGetNamedValue(receiver, name);
@@ -5779,16 +5765,19 @@
__ tst(receiver, Operand(kSmiTagMask));
deferred->Branch(eq);
+ Register scratch = VirtualFrame::scratch0();
+ Register scratch2 = VirtualFrame::scratch1();
+
// Check the map. The null map used below is patched by the inline cache
- // code.
- __ ldr(r2, FieldMemOperand(receiver, HeapObject::kMapOffset));
- __ mov(r3, Operand(Factory::null_value()));
- __ cmp(r2, r3);
+ // code. Therefore we can't use a LoadRoot call.
+ __ ldr(scratch, FieldMemOperand(receiver, HeapObject::kMapOffset));
+ __ mov(scratch2, Operand(Factory::null_value()));
+ __ cmp(scratch, scratch2);
deferred->Branch(ne);
// Initially use an invalid index. The index will be patched by the
// inline cache code.
- __ ldr(r0, MemOperand(receiver, 0));
+ __ ldr(receiver, MemOperand(receiver, 0));
// Make sure that the expected number of instructions are generated.
ASSERT_EQ(kInlinedNamedLoadInstructions,
@@ -5796,6 +5785,9 @@
}
deferred->BindExit();
+ // At this point the receiver register has the result, either from the
+ // deferred code or from the inlined code.
+ frame_->EmitPush(receiver);
}
}
@@ -6011,6 +6003,27 @@
}
+void Reference::DupIfPersist() {
+ if (persist_after_get_) {
+ switch (type_) {
+ case KEYED:
+ cgen_->frame()->Dup2();
+ break;
+ case NAMED:
+ cgen_->frame()->Dup();
+ // Fall through.
+ case UNLOADED:
+ case ILLEGAL:
+ case SLOT:
+ // Do nothing.
+ ;
+ }
+ } else {
+ set_unloaded();
+ }
+}
+
+
void Reference::GetValue() {
ASSERT(cgen_->HasValidEntryRegisters());
ASSERT(!is_illegal());
@@ -6026,10 +6039,8 @@
Comment cmnt(masm, "[ Load from Slot");
Slot* slot = expression_->AsVariableProxy()->AsVariable()->slot();
ASSERT(slot != NULL);
+ DupIfPersist();
cgen_->LoadFromSlotCheckForArguments(slot, NOT_INSIDE_TYPEOF);
- if (!persist_after_get_) {
- cgen_->UnloadReference(this);
- }
break;
}
@@ -6037,23 +6048,17 @@
Variable* var = expression_->AsVariableProxy()->AsVariable();
bool is_global = var != NULL;
ASSERT(!is_global || var->is_global());
- if (persist_after_get_) {
- cgen_->frame()->Dup();
- }
- cgen_->EmitNamedLoad(GetName(), is_global);
- cgen_->frame()->EmitPush(r0);
- if (!persist_after_get_) set_unloaded();
+ Handle<String> name = GetName();
+ DupIfPersist();
+ cgen_->EmitNamedLoad(name, is_global);
break;
}
case KEYED: {
ASSERT(property != NULL);
- if (persist_after_get_) {
- cgen_->frame()->Dup2();
- }
+ DupIfPersist();
cgen_->EmitKeyedLoad();
cgen_->frame()->EmitPush(r0);
- if (!persist_after_get_) set_unloaded();
break;
}
« no previous file with comments | « src/arm/codegen-arm.h ('k') | src/arm/ic-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698