@@ -11563,24 +11563,37 @@ void HOptimizedGraphBuilder::VisitCompareOperation(CompareOperation* expr) {
1156311563 HConstant::cast (right)->handle (isolate ())->IsJSFunction ()) {
1156411564 Handle<JSFunction> function =
1156511565 Handle<JSFunction>::cast (HConstant::cast (right)->handle (isolate ()));
11566- // Make sure the prototype of {function} is the %FunctionPrototype%, and
11567- // it already has a meaningful initial map (i.e. we constructed at least
11568- // one instance using the constructor {function}).
11569- // We can only use the fast case if @@hasInstance was not used so far.
11570- if (function->has_initial_map () &&
11571- function->map ()->prototype () ==
11572- function->native_context ()->closure () &&
11573- !function->map ()->has_non_instance_prototype () &&
11574- isolate ()->IsHasInstanceLookupChainIntact ()) {
11575- Handle<Map> initial_map (function->initial_map (), isolate ());
11576- top_info ()->dependencies ()->AssumeInitialMapCantChange (initial_map);
11577- top_info ()->dependencies ()->AssumePropertyCell (
11578- isolate ()->factory ()->has_instance_protector ());
11579- HInstruction* prototype =
11580- Add<HConstant>(handle (initial_map->prototype (), isolate ()));
11581- HHasInPrototypeChainAndBranch* result =
11582- New<HHasInPrototypeChainAndBranch>(left, prototype);
11583- return ast_context ()->ReturnControl (result, expr->id ());
11566+ // Make sure that the {function} already has a meaningful initial map
11567+ // (i.e. we constructed at least one instance using the constructor
11568+ // {function}).
11569+ if (function->has_initial_map ()) {
11570+ // Lookup @@hasInstance on the {function}.
11571+ Handle<Map> function_map (function->map (), isolate ());
11572+ PropertyAccessInfo has_instance (
11573+ this , LOAD, function_map,
11574+ isolate ()->factory ()->has_instance_symbol ());
11575+ // Check if we are using the Function.prototype[@@hasInstance].
11576+ if (has_instance.CanAccessMonomorphic () &&
11577+ has_instance.IsDataConstant () &&
11578+ has_instance.constant ().is_identical_to (
11579+ isolate ()->function_has_instance ())) {
11580+ // Add appropriate receiver map check and prototype chain
11581+ // checks to guard the @@hasInstance lookup chain.
11582+ AddCheckMap (right, function_map);
11583+ if (has_instance.has_holder ()) {
11584+ Handle<JSObject> prototype (
11585+ JSObject::cast (has_instance.map ()->prototype ()), isolate ());
11586+ BuildCheckPrototypeMaps (prototype, has_instance.holder ());
11587+ }
11588+ // Perform the prototype chain walk.
11589+ Handle<Map> initial_map (function->initial_map (), isolate ());
11590+ top_info ()->dependencies ()->AssumeInitialMapCantChange (initial_map);
11591+ HInstruction* prototype =
11592+ Add<HConstant>(handle (initial_map->prototype (), isolate ()));
11593+ HHasInPrototypeChainAndBranch* result =
11594+ New<HHasInPrototypeChainAndBranch>(left, prototype);
11595+ return ast_context ()->ReturnControl (result, expr->id ());
11596+ }
1158411597 }
1158511598 }
1158611599
0 commit comments