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

Unified Diff: src/codegen-ia32.cc

Issue 16412: Experimental: push the new code generator infrastructure into the... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/toiger/
Patch Set: Created 12 years 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/codegen-ia32.h ('k') | src/jump-target.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/codegen-ia32.cc
===================================================================
--- src/codegen-ia32.cc (revision 1016)
+++ src/codegen-ia32.cc (working copy)
@@ -3761,22 +3761,29 @@
void DeferredCountOperation::Generate() {
- // The argument is actually passed in eax.
- enter()->Bind();
- VirtualFrame::SpilledScope spilled_scope(generator());
+ CodeGenerator* cgen = generator();
+
+ // The argument will be passed in a register and the result returned in
+ // the same register.
+ Result value(cgen);
+ enter()->Bind(&value);
+ ASSERT(value.is_register());
+ Register target = value.reg();
+ value.ToRegister(eax); // The stubs below expect their argument in eax.
+
if (is_postfix_) {
RevertToNumberStub to_number_stub(is_increment_);
- generator()->frame()->CallStub(&to_number_stub, 0);
+ value = generator()->frame()->CallStub(&to_number_stub, &value, 0);
}
+
CounterOpStub stub(result_offset_, is_postfix_, is_increment_);
- generator()->frame()->CallStub(&stub, 0);
- // The result is actually returned in eax.
- exit()->Jump();
+ value = generator()->frame()->CallStub(&stub, &value, 0);
+ value.ToRegister(target);
+ exit()->Jump(&value);
}
void CodeGenerator::VisitCountOperation(CountOperation* node) {
- VirtualFrame::SpilledScope spilled_scope(this);
Comment cmnt(masm_, "[ CountOperation");
bool is_postfix = node->is_postfix();
@@ -3787,7 +3794,7 @@
// Postfix: Make room for the result.
if (is_postfix) {
- frame_->EmitPush(Immediate(0));
+ frame_->Push(Handle<Object>(Smi::FromInt(0)));
}
{ Reference target(this, node->expression());
@@ -3795,41 +3802,49 @@
// Spoof the virtual frame to have the expected height (one higher
// than on entry).
if (!is_postfix) {
- frame_->EmitPush(Immediate(Smi::FromInt(0)));
+ frame_->Push(Handle<Object>(Smi::FromInt(0)));
}
return;
}
- target.GetValueAndSpill(NOT_INSIDE_TYPEOF);
+ target.TakeValue(NOT_INSIDE_TYPEOF);
DeferredCountOperation* deferred =
new DeferredCountOperation(this, is_postfix, is_increment,
target.size() * kPointerSize);
- frame_->EmitPop(eax); // Load TOS into eax for calculations below
+ Result value = frame_->Pop();
+ value.ToRegister();
+ ASSERT(value.is_valid());
// Postfix: Store the old value as the result.
if (is_postfix) {
- __ mov(frame_->ElementAt(target.size()), eax);
+ Result old_value = value;
+ frame_->SetElementAt(target.size(), &old_value);
}
- // Perform optimistic increment/decrement.
+ // Perform optimistic increment/decrement. Ensure the value is
+ // writable.
+ frame_->Spill(value.reg());
+ ASSERT(allocator_->count(value.reg()) == 1);
if (is_increment) {
- __ add(Operand(eax), Immediate(Smi::FromInt(1)));
+ __ add(Operand(value.reg()), Immediate(Smi::FromInt(1)));
} else {
- __ sub(Operand(eax), Immediate(Smi::FromInt(1)));
+ __ sub(Operand(value.reg()), Immediate(Smi::FromInt(1)));
}
// If the count operation didn't overflow and the result is a
// valid smi, we're done. Otherwise, we jump to the deferred
// slow-case code.
- deferred->enter()->Branch(overflow, not_taken);
- __ test(eax, Immediate(kSmiTagMask));
- deferred->enter()->Branch(not_zero, not_taken);
+ deferred->enter()->Branch(overflow, &value, not_taken);
+ __ test(value.reg(), Immediate(kSmiTagMask));
+ deferred->enter()->Branch(not_zero, &value, not_taken);
// Store the new value in the target if not const.
- deferred->exit()->Bind();
- frame_->EmitPush(eax); // Push the new value to TOS
- if (!is_const) target.SetValue(NOT_CONST_INIT);
+ deferred->exit()->Bind(&value);
+ frame_->Push(&value);
+ if (!is_const) {
+ target.SetValue(NOT_CONST_INIT);
+ }
}
// Postfix: Discard the new value and use the old.
@@ -4303,6 +4318,37 @@
}
+void Reference::TakeValue(TypeofState typeof_state) {
+ // For non-constant frame-allocated slots, we invalidate the value in the
+ // slot. For all others, we fall back on GetValue.
+ ASSERT(!cgen_->in_spilled_code());
+ ASSERT(!is_illegal());
+ ASSERT(!cgen_->has_cc());
+ if (type_ != SLOT) {
+ GetValue(typeof_state);
+ return;
+ }
+
+ Slot* slot = expression_->AsVariableProxy()->AsVariable()->slot();
+ ASSERT(slot != NULL);
+ if (slot->type() == Slot::LOOKUP ||
+ slot->type() == Slot::CONTEXT ||
+ slot->var()->mode() == Variable::CONST) {
+ GetValue(typeof_state);
+ return;
+ }
+
+ // Only non-constant, frame-allocated parameters and locals can reach
+ // here.
+ if (slot->type() == Slot::PARAMETER) {
+ cgen_->frame()->TakeParameterAt(slot->index());
+ } else {
+ ASSERT(slot->type() == Slot::LOCAL);
+ cgen_->frame()->TakeLocalAt(slot->index());
+ }
+}
+
+
void Reference::SetValue(InitState init_state) {
ASSERT(!is_illegal());
ASSERT(!cgen_->has_cc());
« no previous file with comments | « src/codegen-ia32.h ('k') | src/jump-target.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698