Skip to content
This repository has been archived by the owner on Feb 12, 2022. It is now read-only.

Commit

Permalink
Optimize a fast path for instanceof binary expressions (#2506)
Browse files Browse the repository at this point in the history
Summary:
Release notes: none

Looking through our internal bundles and there are frequent cases where `instanceof` is used where the left-hand side is a primitive and the right-hand side is an abstract value. In the case where the left-hand side is a primitive and the right-hand side is a simple object, the instanceof binary expression should always return `false`.
Pull Request resolved: #2506

Differential Revision: D9567344

Pulled By: trueadm

fbshipit-source-id: 7333f3b81627657c184c77d4cfffd4511bee0cbf
  • Loading branch information
trueadm authored and facebook-github-bot committed Aug 30, 2018
1 parent dfa38c2 commit f062f34
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 0 deletions.
13 changes: 13 additions & 0 deletions src/evaluators/BinaryExpression.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,15 @@ import { TypesDomain, ValuesDomain } from "../domains/index.js";
import type { LexicalEnvironment } from "../environment.js";
import { CompilerDiagnostic, FatalError } from "../errors.js";
import {
AbstractObjectValue,
AbstractValue,
BooleanValue,
ConcreteValue,
NullValue,
NumberValue,
IntegralValue,
ObjectValue,
PrimitiveValue,
StringValue,
SymbolValue,
UndefinedValue,
Expand Down Expand Up @@ -195,6 +197,17 @@ export function computeBinary(
let resultType;
const compute = () => {
if (lval instanceof AbstractValue || rval instanceof AbstractValue) {
// If the left-hand side of an instanceof operation is a primitive,
// and the right-hand side is a simple object (it does not have [Symbol.hasInstance]),
// then the result should always compute to `false`.
if (
op === "instanceof" &&
Value.isTypeCompatibleWith(lval.getType(), PrimitiveValue) &&
rval instanceof AbstractObjectValue &&
rval.isSimpleObject()
) {
return realm.intrinsics.false;
}
try {
// generate error if binary operation might throw or have side effects
resultType = getPureBinaryOperationResultType(realm, op, lval, rval, lloc, rloc);
Expand Down
36 changes: 36 additions & 0 deletions test/serializer/optimized-functions/instanceof.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// does not contain:instanceof

function fn(a) {
var x = Object.assign(a);

if (global.__makeSimple) {
__makeSimple(x);
}
if (undefined instanceof x) {
return "impossible";
}
if (null instanceof x) {
return "also impossible";
}
if (false instanceof x) {
return "also impossible 2";
}
if (true instanceof x) {
return "also impossible 3";
}
if (0 instanceof x) {
return "also impossible 4";
}
if (1 instanceof x) {
return "also impossible 5";
}
if ("" instanceof x) {
return "also impossible 6";
}
}

this.__optimize && __optimize(fn);

inspect = function() {
return fn(Object);
};

0 comments on commit f062f34

Please sign in to comment.