[turbofan] Properly specialize JSCreateIterResultObject map.

If possible, take the constant map from the (known) native context for
JSCreateIterResultObject, so that subsequent map checks can be
eliminated in case of iterator inlining.

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

Review-Url: https://codereview.chromium.org/2394783002
Cr-Commit-Position: refs/heads/master@{#39974}
This commit is contained in:
bmeurer 2016-10-04 23:32:02 -07:00 committed by Commit bot
parent 9701e79127
commit 50c458a389
4 changed files with 32 additions and 11 deletions

View File

@ -722,16 +722,25 @@ Reduction JSCreateLowering::ReduceJSCreateIterResultObject(Node* node) {
DCHECK_EQ(IrOpcode::kJSCreateIterResultObject, node->opcode());
Node* value = NodeProperties::GetValueInput(node, 0);
Node* done = NodeProperties::GetValueInput(node, 1);
Node* context = NodeProperties::GetContextInput(node);
Node* effect = NodeProperties::GetEffectInput(node);
// Load the JSIteratorResult map for the {context}.
Node* native_context = effect = graph()->NewNode(
javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true),
context, context, effect);
Node* iterator_result_map = effect = graph()->NewNode(
javascript()->LoadContext(0, Context::ITERATOR_RESULT_MAP_INDEX, true),
native_context, native_context, effect);
Node* iterator_result_map;
Handle<Context> native_context;
if (GetSpecializationNativeContext(node).ToHandle(&native_context)) {
// Specialize to the constant JSIteratorResult map to enable map check
// elimination to eliminate subsequent checks in case of inlining.
iterator_result_map = jsgraph()->HeapConstant(
handle(native_context->iterator_result_map(), isolate()));
} else {
// Load the JSIteratorResult map for the {context}.
Node* context = NodeProperties::GetContextInput(node);
Node* native_context = effect = graph()->NewNode(
javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true),
context, context, effect);
iterator_result_map = effect = graph()->NewNode(
javascript()->LoadContext(0, Context::ITERATOR_RESULT_MAP_INDEX, true),
native_context, native_context, effect);
}
// Emit code to allocate the JSIteratorResult instance.
AllocationBuilder a(jsgraph(), effect, graph()->start());
@ -1271,6 +1280,13 @@ MaybeHandle<LiteralsArray> JSCreateLowering::GetSpecializationLiterals(
return MaybeHandle<LiteralsArray>();
}
MaybeHandle<Context> JSCreateLowering::GetSpecializationNativeContext(
Node* node) {
Node* const context = NodeProperties::GetContextInput(node);
return NodeProperties::GetSpecializationNativeContext(context,
native_context_);
}
Factory* JSCreateLowering::factory() const { return isolate()->factory(); }
Graph* JSCreateLowering::graph() const { return jsgraph()->graph(); }

View File

@ -31,11 +31,12 @@ class JSCreateLowering final : public AdvancedReducer {
public:
JSCreateLowering(Editor* editor, CompilationDependencies* dependencies,
JSGraph* jsgraph, MaybeHandle<LiteralsArray> literals_array,
Zone* zone)
MaybeHandle<Context> native_context, Zone* zone)
: AdvancedReducer(editor),
dependencies_(dependencies),
jsgraph_(jsgraph),
literals_array_(literals_array),
native_context_(native_context),
zone_(zone) {}
~JSCreateLowering() final {}
@ -76,6 +77,8 @@ class JSCreateLowering final : public AdvancedReducer {
// Infers the LiteralsArray to use for a given {node}.
MaybeHandle<LiteralsArray> GetSpecializationLiterals(Node* node);
// Infers the native context to use for a given {node}.
MaybeHandle<Context> GetSpecializationNativeContext(Node* node);
Factory* factory() const;
Graph* graph() const;
@ -91,6 +94,7 @@ class JSCreateLowering final : public AdvancedReducer {
CompilationDependencies* const dependencies_;
JSGraph* const jsgraph_;
MaybeHandle<LiteralsArray> const literals_array_;
MaybeHandle<Context> const native_context_;
Zone* const zone_;
};

View File

@ -936,7 +936,7 @@ struct TypedLoweringPhase {
: MaybeHandle<LiteralsArray>();
JSCreateLowering create_lowering(
&graph_reducer, data->info()->dependencies(), data->jsgraph(),
literals_array, temp_zone);
literals_array, data->native_context(), temp_zone);
JSTypedLowering::Flags typed_lowering_flags = JSTypedLowering::kNoFlags;
if (data->info()->is_deoptimization_enabled()) {
typed_lowering_flags |= JSTypedLowering::kDeoptimizationEnabled;

View File

@ -40,7 +40,8 @@ class JSCreateLoweringTest : public TypedGraphTest {
// TODO(titzer): mock the GraphReducer here for better unit testing.
GraphReducer graph_reducer(zone(), graph());
JSCreateLowering reducer(&graph_reducer, &deps_, &jsgraph,
MaybeHandle<LiteralsArray>(), zone());
MaybeHandle<LiteralsArray>(),
MaybeHandle<Context>(), zone());
return reducer.Reduce(node);
}