v8/test/mjsunit/compiler/instanceof.js
bmeurer 241c024c10 [turbofan] Properly optimize instanceof (even in the presence of @@hasInstance).
This is the TurboFan counterpart of http://crrev.com/2504263004, but it
is a bit more involved, since in TurboFan we always inline the appropriate
call to the @@hasInstance handler, and by that we can optimize a lot more
patterns of instanceof than Crankshaft, and even yield fast instanceof
for custom @@hasInstance handlers (which we can now properly inline as
well).

Also we now properly optimize Function.prototype[@@hasInstance], even if
the right hand side of an instanceof doesn't have the Function.prototype
as its direct prototype.

For the baseline case, we still rely on the global protector cell, but
we can address that in a follow-up as well, and make it more robust in
general.

TEST=mjsunit/compiler/instanceof
BUG=v8:5640
R=yangguo@chromium.org

Review-Url: https://codereview.chromium.org/2511223003
Cr-Commit-Position: refs/heads/master@{#41092}
2016-11-18 06:31:42 +00:00

134 lines
2.5 KiB
JavaScript

// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax
function A() {}
var a = new A();
var B = {
[Symbol.hasInstance](o) {
return false;
}
};
%ToFastProperties(B.__proto__);
var C = Object.create({
[Symbol.hasInstance](o) {
return true;
}
});
%ToFastProperties(C.__proto__);
var D = Object.create({
[Symbol.hasInstance](o) {
return o === a;
}
});
%ToFastProperties(D.__proto__);
var E = Object.create({
[Symbol.hasInstance](o) {
if (o === a) throw o;
return true;
}
});
%ToFastProperties(E.__proto__);
function F() {}
F.__proto__ = null;
(function() {
function foo(o) { return o instanceof A; }
assertTrue(foo(a));
assertTrue(foo(a));
assertTrue(foo(new A()));
%OptimizeFunctionOnNextCall(foo);
assertTrue(foo(a));
assertTrue(foo(new A()));
})();
(function() {
function foo(o) {
try {
return o instanceof A;
} catch (e) {
return e;
}
}
assertTrue(foo(a));
assertTrue(foo(a));
assertTrue(foo(new A()));
assertEquals(1, foo(new Proxy({}, {getPrototypeOf() { throw 1; }})));
%OptimizeFunctionOnNextCall(foo);
assertTrue(foo(a));
assertTrue(foo(new A()));
assertEquals(1, foo(new Proxy({}, {getPrototypeOf() { throw 1; }})));
})();
(function() {
function foo(o) { return o instanceof B; }
assertFalse(foo(a));
assertFalse(foo(a));
assertFalse(foo(new A()));
%OptimizeFunctionOnNextCall(foo);
assertFalse(foo(a));
assertFalse(foo(new A()));
})();
(function() {
function foo(o) { return o instanceof C; }
assertTrue(foo(a));
assertTrue(foo(a));
assertTrue(foo(new A()));
%OptimizeFunctionOnNextCall(foo);
assertTrue(foo(a));
assertTrue(foo(new A()));
})();
(function() {
function foo(o) { return o instanceof D; }
assertTrue(foo(a));
assertTrue(foo(a));
assertFalse(foo(new A()));
%OptimizeFunctionOnNextCall(foo);
assertTrue(foo(a));
assertFalse(foo(new A()));
})();
(function() {
function foo(o) {
try {
return o instanceof E;
} catch (e) {
return false;
}
}
assertFalse(foo(a));
assertTrue(foo(new A()));
%OptimizeFunctionOnNextCall(foo);
assertFalse(foo(a));
assertTrue(foo(new A()));
})();
(function() {
function foo(o) {
return o instanceof F;
}
assertFalse(foo(a));
assertFalse(foo(new A()));
assertTrue(foo(new F()));
%OptimizeFunctionOnNextCall(foo);
assertFalse(foo(a));
assertFalse(foo(new A()));
assertTrue(foo(new F()));
})();