Commit 94b33165 authored by bmeurer's avatar bmeurer Committed by Commit bot

[turbofan] Skip JSCallReducer and JSNativeContextSpecialization on asm.js.

For the old asm.js pipeline, there's no point in running either the
JSCallReducer or the JSNativeContextSpecialization, as both will not
kick in for any asm.js relevant code.

So remove the kDeoptimizationEnabled flag from both of them and just
run them on regular JavaScript only.

Drive-by-fix: Slightly rearrange keyed access to String receivers in the
JSNativeContextSpecialization::ReduceKeyedAccess method to access constant
characters independent of the IC mode (as long as the constant index is
within the range of the receiver).

BUG=v8:5267
R=jarin@chromium.org

Review-Url: https://codereview.chromium.org/2743253002
Cr-Commit-Position: refs/heads/master@{#43813}
parent 5790aad4
...@@ -617,9 +617,6 @@ Reduction JSCallReducer::ReduceJSCall(Node* node) { ...@@ -617,9 +617,6 @@ Reduction JSCallReducer::ReduceJSCall(Node* node) {
return Changed(node); return Changed(node);
} }
// Not much we can do if deoptimization support is disabled.
if (!(flags() & kDeoptimizationEnabled)) return NoChange();
Handle<Object> feedback(nexus.GetFeedback(), isolate()); Handle<Object> feedback(nexus.GetFeedback(), isolate());
if (feedback->IsAllocationSite()) { if (feedback->IsAllocationSite()) {
// Retrieve the Array function from the {node}. // Retrieve the Array function from the {node}.
...@@ -727,9 +724,6 @@ Reduction JSCallReducer::ReduceJSConstruct(Node* node) { ...@@ -727,9 +724,6 @@ Reduction JSCallReducer::ReduceJSConstruct(Node* node) {
return NoChange(); return NoChange();
} }
// Not much we can do if deoptimization support is disabled.
if (!(flags() & kDeoptimizationEnabled)) return NoChange();
if (!p.feedback().IsValid()) return NoChange(); if (!p.feedback().IsValid()) return NoChange();
CallICNexus nexus(p.feedback().vector(), p.feedback().slot()); CallICNexus nexus(p.feedback().vector(), p.feedback().slot());
Handle<Object> feedback(nexus.GetFeedback(), isolate()); Handle<Object> feedback(nexus.GetFeedback(), isolate());
......
...@@ -27,19 +27,11 @@ class SimplifiedOperatorBuilder; ...@@ -27,19 +27,11 @@ class SimplifiedOperatorBuilder;
// which might allow inlining or other optimizations to be performed afterwards. // which might allow inlining or other optimizations to be performed afterwards.
class JSCallReducer final : public AdvancedReducer { class JSCallReducer final : public AdvancedReducer {
public: public:
// Flags that control the mode of operation. JSCallReducer(Editor* editor, JSGraph* jsgraph,
enum Flag {
kNoFlags = 0u,
kDeoptimizationEnabled = 1u << 0,
};
typedef base::Flags<Flag> Flags;
JSCallReducer(Editor* editor, JSGraph* jsgraph, Flags flags,
Handle<Context> native_context, Handle<Context> native_context,
CompilationDependencies* dependencies) CompilationDependencies* dependencies)
: AdvancedReducer(editor), : AdvancedReducer(editor),
jsgraph_(jsgraph), jsgraph_(jsgraph),
flags_(flags),
native_context_(native_context), native_context_(native_context),
dependencies_(dependencies) {} dependencies_(dependencies) {}
...@@ -68,7 +60,6 @@ class JSCallReducer final : public AdvancedReducer { ...@@ -68,7 +60,6 @@ class JSCallReducer final : public AdvancedReducer {
Handle<JSObject>* holder); Handle<JSObject>* holder);
Graph* graph() const; Graph* graph() const;
Flags flags() const { return flags_; }
JSGraph* jsgraph() const { return jsgraph_; } JSGraph* jsgraph() const { return jsgraph_; }
Isolate* isolate() const; Isolate* isolate() const;
Factory* factory() const; Factory* factory() const;
...@@ -79,13 +70,10 @@ class JSCallReducer final : public AdvancedReducer { ...@@ -79,13 +70,10 @@ class JSCallReducer final : public AdvancedReducer {
CompilationDependencies* dependencies() const { return dependencies_; } CompilationDependencies* dependencies() const { return dependencies_; }
JSGraph* const jsgraph_; JSGraph* const jsgraph_;
Flags const flags_;
Handle<Context> const native_context_; Handle<Context> const native_context_;
CompilationDependencies* const dependencies_; CompilationDependencies* const dependencies_;
}; };
DEFINE_OPERATORS_FOR_FLAGS(JSCallReducer::Flags)
} // namespace compiler } // namespace compiler
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
......
...@@ -138,9 +138,6 @@ Reduction JSNativeContextSpecialization::ReduceJSGetSuperConstructor( ...@@ -138,9 +138,6 @@ Reduction JSNativeContextSpecialization::ReduceJSGetSuperConstructor(
DCHECK_EQ(IrOpcode::kJSGetSuperConstructor, node->opcode()); DCHECK_EQ(IrOpcode::kJSGetSuperConstructor, node->opcode());
Node* constructor = NodeProperties::GetValueInput(node, 0); 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. // Check if the input is a known JSFunction.
HeapObjectMatcher m(constructor); HeapObjectMatcher m(constructor);
if (!m.HasValue()) return NoChange(); if (!m.HasValue()) return NoChange();
...@@ -176,9 +173,6 @@ Reduction JSNativeContextSpecialization::ReduceJSInstanceOf(Node* node) { ...@@ -176,9 +173,6 @@ Reduction JSNativeContextSpecialization::ReduceJSInstanceOf(Node* node) {
Node* effect = NodeProperties::GetEffectInput(node); Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node); Node* control = NodeProperties::GetControlInput(node);
// If deoptimization is disabled, we cannot optimize.
if (!(flags() & kDeoptimizationEnabled)) return NoChange();
// Check if the right hand side is a known {receiver}. // Check if the right hand side is a known {receiver}.
HeapObjectMatcher m(constructor); HeapObjectMatcher m(constructor);
if (!m.HasValue() || !m.Value()->IsJSObject()) return NoChange(); if (!m.HasValue() || !m.Value()->IsJSObject()) return NoChange();
...@@ -529,9 +523,6 @@ Reduction JSNativeContextSpecialization::ReduceJSLoadGlobal(Node* node) { ...@@ -529,9 +523,6 @@ Reduction JSNativeContextSpecialization::ReduceJSLoadGlobal(Node* node) {
return Replace(value); return Replace(value);
} }
// Not much we can do if deoptimization support is disabled.
if (!(flags() & kDeoptimizationEnabled)) return NoChange();
// Lookup the {name} on the global object instead. // Lookup the {name} on the global object instead.
return ReduceGlobalAccess(node, nullptr, nullptr, name, AccessMode::kLoad); return ReduceGlobalAccess(node, nullptr, nullptr, name, AccessMode::kLoad);
} }
...@@ -555,9 +546,6 @@ Reduction JSNativeContextSpecialization::ReduceJSStoreGlobal(Node* node) { ...@@ -555,9 +546,6 @@ Reduction JSNativeContextSpecialization::ReduceJSStoreGlobal(Node* node) {
return Replace(value); return Replace(value);
} }
// Not much we can do if deoptimization support is disabled.
if (!(flags() & kDeoptimizationEnabled)) return NoChange();
// Lookup the {name} on the global object instead. // Lookup the {name} on the global object instead.
return ReduceGlobalAccess(node, nullptr, value, name, AccessMode::kStore); return ReduceGlobalAccess(node, nullptr, value, name, AccessMode::kStore);
} }
...@@ -577,9 +565,6 @@ Reduction JSNativeContextSpecialization::ReduceNamedAccess( ...@@ -577,9 +565,6 @@ Reduction JSNativeContextSpecialization::ReduceNamedAccess(
Node* effect = NodeProperties::GetEffectInput(node); Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node); Node* control = NodeProperties::GetControlInput(node);
// Not much we can do if deoptimization support is disabled.
if (!(flags() & kDeoptimizationEnabled)) return NoChange();
// Check if we have an access o.x or o.x=v where o is the current // Check if we have an access o.x or o.x=v where o is the current
// native contexts' global proxy, and turn that into a direct access // native contexts' global proxy, and turn that into a direct access
// to the current native contexts' global object instead. // to the current native contexts' global object instead.
...@@ -806,19 +791,16 @@ Reduction JSNativeContextSpecialization::ReduceNamedAccessFromNexus( ...@@ -806,19 +791,16 @@ Reduction JSNativeContextSpecialization::ReduceNamedAccessFromNexus(
Node* const receiver = NodeProperties::GetValueInput(node, 0); Node* const receiver = NodeProperties::GetValueInput(node, 0);
Node* const effect = NodeProperties::GetEffectInput(node); Node* const effect = NodeProperties::GetEffectInput(node);
if (flags() & kDeoptimizationEnabled) { // Check if we are accessing the current native contexts' global proxy.
// Check if we are accessing the current native contexts' global proxy. HeapObjectMatcher m(receiver);
HeapObjectMatcher m(receiver); if (m.HasValue() && m.Value().is_identical_to(global_proxy())) {
if (m.HasValue() && m.Value().is_identical_to(global_proxy())) { // Optimize accesses to the current native contexts' global proxy.
// Optimize accesses to the current native contexts' global proxy. return ReduceGlobalAccess(node, nullptr, value, name, access_mode);
return ReduceGlobalAccess(node, nullptr, value, name, access_mode);
}
} }
// Check if the {nexus} reports type feedback for the IC. // Check if the {nexus} reports type feedback for the IC.
if (nexus.IsUninitialized()) { if (nexus.IsUninitialized()) {
if ((flags() & kDeoptimizationEnabled) && if (flags() & kBailoutOnUninitialized) {
(flags() & kBailoutOnUninitialized)) {
return ReduceSoftDeoptimize( return ReduceSoftDeoptimize(
node, node,
DeoptimizeReason::kInsufficientTypeFeedbackForGenericNamedAccess); DeoptimizeReason::kInsufficientTypeFeedbackForGenericNamedAccess);
...@@ -831,8 +813,7 @@ Reduction JSNativeContextSpecialization::ReduceNamedAccessFromNexus( ...@@ -831,8 +813,7 @@ Reduction JSNativeContextSpecialization::ReduceNamedAccessFromNexus(
if (!ExtractReceiverMaps(receiver, effect, nexus, &receiver_maps)) { if (!ExtractReceiverMaps(receiver, effect, nexus, &receiver_maps)) {
return NoChange(); return NoChange();
} else if (receiver_maps.length() == 0) { } else if (receiver_maps.length() == 0) {
if ((flags() & kDeoptimizationEnabled) && if (flags() & kBailoutOnUninitialized) {
(flags() & kBailoutOnUninitialized)) {
return ReduceSoftDeoptimize( return ReduceSoftDeoptimize(
node, node,
DeoptimizeReason::kInsufficientTypeFeedbackForGenericNamedAccess); DeoptimizeReason::kInsufficientTypeFeedbackForGenericNamedAccess);
...@@ -863,14 +844,12 @@ Reduction JSNativeContextSpecialization::ReduceJSLoadNamed(Node* node) { ...@@ -863,14 +844,12 @@ Reduction JSNativeContextSpecialization::ReduceJSLoadNamed(Node* node) {
// {function} in order to be notified about changes to the // {function} in order to be notified about changes to the
// "prototype" of {function}, so it doesn't make sense to // "prototype" of {function}, so it doesn't make sense to
// continue unless deoptimization is enabled. // continue unless deoptimization is enabled.
if (flags() & kDeoptimizationEnabled) { Handle<Map> initial_map(function->initial_map(), isolate());
Handle<Map> initial_map(function->initial_map(), isolate()); dependencies()->AssumeInitialMapCantChange(initial_map);
dependencies()->AssumeInitialMapCantChange(initial_map); Handle<Object> prototype(initial_map->prototype(), isolate());
Handle<Object> prototype(initial_map->prototype(), isolate()); Node* value = jsgraph()->Constant(prototype);
Node* value = jsgraph()->Constant(prototype); ReplaceWithValue(node, value);
ReplaceWithValue(node, value); return Replace(value);
return Replace(value);
}
} }
} else if (m.Value()->IsString() && } else if (m.Value()->IsString() &&
p.name().is_identical_to(factory()->length_string())) { p.name().is_identical_to(factory()->length_string())) {
...@@ -931,9 +910,6 @@ Reduction JSNativeContextSpecialization::ReduceElementAccess( ...@@ -931,9 +910,6 @@ Reduction JSNativeContextSpecialization::ReduceElementAccess(
Node* control = NodeProperties::GetControlInput(node); Node* control = NodeProperties::GetControlInput(node);
Node* frame_state = NodeProperties::FindFrameStateBefore(node); Node* frame_state = NodeProperties::FindFrameStateBefore(node);
// Not much we can do if deoptimization support is disabled.
if (!(flags() & kDeoptimizationEnabled)) return NoChange();
// Check for keyed access to strings. // Check for keyed access to strings.
if (HasOnlyStringMaps(receiver_maps)) { if (HasOnlyStringMaps(receiver_maps)) {
// Strings are immutable in JavaScript. // Strings are immutable in JavaScript.
...@@ -1179,41 +1155,40 @@ Reduction JSNativeContextSpecialization::ReduceKeyedAccess( ...@@ -1179,41 +1155,40 @@ Reduction JSNativeContextSpecialization::ReduceKeyedAccess(
if (mreceiver.HasValue() && mreceiver.Value()->IsString()) { if (mreceiver.HasValue() && mreceiver.Value()->IsString()) {
Handle<String> string = Handle<String>::cast(mreceiver.Value()); Handle<String> string = Handle<String>::cast(mreceiver.Value());
// Strings are immutable in JavaScript.
if (access_mode == AccessMode::kStore) return NoChange();
// Properly deal with constant {index}.
NumberMatcher mindex(index);
if (mindex.IsInteger() && mindex.IsInRange(0.0, string->length() - 1)) {
// Constant-fold the {index} access to {string}.
Node* value = jsgraph()->HeapConstant(
factory()->LookupSingleCharacterStringFromCode(
string->Get(static_cast<int>(mindex.Value()))));
ReplaceWithValue(node, value, effect, control);
return Replace(value);
}
// We can only assume that the {index} is a valid array index if the IC // We can only assume that the {index} is a valid array index if the IC
// is in element access mode and not MEGAMORPHIC, otherwise there's no // is in element access mode and not MEGAMORPHIC, otherwise there's no
// guard for the bounds check below. // guard for the bounds check below.
if (nexus.ic_state() != MEGAMORPHIC && nexus.GetKeyType() == ELEMENT) { if (nexus.ic_state() != MEGAMORPHIC && nexus.GetKeyType() == ELEMENT) {
// Strings are immutable in JavaScript. // Ensure that {index} is less than {receiver} length.
if (access_mode == AccessMode::kStore) return NoChange(); Node* length = jsgraph()->Constant(string->length());
index = effect = graph()->NewNode(simplified()->CheckBounds(), index,
// Properly deal with constant {index}. length, effect, control);
NumberMatcher mindex(index);
if (mindex.IsInteger() && mindex.IsInRange(0.0, string->length() - 1)) { // Return the character from the {receiver} as single character string.
// Constant-fold the {index} access to {string}. value = graph()->NewNode(simplified()->StringCharAt(), receiver, index,
Node* value = jsgraph()->HeapConstant( control);
factory()->LookupSingleCharacterStringFromCode( ReplaceWithValue(node, value, effect, control);
string->Get(static_cast<int>(mindex.Value())))); return Replace(value);
ReplaceWithValue(node, value, effect, control);
return Replace(value);
} else if (flags() & kDeoptimizationEnabled) {
// Ensure that {index} is less than {receiver} length.
Node* length = jsgraph()->Constant(string->length());
index = effect = graph()->NewNode(simplified()->CheckBounds(), index,
length, effect, control);
// Return the character from the {receiver} as single character string.
value = graph()->NewNode(simplified()->StringCharAt(), receiver, index,
control);
ReplaceWithValue(node, value, effect, control);
return Replace(value);
}
} }
} }
// Check if the {nexus} reports type feedback for the IC. // Check if the {nexus} reports type feedback for the IC.
if (nexus.IsUninitialized()) { if (nexus.IsUninitialized()) {
if ((flags() & kDeoptimizationEnabled) && if (flags() & kBailoutOnUninitialized) {
(flags() & kBailoutOnUninitialized)) {
return ReduceSoftDeoptimize( return ReduceSoftDeoptimize(
node, node,
DeoptimizeReason::kInsufficientTypeFeedbackForGenericKeyedAccess); DeoptimizeReason::kInsufficientTypeFeedbackForGenericKeyedAccess);
...@@ -1226,8 +1201,7 @@ Reduction JSNativeContextSpecialization::ReduceKeyedAccess( ...@@ -1226,8 +1201,7 @@ Reduction JSNativeContextSpecialization::ReduceKeyedAccess(
if (!ExtractReceiverMaps(receiver, effect, nexus, &receiver_maps)) { if (!ExtractReceiverMaps(receiver, effect, nexus, &receiver_maps)) {
return NoChange(); return NoChange();
} else if (receiver_maps.length() == 0) { } else if (receiver_maps.length() == 0) {
if ((flags() & kDeoptimizationEnabled) && if (flags() & kBailoutOnUninitialized) {
(flags() & kBailoutOnUninitialized)) {
return ReduceSoftDeoptimize( return ReduceSoftDeoptimize(
node, node,
DeoptimizeReason::kInsufficientTypeFeedbackForGenericKeyedAccess); DeoptimizeReason::kInsufficientTypeFeedbackForGenericKeyedAccess);
...@@ -1698,9 +1672,6 @@ Reduction JSNativeContextSpecialization::ReduceJSStoreDataPropertyInLiteral( ...@@ -1698,9 +1672,6 @@ Reduction JSNativeContextSpecialization::ReduceJSStoreDataPropertyInLiteral(
Node* node) { Node* node) {
DCHECK_EQ(IrOpcode::kJSStoreDataPropertyInLiteral, node->opcode()); DCHECK_EQ(IrOpcode::kJSStoreDataPropertyInLiteral, node->opcode());
// If deoptimization is disabled, we cannot optimize.
if (!(flags() & kDeoptimizationEnabled)) return NoChange();
FeedbackParameter const& p = FeedbackParameterOf(node->op()); FeedbackParameter const& p = FeedbackParameterOf(node->op());
if (!p.feedback().IsValid()) return NoChange(); if (!p.feedback().IsValid()) return NoChange();
......
...@@ -40,8 +40,7 @@ class JSNativeContextSpecialization final : public AdvancedReducer { ...@@ -40,8 +40,7 @@ class JSNativeContextSpecialization final : public AdvancedReducer {
enum Flag { enum Flag {
kNoFlags = 0u, kNoFlags = 0u,
kAccessorInliningEnabled = 1u << 0, kAccessorInliningEnabled = 1u << 0,
kBailoutOnUninitialized = 1u << 1, kBailoutOnUninitialized = 1u << 1
kDeoptimizationEnabled = 1u << 2,
}; };
typedef base::Flags<Flag> Flags; typedef base::Flags<Flag> Flags;
......
...@@ -783,12 +783,8 @@ struct InliningPhase { ...@@ -783,12 +783,8 @@ struct InliningPhase {
CheckpointElimination checkpoint_elimination(&graph_reducer); CheckpointElimination checkpoint_elimination(&graph_reducer);
CommonOperatorReducer common_reducer(&graph_reducer, data->graph(), CommonOperatorReducer common_reducer(&graph_reducer, data->graph(),
data->common(), data->machine()); data->common(), data->machine());
JSCallReducer::Flags call_reducer_flags = JSCallReducer::kNoFlags;
if (data->info()->is_deoptimization_enabled()) {
call_reducer_flags |= JSCallReducer::kDeoptimizationEnabled;
}
JSCallReducer call_reducer(&graph_reducer, data->jsgraph(), JSCallReducer call_reducer(&graph_reducer, data->jsgraph(),
call_reducer_flags, data->native_context(), data->native_context(),
data->info()->dependencies()); data->info()->dependencies());
JSContextSpecialization context_specialization( JSContextSpecialization context_specialization(
&graph_reducer, data->jsgraph(), &graph_reducer, data->jsgraph(),
...@@ -805,9 +801,6 @@ struct InliningPhase { ...@@ -805,9 +801,6 @@ struct InliningPhase {
if (data->info()->is_bailout_on_uninitialized()) { if (data->info()->is_bailout_on_uninitialized()) {
flags |= JSNativeContextSpecialization::kBailoutOnUninitialized; flags |= JSNativeContextSpecialization::kBailoutOnUninitialized;
} }
if (data->info()->is_deoptimization_enabled()) {
flags |= JSNativeContextSpecialization::kDeoptimizationEnabled;
}
JSNativeContextSpecialization native_context_specialization( JSNativeContextSpecialization native_context_specialization(
&graph_reducer, data->jsgraph(), flags, data->native_context(), &graph_reducer, data->jsgraph(), flags, data->native_context(),
data->info()->dependencies(), temp_zone); data->info()->dependencies(), temp_zone);
...@@ -827,10 +820,14 @@ struct InliningPhase { ...@@ -827,10 +820,14 @@ struct InliningPhase {
if (data->info()->is_frame_specializing()) { if (data->info()->is_frame_specializing()) {
AddReducer(data, &graph_reducer, &frame_specialization); AddReducer(data, &graph_reducer, &frame_specialization);
} }
AddReducer(data, &graph_reducer, &native_context_specialization); if (data->info()->is_deoptimization_enabled()) {
AddReducer(data, &graph_reducer, &native_context_specialization);
}
AddReducer(data, &graph_reducer, &context_specialization); AddReducer(data, &graph_reducer, &context_specialization);
AddReducer(data, &graph_reducer, &intrinsic_lowering); AddReducer(data, &graph_reducer, &intrinsic_lowering);
AddReducer(data, &graph_reducer, &call_reducer); if (data->info()->is_deoptimization_enabled()) {
AddReducer(data, &graph_reducer, &call_reducer);
}
AddReducer(data, &graph_reducer, &inlining); AddReducer(data, &graph_reducer, &inlining);
graph_reducer.ReduceGraph(); graph_reducer.ReduceGraph();
} }
......
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