Reviewers: fschneider,
Description:
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.
Please review this at http://codereview.chromium.org/6353014/
Affected files:
M src/ast.cc
M test/mjsunit/string-charcodeat.js
Index: src/ast.cc
diff --git a/src/ast.cc b/src/ast.cc
index
fa01be016c038714976af27bb8c532ef39576bb5..2e0beae6a4f95eb5532f9276d8747d6bfe897a06
100644
--- a/src/ast.cc
+++ b/src/ast.cc
@@ -570,7 +570,14 @@ static bool CanCallWithoutIC(Handle<JSFunction>
target, int arity) {
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);
@@ -640,8 +647,9 @@ void Call::RecordTypeFeedback(TypeFeedbackOracle*
oracle) {
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);
}
Index: test/mjsunit/string-charcodeat.js
diff --git a/test/mjsunit/string-charcodeat.js
b/test/mjsunit/string-charcodeat.js
index
fb7ab9af86c3505df9aac480e8757a7bca5789e3..e3cbc7d6e3f1ab7b247bee12022c381fe1772232
100644
--- a/test/mjsunit/string-charcodeat.js
+++ b/test/mjsunit/string-charcodeat.js
@@ -28,7 +28,6 @@
/**
* @fileoverview Check all sorts of borderline cases for charCodeAt.
*/
-
function Cons() {
return "Te" + "st testing 123";
}
@@ -205,3 +204,20 @@ assertTrue(isNaN(long.charCodeAt(-1)), 35);
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));
+}
+
+for (var i = 0; i < 10000; i++) {
+ directlyOnPrototype();
+}
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev