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

Unified Diff: src/x64/fast-codegen-x64.cc

Issue 523052: More cleanup of slot handling in the nonoptimizing code generator.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 12 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/ia32/macro-assembler-ia32.h ('k') | src/x64/macro-assembler-x64.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/x64/fast-codegen-x64.cc
===================================================================
--- src/x64/fast-codegen-x64.cc (revision 3532)
+++ src/x64/fast-codegen-x64.cc (working copy)
@@ -270,30 +270,28 @@
}
-template <>
-Operand FastCodeGenerator::CreateSlotOperand<Operand>(Slot* source,
- Register scratch) {
- switch (source->type()) {
+MemOperand FastCodeGenerator::EmitSlotSearch(Slot* slot, Register scratch) {
+ switch (slot->type()) {
case Slot::PARAMETER:
case Slot::LOCAL:
- return Operand(rbp, SlotOffset(source));
+ return Operand(rbp, SlotOffset(slot));
case Slot::CONTEXT: {
int context_chain_length =
- function_->scope()->ContextChainLength(source->var()->scope());
+ function_->scope()->ContextChainLength(slot->var()->scope());
__ LoadContext(scratch, context_chain_length);
- return CodeGenerator::ContextOperand(scratch, source->index());
+ return CodeGenerator::ContextOperand(scratch, slot->index());
}
case Slot::LOOKUP:
- UNIMPLEMENTED();
+ UNREACHABLE();
}
UNREACHABLE();
return Operand(rax, 0);
}
-void FastCodeGenerator::Move(Register dst, Slot* source) {
- Operand location = CreateSlotOperand<Operand>(source, dst);
- __ movq(dst, location);
+void FastCodeGenerator::Move(Register destination, Slot* source) {
+ MemOperand location = EmitSlotSearch(source, destination);
+ __ movq(destination, location);
}
@@ -306,7 +304,7 @@
case Expression::kEffect:
break;
case Expression::kValue: {
- Operand location = CreateSlotOperand<Operand>(source, scratch);
+ MemOperand location = EmitSlotSearch(source, scratch);
__ push(location);
break;
}
@@ -343,25 +341,14 @@
Register src,
Register scratch1,
Register scratch2) {
- switch (dst->type()) {
- case Slot::PARAMETER:
- case Slot::LOCAL:
- __ movq(Operand(rbp, SlotOffset(dst)), src);
- break;
- case Slot::CONTEXT: {
- ASSERT(!src.is(scratch1));
- ASSERT(!src.is(scratch2));
- ASSERT(!scratch1.is(scratch2));
- int context_chain_length =
- function_->scope()->ContextChainLength(dst->var()->scope());
- __ LoadContext(scratch1, context_chain_length);
- __ movq(Operand(scratch1, Context::SlotOffset(dst->index())), src);
- int offset = FixedArray::kHeaderSize + dst->index() * kPointerSize;
- __ RecordWrite(scratch1, offset, src, scratch2);
- break;
- }
- case Slot::LOOKUP:
- UNIMPLEMENTED();
+ ASSERT(dst->type() != Slot::LOOKUP); // Not yet implemented.
+ ASSERT(!scratch1.is(src) && !scratch2.is(src));
+ MemOperand location = EmitSlotSearch(dst, scratch1);
+ __ movq(location, src);
+ // Emit the write barrier code if the location is in the heap.
+ if (dst->type() == Slot::CONTEXT) {
+ int offset = FixedArray::kHeaderSize + dst->index() * kPointerSize;
+ __ RecordWrite(scratch1, offset, src, scratch2);
}
}
@@ -457,14 +444,17 @@
case Slot::LOCAL:
if (decl->mode() == Variable::CONST) {
__ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex);
- __ movq(Operand(rbp, SlotOffset(var->slot())), kScratchRegister);
+ __ movq(Operand(rbp, SlotOffset(slot)), kScratchRegister);
} else if (decl->fun() != NULL) {
Visit(decl->fun());
- __ pop(Operand(rbp, SlotOffset(var->slot())));
+ __ pop(Operand(rbp, SlotOffset(slot)));
}
break;
case Slot::CONTEXT:
+ // We bypass the general EmitSlotSearch because we know more about
+ // this specific context.
+
// The variable in the decl always resides in the current context.
ASSERT_EQ(0, function_->scope()->ContextChainLength(var->scope()));
if (FLAG_debug_code) {
@@ -908,34 +898,34 @@
// Overwrite the global object on the stack with the result if needed.
DropAndMove(context, rax);
- } else if (var->slot()) {
+ } else if (var->slot() != NULL) {
Slot* slot = var->slot();
- ASSERT_NOT_NULL(slot); // Variables rewritten as properties not handled.
switch (slot->type()) {
case Slot::LOCAL:
case Slot::PARAMETER: {
+ Operand target = Operand(rbp, SlotOffset(slot));
switch (context) {
case Expression::kUninitialized:
UNREACHABLE();
case Expression::kEffect:
// Perform assignment and discard value.
- __ pop(Operand(rbp, SlotOffset(var->slot())));
+ __ pop(target);
break;
case Expression::kValue:
// Perform assignment and preserve value.
__ movq(rax, Operand(rsp, 0));
- __ movq(Operand(rbp, SlotOffset(var->slot())), rax);
+ __ movq(target, rax);
break;
case Expression::kTest:
// Perform assignment and test (and discard) value.
__ pop(rax);
- __ movq(Operand(rbp, SlotOffset(var->slot())), rax);
+ __ movq(target, rax);
TestAndBranch(rax, true_label_, false_label_);
break;
case Expression::kValueTest: {
Label discard;
__ movq(rax, Operand(rsp, 0));
- __ movq(Operand(rbp, SlotOffset(var->slot())), rax);
+ __ movq(target, rax);
TestAndBranch(rax, true_label_, &discard);
__ bind(&discard);
__ addq(rsp, Immediate(kPointerSize));
@@ -945,7 +935,7 @@
case Expression::kTestValue: {
Label discard;
__ movq(rax, Operand(rsp, 0));
- __ movq(Operand(rbp, SlotOffset(var->slot())), rax);
+ __ movq(target, rax);
TestAndBranch(rax, &discard, false_label_);
__ bind(&discard);
__ addq(rsp, Immediate(kPointerSize));
@@ -957,38 +947,18 @@
}
case Slot::CONTEXT: {
- int chain_length =
- function_->scope()->ContextChainLength(slot->var()->scope());
- if (chain_length > 0) {
- // Move up the context chain to the context containing the slot.
- __ movq(rax,
- Operand(rsi, Context::SlotOffset(Context::CLOSURE_INDEX)));
- // Load the function context (which is the incoming, outer context).
- __ movq(rax, FieldOperand(rax, JSFunction::kContextOffset));
- for (int i = 1; i < chain_length; i++) {
- __ movq(rax,
- Operand(rax, Context::SlotOffset(Context::CLOSURE_INDEX)));
- __ movq(rax, FieldOperand(rax, JSFunction::kContextOffset));
- }
- } else { // Slot is in the current context. Generate optimized code.
- __ movq(rax, rsi); // RecordWrite destroys the object register.
- }
- if (FLAG_debug_code) {
- __ cmpq(rax,
- Operand(rax, Context::SlotOffset(Context::FCONTEXT_INDEX)));
- __ Check(equal, "Context Slot chain length wrong.");
- }
- __ pop(rcx);
- __ movq(Operand(rax, Context::SlotOffset(slot->index())), rcx);
+ MemOperand target = EmitSlotSearch(slot, rcx);
+ __ pop(rax);
+ __ movq(target, rax);
// RecordWrite may destroy all its register arguments.
if (context == Expression::kValue) {
- __ push(rcx);
+ __ push(rax);
} else if (context != Expression::kEffect) {
- __ movq(rdx, rcx);
+ __ movq(rdx, rax);
}
int offset = FixedArray::kHeaderSize + slot->index() * kPointerSize;
- __ RecordWrite(rax, offset, rcx, rbx);
+ __ RecordWrite(rcx, offset, rax, rbx);
if (context != Expression::kEffect &&
context != Expression::kValue) {
Move(context, rdx);
@@ -1000,6 +970,10 @@
UNREACHABLE();
break;
}
+ } else {
+ // Variables rewritten as properties are not treated as variables in
+ // assignments.
+ UNREACHABLE();
}
}
« no previous file with comments | « src/ia32/macro-assembler-ia32.h ('k') | src/x64/macro-assembler-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698