Revision: 3425 Author: [email protected] Date: Fri Dec 4 06:30:27 2009 Log: Refactor code for generating assignments in the fast compiler.
1. Refactor the structure of VisitAssignment: The existing code is not ideal to be extended with support for compound assignments. 2. Reuse common code for keyed property assigments: Now variables rewritten to a property (.arguments access) are treated like normal keyed property assignments. This allows us to remove some code duplication. Review URL: http://codereview.chromium.org/456024 http://code.google.com/p/v8/source/detail?r=3425 Modified: /branches/bleeding_edge/src/arm/fast-codegen-arm.cc /branches/bleeding_edge/src/compiler.cc /branches/bleeding_edge/src/fast-codegen.cc /branches/bleeding_edge/src/ia32/fast-codegen-ia32.cc /branches/bleeding_edge/src/x64/fast-codegen-x64.cc ======================================= --- /branches/bleeding_edge/src/arm/fast-codegen-arm.cc Mon Nov 30 07:09:49 2009 +++ /branches/bleeding_edge/src/arm/fast-codegen-arm.cc Fri Dec 4 06:30:27 2009 @@ -863,7 +863,7 @@ void FastCodeGenerator::EmitVariableAssignment(Assignment* expr) { Variable* var = expr->target()->AsVariableProxy()->AsVariable(); ASSERT(var != NULL); - + ASSERT(var->is_global() || var->slot() != NULL); if (var->is_global()) { // Assignment to a global variable. Use inline caching for the // assignment. Right-hand-side value is passed in r0, variable name in @@ -976,35 +976,6 @@ UNREACHABLE(); break; } - } else { - Property* property = var->rewrite()->AsProperty(); - ASSERT_NOT_NULL(property); - - // Load object and key onto the stack. - Slot* object_slot = property->obj()->AsSlot(); - ASSERT_NOT_NULL(object_slot); - Move(Expression::kValue, object_slot, r0); - - Literal* key_literal = property->key()->AsLiteral(); - ASSERT_NOT_NULL(key_literal); - Move(Expression::kValue, key_literal); - - // Value to store was pushed before object and key on the stack. - __ ldr(r0, MemOperand(sp, 2 * kPointerSize)); - - // Arguments to ic is value in r0, object and key on stack. - Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); - __ Call(ic, RelocInfo::CODE_TARGET); - - if (expr->context() == Expression::kEffect) { - __ add(sp, sp, Operand(3 * kPointerSize)); - } else if (expr->context() == Expression::kValue) { - // Value is still on the stack in esp[2 * kPointerSize] - __ add(sp, sp, Operand(2 * kPointerSize)); - } else { - __ ldr(r0, MemOperand(sp, 2 * kPointerSize)); - DropAndMove(expr->context(), r0, 3); - } } } ======================================= --- /branches/bleeding_edge/src/compiler.cc Tue Dec 1 07:52:02 2009 +++ /branches/bleeding_edge/src/compiler.cc Fri Dec 4 06:30:27 2009 @@ -891,28 +891,19 @@ Variable* var = expr->target()->AsVariableProxy()->AsVariable(); Property* prop = expr->target()->AsProperty(); + ASSERT(var == NULL || prop == NULL); if (var != NULL) { // All global variables are supported. if (!var->is_global()) { - if (var->slot() == NULL) { - Property* property = var->AsProperty(); - if (property == NULL) { - BAILOUT("non-global/non-slot/non-property assignment"); - } - if (property->obj()->AsSlot() == NULL) { - BAILOUT("variable rewritten to property non slot object assignment"); - } - if (property->key()->AsLiteral() == NULL) { - BAILOUT("variable rewritten to property non literal key assignment"); - } - } else { - Slot::Type type = var->slot()->type(); - if (type == Slot::LOOKUP) { - BAILOUT("Lookup slot"); - } + ASSERT(var->slot() != NULL); + Slot::Type type = var->slot()->type(); + if (type == Slot::LOOKUP) { + BAILOUT("Lookup slot"); } } } else if (prop != NULL) { + ASSERT(prop->obj()->context() == Expression::kUninitialized || + prop->obj()->context() == Expression::kValue); ProcessExpression(prop->obj(), Expression::kValue); CHECK_BAILOUT; // We will only visit the key during code generation for keyed property @@ -923,6 +914,8 @@ if (lit == NULL || !lit->handle()->IsSymbol() || String::cast(*(lit->handle()))->AsArrayIndex(&ignored)) { + ASSERT(prop->key()->context() == Expression::kUninitialized || + prop->key()->context() == Expression::kValue); ProcessExpression(prop->key(), Expression::kValue); CHECK_BAILOUT; } ======================================= --- /branches/bleeding_edge/src/fast-codegen.cc Wed Nov 25 01:05:30 2009 +++ /branches/bleeding_edge/src/fast-codegen.cc Fri Dec 4 06:30:27 2009 @@ -505,35 +505,41 @@ // Record source code position of the (possible) IC call. SetSourcePosition(expr->position()); - Expression* rhs = expr->value(); - // Left-hand side can only be a property, a global or a (parameter or - // local) slot. - Variable* var = expr->target()->AsVariableProxy()->AsVariable(); + // 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 }; + LhsKind assign_type = VARIABLE; Property* prop = expr->target()->AsProperty(); - if (var != NULL) { - Visit(rhs); - ASSERT_EQ(Expression::kValue, rhs->context()); - EmitVariableAssignment(expr); - } else if (prop != NULL) { - // Assignment to a property. - Visit(prop->obj()); - ASSERT_EQ(Expression::kValue, prop->obj()->context()); - // Use the expression context of the key subexpression to detect whether - // we have decided to us a named or keyed IC. - if (prop->key()->context() == Expression::kUninitialized) { - ASSERT(prop->key()->AsLiteral() != NULL); + // In case of a property we use the uninitialized expression context + // of the key to detect a named property. + if (prop != NULL) { + assign_type = (prop->key()->context() == Expression::kUninitialized) + ? NAMED_PROPERTY + : KEYED_PROPERTY; + } + + Expression* rhs = expr->value(); + ASSERT_EQ(Expression::kValue, rhs->context()); + + switch (assign_type) { + case VARIABLE: Visit(rhs); - ASSERT_EQ(Expression::kValue, rhs->context()); + EmitVariableAssignment(expr); + break; + case NAMED_PROPERTY: + Visit(prop->obj()); + ASSERT_EQ(Expression::kValue, prop->obj()->context()); + Visit(rhs); EmitNamedPropertyAssignment(expr); - } else { + break; + case KEYED_PROPERTY: + Visit(prop->obj()); + ASSERT_EQ(Expression::kValue, prop->obj()->context()); Visit(prop->key()); ASSERT_EQ(Expression::kValue, prop->key()->context()); Visit(rhs); - ASSERT_EQ(Expression::kValue, rhs->context()); EmitKeyedPropertyAssignment(expr); - } - } else { - UNREACHABLE(); + break; } } ======================================= --- /branches/bleeding_edge/src/ia32/fast-codegen-ia32.cc Mon Nov 30 07:09:49 2009 +++ /branches/bleeding_edge/src/ia32/fast-codegen-ia32.cc Fri Dec 4 06:30:27 2009 @@ -855,7 +855,7 @@ void FastCodeGenerator::EmitVariableAssignment(Assignment* expr) { Variable* var = expr->target()->AsVariableProxy()->AsVariable(); ASSERT(var != NULL); - + ASSERT(var->is_global() || var->slot() != NULL); if (var->is_global()) { // Assignment to a global variable. Use inline caching for the // assignment. Right-hand-side value is passed in eax, variable name in @@ -960,35 +960,6 @@ UNREACHABLE(); break; } - } else { - Property* property = var->rewrite()->AsProperty(); - ASSERT_NOT_NULL(property); - - // Load object and key onto the stack. - Slot* object_slot = property->obj()->AsSlot(); - ASSERT_NOT_NULL(object_slot); - Move(Expression::kValue, object_slot, eax); - - Literal* key_literal = property->key()->AsLiteral(); - ASSERT_NOT_NULL(key_literal); - Move(Expression::kValue, key_literal); - - // Value to store was pushed before object and key on the stack. - __ mov(eax, Operand(esp, 2 * kPointerSize)); - - // Arguments to ic is value in eax, object and key on stack. - Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); - __ call(ic, RelocInfo::CODE_TARGET); - - if (expr->context() == Expression::kEffect) { - __ add(Operand(esp), Immediate(3 * kPointerSize)); - } else if (expr->context() == Expression::kValue) { - // Value is still on the stack in esp[2 * kPointerSize] - __ add(Operand(esp), Immediate(2 * kPointerSize)); - } else { - __ mov(eax, Operand(esp, 2 * kPointerSize)); - DropAndMove(expr->context(), eax, 3); - } } } ======================================= --- /branches/bleeding_edge/src/x64/fast-codegen-x64.cc Mon Nov 30 07:09:49 2009 +++ /branches/bleeding_edge/src/x64/fast-codegen-x64.cc Fri Dec 4 06:30:27 2009 @@ -856,7 +856,7 @@ void FastCodeGenerator::EmitVariableAssignment(Assignment* expr) { Variable* var = expr->target()->AsVariableProxy()->AsVariable(); ASSERT(var != NULL); - + ASSERT(var->is_global() || var->slot() != NULL); if (var->is_global()) { // Assignment to a global variable. Use inline caching for the // assignment. Right-hand-side value is passed in rax, variable name in @@ -961,36 +961,6 @@ UNREACHABLE(); break; } - } else { - Property* property = var->AsProperty(); - ASSERT_NOT_NULL(property); - // A variable has been rewritten into a property on an object. - - // Load object and key onto the stack. - Slot* object_slot = property->obj()->AsSlot(); - ASSERT_NOT_NULL(object_slot); - Move(Expression::kValue, object_slot, rax); - - Literal* key_literal = property->key()->AsLiteral(); - ASSERT_NOT_NULL(key_literal); - Move(Expression::kValue, key_literal); - - // Value to store was pushed before object and key on the stack. - __ movq(rax, Operand(rsp, 2 * kPointerSize)); - - // Arguments to ic is value in rax, object and key on stack. - Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); - __ call(ic, RelocInfo::CODE_TARGET); - - if (expr->context() == Expression::kEffect) { - __ addq(rsp, Immediate(3 * kPointerSize)); - } else if (expr->context() == Expression::kValue) { - // Value is still on the stack in rsp[2 * kPointerSize] - __ addq(rsp, Immediate(2 * kPointerSize)); - } else { - __ movq(rax, Operand(rsp, 2 * kPointerSize)); - DropAndMove(expr->context(), rax, 3); - } } } -- v8-dev mailing list [email protected] http://groups.google.com/group/v8-dev
