Commit 47892136 authored by Manos Koukoutos's avatar Manos Koukoutos Committed by Commit Bot

[wasm] Do not call CheckForException on every node

Calling CheckForException through the BUILD macro for almost every
invocation of WasmGraphBuilder from graph-builder-interface created
multiple issues:
- It generated an invalid graph with GetExceptionValues, resulting in
  us having to hack CallBuiltin().
- It will generate multiple problems with wasm-gc operations.
- It needlessly slowed down compilation.

Changes:
- Remove BUILD macro, call CheckForException directly only for function
  calls and throws.
- Split CheckForException into a fast inline path and a slow non-inline
  one.
- Move BUILD's DCHECK into CHECK_INTERFACE.
- Add an early exit to Decode().
- Since we do not need the hack anymore, implement CallBuiltin properly.

Change-Id: I38e3c73e0af80894584ce37e2f3bfc90111ac54f
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2717304
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@{#73036}
parent 43648c5b
......@@ -204,18 +204,10 @@ class WasmGraphAssembler : public GraphAssembler {
template <typename... Args>
Node* CallBuiltin(Builtins::Name name, Args*... args) {
// We would like to use gasm_->Call() to implement this method,
// but this doesn't work currently when we try to call it from functions
// which set IfSuccess/IfFailure control paths (e.g. within Throw()).
// TODO(manoskouk): Maybe clean this up at some point and unite with
// CallRuntimeStub?
auto* call_descriptor = GetBuiltinCallDescriptor(
name, temp_zone(), StubCallMode::kCallBuiltinPointer);
Node* call_target = GetBuiltinPointerTarget(name);
Node* call = graph()->NewNode(mcgraph()->common()->Call(call_descriptor),
call_target, args..., effect(), control());
InitializeEffectControl(call, control());
return call;
return Call(call_descriptor, call_target, args...);
}
void EnsureEnd() {
......
......@@ -2176,7 +2176,11 @@ MemoryAccessImmediate<validate>::MemoryAccessImmediate(
: MemoryAccessImmediate(decoder, pc, max_alignment,
decoder->module_->is_memory64) {}
#define CALL_INTERFACE(name, ...) interface_.name(this, ##__VA_ARGS__)
#define CALL_INTERFACE(name, ...) \
do { \
DCHECK(this->ok()); \
interface_.name(this, ##__VA_ARGS__); \
} while (false)
#define CALL_INTERFACE_IF_REACHABLE(name, ...) \
do { \
DCHECK(!control_.empty()); \
......@@ -2227,6 +2231,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
uint32_t params_count = static_cast<uint32_t>(this->num_locals());
uint32_t locals_length;
this->DecodeLocals(this->pc(), &locals_length, params_count);
if (this->failed()) return TraceFailed();
this->consume_bytes(locals_length);
for (uint32_t index = params_count; index < this->num_locals(); index++) {
if (!VALIDATE(this->local_type(index).is_defaultable())) {
......@@ -4770,7 +4775,8 @@ class WasmFullDecoder : public WasmDecoder<validate> {
this->end_ = this->pc_; // Terminate decoding loop.
this->current_code_reachable_ = false;
TRACE(" !%s\n", this->error_.message().c_str());
CALL_INTERFACE(OnFirstError);
// Cannot use CALL_INTERFACE here because it checks if this->ok().
interface_.OnFirstError(this);
}
int BuildSimplePrototypeOperator(WasmOpcode opcode) {
......
......@@ -67,12 +67,6 @@ struct SsaEnv : public ZoneObject {
}
};
#define BUILD(func, ...) \
([&] { \
DCHECK(decoder->ok()); \
return CheckForException(decoder, builder_->func(__VA_ARGS__)); \
})()
constexpr uint32_t kNullCatch = static_cast<uint32_t>(-1);
class WasmGraphBuildingInterface {
......@@ -147,7 +141,7 @@ class WasmGraphBuildingInterface {
}
LoadContextIntoSsa(ssa_env);
if (FLAG_trace_wasm) BUILD(TraceFunctionEntry, decoder->position());
if (FLAG_trace_wasm) builder_->TraceFunctionEntry(decoder->position());
}
// Reload the instance cache entries into the Ssa Environment.
......@@ -256,7 +250,7 @@ class WasmGraphBuildingInterface {
void If(FullDecoder* decoder, const Value& cond, Control* if_block) {
TFNode* if_true = nullptr;
TFNode* if_false = nullptr;
BUILD(BranchNoHint, cond.node, &if_true, &if_false);
builder_->BranchNoHint(cond.node, &if_true, &if_false);
SsaEnv* end_env = ssa_env_;
SsaEnv* false_env = Split(decoder->zone(), ssa_env_);
false_env->control = if_false;
......@@ -310,13 +304,13 @@ class WasmGraphBuildingInterface {
void UnOp(FullDecoder* decoder, WasmOpcode opcode, const Value& value,
Value* result) {
result->node = BUILD(Unop, opcode, value.node, decoder->position());
result->node = builder_->Unop(opcode, value.node, decoder->position());
}
void BinOp(FullDecoder* decoder, WasmOpcode opcode, const Value& lhs,
const Value& rhs, Value* result) {
TFNode* node =
BUILD(Binop, opcode, lhs.node, rhs.node, decoder->position());
builder_->Binop(opcode, lhs.node, rhs.node, decoder->position());
if (result) result->node = node;
}
......@@ -346,11 +340,11 @@ class WasmGraphBuildingInterface {
}
void RefFunc(FullDecoder* decoder, uint32_t function_index, Value* result) {
result->node = BUILD(RefFunc, function_index);
result->node = builder_->RefFunc(function_index);
}
void RefAsNonNull(FullDecoder* decoder, const Value& arg, Value* result) {
result->node = BUILD(RefAsNonNull, arg.node, decoder->position());
result->node = builder_->RefAsNonNull(arg.node, decoder->position());
}
void Drop(FullDecoder* decoder) {}
......@@ -386,22 +380,23 @@ class WasmGraphBuildingInterface {
void GlobalGet(FullDecoder* decoder, Value* result,
const GlobalIndexImmediate<validate>& imm) {
result->node = BUILD(GlobalGet, imm.index);
result->node = builder_->GlobalGet(imm.index);
}
void GlobalSet(FullDecoder* decoder, const Value& value,
const GlobalIndexImmediate<validate>& imm) {
BUILD(GlobalSet, imm.index, value.node);
builder_->GlobalSet(imm.index, value.node);
}
void TableGet(FullDecoder* decoder, const Value& index, Value* result,
const TableIndexImmediate<validate>& imm) {
result->node = BUILD(TableGet, imm.index, index.node, decoder->position());
result->node =
builder_->TableGet(imm.index, index.node, decoder->position());
}
void TableSet(FullDecoder* decoder, const Value& index, const Value& value,
const TableIndexImmediate<validate>& imm) {
BUILD(TableSet, imm.index, index.node, value.node, decoder->position());
builder_->TableSet(imm.index, index.node, value.node, decoder->position());
}
void Unreachable(FullDecoder* decoder) {
......@@ -410,7 +405,7 @@ class WasmGraphBuildingInterface {
BuildNestedLoopExits(decoder, decoder->control_depth() - 1, false,
values);
}
BUILD(Trap, wasm::TrapReason::kTrapUnreachable, decoder->position());
builder_->Trap(wasm::TrapReason::kTrapUnreachable, decoder->position());
}
void NopForTestingUnsupportedInLiftoff(FullDecoder* decoder) {}
......@@ -418,10 +413,10 @@ class WasmGraphBuildingInterface {
void Select(FullDecoder* decoder, const Value& cond, const Value& fval,
const Value& tval, Value* result) {
TFNode* controls[2];
BUILD(BranchNoHint, cond.node, &controls[0], &controls[1]);
TFNode* merge = BUILD(Merge, 2, controls);
builder_->BranchNoHint(cond.node, &controls[0], &controls[1]);
TFNode* merge = builder_->Merge(2, controls);
TFNode* inputs[] = {tval.node, fval.node, merge};
TFNode* phi = BUILD(Phi, tval.type, 2, inputs);
TFNode* phi = builder_->Phi(tval.type, 2, inputs);
result->node = phi;
builder_->SetControl(merge);
}
......@@ -452,9 +447,9 @@ class WasmGraphBuildingInterface {
GetNodes(values.begin(), stack_base, ret_count);
}
if (FLAG_trace_wasm) {
BUILD(TraceFunctionExit, VectorOf(values), decoder->position());
builder_->TraceFunctionExit(VectorOf(values), decoder->position());
}
BUILD(Return, VectorOf(values));
builder_->Return(VectorOf(values));
SetEnv(internal_env);
}
......@@ -483,7 +478,7 @@ class WasmGraphBuildingInterface {
SsaEnv* fenv = ssa_env_;
SsaEnv* tenv = Split(decoder->zone(), fenv);
fenv->SetNotMerged();
BUILD(BranchNoHint, cond.node, &tenv->control, &fenv->control);
builder_->BranchNoHint(cond.node, &tenv->control, &fenv->control);
builder_->SetControl(fenv->control);
SetEnv(tenv);
BrOrRet(decoder, depth);
......@@ -501,7 +496,7 @@ class WasmGraphBuildingInterface {
SsaEnv* branch_env = ssa_env_;
// Build branches to the various blocks based on the table.
TFNode* sw = BUILD(Switch, imm.table_count + 1, key.node);
TFNode* sw = builder_->Switch(imm.table_count + 1, key.node);
SsaEnv* copy = Steal(decoder->zone(), branch_env);
SetEnv(copy);
......@@ -510,8 +505,8 @@ class WasmGraphBuildingInterface {
uint32_t i = iterator.cur_index();
uint32_t target = iterator.next();
SetEnv(Split(decoder->zone(), copy));
builder_->SetControl(i == imm.table_count ? BUILD(IfDefault, sw)
: BUILD(IfValue, i, sw));
builder_->SetControl(i == imm.table_count ? builder_->IfDefault(sw)
: builder_->IfValue(i, sw));
BrOrRet(decoder, target);
}
DCHECK(decoder->ok());
......@@ -529,54 +524,55 @@ class WasmGraphBuildingInterface {
void Prefetch(FullDecoder* decoder,
const MemoryAccessImmediate<validate>& imm, const Value& index,
bool temporal) {
BUILD(Prefetch, index.node, imm.offset, imm.alignment, temporal);
builder_->Prefetch(index.node, imm.offset, imm.alignment, temporal);
}
void LoadMem(FullDecoder* decoder, LoadType type,
const MemoryAccessImmediate<validate>& imm, const Value& index,
Value* result) {
result->node =
BUILD(LoadMem, type.value_type(), type.mem_type(), index.node,
imm.offset, imm.alignment, decoder->position());
builder_->LoadMem(type.value_type(), type.mem_type(), index.node,
imm.offset, imm.alignment, decoder->position());
}
void LoadTransform(FullDecoder* decoder, LoadType type,
LoadTransformationKind transform,
const MemoryAccessImmediate<validate>& imm,
const Value& index, Value* result) {
result->node =
BUILD(LoadTransform, type.value_type(), type.mem_type(), transform,
index.node, imm.offset, imm.alignment, decoder->position());
result->node = builder_->LoadTransform(type.value_type(), type.mem_type(),
transform, index.node, imm.offset,
imm.alignment, decoder->position());
}
void LoadLane(FullDecoder* decoder, LoadType type, const Value& value,
const Value& index, const MemoryAccessImmediate<validate>& imm,
const uint8_t laneidx, Value* result) {
result->node = BUILD(LoadLane, type.value_type(), type.mem_type(),
value.node, index.node, imm.offset, imm.alignment,
laneidx, decoder->position());
result->node = builder_->LoadLane(
type.value_type(), type.mem_type(), value.node, index.node, imm.offset,
imm.alignment, laneidx, decoder->position());
}
void StoreMem(FullDecoder* decoder, StoreType type,
const MemoryAccessImmediate<validate>& imm, const Value& index,
const Value& value) {
BUILD(StoreMem, type.mem_rep(), index.node, imm.offset, imm.alignment,
value.node, decoder->position(), type.value_type());
builder_->StoreMem(type.mem_rep(), index.node, imm.offset, imm.alignment,
value.node, decoder->position(), type.value_type());
}
void StoreLane(FullDecoder* decoder, StoreType type,
const MemoryAccessImmediate<validate>& imm, const Value& index,
const Value& value, const uint8_t laneidx) {
BUILD(StoreLane, type.mem_rep(), index.node, imm.offset, imm.alignment,
value.node, laneidx, decoder->position(), type.value_type());
builder_->StoreLane(type.mem_rep(), index.node, imm.offset, imm.alignment,
value.node, laneidx, decoder->position(),
type.value_type());
}
void CurrentMemoryPages(FullDecoder* decoder, Value* result) {
result->node = BUILD(CurrentMemoryPages);
result->node = builder_->CurrentMemoryPages();
}
void MemoryGrow(FullDecoder* decoder, const Value& value, Value* result) {
result->node = BUILD(MemoryGrow, value.node);
result->node = builder_->MemoryGrow(value.node);
// Always reload the instance cache after growing memory.
LoadContextIntoSsa(ssa_env_);
}
......@@ -637,8 +633,8 @@ class WasmGraphBuildingInterface {
SsaEnv* non_null_env = ssa_env_;
SsaEnv* null_env = Split(decoder->zone(), non_null_env);
non_null_env->SetNotMerged();
BUILD(BrOnNull, ref_object.node, &null_env->control,
&non_null_env->control);
builder_->BrOnNull(ref_object.node, &null_env->control,
&non_null_env->control);
builder_->SetControl(non_null_env->control);
SetEnv(null_env);
BrOrRet(decoder, depth);
......@@ -649,7 +645,7 @@ class WasmGraphBuildingInterface {
Value* result) {
NodeVector inputs(args.size());
GetNodes(inputs.begin(), args);
TFNode* node = BUILD(SimdOp, opcode, inputs.begin());
TFNode* node = builder_->SimdOp(opcode, inputs.begin());
if (result) result->node = node;
}
......@@ -658,7 +654,7 @@ class WasmGraphBuildingInterface {
Value* result) {
NodeVector nodes(inputs.size());
GetNodes(nodes.begin(), inputs);
result->node = BUILD(SimdLaneOp, opcode, imm.lane, nodes.begin());
result->node = builder_->SimdLaneOp(opcode, imm.lane, nodes.begin());
}
void Simd8x16ShuffleOp(FullDecoder* decoder,
......@@ -666,7 +662,7 @@ class WasmGraphBuildingInterface {
const Value& input0, const Value& input1,
Value* result) {
TFNode* input_nodes[] = {input0.node, input1.node};
result->node = BUILD(Simd8x16ShuffleOp, imm.value, input_nodes);
result->node = builder_->Simd8x16ShuffleOp(imm.value, input_nodes);
}
void Throw(FullDecoder* decoder, const ExceptionIndexImmediate<validate>& imm,
......@@ -676,7 +672,9 @@ class WasmGraphBuildingInterface {
for (int i = 0; i < count; ++i) {
args[i] = value_args[i].node;
}
BUILD(Throw, imm.index, imm.exception, VectorOf(args), decoder->position());
CheckForException(decoder,
builder_->Throw(imm.index, imm.exception, VectorOf(args),
decoder->position()));
TerminateThrow(decoder);
}
......@@ -685,7 +683,7 @@ class WasmGraphBuildingInterface {
block->is_try_unwind());
TFNode* exception = block->try_info->exception;
DCHECK_NOT_NULL(exception);
BUILD(Rethrow, exception);
CheckForException(decoder, builder_->Rethrow(exception));
TerminateThrow(decoder);
}
......@@ -711,10 +709,10 @@ class WasmGraphBuildingInterface {
TFNode* if_no_catch = nullptr;
// Get the exception tag and see if it matches the expected one.
TFNode* caught_tag = BUILD(GetExceptionTag, exception);
TFNode* exception_tag = BUILD(LoadExceptionTagFromTable, imm.index);
TFNode* compare = BUILD(ExceptionTagEqual, caught_tag, exception_tag);
BUILD(BranchNoHint, compare, &if_catch, &if_no_catch);
TFNode* caught_tag = builder_->GetExceptionTag(exception);
TFNode* exception_tag = builder_->LoadExceptionTagFromTable(imm.index);
TFNode* compare = builder_->ExceptionTagEqual(caught_tag, exception_tag);
builder_->BranchNoHint(compare, &if_catch, &if_no_catch);
// If the tags don't match we continue with the next tag by setting the
// false environment as the new {TryInfo::catch_env} here.
......@@ -729,7 +727,7 @@ class WasmGraphBuildingInterface {
SetEnv(if_catch_env);
NodeVector caught_values(values.size());
Vector<TFNode*> caught_vector = VectorOf(caught_values);
BUILD(GetExceptionValues, exception, imm.exception, caught_vector);
builder_->GetExceptionValues(exception, imm.exception, caught_vector);
for (size_t i = 0, e = values.size(); i < e; ++i) {
values[i].node = caught_values[i];
}
......@@ -743,6 +741,8 @@ class WasmGraphBuildingInterface {
// Merge the current env into the target handler's env.
SetEnv(block->try_info->catch_env);
if (depth == decoder->control_depth() - 1) {
// We just throw to the caller here, so no need to generate IfSuccess
// and IfFailure nodes.
builder_->Rethrow(block->try_info->exception);
TerminateThrow(decoder);
current_catch_ = block->previous_catch;
......@@ -792,65 +792,65 @@ class WasmGraphBuildingInterface {
const MemoryAccessImmediate<validate>& imm, Value* result) {
NodeVector inputs(args.size());
GetNodes(inputs.begin(), args);
TFNode* node = BUILD(AtomicOp, opcode, inputs.begin(), imm.alignment,
imm.offset, decoder->position());
TFNode* node = builder_->AtomicOp(opcode, inputs.begin(), imm.alignment,
imm.offset, decoder->position());
if (result) result->node = node;
}
void AtomicFence(FullDecoder* decoder) { BUILD(AtomicFence); }
void AtomicFence(FullDecoder* decoder) { builder_->AtomicFence(); }
void MemoryInit(FullDecoder* decoder,
const MemoryInitImmediate<validate>& imm, const Value& dst,
const Value& src, const Value& size) {
BUILD(MemoryInit, imm.data_segment_index, dst.node, src.node, size.node,
decoder->position());
builder_->MemoryInit(imm.data_segment_index, dst.node, src.node, size.node,
decoder->position());
}
void DataDrop(FullDecoder* decoder, const DataDropImmediate<validate>& imm) {
BUILD(DataDrop, imm.index, decoder->position());
builder_->DataDrop(imm.index, decoder->position());
}
void MemoryCopy(FullDecoder* decoder,
const MemoryCopyImmediate<validate>& imm, const Value& dst,
const Value& src, const Value& size) {
BUILD(MemoryCopy, dst.node, src.node, size.node, decoder->position());
builder_->MemoryCopy(dst.node, src.node, size.node, decoder->position());
}
void MemoryFill(FullDecoder* decoder,
const MemoryIndexImmediate<validate>& imm, const Value& dst,
const Value& value, const Value& size) {
BUILD(MemoryFill, dst.node, value.node, size.node, decoder->position());
builder_->MemoryFill(dst.node, value.node, size.node, decoder->position());
}
void TableInit(FullDecoder* decoder, const TableInitImmediate<validate>& imm,
Vector<Value> args) {
BUILD(TableInit, imm.table.index, imm.elem_segment_index, args[0].node,
args[1].node, args[2].node, decoder->position());
builder_->TableInit(imm.table.index, imm.elem_segment_index, args[0].node,
args[1].node, args[2].node, decoder->position());
}
void ElemDrop(FullDecoder* decoder, const ElemDropImmediate<validate>& imm) {
BUILD(ElemDrop, imm.index, decoder->position());
builder_->ElemDrop(imm.index, decoder->position());
}
void TableCopy(FullDecoder* decoder, const TableCopyImmediate<validate>& imm,
Vector<Value> args) {
BUILD(TableCopy, imm.table_dst.index, imm.table_src.index, args[0].node,
args[1].node, args[2].node, decoder->position());
builder_->TableCopy(imm.table_dst.index, imm.table_src.index, args[0].node,
args[1].node, args[2].node, decoder->position());
}
void TableGrow(FullDecoder* decoder, const TableIndexImmediate<validate>& imm,
const Value& value, const Value& delta, Value* result) {
result->node = BUILD(TableGrow, imm.index, value.node, delta.node);
result->node = builder_->TableGrow(imm.index, value.node, delta.node);
}
void TableSize(FullDecoder* decoder, const TableIndexImmediate<validate>& imm,
Value* result) {
result->node = BUILD(TableSize, imm.index);
result->node = builder_->TableSize(imm.index);
}
void TableFill(FullDecoder* decoder, const TableIndexImmediate<validate>& imm,
const Value& start, const Value& value, const Value& count) {
BUILD(TableFill, imm.index, start.node, value.node, count.node);
builder_->TableFill(imm.index, start.node, value.node, count.node);
}
void StructNewWithRtt(FullDecoder* decoder,
......@@ -861,8 +861,8 @@ class WasmGraphBuildingInterface {
for (uint32_t i = 0; i < field_count; i++) {
arg_nodes[i] = args[i].node;
}
result->node = BUILD(StructNewWithRtt, imm.index, imm.struct_type, rtt.node,
VectorOf(arg_nodes));
result->node = builder_->StructNewWithRtt(imm.index, imm.struct_type,
rtt.node, VectorOf(arg_nodes));
}
void StructNewDefault(FullDecoder* decoder,
const StructIndexImmediate<validate>& imm,
......@@ -872,8 +872,8 @@ class WasmGraphBuildingInterface {
for (uint32_t i = 0; i < field_count; i++) {
arg_nodes[i] = DefaultValue(imm.struct_type->field(i));
}
result->node = BUILD(StructNewWithRtt, imm.index, imm.struct_type, rtt.node,
VectorOf(arg_nodes));
result->node = builder_->StructNewWithRtt(imm.index, imm.struct_type,
rtt.node, VectorOf(arg_nodes));
}
void StructGet(FullDecoder* decoder, const Value& struct_object,
......@@ -882,9 +882,9 @@ class WasmGraphBuildingInterface {
CheckForNull null_check = struct_object.type.is_nullable()
? CheckForNull::kWithNullCheck
: CheckForNull::kWithoutNullCheck;
result->node =
BUILD(StructGet, struct_object.node, field.struct_index.struct_type,
field.index, null_check, is_signed, decoder->position());
result->node = builder_->StructGet(
struct_object.node, field.struct_index.struct_type, field.index,
null_check, is_signed, decoder->position());
}
void StructSet(FullDecoder* decoder, const Value& struct_object,
......@@ -893,17 +893,18 @@ class WasmGraphBuildingInterface {
CheckForNull null_check = struct_object.type.is_nullable()
? CheckForNull::kWithNullCheck
: CheckForNull::kWithoutNullCheck;
BUILD(StructSet, struct_object.node, field.struct_index.struct_type,
field.index, field_value.node, null_check, decoder->position());
builder_->StructSet(struct_object.node, field.struct_index.struct_type,
field.index, field_value.node, null_check,
decoder->position());
}
void ArrayNewWithRtt(FullDecoder* decoder,
const ArrayIndexImmediate<validate>& imm,
const Value& length, const Value& initial_value,
const Value& rtt, Value* result) {
result->node =
BUILD(ArrayNewWithRtt, imm.index, imm.array_type, length.node,
initial_value.node, rtt.node, decoder->position());
result->node = builder_->ArrayNewWithRtt(imm.index, imm.array_type,
length.node, initial_value.node,
rtt.node, decoder->position());
}
void ArrayNewDefault(FullDecoder* decoder,
......@@ -911,8 +912,8 @@ class WasmGraphBuildingInterface {
const Value& length, const Value& rtt, Value* result) {
TFNode* initial_value = DefaultValue(imm.array_type->element_type());
result->node =
BUILD(ArrayNewWithRtt, imm.index, imm.array_type, length.node,
initial_value, rtt.node, decoder->position());
builder_->ArrayNewWithRtt(imm.index, imm.array_type, length.node,
initial_value, rtt.node, decoder->position());
}
void ArrayGet(FullDecoder* decoder, const Value& array_obj,
......@@ -921,8 +922,9 @@ class WasmGraphBuildingInterface {
CheckForNull null_check = array_obj.type.is_nullable()
? CheckForNull::kWithNullCheck
: CheckForNull::kWithoutNullCheck;
result->node = BUILD(ArrayGet, array_obj.node, imm.array_type, index.node,
null_check, is_signed, decoder->position());
result->node =
builder_->ArrayGet(array_obj.node, imm.array_type, index.node,
null_check, is_signed, decoder->position());
}
void ArraySet(FullDecoder* decoder, const Value& array_obj,
......@@ -931,8 +933,8 @@ class WasmGraphBuildingInterface {
CheckForNull null_check = array_obj.type.is_nullable()
? CheckForNull::kWithNullCheck
: CheckForNull::kWithoutNullCheck;
BUILD(ArraySet, array_obj.node, imm.array_type, index.node, value.node,
null_check, decoder->position());
builder_->ArraySet(array_obj.node, imm.array_type, index.node, value.node,
null_check, decoder->position());
}
void ArrayLen(FullDecoder* decoder, const Value& array_obj, Value* result) {
......@@ -940,28 +942,28 @@ class WasmGraphBuildingInterface {
? CheckForNull::kWithNullCheck
: CheckForNull::kWithoutNullCheck;
result->node =
BUILD(ArrayLen, array_obj.node, null_check, decoder->position());
builder_->ArrayLen(array_obj.node, null_check, decoder->position());
}
void I31New(FullDecoder* decoder, const Value& input, Value* result) {
result->node = BUILD(I31New, input.node);
result->node = builder_->I31New(input.node);
}
void I31GetS(FullDecoder* decoder, const Value& input, Value* result) {
result->node = BUILD(I31GetS, input.node);
result->node = builder_->I31GetS(input.node);
}
void I31GetU(FullDecoder* decoder, const Value& input, Value* result) {
result->node = BUILD(I31GetU, input.node);
result->node = builder_->I31GetU(input.node);
}
void RttCanon(FullDecoder* decoder, uint32_t type_index, Value* result) {
result->node = BUILD(RttCanon, type_index);
result->node = builder_->RttCanon(type_index);
}
void RttSub(FullDecoder* decoder, uint32_t type_index, const Value& parent,
Value* result) {
result->node = BUILD(RttSub, type_index, parent.node);
result->node = builder_->RttSub(type_index, parent.node);
}
using StaticKnowledge = compiler::WasmGraphBuilder::ObjectReferenceKnowledge;
......@@ -985,7 +987,7 @@ class WasmGraphBuildingInterface {
Value* result) {
StaticKnowledge config =
ComputeStaticKnowledge(object.type, rtt.type, decoder->module_);
result->node = BUILD(RefTest, object.node, rtt.node, config);
result->node = builder_->RefTest(object.node, rtt.node, config);
}
void RefCast(FullDecoder* decoder, const Value& object, const Value& rtt,
......@@ -993,7 +995,7 @@ class WasmGraphBuildingInterface {
StaticKnowledge config =
ComputeStaticKnowledge(object.type, rtt.type, decoder->module_);
result->node =
BUILD(RefCast, object.node, rtt.node, config, decoder->position());
builder_->RefCast(object.node, rtt.node, config, decoder->position());
}
template <TFNode* (compiler::WasmGraphBuilder::*branch_function)(
......@@ -1006,12 +1008,9 @@ class WasmGraphBuildingInterface {
SsaEnv* match_env = Split(decoder->zone(), ssa_env_);
SsaEnv* no_match_env = Steal(decoder->zone(), ssa_env_);
no_match_env->SetNotMerged();
DCHECK(decoder->ok());
CheckForException(
decoder,
(builder_->*branch_function)(
object.node, rtt.node, config, &match_env->control,
&match_env->effect, &no_match_env->control, &no_match_env->effect));
(builder_->*branch_function)(object.node, rtt.node, config,
&match_env->control, &match_env->effect,
&no_match_env->control, &no_match_env->effect);
builder_->SetControl(no_match_env->control);
SetEnv(match_env);
value_on_branch->node = object.node;
......@@ -1026,12 +1025,12 @@ class WasmGraphBuildingInterface {
}
void RefIsData(FullDecoder* decoder, const Value& object, Value* result) {
result->node = BUILD(RefIsData, object.node, object.type.is_nullable());
result->node = builder_->RefIsData(object.node, object.type.is_nullable());
}
void RefAsData(FullDecoder* decoder, const Value& object, Value* result) {
result->node = BUILD(RefAsData, object.node, object.type.is_nullable(),
decoder->position());
result->node = builder_->RefAsData(object.node, object.type.is_nullable(),
decoder->position());
}
void BrOnData(FullDecoder* decoder, const Value& object,
......@@ -1042,12 +1041,12 @@ class WasmGraphBuildingInterface {
}
void RefIsFunc(FullDecoder* decoder, const Value& object, Value* result) {
result->node = BUILD(RefIsFunc, object.node, object.type.is_nullable());
result->node = builder_->RefIsFunc(object.node, object.type.is_nullable());
}
void RefAsFunc(FullDecoder* decoder, const Value& object, Value* result) {
result->node = BUILD(RefAsFunc, object.node, object.type.is_nullable(),
decoder->position());
result->node = builder_->RefAsFunc(object.node, object.type.is_nullable(),
decoder->position());
}
void BrOnFunc(FullDecoder* decoder, const Value& object,
......@@ -1058,11 +1057,11 @@ class WasmGraphBuildingInterface {
}
void RefIsI31(FullDecoder* decoder, const Value& object, Value* result) {
result->node = BUILD(RefIsI31, object.node);
result->node = builder_->RefIsI31(object.node);
}
void RefAsI31(FullDecoder* decoder, const Value& object, Value* result) {
result->node = BUILD(RefAsI31, object.node, decoder->position());
result->node = builder_->RefAsI31(object.node, decoder->position());
}
void BrOnI31(FullDecoder* decoder, const Value& object,
......@@ -1144,13 +1143,17 @@ class WasmGraphBuildingInterface {
builder_->set_instance_cache(&env->instance_cache);
}
TFNode* CheckForException(FullDecoder* decoder, TFNode* node) {
V8_INLINE TFNode* CheckForException(FullDecoder* decoder, TFNode* node) {
if (node == nullptr) return nullptr;
const bool inside_try_scope = current_catch_ != kNullCatch;
if (!inside_try_scope) return node;
return CheckForExceptionImpl(decoder, node);
}
V8_NOINLINE TFNode* CheckForExceptionImpl(FullDecoder* decoder,
TFNode* node) {
TFNode* if_success = nullptr;
TFNode* if_exception = nullptr;
if (!builder_->ThrowsException(node, &if_success, &if_exception)) {
......@@ -1371,16 +1374,22 @@ class WasmGraphBuildingInterface {
}
switch (call_mode) {
case kCallIndirect:
BUILD(CallIndirect, table_index, sig_index, VectorOf(arg_nodes),
VectorOf(return_nodes), decoder->position());
CheckForException(decoder,
builder_->CallIndirect(
table_index, sig_index, VectorOf(arg_nodes),
VectorOf(return_nodes), decoder->position()));
break;
case kCallDirect:
BUILD(CallDirect, sig_index, VectorOf(arg_nodes),
VectorOf(return_nodes), decoder->position());
CheckForException(
decoder,
builder_->CallDirect(sig_index, VectorOf(arg_nodes),
VectorOf(return_nodes), decoder->position()));
break;
case kCallRef:
BUILD(CallRef, sig_index, VectorOf(arg_nodes), VectorOf(return_nodes),
null_check, decoder->position());
CheckForException(decoder,
builder_->CallRef(sig_index, VectorOf(arg_nodes),
VectorOf(return_nodes), null_check,
decoder->position()));
break;
}
for (size_t i = 0; i < return_count; ++i) {
......@@ -1403,21 +1412,26 @@ class WasmGraphBuildingInterface {
}
switch (call_mode) {
case kCallIndirect:
BUILD(ReturnCallIndirect, table_index, sig_index, VectorOf(arg_nodes),
decoder->position());
CheckForException(decoder,
builder_->ReturnCallIndirect(table_index, sig_index,
VectorOf(arg_nodes),
decoder->position()));
break;
case kCallDirect:
BUILD(ReturnCall, sig_index, VectorOf(arg_nodes), decoder->position());
CheckForException(decoder,
builder_->ReturnCall(sig_index, VectorOf(arg_nodes),
decoder->position()));
break;
case kCallRef:
BUILD(ReturnCallRef, sig_index, VectorOf(arg_nodes), null_check,
decoder->position());
CheckForException(
decoder, builder_->ReturnCallRef(sig_index, VectorOf(arg_nodes),
null_check, decoder->position()));
break;
}
}
void BuildLoopExits(FullDecoder* decoder, Control* loop) {
BUILD(LoopExit, loop->loop_node);
builder_->LoopExit(loop->loop_node);
ssa_env_->control = control();
ssa_env_->effect = effect();
}
......@@ -1514,8 +1528,6 @@ DecodeResult BuildTFGraph(AccountingAllocator* allocator,
return decoder.toResult(nullptr);
}
#undef BUILD
} // namespace wasm
} // namespace internal
} // namespace v8
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