@@ -11418,24 +11418,37 @@ void HOptimizedGraphBuilder::VisitCompareOperation(CompareOperation* expr) {
1141811418 HConstant::cast (right)->handle (isolate ())->IsJSFunction ()) {
1141911419 Handle<JSFunction> function =
1142011420 Handle<JSFunction>::cast (HConstant::cast (right)->handle (isolate ()));
11421- // Make sure the prototype of {function} is the %FunctionPrototype%, and
11422- // it already has a meaningful initial map (i.e. we constructed at least
11423- // one instance using the constructor {function}).
11424- // We can only use the fast case if @@hasInstance was not used so far.
11425- if (function->has_initial_map () &&
11426- function->map ()->prototype () ==
11427- function->native_context ()->closure () &&
11428- !function->map ()->has_non_instance_prototype () &&
11429- isolate ()->IsHasInstanceLookupChainIntact ()) {
11430- Handle<Map> initial_map (function->initial_map (), isolate ());
11431- top_info ()->dependencies ()->AssumeInitialMapCantChange (initial_map);
11432- top_info ()->dependencies ()->AssumePropertyCell (
11433- isolate ()->factory ()->has_instance_protector ());
11434- HInstruction* prototype =
11435- Add<HConstant>(handle (initial_map->prototype (), isolate ()));
11436- HHasInPrototypeChainAndBranch* result =
11437- New<HHasInPrototypeChainAndBranch>(left, prototype);
11438- return ast_context ()->ReturnControl (result, expr->id ());
11421+ // Make sure that the {function} already has a meaningful initial map
11422+ // (i.e. we constructed at least one instance using the constructor
11423+ // {function}).
11424+ if (function->has_initial_map ()) {
11425+ // Lookup @@hasInstance on the {function}.
11426+ Handle<Map> function_map (function->map (), isolate ());
11427+ PropertyAccessInfo has_instance (
11428+ this , LOAD, function_map,
11429+ isolate ()->factory ()->has_instance_symbol ());
11430+ // Check if we are using the Function.prototype[@@hasInstance].
11431+ if (has_instance.CanAccessMonomorphic () &&
11432+ has_instance.IsDataConstant () &&
11433+ has_instance.constant ().is_identical_to (
11434+ isolate ()->function_has_instance ())) {
11435+ // Add appropriate receiver map check and prototype chain
11436+ // checks to guard the @@hasInstance lookup chain.
11437+ AddCheckMap (right, function_map);
11438+ if (has_instance.has_holder ()) {
11439+ Handle<JSObject> prototype (
11440+ JSObject::cast (has_instance.map ()->prototype ()), isolate ());
11441+ BuildCheckPrototypeMaps (prototype, has_instance.holder ());
11442+ }
11443+ // Perform the prototype chain walk.
11444+ Handle<Map> initial_map (function->initial_map (), isolate ());
11445+ top_info ()->dependencies ()->AssumeInitialMapCantChange (initial_map);
11446+ HInstruction* prototype =
11447+ Add<HConstant>(handle (initial_map->prototype (), isolate ()));
11448+ HHasInPrototypeChainAndBranch* result =
11449+ New<HHasInPrototypeChainAndBranch>(left, prototype);
11450+ return ast_context ()->ReturnControl (result, expr->id ());
11451+ }
1143911452 }
1144011453 }
1144111454
0 commit comments