Index: src/compiler/js-typed-lowering.cc |
diff --git a/src/compiler/js-typed-lowering.cc b/src/compiler/js-typed-lowering.cc |
index 95ed453ce0f2295db0e25e2eefb7d7373fa1b387..dbbeca6e960d857a7f56973acb46c2b518a131fc 100644 |
--- a/src/compiler/js-typed-lowering.cc |
+++ b/src/compiler/js-typed-lowering.cc |
@@ -1311,47 +1311,35 @@ Reduction JSTypedLowering::ReduceJSStoreProperty(Node* node) { |
return NoChange(); |
} |
-Reduction JSTypedLowering::ReduceJSInstanceOf(Node* node) { |
- DCHECK_EQ(IrOpcode::kJSInstanceOf, node->opcode()); |
- Node* const context = NodeProperties::GetContextInput(node); |
- Node* const frame_state = NodeProperties::GetFrameStateInput(node); |
- |
- // If deoptimization is disabled, we cannot optimize. |
- if (!(flags() & kDeoptimizationEnabled)) return NoChange(); |
- |
- // If we are in a try block, don't optimize since the runtime call |
- // in the proxy case can throw. |
- if (NodeProperties::IsExceptionalCall(node)) return NoChange(); |
- |
- JSBinopReduction r(this, node); |
- Node* object = r.left(); |
- Node* effect = r.effect(); |
- Node* control = r.control(); |
+Reduction JSTypedLowering::ReduceJSOrdinaryHasInstance(Node* node) { |
+ DCHECK_EQ(IrOpcode::kJSOrdinaryHasInstance, node->opcode()); |
+ Node* constructor = NodeProperties::GetValueInput(node, 0); |
+ Type* constructor_type = NodeProperties::GetType(constructor); |
+ Node* object = NodeProperties::GetValueInput(node, 1); |
+ Node* context = NodeProperties::GetContextInput(node); |
+ Node* frame_state = NodeProperties::GetFrameStateInput(node); |
+ Node* effect = NodeProperties::GetEffectInput(node); |
+ Node* control = NodeProperties::GetControlInput(node); |
- if (!r.right_type()->IsHeapConstant() || |
- !r.right_type()->AsHeapConstant()->Value()->IsJSFunction()) { |
+ // Check if the {constructor} is a (known) JSFunction. |
+ if (!constructor_type->IsHeapConstant() || |
+ !constructor_type->AsHeapConstant()->Value()->IsJSFunction()) { |
return NoChange(); |
} |
- |
Handle<JSFunction> function = |
- Handle<JSFunction>::cast(r.right_type()->AsHeapConstant()->Value()); |
- Handle<SharedFunctionInfo> shared(function->shared(), isolate()); |
- |
- // Make sure the prototype of {function} is the %FunctionPrototype%, and it |
- // already has a meaningful initial map (i.e. we constructed at least one |
- // instance using the constructor {function}). |
- if (function->map()->prototype() != function->native_context()->closure() || |
- function->map()->has_non_instance_prototype() || |
- !function->has_initial_map()) { |
- return NoChange(); |
- } |
+ Handle<JSFunction>::cast(constructor_type->AsHeapConstant()->Value()); |
+ |
+ // Check if the {function} already has an initial map (i.e. the |
+ // {function} has been used as a constructor at least once). |
+ if (!function->has_initial_map()) return NoChange(); |
- // We can only use the fast case if @@hasInstance was not used so far. |
- if (!isolate()->IsHasInstanceLookupChainIntact()) return NoChange(); |
- dependencies()->AssumePropertyCell(factory()->has_instance_protector()); |
+ // Check if the {function}s "prototype" is a JSReceiver. |
+ if (!function->prototype()->IsJSReceiver()) return NoChange(); |
+ // Install a code dependency on the {function}s initial map. |
Handle<Map> initial_map(function->initial_map(), isolate()); |
dependencies()->AssumeInitialMapCantChange(initial_map); |
+ |
Node* prototype = |
jsgraph()->Constant(handle(initial_map->prototype(), isolate())); |
@@ -1419,6 +1407,15 @@ Reduction JSTypedLowering::ReduceJSInstanceOf(Node* node) { |
javascript()->CallRuntime(Runtime::kHasInPrototypeChain), object, |
prototype, context, frame_state, efalse1, if_false1); |
if_false1 = graph()->NewNode(common()->IfSuccess(), vfalse1); |
+ |
+ // Replace any potential IfException on {node} to catch exceptions |
+ // from this %HasInPrototypeChain runtime call instead. |
+ for (Edge edge : node->use_edges()) { |
+ if (edge.from()->opcode() == IrOpcode::kIfException) { |
+ edge.UpdateTo(vfalse1); |
+ Revisit(edge.from()); |
+ } |
+ } |
} |
// Load the {object} prototype. |
@@ -2198,6 +2195,8 @@ Reduction JSTypedLowering::Reduce(Node* node) { |
case IrOpcode::kJSDivide: |
case IrOpcode::kJSModulus: |
return ReduceNumberBinop(node); |
+ case IrOpcode::kJSOrdinaryHasInstance: |
+ return ReduceJSOrdinaryHasInstance(node); |
case IrOpcode::kJSToBoolean: |
return ReduceJSToBoolean(node); |
case IrOpcode::kJSToInteger: |
@@ -2220,8 +2219,6 @@ Reduction JSTypedLowering::Reduce(Node* node) { |
return ReduceJSLoadProperty(node); |
case IrOpcode::kJSStoreProperty: |
return ReduceJSStoreProperty(node); |
- case IrOpcode::kJSInstanceOf: |
- return ReduceJSInstanceOf(node); |
case IrOpcode::kJSLoadContext: |
return ReduceJSLoadContext(node); |
case IrOpcode::kJSStoreContext: |