Skip to content

Commit a3197fa

Browse files
committed
Merged: Merged: [crankshaft] No need to rely on the @@hasInstance protector.
Revision: 7baee76 BUG=v8:5640 LOG=N NOTRY=true NOPRESUBMIT=true NOTREECHECKS=true TBR=jarin@chromium.org Review URL: https://codereview.chromium.org/2521293003 . Cr-Commit-Position: refs/branch-heads/5.5@{#56} Cr-Branched-From: 3cbd583-refs/heads/5.5.372@{#1} Cr-Branched-From: b3c8b0c-refs/heads/master@{#40015}
1 parent 15e19b4 commit a3197fa

3 files changed

Lines changed: 33 additions & 18 deletions

File tree

src/bootstrapper.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1217,6 +1217,7 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
12171217
JSObject::kHeaderSize, MaybeHandle<JSObject>(),
12181218
Builtins::kFunctionPrototypeHasInstance,
12191219
static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY));
1220+
native_context()->set_function_has_instance(*has_instance);
12201221

12211222
// Set the expected parameters for @@hasInstance to 1; required by builtin.
12221223
has_instance->shared()->set_internal_formal_parameter_count(1);

src/contexts.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ enum ContextLookupFlags {
8686
V(MAP_GET_METHOD_INDEX, JSFunction, map_get) \
8787
V(MAP_HAS_METHOD_INDEX, JSFunction, map_has) \
8888
V(MAP_SET_METHOD_INDEX, JSFunction, map_set) \
89+
V(FUNCTION_HAS_INSTANCE_INDEX, JSFunction, function_has_instance) \
8990
V(OBJECT_VALUE_OF, JSFunction, object_value_of) \
9091
V(OBJECT_TO_STRING, JSFunction, object_to_string) \
9192
V(PROMISE_CATCH_INDEX, JSFunction, promise_catch) \

src/crankshaft/hydrogen.cc

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)