[gasm] Add Effect/Control/FrameState wrapper classes

These node/edge kinds don't fit into the heap object type system; add
wrapper classes for them instead. The wrapper class must be explicitly
created, but is implicitly convertible to Node*.

Bug: v8:9972
Change-Id: Ic6c253a95bb5705fb946ee3f35508ea70c9f0070
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1940255
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#65244}
This commit is contained in:
Jakob Gruber 2019-11-28 12:54:25 +01:00 committed by Commit Bot
parent 39b9b26339
commit 87086a1fde
3 changed files with 97 additions and 54 deletions

View File

@ -579,12 +579,12 @@ Node* GraphAssembler::TypeGuard(Type type, Node* value) {
graph()->NewNode(common()->TypeGuard(type), value, effect(), control()));
}
Node* GraphAssembler::Checkpoint(Node* frame_state) {
Node* GraphAssembler::Checkpoint(FrameState frame_state) {
return AddNode(graph()->NewNode(common()->Checkpoint(), frame_state, effect(),
control()));
}
Node* GraphAssembler::LoopExit(Node* loop_header) {
Node* GraphAssembler::LoopExit(Control loop_header) {
return AddNode(
graph()->NewNode(common()->LoopExit(), control(), loop_header));
}

View File

@ -126,6 +126,46 @@ class BasicBlock;
class GraphAssembler;
// Wrapper classes for special node/edge types (effect, control, frame states)
// that otherwise don't fit into the type system.
class NodeWrapper {
public:
explicit constexpr NodeWrapper(Node* node) : node_(node) {}
operator Node*() const { return node_; }
Node* operator->() const { return node_; }
private:
Node* const node_;
};
class Effect : public NodeWrapper {
public:
explicit constexpr Effect(Node* node) : NodeWrapper(node) {
// TODO(jgruber): Remove the End/Dead special case.
SLOW_DCHECK(node == nullptr || node->op()->opcode() == IrOpcode::kEnd ||
node->op()->opcode() == IrOpcode::kDead ||
node->op()->EffectOutputCount() > 0);
}
};
class Control : public NodeWrapper {
public:
explicit constexpr Control(Node* node) : NodeWrapper(node) {
// TODO(jgruber): Remove the End/Dead special case.
SLOW_DCHECK(node == nullptr || node->op()->opcode() == IrOpcode::kEnd ||
node->op()->opcode() == IrOpcode::kDead ||
node->op()->ControlOutputCount() > 0);
}
};
class FrameState : public NodeWrapper {
public:
explicit constexpr FrameState(Node* node) : NodeWrapper(node) {
SLOW_DCHECK(node->op()->opcode() == IrOpcode::kFrameState);
}
};
enum class GraphAssemblerLabelType { kDeferred, kNonDeferred, kLoop };
// Label with statically known count of incoming branches and phis.
@ -304,8 +344,8 @@ class V8_EXPORT_PRIVATE GraphAssembler {
TNode<Boolean> NumberIsFloat64Hole(TNode<Number> value);
Node* TypeGuard(Type type, Node* value);
Node* Checkpoint(Node* frame_state);
Node* LoopExit(Node* loop_header);
Node* Checkpoint(FrameState frame_state);
Node* LoopExit(Control loop_header);
Node* LoopExitEffect();
Node* Store(StoreRepresentation rep, Node* object, Node* offset, Node* value);
@ -392,8 +432,8 @@ class V8_EXPORT_PRIVATE GraphAssembler {
void ConnectUnreachableToEnd();
Node* control() { return control_; }
Node* effect() { return effect_; }
Control control() { return Control(control_); }
Effect effect() { return Effect(effect_); }
protected:
class BasicBlockUpdater;

View File

@ -227,14 +227,14 @@ class JSCallReducerAssembler : public GraphAssembler {
// Javascript operators.
TNode<Object> JSCall3(TNode<Object> function, TNode<Object> this_arg,
TNode<Object> arg0, TNode<Object> arg1,
TNode<Object> arg2, Node* frame_state);
TNode<Object> arg2, FrameState frame_state);
TNode<Object> JSCall4(TNode<Object> function, TNode<Object> this_arg,
TNode<Object> arg0, TNode<Object> arg1,
TNode<Object> arg2, TNode<Object> arg3,
Node* frame_state);
FrameState frame_state);
TNode<Object> JSCallRuntime2(Runtime::FunctionId function_id,
TNode<Object> arg0, TNode<Object> arg1,
Node* frame_state);
FrameState frame_state);
void MaybeInsertMapChecks(MapInference* inference,
bool has_stability_dependency) {
@ -257,8 +257,8 @@ class JSCallReducerAssembler : public GraphAssembler {
TNode<Object> result = body();
if (has_external_exception_handler()) {
Node* e = effect();
Node* c = control();
Effect e = effect();
Control c = control();
// The IfException node is later merged into the outer graph.
Node* if_exception =
@ -293,7 +293,7 @@ class JSCallReducerAssembler : public GraphAssembler {
gasm_->Goto(&loop_header, initial_value_);
gasm_->Bind(&loop_header);
Node* loop_header_control = gasm_->control(); // For LoopExit below.
Control loop_header_control = gasm_->control(); // For LoopExit below.
TNode<Number> i = loop_header.PhiAt<Number>(0);
gasm_->BranchWithHint(cond_(i), &loop_body, &loop_exit,
@ -363,7 +363,7 @@ class JSCallReducerAssembler : public GraphAssembler {
gasm_->Goto(&loop_header, initial_value_, initial_arg0_);
gasm_->Bind(&loop_header);
Node* loop_header_control = gasm_->control(); // For LoopExit below.
Control loop_header_control = gasm_->control(); // For LoopExit below.
TNode<Number> i = loop_header.PhiAt<Number>(0);
arg0 = loop_header.PhiAt<Object>(1);
@ -429,8 +429,8 @@ class JSCallReducerAssembler : public GraphAssembler {
NodeProperties::GetContextInput(node_));
}
Node* FrameStateInput() const {
return NodeProperties::GetFrameStateInput(node_);
FrameState FrameStateInput() const {
return FrameState(NodeProperties::GetFrameStateInput(node_));
}
JSOperatorBuilder* javascript() const { return jsgraph()->javascript(); }
@ -462,7 +462,8 @@ class IteratingArrayBuiltinReducerAssembler : public JSCallReducerAssembler {
ArrayReduceDirection direction,
const SharedFunctionInfoRef& shared);
void ThrowIfNotCallable(TNode<Object> maybe_callable, Node* frame_state) {
void ThrowIfNotCallable(TNode<Object> maybe_callable,
FrameState frame_state) {
IfNot(ObjectIsCallable(maybe_callable))
.Then(_ {
JSCallRuntime2(Runtime::kThrowTypeError,
@ -539,7 +540,7 @@ TNode<Object> JSCallReducerAssembler::TypeGuardNonInternal(
TNode<Object> JSCallReducerAssembler::JSCall3(
TNode<Object> function, TNode<Object> this_arg, TNode<Object> arg0,
TNode<Object> arg1, TNode<Object> arg2, Node* frame_state) {
TNode<Object> arg1, TNode<Object> arg2, FrameState frame_state) {
CallParameters const& p = CallParametersOf(node_ptr()->op());
return MayThrow(_ {
return AddNode<Object>(graph()->NewNode(
@ -554,7 +555,7 @@ TNode<Object> JSCallReducerAssembler::JSCall3(
TNode<Object> JSCallReducerAssembler::JSCall4(
TNode<Object> function, TNode<Object> this_arg, TNode<Object> arg0,
TNode<Object> arg1, TNode<Object> arg2, TNode<Object> arg3,
Node* frame_state) {
FrameState frame_state) {
CallParameters const& p = CallParametersOf(node_ptr()->op());
return MayThrow(_ {
return AddNode<Object>(graph()->NewNode(
@ -568,7 +569,7 @@ TNode<Object> JSCallReducerAssembler::JSCall4(
TNode<Object> JSCallReducerAssembler::JSCallRuntime2(
Runtime::FunctionId function_id, TNode<Object> arg0, TNode<Object> arg1,
Node* frame_state) {
FrameState frame_state) {
return MayThrow(_ {
return AddNode<Object>(
graph()->NewNode(javascript()->CallRuntime(function_id, 2), arg0, arg1,
@ -698,33 +699,33 @@ struct ForEachFrameStateParams {
SharedFunctionInfoRef shared;
TNode<Context> context;
TNode<Object> target;
Node* outer_frame_state;
FrameState outer_frame_state;
TNode<Object> receiver;
TNode<Object> callback;
TNode<Object> this_arg;
TNode<Object> original_length;
};
Node* ForEachLoopLazyFrameState(const ForEachFrameStateParams& params,
TNode<Object> k) {
FrameState ForEachLoopLazyFrameState(const ForEachFrameStateParams& params,
TNode<Object> k) {
Builtins::Name builtin = Builtins::kArrayForEachLoopLazyDeoptContinuation;
Node* checkpoint_params[] = {params.receiver, params.callback,
params.this_arg, k, params.original_length};
return CreateJavaScriptBuiltinContinuationFrameState(
return FrameState(CreateJavaScriptBuiltinContinuationFrameState(
params.jsgraph, params.shared, builtin, params.target, params.context,
checkpoint_params, arraysize(checkpoint_params), params.outer_frame_state,
ContinuationFrameStateMode::LAZY);
ContinuationFrameStateMode::LAZY));
}
Node* ForEachLoopEagerFrameState(const ForEachFrameStateParams& params,
TNode<Object> k) {
FrameState ForEachLoopEagerFrameState(const ForEachFrameStateParams& params,
TNode<Object> k) {
Builtins::Name builtin = Builtins::kArrayForEachLoopEagerDeoptContinuation;
Node* checkpoint_params[] = {params.receiver, params.callback,
params.this_arg, k, params.original_length};
return CreateJavaScriptBuiltinContinuationFrameState(
return FrameState(CreateJavaScriptBuiltinContinuationFrameState(
params.jsgraph, params.shared, builtin, params.target, params.context,
checkpoint_params, arraysize(checkpoint_params), params.outer_frame_state,
ContinuationFrameStateMode::EAGER);
ContinuationFrameStateMode::EAGER));
}
} // namespace
@ -735,7 +736,7 @@ IteratingArrayBuiltinReducerAssembler::ReduceArrayPrototypeForEach(
ElementsKind kind, const SharedFunctionInfoRef& shared) {
DCHECK(FLAG_turbo_inline_array_builtins);
Node* outer_frame_state = FrameStateInput();
FrameState outer_frame_state = FrameStateInput();
TNode<Context> context = ContextInput();
TNode<Object> target = ValueInput(0);
TNode<HeapObject> receiver = TNode<HeapObject>::UncheckedCast(ValueInput(1));
@ -794,67 +795,69 @@ struct ReduceFrameStateParams {
ArrayReduceDirection direction;
TNode<Context> context;
TNode<Object> target;
Node* outer_frame_state;
FrameState outer_frame_state;
};
Node* ReducePreLoopLazyFrameState(const ReduceFrameStateParams& params,
TNode<Object> receiver,
TNode<Object> callback, TNode<Object> k,
TNode<Number> original_length) {
FrameState ReducePreLoopLazyFrameState(const ReduceFrameStateParams& params,
TNode<Object> receiver,
TNode<Object> callback, TNode<Object> k,
TNode<Number> original_length) {
Builtins::Name builtin =
(params.direction == ArrayReduceDirection::kLeft)
? Builtins::kArrayReduceLoopLazyDeoptContinuation
: Builtins::kArrayReduceRightLoopLazyDeoptContinuation;
Node* checkpoint_params[] = {receiver, callback, k, original_length};
return CreateJavaScriptBuiltinContinuationFrameState(
return FrameState(CreateJavaScriptBuiltinContinuationFrameState(
params.jsgraph, params.shared, builtin, params.target, params.context,
checkpoint_params, arraysize(checkpoint_params), params.outer_frame_state,
ContinuationFrameStateMode::LAZY);
ContinuationFrameStateMode::LAZY));
}
Node* ReducePreLoopEagerFrameState(const ReduceFrameStateParams& params,
TNode<Object> receiver,
TNode<Object> callback,
TNode<Number> original_length) {
FrameState ReducePreLoopEagerFrameState(const ReduceFrameStateParams& params,
TNode<Object> receiver,
TNode<Object> callback,
TNode<Number> original_length) {
Builtins::Name builtin =
(params.direction == ArrayReduceDirection::kLeft)
? Builtins::kArrayReducePreLoopEagerDeoptContinuation
: Builtins::kArrayReduceRightPreLoopEagerDeoptContinuation;
Node* checkpoint_params[] = {receiver, callback, original_length};
return CreateJavaScriptBuiltinContinuationFrameState(
return FrameState(CreateJavaScriptBuiltinContinuationFrameState(
params.jsgraph, params.shared, builtin, params.target, params.context,
checkpoint_params, arraysize(checkpoint_params), params.outer_frame_state,
ContinuationFrameStateMode::EAGER);
ContinuationFrameStateMode::EAGER));
}
Node* ReduceLoopLazyFrameState(const ReduceFrameStateParams& params,
TNode<Object> receiver, TNode<Object> callback,
TNode<Object> k, TNode<Number> original_length) {
FrameState ReduceLoopLazyFrameState(const ReduceFrameStateParams& params,
TNode<Object> receiver,
TNode<Object> callback, TNode<Object> k,
TNode<Number> original_length) {
Builtins::Name builtin =
(params.direction == ArrayReduceDirection::kLeft)
? Builtins::kArrayReduceLoopLazyDeoptContinuation
: Builtins::kArrayReduceRightLoopLazyDeoptContinuation;
Node* checkpoint_params[] = {receiver, callback, k, original_length};
return CreateJavaScriptBuiltinContinuationFrameState(
return FrameState(CreateJavaScriptBuiltinContinuationFrameState(
params.jsgraph, params.shared, builtin, params.target, params.context,
checkpoint_params, arraysize(checkpoint_params), params.outer_frame_state,
ContinuationFrameStateMode::LAZY);
ContinuationFrameStateMode::LAZY));
}
Node* ReduceLoopEagerFrameState(const ReduceFrameStateParams& params,
TNode<Object> receiver, TNode<Object> callback,
TNode<Object> k, TNode<Number> original_length,
TNode<Object> accumulator) {
FrameState ReduceLoopEagerFrameState(const ReduceFrameStateParams& params,
TNode<Object> receiver,
TNode<Object> callback, TNode<Object> k,
TNode<Number> original_length,
TNode<Object> accumulator) {
Builtins::Name builtin =
(params.direction == ArrayReduceDirection::kLeft)
? Builtins::kArrayReduceLoopEagerDeoptContinuation
: Builtins::kArrayReduceRightLoopEagerDeoptContinuation;
Node* checkpoint_params[] = {receiver, callback, k, original_length,
accumulator};
return CreateJavaScriptBuiltinContinuationFrameState(
return FrameState(CreateJavaScriptBuiltinContinuationFrameState(
params.jsgraph, params.shared, builtin, params.target, params.context,
checkpoint_params, arraysize(checkpoint_params), params.outer_frame_state,
ContinuationFrameStateMode::EAGER);
ContinuationFrameStateMode::EAGER));
}
} // namespace
@ -865,7 +868,7 @@ TNode<Object> IteratingArrayBuiltinReducerAssembler::ReduceArrayPrototypeReduce(
const SharedFunctionInfoRef& shared) {
DCHECK(FLAG_turbo_inline_array_builtins);
Node* outer_frame_state = FrameStateInput();
FrameState outer_frame_state = FrameStateInput();
TNode<Context> context = ContextInput();
TNode<Object> target = ValueInput(0);
TNode<HeapObject> receiver = TNode<HeapObject>::UncheckedCast(ValueInput(1));