Chromium Code Reviews

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

Issue 1989012: Add complete implementation of full compiler for the ia32 architecture... (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.
Jump to:
View side-by-side diff with in-line comments
« no previous file with comments | « src/ia32/full-codegen-ia32.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/x64/full-codegen-x64.cc
===================================================================
--- src/x64/full-codegen-x64.cc (revision 4643)
+++ src/x64/full-codegen-x64.cc (working copy)
@@ -777,19 +777,28 @@
}
-void FullCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) {
- Comment cmnt(masm_, "[ FunctionLiteral");
+void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
+ UNREACHABLE();
+}
- // Build the shared function info and instantiate the function based
- // on it.
- Handle<SharedFunctionInfo> function_info =
- Compiler::BuildFunctionInfo(expr, script(), this);
- if (HasStackOverflow()) return;
- // Create a new closure.
- __ push(rsi);
- __ Push(function_info);
- __ CallRuntime(Runtime::kNewClosure, 2);
+void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
+ UNREACHABLE();
+}
+
+
+void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info) {
+ // Use the fast case closure allocation code that allocates in new
+ // space for nested functions that don't need literals cloning.
+ if (scope()->is_function_scope() && info->num_literals() == 0) {
+ FastNewClosureStub stub;
+ __ Push(info);
+ __ CallStub(&stub);
+ } else {
+ __ push(rsi);
+ __ Push(info);
+ __ CallRuntime(Runtime::kNewClosure, 2);
+ }
Apply(context_, rax);
}
@@ -1019,7 +1028,13 @@
void FullCodeGenerator::VisitAssignment(Assignment* expr) {
Comment cmnt(masm_, "[ Assignment");
- ASSERT(expr->op() != Token::INIT_CONST);
+ // Invalid left-hand sides are rewritten to have a 'throw ReferenceError'
+ // on the left-hand side.
+ if (!expr->target()->IsValidLeftHandSide()) {
+ VisitForEffect(expr->target());
+ return;
+ }
+
// Left-hand side can only be a property, a global or a (parameter or local)
// slot. Variables with rewrite to .arguments are treated as KEYED_PROPERTY.
enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
@@ -1045,8 +1060,15 @@
}
break;
case KEYED_PROPERTY:
- VisitForValue(prop->obj(), kStack);
- VisitForValue(prop->key(), kStack);
+ if (expr->is_compound()) {
+ VisitForValue(prop->obj(), kStack);
+ VisitForValue(prop->key(), kAccumulator);
+ __ movq(rdx, Operand(rsp, 0));
+ __ push(rax);
+ } else {
+ VisitForValue(prop->obj(), kStack);
+ VisitForValue(prop->key(), kStack);
+ }
break;
}
@@ -1091,6 +1113,7 @@
switch (assign_type) {
case VARIABLE:
EmitVariableAssignment(expr->target()->AsVariableProxy()->var(),
+ expr->op(),
context_);
break;
case NAMED_PROPERTY:
@@ -1133,60 +1156,78 @@
void FullCodeGenerator::EmitVariableAssignment(Variable* var,
+ Token::Value op,
Expression::Context context) {
- // Three main cases: non-this global variables, lookup slots, and
- // all other types of slots. Left-hand-side parameters that rewrite
- // to explicit property accesses do not reach here.
+ // Left-hand sides that rewrite to explicit property accesses do not reach
+ // here.
ASSERT(var != NULL);
ASSERT(var->is_global() || var->slot() != NULL);
- Slot* slot = var->slot();
+
if (var->is_global()) {
ASSERT(!var->is_this());
// Assignment to a global variable. Use inline caching for the
// assignment. Right-hand-side value is passed in rax, variable name in
- // rcx, and the global object in rdx.
+ // rcx, and the global object on the stack.
__ Move(rcx, var->name());
__ movq(rdx, CodeGenerator::GlobalObject());
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET);
- Apply(context, rax);
+ __ nop();
- } else if (slot != NULL && slot->type() == Slot::LOOKUP) {
- __ push(result_register()); // Value.
- __ push(rsi); // Context.
- __ Push(var->name());
- __ CallRuntime(Runtime::kStoreContextSlot, 3);
- Apply(context, rax);
-
- } else if (var->slot() != NULL) {
+ } else if (var->mode() != Variable::CONST || op == Token::INIT_CONST) {
+ // Perform the assignment for non-const variables and for initialization
+ // of const variables. Const assignments are simply skipped.
+ Label done;
+ Slot* slot = var->slot();
switch (slot->type()) {
+ case Slot::PARAMETER:
case Slot::LOCAL:
- case Slot::PARAMETER:
- __ movq(Operand(rbp, SlotOffset(slot)), result_register());
+ if (op == Token::INIT_CONST) {
+ // Detect const reinitialization by checking for the hole value.
+ __ movq(rdx, Operand(rbp, SlotOffset(slot)));
+ __ Cmp(rdx, Factory::the_hole_value());
+ __ j(not_equal, &done);
+ }
+ // Perform the assignment.
+ __ movq(Operand(rbp, SlotOffset(slot)), rax);
break;
case Slot::CONTEXT: {
MemOperand target = EmitSlotSearch(slot, rcx);
- __ movq(target, result_register());
-
- // RecordWrite may destroy all its register arguments.
- __ movq(rdx, result_register());
+ if (op == Token::INIT_CONST) {
+ // Detect const reinitialization by checking for the hole value.
+ __ movq(rdx, target);
+ __ Cmp(rdx, Factory::the_hole_value());
+ __ j(not_equal, &done);
+ }
+ // Perform the assignment and issue the write barrier.
+ __ movq(target, rax);
+ // The value of the assignment is in rax. RecordWrite clobbers its
+ // register arguments.
+ __ movq(rdx, rax);
int offset = FixedArray::kHeaderSize + slot->index() * kPointerSize;
__ RecordWrite(rcx, offset, rdx, rbx);
break;
}
case Slot::LOOKUP:
- UNREACHABLE();
+ // Call the runtime for the assignment. The runtime will ignore
+ // const reinitialization.
+ __ push(rax); // Value.
+ __ push(rsi); // Context.
+ __ Push(var->name());
+ if (op == Token::INIT_CONST) {
+ // The runtime will ignore const redeclaration.
+ __ CallRuntime(Runtime::kInitializeConstContextSlot, 3);
+ } else {
+ __ CallRuntime(Runtime::kStoreContextSlot, 3);
+ }
break;
}
- Apply(context, result_register());
+ __ bind(&done);
+ }
- } else {
- // Variables rewritten as properties are not treated as variables in
- // assignments.
- UNREACHABLE();
- }
+ Apply(context, rax);
}
@@ -1735,7 +1776,9 @@
switch (assign_type) {
case VARIABLE:
if (expr->is_postfix()) {
+ // Perform the assignment as if via '='.
EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
+ Token::ASSIGN,
Expression::kEffect);
// For all contexts except kEffect: We have the result on
// top of the stack.
@@ -1743,7 +1786,9 @@
ApplyTOS(context_);
}
} else {
+ // Perform the assignment as if via '='.
EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
+ Token::ASSIGN,
context_);
}
break;
« no previous file with comments | « src/ia32/full-codegen-ia32.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine