Revision: 3194
Author: [email protected]
Date: Mon Nov  2 02:22:22 2009
Log: Support for post-fix count operations (x++, x--) where x is a global
variable for the top-level compiler.

Review URL: http://codereview.chromium.org/342058
http://code.google.com/p/v8/source/detail?r=3194

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/test/mjsunit/compiler/globals.js

=======================================
--- /branches/bleeding_edge/src/arm/fast-codegen-arm.cc Mon Nov  2 02:17:12  
2009
+++ /branches/bleeding_edge/src/arm/fast-codegen-arm.cc Mon Nov  2 02:22:22  
2009
@@ -380,7 +380,7 @@
    }

    // If result_saved == true: the result is saved on top of the stack.
-  // If result_saved == false: the result is in eax.
+  // If result_saved == false: the result is in r0.
    bool result_saved = false;

    for (int i = 0; i < expr->properties()->length(); i++) {
@@ -970,6 +970,81 @@
        UNREACHABLE();
    }
  }
+
+
+void FastCodeGenerator::VisitCountOperation(CountOperation* expr) {
+  VariableProxy* v = expr->expression()->AsVariableProxy();
+  ASSERT(v->AsVariable() != NULL);
+  ASSERT(v->AsVariable()->is_global());
+
+  Visit(v);
+
+  __ InvokeBuiltin(Builtins::TO_NUMBER, CALL_JS);
+
+  switch (expr->context()) {
+    case Expression::kUninitialized:
+      UNREACHABLE();
+    case Expression::kValue:  // Fall through
+    case Expression::kTest:  // Fall through
+    case Expression::kTestValue:  // Fall through
+    case Expression::kValueTest:
+      // Duplicate the result on the stack.
+      __ push(r0);
+      break;
+    case Expression::kEffect:
+      // Do not save result.
+      break;
+  }
+  // Call runtime for +1/-1.
+  __ push(r0);
+  __ mov(ip, Operand(Smi::FromInt(1)));
+  __ push(ip);
+  if (expr->op() == Token::INC) {
+    __ CallRuntime(Runtime::kNumberAdd, 2);
+  } else {
+    __ CallRuntime(Runtime::kNumberSub, 2);
+  }
+  // Call Store IC.
+  __ mov(r2, Operand(v->AsVariable()->name()));
+  __ ldr(ip, CodeGenerator::GlobalObject());
+  __ push(ip);
+  Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
+  __ Call(ic, RelocInfo::CODE_TARGET);
+  // Restore up stack after store IC.
+  __ add(sp, sp, Operand(kPointerSize));
+
+  switch (expr->context()) {
+    case Expression::kUninitialized:
+      UNREACHABLE();
+    case Expression::kEffect:  // Fall through
+    case Expression::kValue:
+      // Do nothing. Result in either on the stack for value context
+      // or discarded for effect context.
+      break;
+    case Expression::kTest:
+      __ pop(r0);
+      TestAndBranch(r0, true_label_, false_label_);
+      break;
+    case Expression::kValueTest: {
+      Label discard;
+      __ ldr(r0, MemOperand(sp));
+      TestAndBranch(r0, true_label_, &discard);
+      __ bind(&discard);
+      __ add(sp, sp, Operand(kPointerSize));
+      __ b(false_label_);
+      break;
+    }
+    case Expression::kTestValue: {
+      Label discard;
+      __ ldr(r0, MemOperand(sp));
+      TestAndBranch(r0, &discard, false_label_);
+      __ bind(&discard);
+      __ add(sp, sp, Operand(kPointerSize));
+      __ b(true_label_);
+      break;
+    }
+  }
+}


  void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
=======================================
--- /branches/bleeding_edge/src/compiler.cc     Mon Nov  2 02:17:12 2009
+++ /branches/bleeding_edge/src/compiler.cc     Mon Nov  2 02:22:22 2009
@@ -847,7 +847,11 @@


  void CodeGenSelector::VisitCountOperation(CountOperation* expr) {
-  BAILOUT("CountOperation");
+  // We support postfix count operations on global variables.
+  if (expr->is_prefix()) BAILOUT("Prefix CountOperation");
+  Variable* var = expr->expression()->AsVariableProxy()->AsVariable();
+  if (var == NULL || !var->is_global()) BAILOUT("non-global  
postincrement");
+  ProcessExpression(expr->expression(), Expression::kValue);
  }


=======================================
--- /branches/bleeding_edge/src/fast-codegen.cc Mon Nov  2 00:44:19 2009
+++ /branches/bleeding_edge/src/fast-codegen.cc Mon Nov  2 02:22:22 2009
@@ -432,11 +432,6 @@
  void FastCodeGenerator::VisitThrow(Throw* expr) {
    UNREACHABLE();
  }
-
-
-void FastCodeGenerator::VisitCountOperation(CountOperation* expr) {
-  UNREACHABLE();
-}


  void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
=======================================
--- /branches/bleeding_edge/src/ia32/fast-codegen-ia32.cc       Mon Nov  2  
02:17:12 2009
+++ /branches/bleeding_edge/src/ia32/fast-codegen-ia32.cc       Mon Nov  2  
02:22:22 2009
@@ -991,6 +991,79 @@
        UNREACHABLE();
    }
  }
+
+
+void FastCodeGenerator::VisitCountOperation(CountOperation* expr) {
+  VariableProxy* v = expr->expression()->AsVariableProxy();
+  ASSERT(v->AsVariable() != NULL);
+  ASSERT(v->AsVariable()->is_global());
+
+  Visit(v);
+
+  __ InvokeBuiltin(Builtins::TO_NUMBER, CALL_FUNCTION);
+
+  switch (expr->context()) {
+    case Expression::kUninitialized:
+      UNREACHABLE();
+    case Expression::kValue:  // Fall through
+    case Expression::kTest:  // Fall through
+    case Expression::kTestValue:  // Fall through
+    case Expression::kValueTest:
+      // Duplicate the result on the stack.
+      __ push(eax);
+      break;
+    case Expression::kEffect:
+      // Do not save result.
+      break;
+  }
+  // Call runtime for +1/-1.
+  __ push(eax);
+  __ push(Immediate(Smi::FromInt(1)));
+  if (expr->op() == Token::INC) {
+    __ CallRuntime(Runtime::kNumberAdd, 2);
+  } else {
+    __ CallRuntime(Runtime::kNumberSub, 2);
+  }
+  // Call Store IC.
+  __ mov(ecx, v->AsVariable()->name());
+  __ push(CodeGenerator::GlobalObject());
+  Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
+  __ call(ic, RelocInfo::CODE_TARGET);
+  // Restore up stack after store IC.
+  __ add(Operand(esp), Immediate(kPointerSize));
+
+  switch (expr->context()) {
+    case Expression::kUninitialized:
+      UNREACHABLE();
+    case Expression::kEffect:  // Fall through
+    case Expression::kValue:
+      // Do nothing. Result in either on the stack for value context
+      // or discarded for effect context.
+      break;
+    case Expression::kTest:
+      __ pop(eax);
+      TestAndBranch(eax, true_label_, false_label_);
+      break;
+    case Expression::kValueTest: {
+      Label discard;
+      __ mov(eax, Operand(esp, 0));
+      TestAndBranch(eax, true_label_, &discard);
+      __ bind(&discard);
+      __ add(Operand(esp), Immediate(kPointerSize));
+      __ jmp(false_label_);
+      break;
+    }
+    case Expression::kTestValue: {
+      Label discard;
+      __ mov(eax, Operand(esp, 0));
+      TestAndBranch(eax, &discard, false_label_);
+      __ bind(&discard);
+      __ add(Operand(esp), Immediate(kPointerSize));
+      __ jmp(true_label_);
+      break;
+    }
+  }
+}


  void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
=======================================
--- /branches/bleeding_edge/src/x64/fast-codegen-x64.cc Mon Nov  2 02:17:12  
2009
+++ /branches/bleeding_edge/src/x64/fast-codegen-x64.cc Mon Nov  2 02:22:22  
2009
@@ -913,6 +913,78 @@
    __ CallRuntime(function, arg_count);
    Move(expr->context(), rax);
  }
+
+void FastCodeGenerator::VisitCountOperation(CountOperation* expr) {
+  VariableProxy* v = expr->expression()->AsVariableProxy();
+  ASSERT(v->AsVariable() != NULL);
+  ASSERT(v->AsVariable()->is_global());
+
+  Visit(v);
+
+  __ InvokeBuiltin(Builtins::TO_NUMBER, CALL_FUNCTION);
+
+  switch (expr->context()) {
+    case Expression::kUninitialized:
+      UNREACHABLE();
+    case Expression::kValue:  // Fall through
+    case Expression::kTest:  // Fall through
+    case Expression::kTestValue:  // Fall through
+    case Expression::kValueTest:
+      // Duplicate the result on the stack.
+      __ push(rax);
+      break;
+    case Expression::kEffect:
+      // Do not save result.
+      break;
+  }
+  // Call runtime for +1/-1.
+  __ push(rax);
+  __ Push(Smi::FromInt(1));
+  if (expr->op() == Token::INC) {
+    __ CallRuntime(Runtime::kNumberAdd, 2);
+  } else {
+    __ CallRuntime(Runtime::kNumberSub, 2);
+  }
+  // Call Store IC.
+  __ Move(rcx, v->AsVariable()->name());
+  __ push(CodeGenerator::GlobalObject());
+  Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
+  __ call(ic, RelocInfo::CODE_TARGET);
+  // Restore up stack after store IC
+  __ addq(rsp, Immediate(kPointerSize));
+
+  switch (expr->context()) {
+    case Expression::kUninitialized:
+      UNREACHABLE();
+    case Expression::kEffect:  // Fall through
+    case Expression::kValue:
+      // Do nothing. Result in either on the stack for value context
+      // or discarded for effect context.
+      break;
+    case Expression::kTest:
+      __ pop(rax);
+      TestAndBranch(rax, true_label_, false_label_);
+      break;
+    case Expression::kValueTest: {
+      Label discard;
+      __ movq(rax, Operand(rsp, 0));
+      TestAndBranch(rax, true_label_, &discard);
+      __ bind(&discard);
+      __ addq(rsp, Immediate(kPointerSize));
+      __ jmp(false_label_);
+      break;
+    }
+    case Expression::kTestValue: {
+      Label discard;
+      __ movq(rax, Operand(rsp, 0));
+      TestAndBranch(rax, &discard, false_label_);
+      __ bind(&discard);
+      __ addq(rsp, Immediate(kPointerSize));
+      __ jmp(true_label_);
+      break;
+    }
+  }
+}


  void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
=======================================
--- /branches/bleeding_edge/test/mjsunit/compiler/globals.js    Wed Oct 21  
02:38:21 2009
+++ /branches/bleeding_edge/test/mjsunit/compiler/globals.js    Mon Nov  2  
02:22:22 2009
@@ -53,3 +53,13 @@
  // Test a second load.
  g = 3;
  assertEquals(3, eval('g'));
+
+// Test postfix count operation
+var t;
+t = g++;
+assertEquals(3, t);
+assertEquals(4, g);
+
+code = "g--; 1";
+assertEquals(1, eval(code));
+assertEquals(3, g);

--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---

Reply via email to