diff options
Diffstat (limited to 'chromium/v8/src/wasm/graph-builder-interface.cc')
-rw-r--r-- | chromium/v8/src/wasm/graph-builder-interface.cc | 142 |
1 files changed, 74 insertions, 68 deletions
diff --git a/chromium/v8/src/wasm/graph-builder-interface.cc b/chromium/v8/src/wasm/graph-builder-interface.cc index 5d23dbf1836..dc8cbf20f05 100644 --- a/chromium/v8/src/wasm/graph-builder-interface.cc +++ b/chromium/v8/src/wasm/graph-builder-interface.cc @@ -16,7 +16,7 @@ #include "src/wasm/wasm-limits.h" #include "src/wasm/wasm-linkage.h" #include "src/wasm/wasm-module.h" -#include "src/wasm/wasm-opcodes.h" +#include "src/wasm/wasm-opcodes-inl.h" namespace v8 { namespace internal { @@ -28,18 +28,33 @@ namespace { // as well as the current effect and control dependency in the TF graph. // It maintains a control state that tracks whether the environment // is reachable, has reached a control end, or has been merged. -struct SsaEnv { +struct SsaEnv : public ZoneObject { enum State { kControlEnd, kUnreachable, kReached, kMerged }; State state; TFNode* control; TFNode* effect; compiler::WasmInstanceCacheNodes instance_cache; - TFNode** locals; + ZoneVector<TFNode*> locals; + + SsaEnv(Zone* zone, State state, TFNode* control, TFNode* effect, + uint32_t locals_size) + : state(state), control(control), effect(effect), locals(zone) { + if (locals_size > 0) locals.resize(locals_size); + } + + SsaEnv(const SsaEnv& other) V8_NOEXCEPT = default; + SsaEnv(SsaEnv&& other) V8_NOEXCEPT : state(other.state), + control(other.control), + effect(other.effect), + instance_cache(other.instance_cache), + locals(std::move(other.locals)) { + other.Kill(kUnreachable); + } void Kill(State new_state = kControlEnd) { state = new_state; - locals = nullptr; + locals.clear(); control = nullptr; effect = nullptr; instance_cache = {}; @@ -98,22 +113,14 @@ class WasmGraphBuildingInterface { : builder_(builder) {} void StartFunction(FullDecoder* decoder) { - SsaEnv* ssa_env = - reinterpret_cast<SsaEnv*>(decoder->zone()->New(sizeof(SsaEnv))); - uint32_t num_locals = decoder->num_locals(); - uint32_t env_count = num_locals; - size_t size = sizeof(TFNode*) * env_count; - ssa_env->state = SsaEnv::kReached; - ssa_env->locals = - size > 0 ? reinterpret_cast<TFNode**>(decoder->zone()->New(size)) - : nullptr; - // The first '+ 1' is needed by TF Start node, the second '+ 1' is for the // instance parameter. TFNode* start = builder_->Start( static_cast<int>(decoder->sig_->parameter_count() + 1 + 1)); - ssa_env->effect = start; - ssa_env->control = start; + uint32_t num_locals = decoder->num_locals(); + SsaEnv* ssa_env = new (decoder->zone()) + SsaEnv(decoder->zone(), SsaEnv::kReached, start, start, num_locals); + // Initialize effect and control before initializing the locals default // values (which might require instance loads) or loading the context. builder_->SetEffectControl(start); @@ -135,6 +142,8 @@ class WasmGraphBuildingInterface { } SetEnv(ssa_env); LoadContextIntoSsa(ssa_env); + + if (FLAG_trace_wasm) BUILD(TraceFunctionEntry, decoder->position()); } // Reload the instance cache entries into the Ssa Environment. @@ -174,7 +183,7 @@ class WasmGraphBuildingInterface { void Try(FullDecoder* decoder, Control* block) { SsaEnv* outer_env = ssa_env_; - SsaEnv* catch_env = Split(decoder, outer_env); + SsaEnv* catch_env = Split(decoder->zone(), outer_env); // Mark catch environment as unreachable, since only accessable // through catch unwinding (i.e. landing pads). catch_env->state = SsaEnv::kUnreachable; @@ -192,7 +201,7 @@ class WasmGraphBuildingInterface { TFNode* if_false = nullptr; BUILD(BranchNoHint, cond.node, &if_true, &if_false); SsaEnv* end_env = ssa_env_; - SsaEnv* false_env = Split(decoder, ssa_env_); + SsaEnv* false_env = Split(decoder->zone(), ssa_env_); false_env->control = if_false; SsaEnv* true_env = Steal(decoder->zone(), ssa_env_); true_env->control = if_true; @@ -232,7 +241,8 @@ class WasmGraphBuildingInterface { void BinOp(FullDecoder* decoder, WasmOpcode opcode, const Value& lhs, const Value& rhs, Value* result) { - auto node = BUILD(Binop, opcode, lhs.node, rhs.node, decoder->position()); + TFNode* node = + BUILD(Binop, opcode, lhs.node, rhs.node, decoder->position()); if (result) result->node = node; } @@ -269,28 +279,41 @@ class WasmGraphBuildingInterface { void DoReturn(FullDecoder* decoder, Vector<Value> values) { base::SmallVector<TFNode*, 8> nodes(values.size()); GetNodes(nodes.begin(), values); + if (FLAG_trace_wasm) { + BUILD(TraceFunctionExit, VectorOf(nodes), decoder->position()); + } BUILD(Return, VectorOf(nodes)); } void LocalGet(FullDecoder* decoder, Value* result, const LocalIndexImmediate<validate>& imm) { - if (!ssa_env_->locals) return; // unreachable result->node = ssa_env_->locals[imm.index]; } void LocalSet(FullDecoder* decoder, const Value& value, const LocalIndexImmediate<validate>& imm) { - if (!ssa_env_->locals) return; // unreachable ssa_env_->locals[imm.index] = value.node; } void LocalTee(FullDecoder* decoder, const Value& value, Value* result, const LocalIndexImmediate<validate>& imm) { result->node = value.node; - if (!ssa_env_->locals) return; // unreachable ssa_env_->locals[imm.index] = value.node; } + void AllocateLocals(FullDecoder* decoder, Vector<Value> local_values) { + ZoneVector<TFNode*>* locals = &ssa_env_->locals; + locals->insert(locals->begin(), local_values.size(), nullptr); + for (uint32_t i = 0; i < local_values.size(); i++) { + (*locals)[i] = local_values[i].node; + } + } + + void DeallocateLocals(FullDecoder* decoder, uint32_t count) { + ZoneVector<TFNode*>* locals = &ssa_env_->locals; + locals->erase(locals->begin(), locals->begin() + count); + } + void GlobalGet(FullDecoder* decoder, Value* result, const GlobalIndexImmediate<validate>& imm) { result->node = BUILD(GlobalGet, imm.index); @@ -345,7 +368,7 @@ class WasmGraphBuildingInterface { void BrIf(FullDecoder* decoder, const Value& cond, uint32_t depth) { SsaEnv* fenv = ssa_env_; - SsaEnv* tenv = Split(decoder, fenv); + SsaEnv* tenv = Split(decoder->zone(), fenv); fenv->SetNotMerged(); BUILD(BranchNoHint, cond.node, &tenv->control, &fenv->control); builder_->SetControl(fenv->control); @@ -373,7 +396,7 @@ class WasmGraphBuildingInterface { while (iterator.has_next()) { uint32_t i = iterator.cur_index(); uint32_t target = iterator.next(); - SetEnv(Split(decoder, copy)); + SetEnv(Split(decoder->zone(), copy)); builder_->SetControl(i == imm.table_count ? BUILD(IfDefault, sw) : BUILD(IfValue, i, sw)); BrOrRet(decoder, target); @@ -452,7 +475,7 @@ class WasmGraphBuildingInterface { void BrOnNull(FullDecoder* decoder, const Value& ref_object, uint32_t depth) { SsaEnv* non_null_env = ssa_env_; - SsaEnv* null_env = Split(decoder, non_null_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); @@ -514,7 +537,7 @@ class WasmGraphBuildingInterface { TFNode* exception_tag = BUILD(LoadExceptionTagFromTable, imm.index); TFNode* compare = BUILD(ExceptionTagEqual, caught_tag, exception_tag); BUILD(BranchNoHint, compare, &if_match, &if_no_match); - SsaEnv* if_no_match_env = Split(decoder, ssa_env_); + SsaEnv* if_no_match_env = Split(decoder->zone(), ssa_env_); SsaEnv* if_match_env = Steal(decoder->zone(), ssa_env_); if_no_match_env->control = if_no_match; if_match_env->control = if_match; @@ -536,6 +559,7 @@ class WasmGraphBuildingInterface { void Catch(FullDecoder* decoder, Control* block, Value* exception) { DCHECK(block->is_try_catch()); + DCHECK_EQ(decoder->control_at(0), block); current_catch_ = block->previous_catch; // Pop try scope. @@ -543,7 +567,7 @@ class WasmGraphBuildingInterface { // exist. We only build a landing pad if some node in the try block can // (possibly) throw. Otherwise the catch environments remain empty. if (!block->try_info->might_throw()) { - block->reachability = kSpecOnlyReachable; + decoder->SetSucceedingCodeDynamicallyUnreachable(); return; } @@ -630,14 +654,15 @@ class WasmGraphBuildingInterface { } void StructGet(FullDecoder* decoder, const Value& struct_object, - const FieldIndexImmediate<validate>& field, Value* result) { + const FieldIndexImmediate<validate>& field, bool is_signed, + Value* result) { using CheckForNull = compiler::WasmGraphBuilder::CheckForNull; CheckForNull null_check = struct_object.type.kind() == ValueType::kRef ? CheckForNull::kWithoutNullCheck : CheckForNull::kWithNullCheck; result->node = BUILD(StructGet, struct_object.node, field.struct_index.struct_type, - field.index, null_check, decoder->position()); + field.index, null_check, is_signed, decoder->position()); } void StructSet(FullDecoder* decoder, const Value& struct_object, @@ -660,9 +685,9 @@ class WasmGraphBuildingInterface { void ArrayGet(FullDecoder* decoder, const Value& array_obj, const ArrayIndexImmediate<validate>& imm, const Value& index, - Value* result) { + bool is_signed, Value* result) { result->node = BUILD(ArrayGet, array_obj.node, imm.array_type, index.node, - decoder->position()); + is_signed, decoder->position()); } void ArraySet(FullDecoder* decoder, const Value& array_obj, @@ -676,6 +701,11 @@ class WasmGraphBuildingInterface { result->node = BUILD(ArrayLen, array_obj.node, decoder->position()); } + void RttCanon(FullDecoder* decoder, const TypeIndexImmediate<validate>& imm, + Value* result) { + result->node = BUILD(RttCanon, imm.index); + } + void PassThrough(FullDecoder* decoder, const Value& from, Value* to) { to->node = from.node; } @@ -755,7 +785,7 @@ class WasmGraphBuildingInterface { SsaEnv* success_env = Steal(decoder->zone(), ssa_env_); success_env->control = if_success; - SsaEnv* exception_env = Split(decoder, success_env); + SsaEnv* exception_env = Split(decoder->zone(), success_env); exception_env->control = if_exception; exception_env->effect = if_exception; SetEnv(exception_env); @@ -777,6 +807,8 @@ class WasmGraphBuildingInterface { TFNode* DefaultValue(ValueType type) { switch (type.kind()) { + case ValueType::kI8: + case ValueType::kI16: case ValueType::kI32: return builder_->Int32Constant(0); case ValueType::kI64: @@ -787,14 +819,12 @@ class WasmGraphBuildingInterface { return builder_->Float64Constant(0); case ValueType::kS128: return builder_->S128Zero(); - case ValueType::kAnyRef: - case ValueType::kFuncRef: - case ValueType::kNullRef: - case ValueType::kExnRef: case ValueType::kOptRef: - case ValueType::kEqRef: return builder_->RefNull(); - default: + case ValueType::kRtt: + case ValueType::kStmt: + case ValueType::kBottom: + case ValueType::kRef: UNREACHABLE(); } } @@ -920,7 +950,7 @@ class WasmGraphBuildingInterface { control()); } - SetEnv(Split(decoder, ssa_env_)); + SetEnv(Split(decoder->zone(), ssa_env_)); builder_->StackCheck(decoder->position()); return; } @@ -934,32 +964,19 @@ class WasmGraphBuildingInterface { // Conservatively introduce phis for instance cache. builder_->PrepareInstanceCacheForLoop(&ssa_env_->instance_cache, control()); - SetEnv(Split(decoder, ssa_env_)); + SetEnv(Split(decoder->zone(), ssa_env_)); builder_->StackCheck(decoder->position()); } // Create a complete copy of {from}. - SsaEnv* Split(FullDecoder* decoder, SsaEnv* from) { + SsaEnv* Split(Zone* zone, SsaEnv* from) { DCHECK_NOT_NULL(from); if (from == ssa_env_) { ssa_env_->control = control(); ssa_env_->effect = effect(); } - SsaEnv* result = - reinterpret_cast<SsaEnv*>(decoder->zone()->New(sizeof(SsaEnv))); - size_t size = sizeof(TFNode*) * decoder->num_locals(); - result->control = from->control; - result->effect = from->effect; - + SsaEnv* result = new (zone) SsaEnv(*from); result->state = SsaEnv::kReached; - if (size > 0) { - result->locals = reinterpret_cast<TFNode**>(decoder->zone()->New(size)); - memcpy(result->locals, from->locals, size); - } else { - result->locals = nullptr; - } - result->instance_cache = from->instance_cache; - return result; } @@ -971,25 +988,14 @@ class WasmGraphBuildingInterface { ssa_env_->control = control(); ssa_env_->effect = effect(); } - SsaEnv* result = reinterpret_cast<SsaEnv*>(zone->New(sizeof(SsaEnv))); + SsaEnv* result = new (zone) SsaEnv(std::move(*from)); result->state = SsaEnv::kReached; - result->locals = from->locals; - result->control = from->control; - result->effect = from->effect; - result->instance_cache = from->instance_cache; - from->Kill(SsaEnv::kUnreachable); return result; } // Create an unreachable environment. SsaEnv* UnreachableEnv(Zone* zone) { - SsaEnv* result = reinterpret_cast<SsaEnv*>(zone->New(sizeof(SsaEnv))); - result->state = SsaEnv::kUnreachable; - result->control = nullptr; - result->effect = nullptr; - result->locals = nullptr; - result->instance_cache = {}; - return result; + return new (zone) SsaEnv(zone, SsaEnv::kUnreachable, nullptr, nullptr, 0); } void DoCall(FullDecoder* decoder, uint32_t table_index, TFNode* index_node, |