Commit d0a24e91 authored by bmeurer's avatar bmeurer Committed by Commit bot

[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}
parent 4ec37280
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment