Revision: 4601
Author: [email protected]
Date: Thu May  6 03:50:22 2010
Log: Inlined load of string.length and array.length.

http://compute1.aar:9013/golem/r4583-v8-serya-length-inlined-vs-4583-v8.html

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

Modified:
 /branches/bleeding_edge/src/debug.cc
 /branches/bleeding_edge/src/ic.cc
 /branches/bleeding_edge/src/ic.h
 /branches/bleeding_edge/test/cctest/test-debug.cc

=======================================
--- /branches/bleeding_edge/src/debug.cc        Wed May  5 05:25:58 2010
+++ /branches/bleeding_edge/src/debug.cc        Thu May  6 03:50:22 2010
@@ -430,8 +430,13 @@
// is set the patching performed by the runtime system will take place in
     // the code copy and will therefore have no effect on the running code
     // keeping it from using the inlined code.
-    if (code->is_keyed_load_stub()) KeyedLoadIC::ClearInlinedVersion(pc());
- if (code->is_keyed_store_stub()) KeyedStoreIC::ClearInlinedVersion(pc());
+    if (code->is_keyed_load_stub()) {
+      KeyedLoadIC::ClearInlinedVersion(pc());
+    } else if (code->is_keyed_store_stub()) {
+      KeyedStoreIC::ClearInlinedVersion(pc());
+    } else if (code->is_load_stub()) {
+      LoadIC::ClearInlinedVersion(pc());
+    }
   }
 }

=======================================
--- /branches/bleeding_edge/src/ic.cc   Wed Apr 28 05:05:40 2010
+++ /branches/bleeding_edge/src/ic.cc   Thu May  6 03:50:22 2010
@@ -596,10 +596,16 @@
 #ifdef DEBUG
       if (FLAG_trace_ic) PrintF("[LoadIC : +#length /string]\n");
 #endif
+      Map* map = HeapObject::cast(*object)->map();
+      if (object->IsString()) {
+        const int offset = String::kLengthOffset;
+        PatchInlinedLoad(address(), map, offset);
+      }
+
       Code* target = NULL;
       target = Builtins::builtin(Builtins::LoadIC_StringLength);
       set_target(target);
-      StubCache::Set(*name, HeapObject::cast(*object)->map(), target);
+      StubCache::Set(*name, map, target);
       return Smi::FromInt(String::cast(*object)->length());
     }

@@ -608,9 +614,13 @@
 #ifdef DEBUG
       if (FLAG_trace_ic) PrintF("[LoadIC : +#length /array]\n");
 #endif
+      Map* map = HeapObject::cast(*object)->map();
+      const int offset = JSArray::kLengthOffset;
+      PatchInlinedLoad(address(), map, offset);
+
       Code* target = Builtins::builtin(Builtins::LoadIC_ArrayLength);
       set_target(target);
-      StubCache::Set(*name, HeapObject::cast(*object)->map(), target);
+      StubCache::Set(*name, map, target);
       return JSArray::cast(*object)->length();
     }

=======================================
--- /branches/bleeding_edge/src/ic.h    Thu Apr 29 08:14:39 2010
+++ /branches/bleeding_edge/src/ic.h    Thu May  6 03:50:22 2010
@@ -239,6 +239,9 @@
   static void GenerateStringLength(MacroAssembler* masm);
   static void GenerateFunctionPrototype(MacroAssembler* masm);

+  // Clear the use of the inlined version.
+  static void ClearInlinedVersion(Address address);
+
   // The offset from the inlined patch site to the start of the
   // inlined load instruction.  It is architecture-dependent, and not
   // used on ARM.
@@ -265,9 +268,6 @@

   static void Clear(Address address, Code* target);

-  // Clear the use of the inlined version.
-  static void ClearInlinedVersion(Address address);
-
   static bool PatchInlinedLoad(Address address, Object* map, int index);

   friend class IC;
=======================================
--- /branches/bleeding_edge/test/cctest/test-debug.cc Wed Apr 28 04:59:43 2010 +++ /branches/bleeding_edge/test/cctest/test-debug.cc Thu May 6 03:50:22 2010
@@ -2509,6 +2509,50 @@
   v8::Debug::SetDebugEventListener(NULL);
   CheckDebuggerUnloaded();
 }
+
+
+// Test of the stepping mechanism for named load in a loop.
+TEST(DebugStepNamedLoadLoop) {
+  v8::HandleScope scope;
+  DebugLocalContext env;
+
+  // Create a function for testing stepping of named load.
+  v8::Local<v8::Function> foo = CompileFunction(
+      &env,
+      "function foo() {\n"
+          "  var a = [];\n"
+          "  var s = \"\";\n"
+          "  for (var i = 0; i < 10; i++) {\n"
+          "    var v = new V(i, i + 1);\n"
+          "    v.y;\n"
+          "    a.length;\n"  // Special case: array length.
+          "    s.length;\n"  // Special case: string length.
+          "  }\n"
+          "}\n"
+          "function V(x, y) {\n"
+          "  this.x = x;\n"
+          "  this.y = y;\n"
+          "}\n",
+          "foo");
+
+  // Call function without any break points to ensure inlining is in place.
+  foo->Call(env->Global(), 0, NULL);
+
+  // Register a debug event listener which steps and counts.
+  v8::Debug::SetDebugEventListener(DebugEventStep);
+
+  // Setup break point and step through the function.
+  SetBreakPoint(foo, 4);
+  step_action = StepNext;
+  break_point_hit_count = 0;
+  foo->Call(env->Global(), 0, NULL);
+
+  // With stepping all break locations are hit.
+  CHECK_EQ(41, break_point_hit_count);
+
+  v8::Debug::SetDebugEventListener(NULL);
+  CheckDebuggerUnloaded();
+}


 // Test the stepping mechanism with different ICs.

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

Reply via email to