[turbofan] Constant-fold JSGetSuperConstructor.
This adds support to constant-fold JSGetSuperConstructor(constructor) for constructors with stable maps, i.e. where we can add a stability dependency on the constructors map to get notified when the [[Prototype]] of constructor changes. R=petermarshall@chromium.org BUG=v8:5517 Review-Url: https://codereview.chromium.org/2652763010 Cr-Commit-Position: refs/heads/master@{#42647}
This commit is contained in:
parent
4ec372801e
commit
d0a24e913f
@ -69,6 +69,8 @@ JSNativeContextSpecialization::JSNativeContextSpecialization(
|
||||
|
||||
Reduction JSNativeContextSpecialization::Reduce(Node* node) {
|
||||
switch (node->opcode()) {
|
||||
case IrOpcode::kJSGetSuperConstructor:
|
||||
return ReduceJSGetSuperConstructor(node);
|
||||
case IrOpcode::kJSInstanceOf:
|
||||
return ReduceJSInstanceOf(node);
|
||||
case IrOpcode::kJSOrdinaryHasInstance:
|
||||
@ -91,6 +93,41 @@ Reduction JSNativeContextSpecialization::Reduce(Node* node) {
|
||||
return NoChange();
|
||||
}
|
||||
|
||||
Reduction JSNativeContextSpecialization::ReduceJSGetSuperConstructor(
|
||||
Node* node) {
|
||||
DCHECK_EQ(IrOpcode::kJSGetSuperConstructor, node->opcode());
|
||||
Node* constructor = NodeProperties::GetValueInput(node, 0);
|
||||
|
||||
// If deoptimization is disabled, we cannot optimize.
|
||||
if (!(flags() & kDeoptimizationEnabled)) return NoChange();
|
||||
|
||||
// Check if the input is a known JSFunction.
|
||||
HeapObjectMatcher m(constructor);
|
||||
if (!m.HasValue()) return NoChange();
|
||||
Handle<JSFunction> function = Handle<JSFunction>::cast(m.Value());
|
||||
Handle<Map> function_map(function->map(), isolate());
|
||||
Handle<Object> function_prototype(function_map->prototype(), isolate());
|
||||
|
||||
// We can constant-fold the super constructor access if the
|
||||
// {function}s map is stable, i.e. we can use a code dependency
|
||||
// to guard against [[Prototype]] changes of {function}.
|
||||
if (function_map->is_stable()) {
|
||||
Node* value = jsgraph()->Constant(function_prototype);
|
||||
dependencies()->AssumeMapStable(function_map);
|
||||
if (function_prototype->IsConstructor()) {
|
||||
ReplaceWithValue(node, value);
|
||||
return Replace(value);
|
||||
} else {
|
||||
node->InsertInput(graph()->zone(), 0, value);
|
||||
NodeProperties::ChangeOp(
|
||||
node, javascript()->CallRuntime(Runtime::kThrowNotSuperConstructor));
|
||||
return Changed(node);
|
||||
}
|
||||
}
|
||||
|
||||
return NoChange();
|
||||
}
|
||||
|
||||
Reduction JSNativeContextSpecialization::ReduceJSInstanceOf(Node* node) {
|
||||
DCHECK_EQ(IrOpcode::kJSInstanceOf, node->opcode());
|
||||
Node* object = NodeProperties::GetValueInput(node, 0);
|
||||
|
@ -53,6 +53,7 @@ class JSNativeContextSpecialization final : public AdvancedReducer {
|
||||
Reduction Reduce(Node* node) final;
|
||||
|
||||
private:
|
||||
Reduction ReduceJSGetSuperConstructor(Node* node);
|
||||
Reduction ReduceJSInstanceOf(Node* node);
|
||||
Reduction ReduceJSOrdinaryHasInstance(Node* node);
|
||||
Reduction ReduceJSLoadContext(Node* node);
|
||||
|
Loading…
Reference in New Issue
Block a user