Revision: 3101
Author: [email protected]
Date: Wed Oct 21 02:38:21 2009
Log: Add support for global variable references in toplevel code. We use
the normal named load IC mechanism for now.  Generated code is similar
to the case for global variable assignments.

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

Modified:
  /branches/bleeding_edge/src/arm/fast-codegen-arm.cc
  /branches/bleeding_edge/src/compiler.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 Wed Oct 21 02:17:39  
2009
+++ /branches/bleeding_edge/src/arm/fast-codegen-arm.cc Wed Oct 21 02:38:21  
2009
@@ -185,11 +185,27 @@
  void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
    Comment cmnt(masm_, "[ VariableProxy");
    Expression* rewrite = expr->var()->rewrite();
-  ASSERT(rewrite != NULL);
-
-  Slot* slot = rewrite->AsSlot();
-  ASSERT(slot != NULL);
-  { Comment cmnt(masm_, "[ Slot");
+  if (rewrite == NULL) {
+    Comment cmnt(masm_, "Global variable");
+    // Use inline caching. Variable name is passed in r2 and the global
+    // object on the stack.
+    __ ldr(ip, CodeGenerator::GlobalObject());
+    __ push(ip);
+    __ mov(r2, Operand(expr->name()));
+    Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
+    __ Call(ic, RelocInfo::CODE_TARGET_CONTEXT);
+    if (expr->location().is_temporary()) {
+      // Replace the global object with the result.
+      __ str(r0, MemOperand(sp));
+    } else {
+      ASSERT(expr->location().is_nowhere());
+      __ pop();
+    }
+
+  } else {
+    Comment cmnt(masm_, "Stack slot");
+    Slot* slot = rewrite->AsSlot();
+    ASSERT(slot != NULL);
      if (expr->location().is_temporary()) {
        __ ldr(ip, MemOperand(fp, SlotOffset(slot)));
        __ push(ip);
=======================================
--- /branches/bleeding_edge/src/compiler.cc     Wed Oct 21 02:17:39 2009
+++ /branches/bleeding_edge/src/compiler.cc     Wed Oct 21 02:38:21 2009
@@ -628,8 +628,7 @@

  void CodeGenSelector::VisitVariableProxy(VariableProxy* expr) {
    Expression* rewrite = expr->var()->rewrite();
-  if (rewrite == NULL) BAILOUT("global variable reference");
-  Visit(rewrite);
+  if (rewrite != NULL) Visit(rewrite);
  }


=======================================
--- /branches/bleeding_edge/src/ia32/fast-codegen-ia32.cc       Wed Oct 21  
02:17:39 2009
+++ /branches/bleeding_edge/src/ia32/fast-codegen-ia32.cc       Wed Oct 21  
02:38:21 2009
@@ -172,11 +172,31 @@
  void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
    Comment cmnt(masm_, "[ VariableProxy");
    Expression* rewrite = expr->var()->rewrite();
-  ASSERT(rewrite != NULL);
-
-  Slot* slot = rewrite->AsSlot();
-  ASSERT(slot != NULL);
-  { Comment cmnt(masm_, "[ Slot");
+  if (rewrite == NULL) {
+    Comment cmnt(masm_, "Global variable");
+    // Use inline caching. Variable name is passed in ecx and the global
+    // object on the stack.
+    __ push(CodeGenerator::GlobalObject());
+    __ mov(ecx, expr->name());
+    Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
+    __ call(ic, RelocInfo::CODE_TARGET_CONTEXT);
+
+    // A test eax instruction following the call is used by the IC to
+    // indicate that the inobject property case was inlined.  Ensure there
+    // is no test eax instruction here.  Remember that the assembler may
+    // choose to do peephole optimization (eg, push/pop elimination).
+    if (expr->location().is_temporary()) {
+      // Replace the global object with the result.
+      __ mov(Operand(esp, 0), eax);
+    } else {
+      ASSERT(expr->location().is_nowhere());
+      __ pop(eax);
+    }
+
+  } else {
+    Comment cmnt(masm_, "Stack slot");
+    Slot* slot = rewrite->AsSlot();
+    ASSERT(slot != NULL);
      if (expr->location().is_temporary()) {
        __ push(Operand(ebp, SlotOffset(slot)));
      } else {
=======================================
--- /branches/bleeding_edge/src/x64/fast-codegen-x64.cc Wed Oct 21 02:17:39  
2009
+++ /branches/bleeding_edge/src/x64/fast-codegen-x64.cc Wed Oct 21 02:38:21  
2009
@@ -189,11 +189,30 @@
  void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
    Comment cmnt(masm_, "[ VariableProxy");
    Expression* rewrite = expr->var()->rewrite();
-  ASSERT(rewrite != NULL);
-
-  Slot* slot = rewrite->AsSlot();
-  ASSERT(slot != NULL);
-  { Comment cmnt(masm_, "[ Slot");
+  if (rewrite == NULL) {
+    Comment cmnt(masm_, "Global variable");
+    // Use inline caching. Variable name is passed in rcx and the global
+    // object on the stack.
+    __ push(CodeGenerator::GlobalObject());
+    __ Move(rcx, expr->name());
+    Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
+    __ Call(ic, RelocInfo::CODE_TARGET_CONTEXT);
+
+    // A test rax instruction following the call is used by the IC to
+    // indicate that the inobject property case was inlined.  Ensure there
+    // is no test rax instruction here.
+    if (expr->location().is_temporary()) {
+      // Replace the global object with the result.
+      __ movq(Operand(rsp, 0), rax);
+    } else {
+      ASSERT(expr->location().is_nowhere());
+      __ pop(rax);
+    }
+
+  } else {
+    Comment cmnt(masm_, "Stack slot");
+    Slot* slot = rewrite->AsSlot();
+    ASSERT(slot != NULL);
      if (expr->location().is_temporary()) {
        __ push(Operand(rbp, SlotOffset(slot)));
      } else {
=======================================
--- /branches/bleeding_edge/test/mjsunit/compiler/globals.js    Tue Oct 20  
06:37:26 2009
+++ /branches/bleeding_edge/test/mjsunit/compiler/globals.js    Wed Oct 21  
02:38:21 2009
@@ -42,3 +42,14 @@
  // Test a second store.
  assertEquals("2", eval('g = "2"'));
  assertEquals("2", g);
+
+// Test a load.
+assertEquals("2", eval('g'));
+
+// Test that patching the IC in the compiled code works.
+assertEquals("2", eval('g'));
+assertEquals("2", eval('g'));
+
+// Test a second load.
+g = 3;
+assertEquals(3, eval('g'));

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

Reply via email to