[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:
parent
39b9b26339
commit
87086a1fde
@ -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));
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
|
Loading…
Reference in New Issue
Block a user