LCOV - code coverage report
Current view: top level - test/cctest/wasm - wasm-run-utils.h (source / functions) Hit Total Coverage
Test: app.info Lines: 107 110 97.3 %
Date: 2019-01-20 Functions: 414 516 80.2 %

          Line data    Source code
       1             : // Copyright 2016 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #ifndef WASM_RUN_UTILS_H
       6             : #define WASM_RUN_UTILS_H
       7             : 
       8             : #include <setjmp.h>
       9             : #include <stdint.h>
      10             : #include <stdlib.h>
      11             : #include <string.h>
      12             : #include <array>
      13             : #include <memory>
      14             : 
      15             : #include "src/base/utils/random-number-generator.h"
      16             : #include "src/compiler/compiler-source-position-table.h"
      17             : #include "src/compiler/graph-visualizer.h"
      18             : #include "src/compiler/int64-lowering.h"
      19             : #include "src/compiler/js-graph.h"
      20             : #include "src/compiler/node.h"
      21             : #include "src/compiler/pipeline.h"
      22             : #include "src/compiler/wasm-compiler.h"
      23             : #include "src/compiler/zone-stats.h"
      24             : #include "src/trap-handler/trap-handler.h"
      25             : #include "src/wasm/function-body-decoder.h"
      26             : #include "src/wasm/local-decl-encoder.h"
      27             : #include "src/wasm/wasm-code-manager.h"
      28             : #include "src/wasm/wasm-external-refs.h"
      29             : #include "src/wasm/wasm-interpreter.h"
      30             : #include "src/wasm/wasm-js.h"
      31             : #include "src/wasm/wasm-module.h"
      32             : #include "src/wasm/wasm-objects-inl.h"
      33             : #include "src/wasm/wasm-objects.h"
      34             : #include "src/wasm/wasm-opcodes.h"
      35             : #include "src/wasm/wasm-tier.h"
      36             : #include "src/zone/accounting-allocator.h"
      37             : #include "src/zone/zone.h"
      38             : 
      39             : #include "test/cctest/cctest.h"
      40             : #include "test/cctest/compiler/call-tester.h"
      41             : #include "test/cctest/compiler/graph-builder-tester.h"
      42             : #include "test/common/wasm/flag-utils.h"
      43             : 
      44             : namespace v8 {
      45             : namespace internal {
      46             : namespace wasm {
      47             : 
      48             : constexpr uint32_t kMaxFunctions = 10;
      49             : constexpr uint32_t kMaxGlobalsSize = 128;
      50             : 
      51             : using compiler::CallDescriptor;
      52             : using compiler::MachineTypeForC;
      53             : using compiler::Node;
      54             : 
      55             : // TODO(titzer): check traps more robustly in tests.
      56             : // Currently, in tests, we just return 0xDEADBEEF from the function in which
      57             : // the trap occurs if the runtime context is not available to throw a JavaScript
      58             : // exception.
      59             : #define CHECK_TRAP32(x) \
      60             :   CHECK_EQ(0xDEADBEEF, (bit_cast<uint32_t>(x)) & 0xFFFFFFFF)
      61             : #define CHECK_TRAP64(x) \
      62             :   CHECK_EQ(0xDEADBEEFDEADBEEF, (bit_cast<uint64_t>(x)) & 0xFFFFFFFFFFFFFFFF)
      63             : #define CHECK_TRAP(x) CHECK_TRAP32(x)
      64             : 
      65             : #define WASM_WRAPPER_RETURN_VALUE 8754
      66             : 
      67             : #define BUILD(r, ...)                      \
      68             :   do {                                     \
      69             :     byte code[] = {__VA_ARGS__};           \
      70             :     r.Build(code, code + arraysize(code)); \
      71             :   } while (false)
      72             : 
      73             : // For tests that must manually import a JSFunction with source code.
      74             : struct ManuallyImportedJSFunction {
      75             :   FunctionSig* sig;
      76             :   Handle<JSFunction> js_function;
      77             : };
      78             : 
      79             : // A  Wasm module builder. Globals are pre-set, however, memory and code may be
      80             : // progressively added by a test. In turn, we piecemeal update the runtime
      81             : // objects, i.e. {WasmInstanceObject}, {WasmModuleObject} and, if necessary,
      82             : // the interpreter.
      83             : class TestingModuleBuilder {
      84             :  public:
      85             :   TestingModuleBuilder(Zone*, ManuallyImportedJSFunction*, ExecutionTier,
      86             :                        RuntimeExceptionSupport, LowerSimd);
      87             : 
      88         480 :   void ChangeOriginToAsmjs() { test_module_->origin = kAsmJsOrigin; }
      89             : 
      90             :   byte* AddMemory(uint32_t size);
      91             : 
      92             :   size_t CodeTableLength() const { return native_module_->num_functions(); }
      93             : 
      94             :   template <typename T>
      95       44200 :   T* AddMemoryElems(uint32_t count) {
      96       49720 :     AddMemory(count * sizeof(T));
      97             :     return raw_mem_start<T>();
      98             :   }
      99             : 
     100             :   template <typename T>
     101             :   T* AddGlobal(
     102         270 :       ValueType type = ValueTypes::ValueTypeFor(MachineTypeForC<T>())) {
     103       23740 :     const WasmGlobal* global = AddGlobal(type);
     104       23725 :     return reinterpret_cast<T*>(globals_data_ + global->offset);
     105             :   }
     106             : 
     107        3885 :   byte AddSignature(FunctionSig* sig) {
     108             :     DCHECK_EQ(test_module_->signatures.size(),
     109             :               test_module_->signature_ids.size());
     110       15540 :     test_module_->signatures.push_back(sig);
     111        7770 :     auto canonical_sig_num = test_module_->signature_map.FindOrInsert(*sig);
     112        3885 :     test_module_->signature_ids.push_back(canonical_sig_num);
     113        3885 :     size_t size = test_module_->signatures.size();
     114        3885 :     CHECK_GT(127, size);
     115        3885 :     return static_cast<byte>(size - 1);
     116             :   }
     117             : 
     118             :   template <typename T>
     119             :   T* raw_mem_start() {
     120             :     DCHECK(mem_start_);
     121             :     return reinterpret_cast<T*>(mem_start_);
     122             :   }
     123             : 
     124             :   template <typename T>
     125             :   T* raw_mem_end() {
     126             :     DCHECK(mem_start_);
     127       19455 :     return reinterpret_cast<T*>(mem_start_ + mem_size_);
     128             :   }
     129             : 
     130             :   template <typename T>
     131             :   T raw_mem_at(int i) {
     132             :     DCHECK(mem_start_);
     133       73200 :     return ReadMemory(&(reinterpret_cast<T*>(mem_start_)[i]));
     134             :   }
     135             : 
     136             :   template <typename T>
     137             :   T raw_val_at(int i) {
     138         990 :     return ReadMemory(reinterpret_cast<T*>(mem_start_ + i));
     139             :   }
     140             : 
     141             :   template <typename T>
     142             :   void WriteMemory(T* p, T val) {
     143             :     WriteLittleEndianValue<T>(reinterpret_cast<Address>(p), val);
     144             :   }
     145             : 
     146             :   template <typename T>
     147             :   T ReadMemory(T* p) {
     148             :     return ReadLittleEndianValue<T>(reinterpret_cast<Address>(p));
     149             :   }
     150             : 
     151             :   // Zero-initialize the memory.
     152         735 :   void BlankMemory() {
     153             :     byte* raw = raw_mem_start<byte>();
     154         735 :     memset(raw, 0, mem_size_);
     155             :   }
     156             : 
     157             :   // Pseudo-randomly intialize the memory.
     158       19455 :   void RandomizeMemory(unsigned int seed = 88) {
     159             :     byte* raw = raw_mem_start<byte>();
     160             :     byte* end = raw_mem_end<byte>();
     161       19455 :     v8::base::RandomNumberGenerator rng;
     162       19455 :     rng.SetSeed(seed);
     163       19455 :     rng.NextBytes(raw, end - raw);
     164       19455 :   }
     165             : 
     166          10 :   void SetMaxMemPages(uint32_t maximum_pages) {
     167          10 :     test_module_->maximum_pages = maximum_pages;
     168          20 :     if (instance_object()->has_memory_object()) {
     169          30 :       instance_object()->memory_object()->set_maximum_pages(maximum_pages);
     170             :     }
     171          10 :   }
     172             : 
     173        1230 :   void SetHasSharedMemory() { test_module_->has_shared_memory = true; }
     174             : 
     175             :   enum FunctionType { kImport, kWasm };
     176             :   uint32_t AddFunction(FunctionSig* sig, const char* name, FunctionType type);
     177             : 
     178             :   Handle<JSFunction> WrapCode(uint32_t index);
     179             : 
     180             :   void AddIndirectFunctionTable(const uint16_t* function_indexes,
     181             :                                 uint32_t table_size);
     182             : 
     183             :   void PopulateIndirectFunctionTable();
     184             : 
     185             :   uint32_t AddBytes(Vector<const byte> bytes);
     186             : 
     187             :   WasmFunction* GetFunctionAt(int index) {
     188     1377410 :     return &test_module_->functions[index];
     189             :   }
     190             : 
     191             :   WasmInterpreter* interpreter() const { return interpreter_; }
     192             :   bool interpret() const { return interpreter_ != nullptr; }
     193             :   LowerSimd lower_simd() const { return lower_simd_; }
     194             :   Isolate* isolate() const { return isolate_; }
     195             :   Handle<WasmInstanceObject> instance_object() const {
     196             :     return instance_object_;
     197             :   }
     198             :   WasmCode* GetFunctionCode(uint32_t index) const {
     199             :     return native_module_->code(index);
     200             :   }
     201             :   Address globals_start() const {
     202             :     return reinterpret_cast<Address>(globals_data_);
     203             :   }
     204             :   void Link() {
     205    11542240 :     if (linked_) return;
     206      910935 :     linked_ = true;
     207      910935 :     native_module_->SetExecutable(true);
     208             :   }
     209             : 
     210             :   CompilationEnv CreateCompilationEnv();
     211             : 
     212             :   ExecutionTier execution_tier() const { return execution_tier_; }
     213             : 
     214             :   RuntimeExceptionSupport runtime_exception_support() const {
     215             :     return runtime_exception_support_;
     216             :   }
     217             : 
     218             :  private:
     219             :   std::shared_ptr<WasmModule> test_module_;
     220             :   WasmModule* test_module_ptr_;
     221             :   Isolate* isolate_;
     222             :   WasmFeatures enabled_features_;
     223             :   uint32_t global_offset = 0;
     224             :   byte* mem_start_ = nullptr;
     225             :   uint32_t mem_size_ = 0;
     226             :   alignas(16) byte globals_data_[kMaxGlobalsSize];
     227             :   WasmInterpreter* interpreter_ = nullptr;
     228             :   ExecutionTier execution_tier_;
     229             :   Handle<WasmInstanceObject> instance_object_;
     230             :   NativeModule* native_module_ = nullptr;
     231             :   bool linked_ = false;
     232             :   RuntimeExceptionSupport runtime_exception_support_;
     233             :   LowerSimd lower_simd_;
     234             : 
     235             :   const WasmGlobal* AddGlobal(ValueType type);
     236             : 
     237             :   Handle<WasmInstanceObject> InitInstanceObject();
     238             : };
     239             : 
     240             : void TestBuildingGraph(Zone* zone, compiler::JSGraph* jsgraph,
     241             :                        CompilationEnv* module, FunctionSig* sig,
     242             :                        compiler::SourcePositionTable* source_position_table,
     243             :                        const byte* start, const byte* end);
     244             : 
     245             : class WasmFunctionWrapper : private compiler::GraphAndBuilders {
     246             :  public:
     247             :   WasmFunctionWrapper(Zone* zone, int num_params);
     248             : 
     249             :   void Init(CallDescriptor* call_descriptor, MachineType return_type,
     250             :             Vector<MachineType> param_types);
     251             : 
     252             :   template <typename ReturnType, typename... ParamTypes>
     253      910990 :   void Init(CallDescriptor* call_descriptor) {
     254             :     std::array<MachineType, sizeof...(ParamTypes)> param_machine_types{
     255       20130 :         {MachineTypeForC<ParamTypes>()...}};
     256             :     Vector<MachineType> param_vec(param_machine_types.data(),
     257             :                                   param_machine_types.size());
     258      910990 :     Init(call_descriptor, MachineTypeForC<ReturnType>(), param_vec);
     259      910990 :   }
     260             : 
     261    11537070 :   void SetInnerCode(WasmCode* code) {
     262             :     intptr_t address = static_cast<intptr_t>(code->instruction_start());
     263             :     compiler::NodeProperties::ChangeOp(
     264             :         inner_code_node_,
     265    11537070 :         common()->ExternalConstant(ExternalReference::FromRawAddress(address)));
     266    11537070 :   }
     267             : 
     268      910990 :   const compiler::Operator* IntPtrConstant(intptr_t value) {
     269             :     return machine()->Is32()
     270           0 :                ? common()->Int32Constant(static_cast<int32_t>(value))
     271      910990 :                : common()->Int64Constant(static_cast<int64_t>(value));
     272             :   }
     273             : 
     274    11537070 :   void SetInstance(Handle<WasmInstanceObject> instance) {
     275             :     compiler::NodeProperties::ChangeOp(context_address_,
     276    11537070 :                                        common()->HeapConstant(instance));
     277    11537070 :   }
     278             : 
     279             :   Handle<Code> GetWrapperCode();
     280             : 
     281             :   Signature<MachineType>* signature() const { return signature_; }
     282             : 
     283             :  private:
     284             :   Node* inner_code_node_;
     285             :   Node* context_address_;
     286             :   MaybeHandle<Code> code_;
     287             :   Signature<MachineType>* signature_;
     288             : };
     289             : 
     290             : // A helper for compiling wasm functions for testing.
     291             : // It contains the internal state for compilation (i.e. TurboFan graph) and
     292             : // interpretation (by adding to the interpreter manually).
     293     1377370 : class WasmFunctionCompiler : public compiler::GraphAndBuilders {
     294             :  public:
     295             :   ~WasmFunctionCompiler();
     296             : 
     297     4111950 :   Isolate* isolate() { return builder_->isolate(); }
     298      910990 :   CallDescriptor* descriptor() {
     299      910990 :     if (descriptor_ == nullptr) {
     300     1821980 :       descriptor_ = compiler::GetWasmCallDescriptor(zone(), sig);
     301             :     }
     302      910990 :     return descriptor_;
     303             :   }
     304        8990 :   uint32_t function_index() { return function_->func_index; }
     305             : 
     306             :   void Build(const byte* start, const byte* end);
     307             : 
     308             :   byte AllocateLocal(ValueType type) {
     309      242250 :     uint32_t index = local_decls.AddLocals(1, type);
     310        6815 :     byte result = static_cast<byte>(index);
     311             :     DCHECK_EQ(index, result);
     312             :     return result;
     313             :   }
     314             : 
     315         120 :   void SetSigIndex(int sig_index) { function_->sig_index = sig_index; }
     316             : 
     317             :  private:
     318             :   friend class WasmRunnerBase;
     319             : 
     320             :   WasmFunctionCompiler(Zone* zone, FunctionSig* sig,
     321             :                        TestingModuleBuilder* builder, const char* name);
     322             : 
     323             :   compiler::JSGraph jsgraph;
     324             :   FunctionSig* sig;
     325             :   // The call descriptor is initialized when the function is compiled.
     326             :   CallDescriptor* descriptor_;
     327             :   TestingModuleBuilder* builder_;
     328             :   WasmFunction* function_;
     329             :   LocalDeclEncoder local_decls;
     330             :   compiler::SourcePositionTable source_position_table_;
     331             :   WasmInterpreter* interpreter_;
     332             : };
     333             : 
     334             : // A helper class to build a module around Wasm bytecode, generate machine
     335             : // code, and run that code.
     336     2733460 : class WasmRunnerBase : public HandleAndZoneScope {
     337             :  public:
     338     1366730 :   WasmRunnerBase(ManuallyImportedJSFunction* maybe_import,
     339             :                  ExecutionTier execution_tier, int num_params,
     340             :                  RuntimeExceptionSupport runtime_exception_support,
     341             :                  LowerSimd lower_simd)
     342             :       : zone_(&allocator_, ZONE_NAME),
     343             :         builder_(&zone_, maybe_import, execution_tier,
     344             :                  runtime_exception_support, lower_simd),
     345     2733460 :         wrapper_(&zone_, num_params) {}
     346             : 
     347             :   // Builds a graph from the given Wasm code and generates the machine
     348             :   // code and call wrapper for that graph. This method must not be called
     349             :   // more than once.
     350     1360010 :   void Build(const byte* start, const byte* end) {
     351     1360010 :     CHECK(!compiled_);
     352     1360010 :     compiled_ = true;
     353     2720020 :     functions_[0]->Build(start, end);
     354     1360010 :   }
     355             : 
     356             :   // Resets the state for building the next function.
     357             :   // The main function called will always be the first function.
     358             :   template <typename ReturnType, typename... ParamTypes>
     359     1366945 :   WasmFunctionCompiler& NewFunction(const char* name = nullptr) {
     360     1366945 :     return NewFunction(CreateSig<ReturnType, ParamTypes...>(), name);
     361             :   }
     362             : 
     363             :   // Resets the state for building the next function.
     364             :   // The main function called will be the last generated function.
     365             :   // Returns the index of the previously built function.
     366     1377370 :   WasmFunctionCompiler& NewFunction(FunctionSig* sig,
     367             :                                     const char* name = nullptr) {
     368             :     functions_.emplace_back(
     369     1377370 :         new WasmFunctionCompiler(&zone_, sig, &builder_, name));
     370     1377370 :     return *functions_.back();
     371             :   }
     372             : 
     373             :   byte AllocateLocal(ValueType type) {
     374      242240 :     return functions_[0]->AllocateLocal(type);
     375             :   }
     376             : 
     377         200 :   uint32_t function_index() { return functions_[0]->function_index(); }
     378    11548730 :   WasmFunction* function() { return functions_[0]->function_; }
     379             :   WasmInterpreter* interpreter() {
     380             :     DCHECK(interpret());
     381    11537980 :     return functions_[0]->interpreter_;
     382             :   }
     383             :   bool possible_nondeterminism() { return possible_nondeterminism_; }
     384             :   TestingModuleBuilder& builder() { return builder_; }
     385             :   Zone* zone() { return &zone_; }
     386             : 
     387    18672770 :   bool interpret() { return builder_.interpret(); }
     388             : 
     389             :   template <typename ReturnType, typename... ParamTypes>
     390     1366975 :   FunctionSig* CreateSig() {
     391             :     std::array<MachineType, sizeof...(ParamTypes)> param_machine_types{
     392       30320 :         {MachineTypeForC<ParamTypes>()...}};
     393             :     Vector<MachineType> param_vec(param_machine_types.data(),
     394             :                                   param_machine_types.size());
     395     1366975 :     return CreateSig(MachineTypeForC<ReturnType>(), param_vec);
     396             :   }
     397             : 
     398             :  private:
     399             :   FunctionSig* CreateSig(MachineType return_type,
     400             :                          Vector<MachineType> param_types);
     401             : 
     402             :  protected:
     403             :   v8::internal::AccountingAllocator allocator_;
     404             :   Zone zone_;
     405             :   TestingModuleBuilder builder_;
     406             :   std::vector<std::unique_ptr<WasmFunctionCompiler>> functions_;
     407             :   WasmFunctionWrapper wrapper_;
     408             :   bool compiled_ = false;
     409             :   bool possible_nondeterminism_ = false;
     410             : 
     411             :  public:
     412             :   // This field has to be static. Otherwise, gcc complains about the use in
     413             :   // the lambda context below.
     414             :   static bool trap_happened;
     415             : };
     416             : 
     417             : template <typename ReturnType, typename... ParamTypes>
     418     1366730 : class WasmRunner : public WasmRunnerBase {
     419             :  public:
     420     1366730 :   WasmRunner(ExecutionTier execution_tier,
     421             :              ManuallyImportedJSFunction* maybe_import = nullptr,
     422             :              const char* main_fn_name = "main",
     423             :              RuntimeExceptionSupport runtime_exception_support =
     424             :                  kNoRuntimeExceptionSupport,
     425             :              LowerSimd lower_simd = kNoLowerSimd)
     426             :       : WasmRunnerBase(maybe_import, execution_tier, sizeof...(ParamTypes),
     427     1366730 :                        runtime_exception_support, lower_simd) {
     428     1366730 :     NewFunction<ReturnType, ParamTypes...>(main_fn_name);
     429     1366730 :     if (!interpret()) {
     430     1821980 :       wrapper_.Init<ReturnType, ParamTypes...>(functions_[0]->descriptor());
     431             :     }
     432     1366730 :   }
     433             : 
     434             :   WasmRunner(ExecutionTier execution_tier, LowerSimd lower_simd)
     435             :       : WasmRunner(execution_tier, nullptr, "main", kNoRuntimeExceptionSupport,
     436       15810 :                    lower_simd) {}
     437             : 
     438    17306040 :   ReturnType Call(ParamTypes... p) {
     439             :     DCHECK(compiled_);
     440    17306040 :     if (interpret()) return CallInterpreter(p...);
     441             : 
     442    11537070 :     ReturnType return_value = static_cast<ReturnType>(0xDEADBEEFDEADBEEF);
     443    11537070 :     WasmRunnerBase::trap_happened = false;
     444             : 
     445      180780 :     auto trap_callback = []() -> void {
     446       90390 :       WasmRunnerBase::trap_happened = true;
     447       90390 :       set_trap_callback_for_testing(nullptr);
     448           0 :     };
     449    11537070 :     set_trap_callback_for_testing(trap_callback);
     450             : 
     451    46148280 :     wrapper_.SetInnerCode(builder_.GetFunctionCode(0));
     452    11537070 :     wrapper_.SetInstance(builder_.instance_object());
     453             :     builder_.Link();
     454    11537070 :     Handle<Code> wrapper_code = wrapper_.GetWrapperCode();
     455             :     compiler::CodeRunner<int32_t> runner(CcTest::InitIsolateOnce(),
     456    11537070 :                                          wrapper_code, wrapper_.signature());
     457             :     int32_t result;
     458             :     {
     459             :       trap_handler::SetThreadInWasm();
     460             : 
     461    11537070 :       result = runner.Call(static_cast<void*>(&p)...,
     462             :                            static_cast<void*>(&return_value));
     463             : 
     464             :       trap_handler::ClearThreadInWasm();
     465             :     }
     466    11537070 :     CHECK_EQ(WASM_WRAPPER_RETURN_VALUE, result);
     467             :     return WasmRunnerBase::trap_happened
     468             :                ? static_cast<ReturnType>(0xDEADBEEFDEADBEEF)
     469    11537070 :                : return_value;
     470             :   }
     471             : 
     472     5768970 :   ReturnType CallInterpreter(ParamTypes... p) {
     473     5768970 :     WasmInterpreter::Thread* thread = interpreter()->GetThread(0);
     474     5768970 :     thread->Reset();
     475             :     std::array<WasmValue, sizeof...(p)> args{{WasmValue(p)...}};
     476     5768970 :     thread->InitFrame(function(), args.data());
     477     5768970 :     if (thread->Run() == WasmInterpreter::FINISHED) {
     478     5723770 :       WasmValue val = thread->GetReturnValue();
     479     5723770 :       possible_nondeterminism_ |= thread->PossibleNondeterminism();
     480             :       return val.to<ReturnType>();
     481       45200 :     } else if (thread->state() == WasmInterpreter::TRAPPED) {
     482             :       // TODO(titzer): return the correct trap code
     483             :       int64_t result = 0xDEADBEEFDEADBEEF;
     484             :       return static_cast<ReturnType>(result);
     485             :     } else {
     486             :       // TODO(titzer): falling off end
     487           0 :       return ReturnType{0};
     488             :     }
     489             :   }
     490             : 
     491             :   Handle<Code> GetWrapperCode() { return wrapper_.GetWrapperCode(); }
     492             : };
     493             : 
     494             : // A macro to define tests that run in different engine configurations.
     495             : #define WASM_EXEC_TEST(name)                                                  \
     496             :   void RunWasm_##name(ExecutionTier execution_tier);                          \
     497             :   TEST(RunWasmTurbofan_##name) { RunWasm_##name(ExecutionTier::kOptimized); } \
     498             :   TEST(RunWasmLiftoff_##name) { RunWasm_##name(ExecutionTier::kBaseline); }   \
     499             :   TEST(RunWasmInterpreter_##name) {                                           \
     500             :     RunWasm_##name(ExecutionTier::kInterpreter);                              \
     501             :   }                                                                           \
     502             :   void RunWasm_##name(ExecutionTier execution_tier)
     503             : 
     504             : #define WASM_COMPILED_EXEC_TEST(name)                                         \
     505             :   void RunWasm_##name(ExecutionTier execution_tier);                          \
     506             :   TEST(RunWasmTurbofan_##name) { RunWasm_##name(ExecutionTier::kOptimized); } \
     507             :   TEST(RunWasmLiftoff_##name) { RunWasm_##name(ExecutionTier::kBaseline); }   \
     508             :   void RunWasm_##name(ExecutionTier execution_tier)
     509             : 
     510             : }  // namespace wasm
     511             : }  // namespace internal
     512             : }  // namespace v8
     513             : 
     514             : #endif

Generated by: LCOV version 1.10