Skip to content

Commit 7baee76

Browse files
committed
Merged: [crankshaft] No need to rely on the @@hasInstance protector.
Revision: 08377af BUG=v8:5640 LOG=N NOTRY=true NOPRESUBMIT=true NOTREECHECKS=true [email protected] Review URL: https://codereview.chromium.org/2513403002 . Cr-Commit-Position: refs/branch-heads/5.6@{#9} Cr-Branched-From: bdd3886-refs/heads/5.6.326@{#1} Cr-Branched-From: 879f659-refs/heads/master@{#41014}
1 parent 9908a48 commit 7baee76

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
@@ -1257,6 +1257,7 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
12571257
JSObject::kHeaderSize, MaybeHandle<JSObject>(),
12581258
Builtins::kFunctionPrototypeHasInstance,
12591259
static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY));
1260+
native_context()->set_function_has_instance(*has_instance);
12601261

12611262
// Set the expected parameters for @@hasInstance to 1; required by builtin.
12621263
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
@@ -88,6 +88,7 @@ enum ContextLookupFlags {
8888
V(MAP_GET_METHOD_INDEX, JSFunction, map_get) \
8989
V(MAP_HAS_METHOD_INDEX, JSFunction, map_has) \
9090
V(MAP_SET_METHOD_INDEX, JSFunction, map_set) \
91+
V(FUNCTION_HAS_INSTANCE_INDEX, JSFunction, function_has_instance) \
9192
V(OBJECT_VALUE_OF, JSFunction, object_value_of) \
9293
V(OBJECT_TO_STRING, JSFunction, object_to_string) \
9394
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
@@ -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

Comments
 (0)