Commit 331b4823 authored by vitalyr@chromium.org's avatar vitalyr@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@6459 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 2a741d49
......@@ -577,7 +577,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);
......@@ -647,8 +654,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);
}
......
......@@ -205,3 +205,23 @@ 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));
assertEquals(97, "a".x(0));
assertEquals(98, "b".x(0));
assertEquals(99, "c".x(0));
}
for (var i = 0; i < 10000; i++) {
directlyOnPrototype();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment