diff --git a/test/cctest/wasm/test-streaming-compilation.cc b/test/cctest/wasm/test-streaming-compilation.cc index 65dc359b95..ff3ac13cee 100644 --- a/test/cctest/wasm/test-streaming-compilation.cc +++ b/test/cctest/wasm/test-streaming-compilation.cc @@ -5,6 +5,7 @@ #include "include/libplatform/libplatform.h" #include "src/api/api-inl.h" #include "src/base/vector.h" +#include "src/handles/global-handles-inl.h" #include "src/init/v8.h" #include "src/objects/managed.h" #include "src/objects/objects-inl.h" @@ -23,9 +24,7 @@ #include "test/common/wasm/wasm-macro-gen.h" #include "test/common/wasm/wasm-module-runner.h" -namespace v8 { -namespace internal { -namespace wasm { +namespace v8::internal::wasm { class MockPlatform final : public TestPlatform { public: @@ -153,17 +152,15 @@ class TestResolver : public CompilationResultResolver { public: TestResolver(i::Isolate* isolate, CompilationState* state, std::string* error_message, - std::shared_ptr* native_module) + Handle* module_object) : isolate_(isolate), state_(state), error_message_(error_message), - native_module_(native_module) {} + module_object_(module_object) {} void OnCompilationSucceeded(i::Handle module) override { *state_ = CompilationState::kFinished; - if (!module.is_null()) { - *native_module_ = module->shared_native_module(); - } + *module_object_ = isolate_->global_handles()->Create(*module); } void OnCompilationFailed(i::Handle error_reason) override { @@ -177,14 +174,13 @@ class TestResolver : public CompilationResultResolver { i::Isolate* isolate_; CompilationState* const state_; std::string* const error_message_; - std::shared_ptr* const native_module_; + Handle* const module_object_; }; class StreamTester { public: explicit StreamTester(v8::Isolate* isolate) - : zone_(&allocator_, "StreamTester"), - internal_scope_(reinterpret_cast(isolate)) { + : zone_(&allocator_, "StreamTester") { Isolate* i_isolate = reinterpret_cast(isolate); v8::Local context = isolate->GetCurrentContext(); @@ -192,13 +188,24 @@ class StreamTester { i_isolate, WasmFeatures::All(), v8::Utils::OpenHandle(*context), "WebAssembly.compileStreaming()", std::make_shared(i_isolate, &state_, &error_message_, - &native_module_)); + &module_object_)); } - std::shared_ptr stream() { return stream_; } + std::shared_ptr stream() const { return stream_; } + + // Compiled module object, valid after successful compile. + Handle module_object() const { + CHECK(!module_object_.is_null()); + return module_object_; + } // Compiled native module, valid after successful compile. - std::shared_ptr native_module() { return native_module_; } + NativeModule* native_module() const { + return module_object()->native_module(); + } + std::shared_ptr shared_native_module() const { + return module_object()->shared_native_module(); + } // Run all compiler tasks, both foreground and background tasks. void RunCompilerTasks() { @@ -228,19 +235,20 @@ class StreamTester { private: AccountingAllocator allocator_; Zone zone_; - i::HandleScope internal_scope_; CompilationState state_ = CompilationState::kPending; std::string error_message_; - std::shared_ptr native_module_; + Handle module_object_; std::shared_ptr stream_; }; } // namespace -#define RUN_STREAM(name) \ - v8::Isolate* isolate = CcTest::isolate(); \ - v8::HandleScope handle_scope(isolate); \ - v8::Local context = v8::Context::New(isolate); \ - v8::Context::Scope context_scope(context); \ +#define RUN_STREAM(name) \ + v8::Isolate* isolate = CcTest::isolate(); \ + v8::HandleScope handle_scope(isolate); \ + v8::Local context = v8::Context::New(isolate); \ + v8::Context::Scope context_scope(context); \ + /* Reduce tiering budget so we do not need to execute too long. */ \ + i::FlagScope reduced_tiering_budget(&i::FLAG_wasm_tiering_budget, 10); \ RunStream_##name(&platform, isolate); #define STREAM_TEST(name) \ @@ -253,25 +261,20 @@ class StreamTester { } \ void RunStream_##name(MockPlatform* platform, v8::Isolate* isolate) +constexpr const char* kExportNames[] = {"a", "b", "c"}; + // Create a valid module with 3 functions. ZoneBuffer GetValidModuleBytes(Zone* zone) { ZoneBuffer buffer(zone); TestSignatures sigs; WasmModuleBuilder builder(zone); - { + uint8_t i = 0; + for (const char* export_name : kExportNames) { WasmFunctionBuilder* f = builder.AddFunction(sigs.i_iii()); - uint8_t code[] = {kExprLocalGet, 0, kExprEnd}; - f->EmitCode(code, arraysize(code)); - } - { - WasmFunctionBuilder* f = builder.AddFunction(sigs.i_iii()); - uint8_t code[] = {kExprLocalGet, 1, kExprEnd}; - f->EmitCode(code, arraysize(code)); - } - { - WasmFunctionBuilder* f = builder.AddFunction(sigs.i_iii()); - uint8_t code[] = {kExprLocalGet, 2, kExprEnd}; + uint8_t code[] = {kExprLocalGet, i, kExprEnd}; f->EmitCode(code, arraysize(code)); + CHECK_GE(3, ++i); + builder.AddExport(base::CStrVector(export_name), f); } builder.WriteTo(&buffer); return buffer; @@ -287,11 +290,47 @@ ZoneBuffer GetValidCompiledModuleBytes(v8::Isolate* isolate, Zone* zone, tester.FinishStream(); tester.RunCompilerTasks(); CHECK(tester.IsPromiseFulfilled()); + + NativeModule* native_module = tester.native_module(); + CHECK_NOT_NULL(native_module); + + auto* i_isolate = reinterpret_cast(isolate); + ErrorThrower thrower{i_isolate, "GetValidCompiledModuleBytes"}; + Handle instance = + GetWasmEngine() + ->SyncInstantiate(i_isolate, &thrower, tester.module_object(), {}, {}) + .ToHandleChecked(); + CHECK(!thrower.error()); + + // Call the exported functions repeatedly until they are all tiered up. + std::vector> exported_functions; + for (const char* export_name : kExportNames) { + exported_functions.push_back( + testing::GetExportedFunction(i_isolate, instance, export_name) + .ToHandleChecked()); + } + while (true) { + WasmCodeRefScope code_ref_scope; + std::vector all_code = native_module->SnapshotCodeTable(); + if (std::all_of(all_code.begin(), all_code.end(), [](const WasmCode* code) { + return code->tier() == ExecutionTier::kTurbofan; + })) { + break; + } + for (Handle exported_function : exported_functions) { + Handle return_value = + Execution::Call(i_isolate, exported_function, + ReadOnlyRoots{i_isolate}.undefined_value_handle(), 0, + nullptr) + .ToHandleChecked(); + CHECK(return_value->IsSmi()); + CHECK_EQ(0, Smi::cast(*return_value).value()); + } + tester.RunCompilerTasks(); + } + // Serialize the NativeModule. - std::shared_ptr native_module = tester.native_module(); - CHECK(native_module); - native_module->compilation_state()->WaitForTopTierFinished(); - i::wasm::WasmSerializer serializer(native_module.get()); + i::wasm::WasmSerializer serializer(native_module); size_t size = serializer.GetSerializedNativeModuleSize(); std::vector buffer(size); CHECK(serializer.SerializeNativeModule(base::VectorOf(buffer))); @@ -1101,7 +1140,6 @@ STREAM_TEST(TestModuleWithImportedFunction) { } STREAM_TEST(TestIncrementalCaching) { - FLAG_VALUE_SCOPE(wasm_dynamic_tiering, true); FLAG_VALUE_SCOPE(wasm_tier_up, false); constexpr int threshold = 10; FlagScope caching_treshold(&FLAG_wasm_caching_threshold, threshold); @@ -1149,10 +1187,10 @@ STREAM_TEST(TestIncrementalCaching) { constexpr base::Vector kNoSourceUrl{"", 0}; Isolate* i_isolate = reinterpret_cast(isolate); Handle