| Index: src/crankshaft/hydrogen.cc
|
| diff --git a/src/crankshaft/hydrogen.cc b/src/crankshaft/hydrogen.cc
|
| index 731d9484d2fa6fe76f6a663e42d4732b4b2ed228..dfb84bb825eec73b62e7889f624155d64914835f 100644
|
| --- a/src/crankshaft/hydrogen.cc
|
| +++ b/src/crankshaft/hydrogen.cc
|
| @@ -11207,24 +11207,37 @@ void HOptimizedGraphBuilder::VisitCompareOperation(CompareOperation* expr) {
|
| HConstant::cast(right)->handle(isolate())->IsJSFunction()) {
|
| Handle<JSFunction> function =
|
| Handle<JSFunction>::cast(HConstant::cast(right)->handle(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}).
|
| - // We can only use the fast case if @@hasInstance was not used so far.
|
| - if (function->has_initial_map() &&
|
| - function->map()->prototype() ==
|
| - function->native_context()->closure() &&
|
| - !function->map()->has_non_instance_prototype() &&
|
| - isolate()->IsHasInstanceLookupChainIntact()) {
|
| - Handle<Map> initial_map(function->initial_map(), isolate());
|
| - top_info()->dependencies()->AssumeInitialMapCantChange(initial_map);
|
| - top_info()->dependencies()->AssumePropertyCell(
|
| - isolate()->factory()->has_instance_protector());
|
| - HInstruction* prototype =
|
| - Add<HConstant>(handle(initial_map->prototype(), isolate()));
|
| - HHasInPrototypeChainAndBranch* result =
|
| - New<HHasInPrototypeChainAndBranch>(left, prototype);
|
| - return ast_context()->ReturnControl(result, expr->id());
|
| + // Make sure that the {function} already has a meaningful initial map
|
| + // (i.e. we constructed at least one instance using the constructor
|
| + // {function}).
|
| + if (function->has_initial_map()) {
|
| + // Lookup @@hasInstance on the {function}.
|
| + Handle<Map> function_map(function->map(), isolate());
|
| + PropertyAccessInfo has_instance(
|
| + this, LOAD, function_map,
|
| + isolate()->factory()->has_instance_symbol());
|
| + // Check if we are using the Function.prototype[@@hasInstance].
|
| + if (has_instance.CanAccessMonomorphic() &&
|
| + has_instance.IsDataConstant() &&
|
| + has_instance.constant().is_identical_to(
|
| + isolate()->function_has_instance())) {
|
| + // Add appropriate receiver map check and prototype chain
|
| + // checks to guard the @@hasInstance lookup chain.
|
| + AddCheckMap(right, function_map);
|
| + if (has_instance.has_holder()) {
|
| + Handle<JSObject> prototype(
|
| + JSObject::cast(has_instance.map()->prototype()), isolate());
|
| + BuildCheckPrototypeMaps(prototype, has_instance.holder());
|
| + }
|
| + // Perform the prototype chain walk.
|
| + Handle<Map> initial_map(function->initial_map(), isolate());
|
| + top_info()->dependencies()->AssumeInitialMapCantChange(initial_map);
|
| + HInstruction* prototype =
|
| + Add<HConstant>(handle(initial_map->prototype(), isolate()));
|
| + HHasInPrototypeChainAndBranch* result =
|
| + New<HHasInPrototypeChainAndBranch>(left, prototype);
|
| + return ast_context()->ReturnControl(result, expr->id());
|
| + }
|
| }
|
| }
|
|
|
|
|