| Index: src/crankshaft/hydrogen.cc
|
| diff --git a/src/crankshaft/hydrogen.cc b/src/crankshaft/hydrogen.cc
|
| index 2304cd5c4c3f7f73ea9bbca50f027bf4c20d5c74..80df22fb09c88d751d2a08627ef06d7580593e9e 100644
|
| --- a/src/crankshaft/hydrogen.cc
|
| +++ b/src/crankshaft/hydrogen.cc
|
| @@ -11498,6 +11498,7 @@ void HOptimizedGraphBuilder::VisitCompareOperation(CompareOperation* expr) {
|
| }
|
|
|
| if (op == Token::INSTANCEOF) {
|
| + DCHECK(!FLAG_harmony_instanceof);
|
| // Check to see if the rhs of the instanceof is a known function.
|
| if (right->IsConstant() &&
|
| HConstant::cast(right)->handle(isolate())->IsJSFunction()) {
|
| @@ -12618,6 +12619,45 @@ void HOptimizedGraphBuilder::GenerateNumberToString(CallRuntime* call) {
|
| void HOptimizedGraphBuilder::GenerateCall(CallRuntime* call) {
|
| DCHECK_LE(2, call->arguments()->length());
|
| CHECK_ALIVE(VisitExpressions(call->arguments()));
|
| +
|
| + // Try and customize ES6 instanceof here.
|
| + // We should at least have the constructor on the expression stack.
|
| + if (FLAG_harmony_instanceof && FLAG_harmony_instanceof_opt &&
|
| + call->arguments()->length() == 3) {
|
| + HValue* target = environment()->ExpressionStackAt(2);
|
| + if (target->IsConstant()) {
|
| + HConstant* constant_function = HConstant::cast(target);
|
| + if (constant_function->handle(isolate())->IsJSFunction()) {
|
| + Handle<JSFunction> func =
|
| + Handle<JSFunction>::cast(constant_function->handle(isolate()));
|
| + if (*func == isolate()->native_context()->ordinary_has_instance()) {
|
| + // Look at the function, which will be argument 1.
|
| + HValue* right = environment()->ExpressionStackAt(1);
|
| + if (right->IsConstant() &&
|
| + HConstant::cast(right)->handle(isolate())->IsJSFunction()) {
|
| + Handle<JSFunction> constructor = Handle<JSFunction>::cast(
|
| + HConstant::cast(right)->handle(isolate()));
|
| + if (constructor->IsConstructor() &&
|
| + !constructor->map()->has_non_instance_prototype()) {
|
| + JSFunction::EnsureHasInitialMap(constructor);
|
| + DCHECK(constructor->has_initial_map());
|
| + Handle<Map> initial_map(constructor->initial_map(), isolate());
|
| + top_info()->dependencies()->AssumeInitialMapCantChange(
|
| + initial_map);
|
| + HInstruction* prototype =
|
| + Add<HConstant>(handle(initial_map->prototype(), isolate()));
|
| + HValue* left = environment()->ExpressionStackAt(0);
|
| + HHasInPrototypeChainAndBranch* result =
|
| + New<HHasInPrototypeChainAndBranch>(left, prototype);
|
| + Drop(3);
|
| + return ast_context()->ReturnControl(result, call->id());
|
| + }
|
| + }
|
| + }
|
| + }
|
| + }
|
| + }
|
| +
|
| CallTrampolineDescriptor descriptor(isolate());
|
| PushArgumentsFromEnvironment(call->arguments()->length() - 1);
|
| HValue* trampoline = Add<HConstant>(isolate()->builtins()->Call());
|
|
|