Revision: 6459
Author: [email protected]
Date: Tue Jan 25 04:21:03 2011
Log: Fix bug 1070: set correct holder for primitive checks.

Code generated for checks starting with primitive receivers skips one step
in the usual prototype checking algorithm, so the holder must always be set.

Not setting the holder did not cause an immediate failure because our
primitives have additional hidden prototypes before the real prototypes.
These extra objects in the chain usually contain no properties and so
allowed the right holders to be selected.

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

Modified:
 /branches/bleeding_edge/src/ast.cc
 /branches/bleeding_edge/test/mjsunit/string-charcodeat.js

=======================================
--- /branches/bleeding_edge/src/ast.cc  Mon Jan 24 23:48:19 2011
+++ /branches/bleeding_edge/src/ast.cc  Tue Jan 25 04:21:03 2011
@@ -577,7 +577,14 @@


 bool Call::ComputeTarget(Handle<Map> type, Handle<String> name) {
-  holder_ = Handle<JSObject>::null();
+  if (check_type_ == RECEIVER_MAP_CHECK) {
+    // For primitive checks the holder is set up to point to the
+    // corresponding prototype object, i.e. one step of the algorithm
+    // below has been already performed.
+    // For non-primitive checks we clear it to allow computing targets
+    // for polymorphic calls.
+    holder_ = Handle<JSObject>::null();
+  }
   while (true) {
     LookupResult lookup;
     type->LookupInDescriptors(NULL, *name, &lookup);
@@ -647,8 +654,9 @@
       map = receiver_types_->at(0);
     } else {
       ASSERT(check_type_ != RECEIVER_MAP_CHECK);
-      map = Handle<Map>(
-          oracle->GetPrototypeForPrimitiveCheck(check_type_)->map());
+      holder_ = Handle<JSObject>(
+          oracle->GetPrototypeForPrimitiveCheck(check_type_));
+      map = Handle<Map>(holder_->map());
     }
     is_monomorphic_ = ComputeTarget(map, name);
   }
=======================================
--- /branches/bleeding_edge/test/mjsunit/string-charcodeat.js Fri Jan 21 00:30:13 2011 +++ /branches/bleeding_edge/test/mjsunit/string-charcodeat.js Tue Jan 25 04:21:03 2011
@@ -205,3 +205,23 @@
 assertEquals(49, long.charCodeAt(0), 36);
 assertEquals(56, long.charCodeAt(65535), 37);
 assertTrue(isNaN(long.charCodeAt(65536)), 38);
+
+
+// Test crankshaft code when the function is set directly on the
+// string prototype object instead of the hidden prototype object.
+// See http://code.google.com/p/v8/issues/detail?id=1070
+
+String.prototype.x = String.prototype.charCodeAt;
+
+function directlyOnPrototype() {
+  assertEquals(97, "a".x(0));
+  assertEquals(98, "b".x(0));
+  assertEquals(99, "c".x(0));
+  assertEquals(97, "a".x(0));
+  assertEquals(98, "b".x(0));
+  assertEquals(99, "c".x(0));
+}
+
+for (var i = 0; i < 10000; i++) {
+  directlyOnPrototype();
+}

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

Reply via email to