@@ -11206,24 +11206,37 @@ void HOptimizedGraphBuilder::VisitCompareOperation(CompareOperation* expr) {
1120611206 HConstant::cast (right)->handle (isolate ())->IsJSFunction ()) {
1120711207 Handle<JSFunction> function =
1120811208 Handle<JSFunction>::cast (HConstant::cast (right)->handle (isolate ()));
11209- // Make sure the prototype of {function} is the %FunctionPrototype%, and
11210- // it already has a meaningful initial map (i.e. we constructed at least
11211- // one instance using the constructor {function}).
11212- // We can only use the fast case if @@hasInstance was not used so far.
11213- if (function->has_initial_map () &&
11214- function->map ()->prototype () ==
11215- function->native_context ()->closure () &&
11216- !function->map ()->has_non_instance_prototype () &&
11217- isolate ()->IsHasInstanceLookupChainIntact ()) {
11218- Handle<Map> initial_map (function->initial_map (), isolate ());
11219- top_info ()->dependencies ()->AssumeInitialMapCantChange (initial_map);
11220- top_info ()->dependencies ()->AssumePropertyCell (
11221- isolate ()->factory ()->has_instance_protector ());
11222- HInstruction* prototype =
11223- Add<HConstant>(handle (initial_map->prototype (), isolate ()));
11224- HHasInPrototypeChainAndBranch* result =
11225- New<HHasInPrototypeChainAndBranch>(left, prototype);
11226- return ast_context ()->ReturnControl (result, expr->id ());
11209+ // Make sure that the {function} already has a meaningful initial map
11210+ // (i.e. we constructed at least one instance using the constructor
11211+ // {function}).
11212+ if (function->has_initial_map ()) {
11213+ // Lookup @@hasInstance on the {function}.
11214+ Handle<Map> function_map (function->map (), isolate ());
11215+ PropertyAccessInfo has_instance (
11216+ this , LOAD, function_map,
11217+ isolate ()->factory ()->has_instance_symbol ());
11218+ // Check if we are using the Function.prototype[@@hasInstance].
11219+ if (has_instance.CanAccessMonomorphic () &&
11220+ has_instance.IsDataConstant () &&
11221+ has_instance.constant ().is_identical_to (
11222+ isolate ()->function_has_instance ())) {
11223+ // Add appropriate receiver map check and prototype chain
11224+ // checks to guard the @@hasInstance lookup chain.
11225+ AddCheckMap (right, function_map);
11226+ if (has_instance.has_holder ()) {
11227+ Handle<JSObject> prototype (
11228+ JSObject::cast (has_instance.map ()->prototype ()), isolate ());
11229+ BuildCheckPrototypeMaps (prototype, has_instance.holder ());
11230+ }
11231+ // Perform the prototype chain walk.
11232+ Handle<Map> initial_map (function->initial_map (), isolate ());
11233+ top_info ()->dependencies ()->AssumeInitialMapCantChange (initial_map);
11234+ HInstruction* prototype =
11235+ Add<HConstant>(handle (initial_map->prototype (), isolate ()));
11236+ HHasInPrototypeChainAndBranch* result =
11237+ New<HHasInPrototypeChainAndBranch>(left, prototype);
11238+ return ast_context ()->ReturnControl (result, expr->id ());
11239+ }
1122711240 }
1122811241 }
1122911242
0 commit comments