Commit 3c922887 authored by Manos Koukoutos's avatar Manos Koukoutos Committed by Commit Bot

[wasm] Move duplicate handling of try scopes from interfaces to decoder

Change-Id: I4f5eed3cc783b340ffbe1c0b3dbd50096514639a
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2831471
Commit-Queue: Manos Koukoutos <manoskouk@chromium.org>
Reviewed-by: 's avatarThibaud Michaud <thibaudm@chromium.org>
Reviewed-by: 's avatarClemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#74024}
parent ccc07119
......@@ -362,7 +362,6 @@ class LiftoffCompiler {
Label catch_label;
bool catch_reached = false;
bool in_handler = false;
int32_t previous_catch = -1;
};
struct Control : public ControlBase<Value, validate> {
......@@ -1085,8 +1084,6 @@ class LiftoffCompiler {
void Try(FullDecoder* decoder, Control* block) {
block->try_info = std::make_unique<TryInfo>();
block->try_info->previous_catch = current_catch_;
current_catch_ = static_cast<int32_t>(decoder->control_depth() - 1);
PushControl(block);
}
......@@ -1119,7 +1116,6 @@ class LiftoffCompiler {
const ExceptionIndexImmediate<validate>& imm,
Control* block, Vector<Value> values) {
DCHECK(block->is_try_catch());
current_catch_ = block->try_info->previous_catch; // Pop try scope.
__ emit_jump(block->label.get());
// The catch block is unreachable if no possible throws in the try block
......@@ -1200,7 +1196,6 @@ class LiftoffCompiler {
__ emit_jump(&target->try_info->catch_label);
}
}
current_catch_ = block->try_info->previous_catch;
}
void Rethrow(FullDecoder* decoder, Control* try_block) {
......@@ -1217,8 +1212,6 @@ class LiftoffCompiler {
block->is_try_unwind());
DCHECK_EQ(decoder->control_at(0), block);
current_catch_ = block->try_info->previous_catch; // Pop try scope.
// The catch block is unreachable if no possible throws in the try block
// exist. We only build a landing pad if some node in the try block can
// (possibly) throw. Otherwise the catch environments remain empty.
......@@ -4064,7 +4057,7 @@ class LiftoffCompiler {
}
void EmitLandingPad(FullDecoder* decoder, int handler_offset) {
if (current_catch_ == -1) return;
if (decoder->current_catch() == -1) return;
MovableLabel handler;
// If we return from the throwing code normally, just skip over the handler.
......@@ -4078,7 +4071,7 @@ class LiftoffCompiler {
__ PushException();
handlers_.push_back({std::move(handler), handler_offset});
Control* current_try =
decoder->control_at(decoder->control_depth() - 1 - current_catch_);
decoder->control_at(decoder->control_depth_of_current_catch());
DCHECK_NOT_NULL(current_try->try_info);
if (!current_try->try_info->catch_reached) {
current_try->try_info->catch_state.InitMerge(
......@@ -6009,9 +6002,6 @@ class LiftoffCompiler {
// at the first breakable opcode in the function (if compiling for debugging).
bool did_function_entry_break_checks_ = false;
// Depth of the current try block.
int32_t current_catch_ = -1;
struct HandlerInfo {
MovableLabel handler;
int pc_offset;
......
......@@ -960,6 +960,8 @@ struct ControlBase : public PcForErrors<validate> {
ControlKind kind = kControlBlock;
uint32_t locals_count = 0; // Additional locals introduced in this 'let'.
uint32_t stack_depth = 0; // Stack height at the beginning of the construct.
int32_t previous_catch = -1; // Depth of the innermost catch containing this
// 'try'.
Reachability reachability = kReachable;
// Values merged into the start or end of this control construct.
......@@ -2275,33 +2277,39 @@ class WasmFullDecoder : public WasmDecoder<validate> {
return WasmOpcodes::OpcodeName(opcode);
}
inline WasmCodePosition position() {
WasmCodePosition position() const {
int offset = static_cast<int>(this->pc_ - this->start_);
DCHECK_EQ(this->pc_ - this->start_, offset); // overflows cannot happen
return offset;
}
inline uint32_t control_depth() const {
uint32_t control_depth() const {
return static_cast<uint32_t>(control_.size());
}
inline Control* control_at(uint32_t depth) {
Control* control_at(uint32_t depth) {
DCHECK_GT(control_.size(), depth);
return &control_.back() - depth;
}
inline uint32_t stack_size() const {
uint32_t stack_size() const {
DCHECK_GE(stack_end_, stack_);
DCHECK_GE(kMaxUInt32, stack_end_ - stack_);
return static_cast<uint32_t>(stack_end_ - stack_);
}
inline Value* stack_value(uint32_t depth) {
Value* stack_value(uint32_t depth) const {
DCHECK_LT(0, depth);
DCHECK_GE(stack_size(), depth);
return stack_end_ - depth;
}
int32_t current_catch() const { return current_catch_; }
uint32_t control_depth_of_current_catch() const {
return control_depth() - 1 - current_catch();
}
void SetSucceedingCodeDynamicallyUnreachable() {
Control* current = &control_.back();
if (current->reachable()) {
......@@ -2326,6 +2334,9 @@ class WasmFullDecoder : public WasmDecoder<validate> {
// a cache for {ok() && control_.back().reachable()}).
bool current_code_reachable_and_ok_ = true;
// Depth of the current try block.
int32_t current_catch_ = -1;
static Value UnreachableValue(const uint8_t* pc) {
return Value{pc, kWasmBottom};
}
......@@ -2505,6 +2516,8 @@ class WasmFullDecoder : public WasmDecoder<validate> {
ArgVector args = PeekArgs(imm.sig);
Control* try_block = PushControl(kControlTry, 0, args.length());
SetBlockType(try_block, imm, args.begin());
try_block->previous_catch = current_catch_;
current_catch_ = static_cast<int>(control_depth() - 1);
CALL_INTERFACE_IF_OK_AND_REACHABLE(Try, try_block);
DropArgs(imm.sig);
PushMergeValues(try_block, &try_block->start_merge);
......@@ -2542,6 +2555,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
Push(CreateValue(sig->GetParam(i)));
}
Vector<Value> values(stack_ + c->stack_depth, sig->parameter_count());
current_catch_ = c->previous_catch; // Pop try scope.
CALL_INTERFACE_IF_OK_AND_PARENT_REACHABLE(CatchException, imm, c, values);
current_code_reachable_and_ok_ = this->ok() && c->reachable();
return 1 + imm.length;
......@@ -2572,6 +2586,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
}
FallThrough();
CALL_INTERFACE_IF_OK_AND_PARENT_REACHABLE(Delegate, imm.depth + 1, c);
current_catch_ = c->previous_catch;
EndControl();
PopControl();
return 1 + imm.length;
......@@ -2596,6 +2611,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
FallThrough();
c->kind = kControlTryCatchAll;
c->reachability = control_at(1)->innerReachability();
current_catch_ = c->previous_catch; // Pop try scope.
CALL_INTERFACE_IF_OK_AND_PARENT_REACHABLE(CatchAll, c);
stack_end_ = stack_ + c->stack_depth;
current_code_reachable_and_ok_ = this->ok() && c->reachable();
......@@ -2618,6 +2634,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
FallThrough();
c->kind = kControlTryUnwind;
c->reachability = control_at(1)->innerReachability();
current_catch_ = c->previous_catch; // Pop try scope.
CALL_INTERFACE_IF_OK_AND_PARENT_REACHABLE(CatchAll, c);
stack_end_ = stack_ + c->stack_depth;
current_code_reachable_and_ok_ = this->ok() && c->reachable();
......
......@@ -67,8 +67,6 @@ struct SsaEnv : public ZoneObject {
}
};
constexpr uint32_t kNullCatch = static_cast<uint32_t>(-1);
class WasmGraphBuildingInterface {
public:
static constexpr Decoder::ValidateFlag validate = Decoder::kFullValidation;
......@@ -240,8 +238,6 @@ class WasmGraphBuildingInterface {
TryInfo* try_info = decoder->zone()->New<TryInfo>(catch_env);
block->end_env = outer_env;
block->try_info = try_info;
block->previous_catch = current_catch_;
current_catch_ = static_cast<int32_t>(decoder->control_depth() - 1);
}
void If(FullDecoder* decoder, const Value& cond, Control* if_block) {
......@@ -687,9 +683,6 @@ class WasmGraphBuildingInterface {
const ExceptionIndexImmediate<validate>& imm,
Control* block, Vector<Value> values) {
DCHECK(block->is_try_catch());
current_catch_ = block->previous_catch; // Pop try scope.
// The catch block is unreachable if no possible throws in the try block
// exist. We only build a landing pad if some node in the try block can
// (possibly) throw. Otherwise the catch environments remain empty.
......@@ -741,7 +734,6 @@ class WasmGraphBuildingInterface {
// and IfFailure nodes.
builder_->Rethrow(block->try_info->exception);
TerminateThrow(decoder);
current_catch_ = block->previous_catch;
return;
}
DCHECK(decoder->control_at(depth)->is_try());
......@@ -763,7 +755,6 @@ class WasmGraphBuildingInterface {
target_try->exception, block->try_info->exception);
}
}
current_catch_ = block->previous_catch;
}
void CatchAll(FullDecoder* decoder, Control* block) {
......@@ -771,8 +762,6 @@ class WasmGraphBuildingInterface {
block->is_try_unwind());
DCHECK_EQ(decoder->control_at(0), block);
current_catch_ = block->previous_catch; // Pop try scope.
// The catch block is unreachable if no possible throws in the try block
// exist. We only build a landing pad if some node in the try block can
// (possibly) throw. Otherwise the catch environments remain empty.
......@@ -1078,7 +1067,6 @@ class WasmGraphBuildingInterface {
private:
SsaEnv* ssa_env_ = nullptr;
compiler::WasmGraphBuilder* builder_;
uint32_t current_catch_ = kNullCatch;
// Tracks loop data for loop unrolling.
std::vector<compiler::WasmLoopInfo> loop_infos_;
......@@ -1086,13 +1074,9 @@ class WasmGraphBuildingInterface {
TFNode* control() { return builder_->control(); }
uint32_t control_depth_of_current_catch(FullDecoder* decoder) {
return decoder->control_depth() - 1 - current_catch_;
}
TryInfo* current_try_info(FullDecoder* decoder) {
DCHECK_LT(current_catch_, decoder->control_depth());
return decoder->control_at(control_depth_of_current_catch(decoder))
DCHECK_LT(decoder->current_catch(), decoder->control_depth());
return decoder->control_at(decoder->control_depth_of_current_catch())
->try_info;
}
......@@ -1141,7 +1125,7 @@ class WasmGraphBuildingInterface {
V8_INLINE TFNode* CheckForException(FullDecoder* decoder, TFNode* node) {
if (node == nullptr) return nullptr;
const bool inside_try_scope = current_catch_ != kNullCatch;
const bool inside_try_scope = decoder->current_catch() != -1;
if (!inside_try_scope) return node;
return CheckForExceptionImpl(decoder, node);
......@@ -1165,7 +1149,7 @@ class WasmGraphBuildingInterface {
TryInfo* try_info = current_try_info(decoder);
if (FLAG_wasm_loop_unrolling) {
ValueVector values;
BuildNestedLoopExits(decoder, control_depth_of_current_catch(decoder),
BuildNestedLoopExits(decoder, decoder->control_depth_of_current_catch(),
true, values, &if_exception);
}
Goto(decoder, try_info->catch_env);
......
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