Refactor code for generating assignments in the fast compiler.
authorfschneider@chromium.org <fschneider@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 4 Dec 2009 14:30:27 +0000 (14:30 +0000)
committerfschneider@chromium.org <fschneider@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 4 Dec 2009 14:30:27 +0000 (14:30 +0000)
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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3425 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/arm/fast-codegen-arm.cc
src/compiler.cc
src/fast-codegen.cc
src/ia32/fast-codegen-ia32.cc
src/x64/fast-codegen-x64.cc

index ab636b6..03e00db 100644 (file)
@@ -863,7 +863,7 @@ void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
 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 @@ void FastCodeGenerator::EmitVariableAssignment(Assignment* expr) {
         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);
-    }
   }
 }
 
index 22b0a03..7f65d46 100644 (file)
@@ -891,28 +891,19 @@ void CodeGenSelector::VisitAssignment(Assignment* expr) {
 
   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 @@ void CodeGenSelector::VisitAssignment(Assignment* expr) {
     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;
     }
index 20de808..87b405d 100644 (file)
@@ -505,35 +505,41 @@ void FastCodeGenerator::VisitAssignment(Assignment* expr) {
   // 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);
+      EmitVariableAssignment(expr);
+      break;
+    case NAMED_PROPERTY:
+      Visit(prop->obj());
+      ASSERT_EQ(Expression::kValue, prop->obj()->context());
       Visit(rhs);
-      ASSERT_EQ(Expression::kValue, rhs->context());
       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;
   }
 }
 
index c5d5441..2601b6a 100644 (file)
@@ -855,7 +855,7 @@ void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
 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 @@ void FastCodeGenerator::EmitVariableAssignment(Assignment* expr) {
         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);
-    }
   }
 }
 
index f73f2b9..4f8f3b1 100644 (file)
@@ -856,7 +856,7 @@ void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
 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 @@ void FastCodeGenerator::EmitVariableAssignment(Assignment* expr) {
         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);
-    }
   }
 }