[turbofan] Lower monomorphic loads during graph building.

We introduce an explicit LoweringResult data structure. Until this change,
the lowering result could be recovered from the node. However, lowering
monomorphic loads requires wiring different value and effect, so we need
a structure that can express such lowering result.

Bug: v8:6357
Change-Id: I92655800890b744d9203a778a1936a8dcd465ed3
Reviewed-on: https://chromium-review.googlesource.com/637304
Commit-Queue: Jaroslav Sevcik <jarin@chromium.org>
Reviewed-by: Michael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47992}
This commit is contained in:
Jaroslav Sevcik 2017-09-13 14:06:26 +02:00 committed by Commit Bot
parent bc69f3450b
commit 14b424c308
7 changed files with 100 additions and 11 deletions

View File

@ -476,7 +476,8 @@ BytecodeGraphBuilder::BytecodeGraphBuilder(
Zone* local_zone, Handle<SharedFunctionInfo> shared_info,
Handle<FeedbackVector> feedback_vector, BailoutId osr_offset,
JSGraph* jsgraph, CallFrequency invocation_frequency,
SourcePositionTable* source_positions, int inlining_id,
SourcePositionTable* source_positions, Handle<Context> native_context,
CompilationDependencies* dependencies, int inlining_id,
JSTypeHintLowering::Flags flags, bool stack_check)
: local_zone_(local_zone),
jsgraph_(jsgraph),
@ -485,7 +486,8 @@ BytecodeGraphBuilder::BytecodeGraphBuilder(
exception_handler_table_(
handle(HandlerTable::cast(bytecode_array()->handler_table()))),
feedback_vector_(feedback_vector),
type_hint_lowering_(jsgraph, feedback_vector, flags),
type_hint_lowering_(jsgraph, feedback_vector, native_context,
dependencies, flags, local_zone),
frame_state_function_info_(common()->CreateFrameStateFunctionInfo(
FrameStateType::kInterpretedFunction,
bytecode_array()->parameter_count(),

View File

@ -16,6 +16,9 @@
namespace v8 {
namespace internal {
class CompilationDependencies;
namespace compiler {
class Reduction;
@ -29,7 +32,8 @@ class BytecodeGraphBuilder {
Zone* local_zone, Handle<SharedFunctionInfo> shared,
Handle<FeedbackVector> feedback_vector, BailoutId osr_offset,
JSGraph* jsgraph, CallFrequency invocation_frequency,
SourcePositionTable* source_positions,
SourcePositionTable* source_positions, Handle<Context> native_context,
CompilationDependencies* dependencies,
int inlining_id = SourcePosition::kNotInlined,
JSTypeHintLowering::Flags flags = JSTypeHintLowering::kNoFlags,
bool stack_check = true);

View File

@ -350,8 +350,7 @@ bool JSInliner::DetermineCallTarget(
// TODO(turbofan): We might want to revisit this restriction later when we
// have a need for this, and we know how to model different native contexts
// in the same graph in a compositional way.
if (function->context()->native_context() !=
info_->context()->native_context()) {
if (function->context()->native_context() != *native_context()) {
return false;
}
@ -430,6 +429,10 @@ Reduction JSInliner::Reduce(Node* node) {
return ReduceJSCall(node);
}
Handle<Context> JSInliner::native_context() const {
return handle(info_->context()->native_context());
}
Reduction JSInliner::ReduceJSCall(Node* node) {
DCHECK(IrOpcode::IsInlineeOpcode(node->opcode()));
Handle<SharedFunctionInfo> shared_info;
@ -541,7 +544,8 @@ Reduction JSInliner::ReduceJSCall(Node* node) {
}
BytecodeGraphBuilder graph_builder(
zone(), shared_info, feedback_vector, BailoutId::None(), jsgraph(),
call.frequency(), source_positions_, inlining_id, flags, false);
call.frequency(), source_positions_, native_context(),
info_->dependencies(), inlining_id, flags, false);
graph_builder.CreateGraph();
// Extract the inlinee start/end nodes.

View File

@ -47,6 +47,7 @@ class JSInliner final : public AdvancedReducer {
SimplifiedOperatorBuilder* simplified() const;
Graph* graph() const;
JSGraph* jsgraph() const { return jsgraph_; }
Handle<Context> native_context() const;
Zone* const local_zone_;
CompilationInfo* info_;

View File

@ -5,10 +5,13 @@
#include "src/compiler/js-type-hint-lowering.h"
#include "src/compiler/access-builder.h"
#include "src/compiler/access-info.h"
#include "src/compiler/js-graph.h"
#include "src/compiler/operator-properties.h"
#include "src/compiler/property-access-builder.h"
#include "src/compiler/simplified-operator.h"
#include "src/feedback-vector.h"
#include "src/handles-inl.h"
#include "src/type-hints.h"
namespace v8 {
@ -209,8 +212,17 @@ class JSSpeculativeBinopBuilder final {
JSTypeHintLowering::JSTypeHintLowering(JSGraph* jsgraph,
Handle<FeedbackVector> feedback_vector,
Flags flags)
: jsgraph_(jsgraph), flags_(flags), feedback_vector_(feedback_vector) {}
Handle<Context> native_context,
CompilationDependencies* dependencies,
Flags flags, Zone* local_zone)
: jsgraph_(jsgraph),
flags_(flags),
feedback_vector_(feedback_vector),
native_context_(native_context),
dependencies_(dependencies),
local_zone_(local_zone) {}
Graph* JSTypeHintLowering::graph() const { return jsgraph_->graph(); }
JSTypeHintLowering::LoweringResult JSTypeHintLowering::ReduceBinaryOperation(
const Operator* op, Node* left, Node* right, Node* effect, Node* control,
@ -360,7 +372,59 @@ JSTypeHintLowering::LoweringResult JSTypeHintLowering::ReduceLoadNamedOperation(
DeoptimizeReason::kInsufficientTypeFeedbackForGenericNamedAccess)) {
return LoweringResult::Exit(node);
}
return LoweringResult::NoChange();
// Try to extract maps from the feedback vector. Give up if the IC
// is megamorphic or unitialized.
MapHandles receiver_maps;
if (nexus.ExtractMaps(&receiver_maps) == 0) {
return LoweringResult::NoChange();
}
// Extract information about accesses from the maps.
NamedAccess const& p = NamedAccessOf(op);
AccessInfoFactory access_info_factory(dependencies(), native_context(),
graph()->zone());
ZoneVector<PropertyAccessInfo> access_infos(local_zone());
if (!access_info_factory.ComputePropertyAccessInfos(
receiver_maps, p.name(), AccessMode::kLoad, &access_infos)) {
return LoweringResult::NoChange();
}
// Bail out if not monomorphic.
if (access_infos.size() != 1) return LoweringResult::NoChange();
// We only lower data fields and data constants.
PropertyAccessInfo const& access_info = access_infos[0];
if (!access_info.IsDataField() && !access_info.IsDataConstant()) {
return LoweringResult::NoChange();
}
PropertyAccessBuilder access_builder(jsgraph(), dependencies());
if (!access_builder.TryBuildStringCheck(access_info.receiver_maps(),
&receiver, &effect, control) &&
!access_builder.TryBuildNumberCheck(access_info.receiver_maps(),
&receiver, &effect, control)) {
receiver = access_builder.BuildCheckHeapObject(receiver, &effect, control);
access_builder.BuildCheckMaps(receiver, &effect, control,
access_info.receiver_maps());
}
Handle<JSObject> holder;
if (access_info.holder().ToHandle(&holder)) {
access_builder.AssumePrototypesStable(native_context(),
access_info.receiver_maps(), holder);
}
Node* value = nullptr;
if (access_info.IsDataConstant()) {
value = jsgraph()->Constant(access_info.constant());
} else {
DCHECK(access_info.IsDataField());
value = access_builder.BuildLoadDataField(p.name(), access_info, receiver,
&effect, &control);
}
return LoweringResult::SideEffectFree(value, effect, control);
}
JSTypeHintLowering::LoweringResult JSTypeHintLowering::ReduceLoadKeyedOperation(

View File

@ -14,6 +14,7 @@ namespace v8 {
namespace internal {
// Forward declarations.
class CompilationDependencies;
class FeedbackNexus;
class FeedbackSlot;
@ -42,7 +43,9 @@ class JSTypeHintLowering {
typedef base::Flags<Flag> Flags;
JSTypeHintLowering(JSGraph* jsgraph, Handle<FeedbackVector> feedback_vector,
Flags flags);
Handle<Context> native_context,
CompilationDependencies* dependencies, Flags flags,
Zone* local_zone);
// {LoweringResult} describes the result of lowering. The following outcomes
// are possible:
@ -156,11 +159,21 @@ class JSTypeHintLowering {
const Handle<FeedbackVector>& feedback_vector() const {
return feedback_vector_;
}
Graph* graph() const;
Zone* local_zone() const { return local_zone_; }
Handle<Context> native_context() const { return native_context_; }
CompilationDependencies* dependencies() const { return dependencies_; }
JSGraph* jsgraph_;
Flags const flags_;
Handle<FeedbackVector> feedback_vector_;
Handle<Context> native_context_;
CompilationDependencies* dependencies_;
Zone* local_zone_;
DISALLOW_COPY_AND_ASSIGN(JSTypeHintLowering);
};

View File

@ -893,7 +893,8 @@ struct GraphBuilderPhase {
temp_zone, data->info()->shared_info(),
handle(data->info()->closure()->feedback_vector()),
data->info()->osr_offset(), data->jsgraph(), CallFrequency(1.0f),
data->source_positions(), SourcePosition::kNotInlined, flags);
data->source_positions(), data->native_context(),
data->info()->dependencies(), SourcePosition::kNotInlined, flags);
graph_builder.CreateGraph();
}
};