Commit 14b424c3 authored by Jaroslav Sevcik's avatar Jaroslav Sevcik Committed by Commit Bot

[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: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47992}
parent bc69f345
......@@ -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(),
......
......@@ -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);
......
......@@ -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.
......
......@@ -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_;
......
......@@ -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(
......
......@@ -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);
};
......
......@@ -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();
}
};
......
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