diff options
Diffstat (limited to 'deps/v8/test/cctest')
51 files changed, 1167 insertions, 1881 deletions
diff --git a/deps/v8/test/cctest/BUILD.gn b/deps/v8/test/cctest/BUILD.gn index d5d20fdfe9..02f475a497 100644 --- a/deps/v8/test/cctest/BUILD.gn +++ b/deps/v8/test/cctest/BUILD.gn @@ -144,13 +144,11 @@ v8_source_set("cctest_sources") { "heap/test-compaction.cc", "heap/test-concurrent-allocation.cc", "heap/test-concurrent-marking.cc", - "heap/test-embedder-tracing.cc", "heap/test-external-string-tracker.cc", "heap/test-heap.cc", "heap/test-incremental-marking.cc", "heap/test-invalidated-slots.cc", "heap/test-iterators.cc", - "heap/test-lab.cc", "heap/test-mark-compact.cc", "heap/test-memory-measurement.cc", "heap/test-page-promotion.cc", diff --git a/deps/v8/test/cctest/cctest.cc b/deps/v8/test/cctest/cctest.cc index 99bca0a29b..5a0895b457 100644 --- a/deps/v8/test/cctest/cctest.cc +++ b/deps/v8/test/cctest/cctest.cc @@ -35,6 +35,11 @@ #include "include/v8-isolate.h" #include "include/v8-local-handle.h" #include "include/v8-locker.h" +#include "src/base/lazy-instance.h" +#include "src/base/logging.h" +#include "src/base/platform/condition-variable.h" +#include "src/base/platform/mutex.h" +#include "src/base/platform/semaphore.h" #include "src/base/strings.h" #include "src/codegen/compiler.h" #include "src/codegen/optimized-compilation-info.h" @@ -62,19 +67,23 @@ enum InitializationState { kUnset, kUninitialized, kInitialized }; static InitializationState initialization_state_ = kUnset; -CcTest* CcTest::last_ = nullptr; +static v8::base::LazyInstance<CcTestMapType>::type g_cctests = + LAZY_INSTANCE_INITIALIZER; + +std::unordered_map<std::string, CcTest*>* tests_ = + new std::unordered_map<std::string, CcTest*>(); bool CcTest::initialize_called_ = false; v8::base::Atomic32 CcTest::isolate_used_ = 0; v8::ArrayBuffer::Allocator* CcTest::allocator_ = nullptr; v8::Isolate* CcTest::isolate_ = nullptr; +v8::Platform* CcTest::default_platform_ = nullptr; CcTest::CcTest(TestFunction* callback, const char* file, const char* name, - bool enabled, bool initialize) + bool enabled, bool initialize, + TestPlatformFactory* test_platform_factory) : callback_(callback), - name_(name), - enabled_(enabled), initialize_(initialize), - prev_(last_) { + test_platform_factory_(test_platform_factory) { // Find the base name of this test (const_cast required on Windows). char *basename = strrchr(const_cast<char *>(file), '/'); if (!basename) { @@ -89,25 +98,57 @@ CcTest::CcTest(TestFunction* callback, const char* file, const char* name, char *extension = strrchr(basename, '.'); if (extension) *extension = 0; // Install this test in the list of tests - file_ = basename; - prev_ = last_; - last_ = this; + + if (enabled) { + auto it = + g_cctests.Pointer()->emplace(std::string(basename) + "/" + name, this); + CHECK_WITH_MSG(it.second, "Test with same name already exists"); + } + v8::internal::DeleteArray(basename); } +void CcTest::Run(const char* snapshot_directory) { + v8::V8::InitializeICUDefaultLocation(snapshot_directory); + std::unique_ptr<v8::Platform> underlying_default_platform( + v8::platform::NewDefaultPlatform()); + default_platform_ = underlying_default_platform.get(); + std::unique_ptr<v8::Platform> platform; + if (test_platform_factory_) { + platform = test_platform_factory_(); + } else { + platform = std::move(underlying_default_platform); + } + v8::V8::InitializePlatform(platform.get()); +#ifdef V8_SANDBOX + CHECK(v8::V8::InitializeSandbox()); +#endif + cppgc::InitializeProcess(platform->GetPageAllocator()); + v8::V8::Initialize(); + v8::V8::InitializeExternalStartupData(snapshot_directory); + +#if V8_ENABLE_WEBASSEMBLY && V8_TRAP_HANDLER_SUPPORTED + constexpr bool kUseDefaultTrapHandler = true; + CHECK(v8::V8::EnableWebAssemblyTrapHandler(kUseDefaultTrapHandler)); +#endif // V8_ENABLE_WEBASSEMBLY && V8_TRAP_HANDLER_SUPPORTED + + CcTest::set_array_buffer_allocator( + v8::ArrayBuffer::Allocator::NewDefaultAllocator()); + + v8::RegisterExtension(std::make_unique<i::PrintExtension>()); + v8::RegisterExtension(std::make_unique<i::ProfilerExtension>()); + v8::RegisterExtension(std::make_unique<i::TraceExtension>()); -void CcTest::Run() { if (!initialize_) { CHECK_NE(initialization_state_, kInitialized); initialization_state_ = kUninitialized; - CHECK_NULL(CcTest::isolate_); + CHECK_NULL(isolate_); } else { CHECK_NE(initialization_state_, kUninitialized); initialization_state_ = kInitialized; - if (isolate_ == nullptr) { - v8::Isolate::CreateParams create_params; - create_params.array_buffer_allocator = allocator_; - isolate_ = v8::Isolate::New(create_params); - } + CHECK_NULL(isolate_); + v8::Isolate::CreateParams create_params; + create_params.array_buffer_allocator = allocator_; + isolate_ = v8::Isolate::New(create_params); isolate_->Enter(); } #ifdef DEBUG @@ -129,7 +170,15 @@ void CcTest::Run() { EmptyMessageQueues(isolate_); } isolate_->Exit(); + isolate_->Dispose(); + isolate_ = nullptr; + } else { + CHECK_NULL(isolate_); } + + v8::V8::Dispose(); + cppgc::ShutdownProcess(); + v8::V8::DisposePlatform(); } i::Heap* CcTest::heap() { return i_isolate()->heap(); } @@ -197,10 +246,6 @@ void CcTest::InitializeVM() { v8::Context::New(CcTest::isolate())->Enter(); } -void CcTest::TearDown() { - if (isolate_ != nullptr) isolate_->Dispose(); -} - v8::Local<v8::Context> CcTest::NewContext(CcTestExtensionFlags extension_flags, v8::Isolate* isolate) { const char* extension_names[kMaxExtensions]; @@ -290,17 +335,10 @@ i::Handle<i::JSFunction> Optimize( return function; } -static void PrintTestList(CcTest* current) { - if (current == nullptr) return; - PrintTestList(current->prev()); - printf("%s/%s\n", current->file(), current->name()); -} - - -static void SuggestTestHarness(int tests) { - if (tests == 0) return; - printf("Running multiple tests in sequence is deprecated and may cause " - "bogus failure. Consider using tools/run-tests.py instead.\n"); +static void PrintTestList() { + for (const auto& entry : g_cctests.Get()) { + printf("%s\n", entry.first.c_str()); + } } int main(int argc, char* argv[]) { @@ -333,82 +371,44 @@ int main(int argc, char* argv[]) { perfetto::Tracing::Initialize(init_args); #endif // V8_USE_PERFETTO - v8::V8::InitializeICUDefaultLocation(argv[0]); - std::unique_ptr<v8::Platform> platform(v8::platform::NewDefaultPlatform()); - v8::V8::InitializePlatform(platform.get()); -#ifdef V8_SANDBOX - CHECK(v8::V8::InitializeSandbox()); -#endif - cppgc::InitializeProcess(platform->GetPageAllocator()); using HelpOptions = v8::internal::FlagList::HelpOptions; v8::internal::FlagList::SetFlagsFromCommandLine( &argc, argv, true, HelpOptions(HelpOptions::kExit, usage.c_str())); - v8::V8::Initialize(); - v8::V8::InitializeExternalStartupData(argv[0]); - -#if V8_ENABLE_WEBASSEMBLY && V8_TRAP_HANDLER_SUPPORTED - constexpr bool kUseDefaultTrapHandler = true; - CHECK(v8::V8::EnableWebAssemblyTrapHandler(kUseDefaultTrapHandler)); -#endif // V8_ENABLE_WEBASSEMBLY && V8_TRAP_HANDLER_SUPPORTED - - CcTest::set_array_buffer_allocator( - v8::ArrayBuffer::Allocator::NewDefaultAllocator()); - - v8::RegisterExtension(std::make_unique<i::PrintExtension>()); - v8::RegisterExtension(std::make_unique<i::ProfilerExtension>()); - v8::RegisterExtension(std::make_unique<i::TraceExtension>()); - int tests_run = 0; - bool print_run_count = true; - for (int i = 1; i < argc; i++) { - char* arg = argv[i]; + const char* test_arg = nullptr; + for (int i = 1; i < argc; ++i) { + const char* arg = argv[i]; if (strcmp(arg, "--list") == 0) { - PrintTestList(CcTest::last()); - print_run_count = false; - - } else { - char* arg_copy = v8::internal::StrDup(arg); - char* testname = strchr(arg_copy, '/'); - if (testname) { - // Split the string in two by nulling the slash and then run - // exact matches. - *testname = 0; - char* file = arg_copy; - char* name = testname + 1; - CcTest* test = CcTest::last(); - while (test != nullptr) { - if (test->enabled() - && strcmp(test->file(), file) == 0 - && strcmp(test->name(), name) == 0) { - SuggestTestHarness(tests_run++); - test->Run(); - } - test = test->prev(); - } - - } else { - // Run all tests with the specified file or test name. - char* file_or_name = arg_copy; - CcTest* test = CcTest::last(); - while (test != nullptr) { - if (test->enabled() - && (strcmp(test->file(), file_or_name) == 0 - || strcmp(test->name(), file_or_name) == 0)) { - SuggestTestHarness(tests_run++); - test->Run(); - } - test = test->prev(); - } - } - v8::internal::DeleteArray<char>(arg_copy); + PrintTestList(); + return 0; + } + if (*arg == '-') { + // Ignore flags that weren't removed by SetFlagsFromCommandLine + continue; } + if (test_arg != nullptr) { + fprintf(stderr, + "Running multiple tests in sequence is not allowed. Use " + "tools/run-tests.py instead.\n"); + return 1; + } + test_arg = arg; } - if (print_run_count && tests_run != 1) { - printf("Ran %i tests.\n", tests_run); + + if (test_arg == nullptr) { + printf("Ran 0 tests.\n"); + return 0; } - CcTest::TearDown(); - v8::V8::Dispose(); - v8::V8::DisposePlatform(); + + auto it = g_cctests.Get().find(test_arg); + if (it == g_cctests.Get().end()) { + fprintf(stderr, "ERROR: Did not find test %s.\n", test_arg); + return 1; + } + + CcTest* test = it->second; + test->Run(argv[0]); + return 0; } @@ -458,3 +458,90 @@ ManualGCScope::~ManualGCScope() { i::FLAG_detect_ineffective_gcs_near_heap_limit = flag_detect_ineffective_gcs_near_heap_limit_; } + +v8::PageAllocator* TestPlatform::GetPageAllocator() { + return CcTest::default_platform()->GetPageAllocator(); +} + +void TestPlatform::OnCriticalMemoryPressure() { + CcTest::default_platform()->OnCriticalMemoryPressure(); +} + +bool TestPlatform::OnCriticalMemoryPressure(size_t length) { + return CcTest::default_platform()->OnCriticalMemoryPressure(length); +} + +int TestPlatform::NumberOfWorkerThreads() { + return CcTest::default_platform()->NumberOfWorkerThreads(); +} + +std::shared_ptr<v8::TaskRunner> TestPlatform::GetForegroundTaskRunner( + v8::Isolate* isolate) { + return CcTest::default_platform()->GetForegroundTaskRunner(isolate); +} + +void TestPlatform::CallOnWorkerThread(std::unique_ptr<v8::Task> task) { + CcTest::default_platform()->CallOnWorkerThread(std::move(task)); +} + +void TestPlatform::CallDelayedOnWorkerThread(std::unique_ptr<v8::Task> task, + double delay_in_seconds) { + CcTest::default_platform()->CallDelayedOnWorkerThread(std::move(task), + delay_in_seconds); +} + +std::unique_ptr<v8::JobHandle> TestPlatform::PostJob( + v8::TaskPriority priority, std::unique_ptr<v8::JobTask> job_task) { + return CcTest::default_platform()->PostJob(priority, std::move(job_task)); +} + +double TestPlatform::MonotonicallyIncreasingTime() { + return CcTest::default_platform()->MonotonicallyIncreasingTime(); +} + +double TestPlatform::CurrentClockTimeMillis() { + return CcTest::default_platform()->CurrentClockTimeMillis(); +} + +bool TestPlatform::IdleTasksEnabled(v8::Isolate* isolate) { + return CcTest::default_platform()->IdleTasksEnabled(isolate); +} + +v8::TracingController* TestPlatform::GetTracingController() { + return CcTest::default_platform()->GetTracingController(); +} + +namespace { + +class ShutdownTask final : public v8::Task { + public: + ShutdownTask(v8::base::Semaphore* destruction_barrier, + v8::base::Mutex* destruction_mutex, + v8::base::ConditionVariable* destruction_condition, + bool* can_destruct) + : destruction_barrier_(destruction_barrier), + destruction_mutex_(destruction_mutex), + destruction_condition_(destruction_condition), + can_destruct_(can_destruct) + + {} + + void Run() final { + destruction_barrier_->Signal(); + { + v8::base::MutexGuard guard(destruction_mutex_); + while (!*can_destruct_) { + destruction_condition_->Wait(destruction_mutex_); + } + } + destruction_barrier_->Signal(); + } + + private: + v8::base::Semaphore* const destruction_barrier_; + v8::base::Mutex* const destruction_mutex_; + v8::base::ConditionVariable* const destruction_condition_; + bool* const can_destruct_; +}; + +} // namespace diff --git a/deps/v8/test/cctest/cctest.h b/deps/v8/test/cctest/cctest.h index 735fc9cc9a..3e4cd3cf12 100644 --- a/deps/v8/test/cctest/cctest.h +++ b/deps/v8/test/cctest/cctest.h @@ -69,23 +69,40 @@ class JSHeapBroker; } // namespace v8 #ifndef TEST -#define TEST(Name) \ - static void Test##Name(); \ - CcTest register_test_##Name(Test##Name, __FILE__, #Name, true, true); \ +#define TEST(Name) \ + static void Test##Name(); \ + CcTest register_test_##Name(Test##Name, __FILE__, #Name, true, true, \ + nullptr); \ static void Test##Name() #endif #ifndef UNINITIALIZED_TEST -#define UNINITIALIZED_TEST(Name) \ - static void Test##Name(); \ - CcTest register_test_##Name(Test##Name, __FILE__, #Name, true, false); \ +#define UNINITIALIZED_TEST(Name) \ + static void Test##Name(); \ + CcTest register_test_##Name(Test##Name, __FILE__, #Name, true, false, \ + nullptr); \ static void Test##Name() #endif +#ifndef TEST_WITH_PLATFORM +#define TEST_WITH_PLATFORM(Name, PlatformClass) \ + static void Test##Name(PlatformClass& platform); \ + static void TestWithoutPlatform##Name() { \ + Test##Name(*static_cast<PlatformClass*>(i::V8::GetCurrentPlatform())); \ + } \ + CcTest register_test_##Name(TestWithoutPlatform##Name, __FILE__, #Name, \ + true, true, \ + []() -> std::unique_ptr<TestPlatform> { \ + return std::make_unique<PlatformClass>(); \ + }); \ + static void Test##Name(PlatformClass& platform) +#endif + #ifndef DISABLED_TEST -#define DISABLED_TEST(Name) \ - static void Test##Name(); \ - CcTest register_test_##Name(Test##Name, __FILE__, #Name, false, true); \ +#define DISABLED_TEST(Name) \ + static void Test##Name(); \ + CcTest register_test_##Name(Test##Name, __FILE__, #Name, false, true, \ + nullptr); \ static void Test##Name() #endif @@ -97,9 +114,9 @@ class JSHeapBroker; // to correctly associate the tests with the test suite using them. // 2. To actually execute the tests, create an instance of the class // containing the MEMBER_TESTs. -#define MEMBER_TEST(Name) \ - CcTest register_test_##Name = \ - CcTest(Test##Name, kTestFileName, #Name, true, true); \ +#define MEMBER_TEST(Name) \ + CcTest register_test_##Name = \ + CcTest(Test##Name, kTestFileName, #Name, true, true, nullptr); \ static void Test##Name() #define EXTENSION_LIST(V) \ @@ -119,18 +136,19 @@ static constexpr const char* kExtensionName[kMaxExtensions] = { EXTENSION_LIST(DEFINE_EXTENSION_NAME)}; #undef DEFINE_EXTENSION_NAME +class CcTest; +class TestPlatform; + +using CcTestMapType = std::map<std::string, CcTest*>; + class CcTest { public: using TestFunction = void(); + using TestPlatformFactory = std::unique_ptr<TestPlatform>(); CcTest(TestFunction* callback, const char* file, const char* name, - bool enabled, bool initialize); - ~CcTest() { i::DeleteArray(file_); } - void Run(); - static CcTest* last() { return last_; } - CcTest* prev() { return prev_; } - const char* file() { return file_; } - const char* name() { return name_; } - bool enabled() { return enabled_; } + bool enabled, bool initialize, + TestPlatformFactory* platform_factory = nullptr); + void Run(const char* argv0); static v8::Isolate* isolate() { CHECK_NOT_NULL(isolate_); @@ -150,6 +168,8 @@ class CcTest { static i::Heap* heap(); static i::ReadOnlyHeap* read_only_heap(); + static v8::Platform* default_platform() { return default_platform_; } + static void AddGlobalFunction(v8::Local<v8::Context> env, const char* name, v8::FunctionCallback callback); static void CollectGarbage(i::AllocationSpace space, @@ -178,9 +198,6 @@ class CcTest { // This must be called first in a test. static void InitializeVM(); - // Only for UNINITIALIZED_TESTs - static void DisableAutomaticDispose(); - // Helper function to configure a context. // Must be in a HandleScope. static v8::Local<v8::Context> NewContext( @@ -196,21 +213,17 @@ class CcTest { return NewContext(CcTestExtensionFlags{extensions}, isolate); } - static void TearDown(); - private: - static CcTest* last_; + static std::unordered_map<std::string, CcTest*>* tests_; static v8::ArrayBuffer::Allocator* allocator_; static v8::Isolate* isolate_; + static v8::Platform* default_platform_; static bool initialize_called_; static v8::base::Atomic32 isolate_used_; TestFunction* callback_; - const char* file_; - const char* name_; - bool enabled_; bool initialize_; - CcTest* prev_; + TestPlatformFactory* test_platform_factory_; friend int main(int argc, char** argv); friend class ManualGCScope; @@ -632,8 +645,7 @@ static inline void DisableDebugger(v8::Isolate* isolate) { static inline void EmptyMessageQueues(v8::Isolate* isolate) { - while (v8::platform::PumpMessageLoop(v8::internal::V8::GetCurrentPlatform(), - isolate)) { + while (v8::platform::PumpMessageLoop(CcTest::default_platform(), isolate)) { } } @@ -700,76 +712,32 @@ class V8_NODISCARD ManualGCScope { const bool flag_detect_ineffective_gcs_near_heap_limit_; }; -// This is an abstract base class that can be overridden to implement a test -// platform. It delegates all operations to a given platform at the time -// of construction. +// This is a base class that can be overridden to implement a test platform. It +// delegates all operations to the default platform. class TestPlatform : public v8::Platform { public: - TestPlatform(const TestPlatform&) = delete; - TestPlatform& operator=(const TestPlatform&) = delete; + ~TestPlatform() override = default; // v8::Platform implementation. - v8::PageAllocator* GetPageAllocator() override { - return old_platform()->GetPageAllocator(); - } - - void OnCriticalMemoryPressure() override { - old_platform()->OnCriticalMemoryPressure(); - } - - bool OnCriticalMemoryPressure(size_t length) override { - return old_platform()->OnCriticalMemoryPressure(length); - } - - int NumberOfWorkerThreads() override { - return old_platform()->NumberOfWorkerThreads(); - } - + v8::PageAllocator* GetPageAllocator() override; + void OnCriticalMemoryPressure() override; + bool OnCriticalMemoryPressure(size_t length) override; + int NumberOfWorkerThreads() override; std::shared_ptr<v8::TaskRunner> GetForegroundTaskRunner( - v8::Isolate* isolate) override { - return old_platform()->GetForegroundTaskRunner(isolate); - } - - void CallOnWorkerThread(std::unique_ptr<v8::Task> task) override { - old_platform()->CallOnWorkerThread(std::move(task)); - } - + v8::Isolate* isolate) override; + void CallOnWorkerThread(std::unique_ptr<v8::Task> task) override; void CallDelayedOnWorkerThread(std::unique_ptr<v8::Task> task, - double delay_in_seconds) override { - old_platform()->CallDelayedOnWorkerThread(std::move(task), - delay_in_seconds); - } - + double delay_in_seconds) override; std::unique_ptr<v8::JobHandle> PostJob( v8::TaskPriority priority, - std::unique_ptr<v8::JobTask> job_task) override { - return old_platform()->PostJob(priority, std::move(job_task)); - } - - double MonotonicallyIncreasingTime() override { - return old_platform()->MonotonicallyIncreasingTime(); - } - - double CurrentClockTimeMillis() override { - return old_platform()->CurrentClockTimeMillis(); - } - - bool IdleTasksEnabled(v8::Isolate* isolate) override { - return old_platform()->IdleTasksEnabled(isolate); - } - - v8::TracingController* GetTracingController() override { - return old_platform()->GetTracingController(); - } + std::unique_ptr<v8::JobTask> job_task) override; + double MonotonicallyIncreasingTime() override; + double CurrentClockTimeMillis() override; + bool IdleTasksEnabled(v8::Isolate* isolate) override; + v8::TracingController* GetTracingController() override; protected: - TestPlatform() : old_platform_(i::V8::GetCurrentPlatform()) {} - ~TestPlatform() override { i::V8::SetPlatformForTesting(old_platform_); } - - v8::Platform* old_platform() const { return old_platform_; } - - private: - std::atomic<v8::Platform*> old_platform_; + TestPlatform() = default; }; #if defined(USE_SIMULATOR) diff --git a/deps/v8/test/cctest/compiler/test-instruction-scheduler.cc b/deps/v8/test/cctest/compiler/test-instruction-scheduler.cc index 2fab39506d..ab65b5d485 100644 --- a/deps/v8/test/cctest/compiler/test-instruction-scheduler.cc +++ b/deps/v8/test/cctest/compiler/test-instruction-scheduler.cc @@ -72,13 +72,10 @@ TEST(DeoptInMiddleOfBasicBlock) { tester.StartBlock(); InstructionCode jmp_opcode = kArchJmp; - // Dummy node for FlagsContinuation::ForDeoptimize (which won't accept - // nullptr). - Node* node = Node::New(zone, 0, nullptr, 0, nullptr, false); - FeedbackSource feedback; - FlagsContinuation cont = FlagsContinuation::ForDeoptimize( - kEqual, DeoptimizeKind::kEager, DeoptimizeReason::kUnknown, node->id(), - feedback, node); + Node* dummy_frame_state = Node::New(zone, 0, nullptr, 0, nullptr, false); + FlagsContinuation cont = FlagsContinuation::ForDeoptimizeForTesting( + kEqual, DeoptimizeReason::kUnknown, dummy_frame_state->id(), + FeedbackSource{}, dummy_frame_state); jmp_opcode = cont.Encode(jmp_opcode); Instruction* jmp_inst = Instruction::New(zone, jmp_opcode); tester.CheckIsDeopt(jmp_inst); diff --git a/deps/v8/test/cctest/heap/heap-utils.cc b/deps/v8/test/cctest/heap/heap-utils.cc index b5fd905a34..a57f074eac 100644 --- a/deps/v8/test/cctest/heap/heap-utils.cc +++ b/deps/v8/test/cctest/heap/heap-utils.cc @@ -10,6 +10,7 @@ #include "src/heap/heap-inl.h" #include "src/heap/incremental-marking.h" #include "src/heap/mark-compact.h" +#include "src/heap/marking-barrier.h" #include "src/heap/memory-chunk.h" #include "src/heap/safepoint.h" #include "test/cctest/cctest.h" @@ -189,6 +190,8 @@ void SimulateIncrementalMarking(i::Heap* heap, bool force_completion) { i::StepOrigin::kV8); if (marking->IsReadyToOverApproximateWeakClosure()) { SafepointScope scope(heap); + MarkingBarrier::PublishAll(heap); + marking->MarkRootsForTesting(); marking->FinalizeIncrementally(); } } diff --git a/deps/v8/test/cctest/heap/test-array-buffer-tracker.cc b/deps/v8/test/cctest/heap/test-array-buffer-tracker.cc index 56a8389c2c..2a8e450765 100644 --- a/deps/v8/test/cctest/heap/test-array-buffer-tracker.cc +++ b/deps/v8/test/cctest/heap/test-array-buffer-tracker.cc @@ -210,7 +210,7 @@ TEST(ArrayBuffer_UnregisterDuringSweep) { } TEST(ArrayBuffer_NonLivePromotion) { - if (!FLAG_incremental_marking) return; + if (!FLAG_incremental_marking || FLAG_separate_gc_phases) return; FLAG_concurrent_array_buffer_sweeping = false; ManualGCScope manual_gc_scope; // The test verifies that the marking state is preserved when promoting @@ -248,7 +248,7 @@ TEST(ArrayBuffer_NonLivePromotion) { } TEST(ArrayBuffer_LivePromotion) { - if (!FLAG_incremental_marking) return; + if (!FLAG_incremental_marking || FLAG_separate_gc_phases) return; FLAG_concurrent_array_buffer_sweeping = false; ManualGCScope manual_gc_scope; // The test verifies that the marking state is preserved when promoting diff --git a/deps/v8/test/cctest/heap/test-embedder-tracing.cc b/deps/v8/test/cctest/heap/test-embedder-tracing.cc deleted file mode 100644 index 45e025996f..0000000000 --- a/deps/v8/test/cctest/heap/test-embedder-tracing.cc +++ /dev/null @@ -1,1020 +0,0 @@ -// Copyright 2017 the V8 project authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <unordered_map> -#include <vector> - -#include "include/v8-context.h" -#include "include/v8-function.h" -#include "include/v8-local-handle.h" -#include "include/v8-object.h" -#include "include/v8-persistent-handle.h" -#include "include/v8-template.h" -#include "include/v8-traced-handle.h" -#include "src/api/api-inl.h" -#include "src/common/allow-deprecated.h" -#include "src/handles/global-handles.h" -#include "src/heap/embedder-tracing.h" -#include "src/heap/gc-tracer.h" -#include "src/heap/heap-inl.h" -#include "src/heap/heap.h" -#include "src/heap/safepoint.h" -#include "src/objects/module.h" -#include "src/objects/objects-inl.h" -#include "src/objects/script.h" -#include "src/objects/shared-function-info.h" -#include "test/cctest/cctest.h" -#include "test/cctest/heap/heap-utils.h" - -START_ALLOW_USE_DEPRECATED() - -namespace v8 { - -namespace internal { -namespace heap { - -namespace { - -v8::Local<v8::Object> ConstructTraceableJSApiObject( - v8::Local<v8::Context> context, void* first_field, void* second_field) { - v8::EscapableHandleScope scope(context->GetIsolate()); - v8::Local<v8::FunctionTemplate> function_t = - v8::FunctionTemplate::New(context->GetIsolate()); - v8::Local<v8::ObjectTemplate> instance_t = function_t->InstanceTemplate(); - instance_t->SetInternalFieldCount(2); - v8::Local<v8::Function> function = - function_t->GetFunction(context).ToLocalChecked(); - v8::Local<v8::Object> instance = - function->NewInstance(context).ToLocalChecked(); - instance->SetAlignedPointerInInternalField(0, first_field); - instance->SetAlignedPointerInInternalField(1, second_field); - CHECK(!instance.IsEmpty()); - i::Handle<i::JSReceiver> js_obj = v8::Utils::OpenHandle(*instance); - CHECK_EQ(i::JS_API_OBJECT_TYPE, js_obj->map().instance_type()); - return scope.Escape(instance); -} - -enum class TracePrologueBehavior { kNoop, kCallV8WriteBarrier }; - -class TestEmbedderHeapTracer final : public v8::EmbedderHeapTracer { - public: - TestEmbedderHeapTracer() = default; - TestEmbedderHeapTracer(TracePrologueBehavior prologue_behavior, - v8::Global<v8::Array> array) - : prologue_behavior_(prologue_behavior), array_(std::move(array)) {} - - void RegisterV8References( - const std::vector<std::pair<void*, void*>>& embedder_fields) final { - registered_from_v8_.insert(registered_from_v8_.end(), - embedder_fields.begin(), embedder_fields.end()); - } - - void AddReferenceForTracing(v8::TracedReference<v8::Value>* ref) { - to_register_with_v8_references_.push_back(ref); - } - - bool AdvanceTracing(double deadline_in_ms) final { - for (auto ref : to_register_with_v8_references_) { - RegisterEmbedderReference(ref->As<v8::Data>()); - } - to_register_with_v8_references_.clear(); - return true; - } - - bool IsTracingDone() final { return to_register_with_v8_references_.empty(); } - - void TracePrologue(EmbedderHeapTracer::TraceFlags) final { - if (prologue_behavior_ == TracePrologueBehavior::kCallV8WriteBarrier) { - auto local = array_.Get(isolate()); - local - ->Set(local->GetCreationContext().ToLocalChecked(), 0, - v8::Object::New(isolate())) - .Check(); - } - } - - void TraceEpilogue(TraceSummary*) final {} - void EnterFinalPause(EmbedderStackState) final {} - - bool IsRegisteredFromV8(void* first_field) const { - for (auto pair : registered_from_v8_) { - if (pair.first == first_field) return true; - } - return false; - } - - void DoNotConsiderAsRootForScavenge(v8::TracedReference<v8::Value>* handle) { - handle->SetWrapperClassId(17); - non_root_handles_.push_back(handle); - } - - bool IsRootForNonTracingGC( - const v8::TracedReference<v8::Value>& handle) final { - return handle.WrapperClassId() != 17; - } - - void ResetHandleInNonTracingGC( - const v8::TracedReference<v8::Value>& handle) final { - for (auto* non_root_handle : non_root_handles_) { - if (*non_root_handle == handle) { - non_root_handle->Reset(); - } - } - } - - private: - std::vector<std::pair<void*, void*>> registered_from_v8_; - std::vector<v8::TracedReference<v8::Value>*> to_register_with_v8_references_; - TracePrologueBehavior prologue_behavior_ = TracePrologueBehavior::kNoop; - v8::Global<v8::Array> array_; - std::vector<v8::TracedReference<v8::Value>*> non_root_handles_; -}; - -} // namespace - -TEST(V8RegisteringEmbedderReference) { - // Tests that wrappers are properly registered with the embedder heap - // tracer. - ManualGCScope manual_gc; - CcTest::InitializeVM(); - v8::Isolate* isolate = CcTest::isolate(); - TestEmbedderHeapTracer tracer; - heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer); - v8::HandleScope scope(isolate); - v8::Local<v8::Context> context = v8::Context::New(isolate); - v8::Context::Scope context_scope(context); - - void* first_and_second_field = reinterpret_cast<void*>(0x2); - v8::Local<v8::Object> api_object = ConstructTraceableJSApiObject( - context, first_and_second_field, first_and_second_field); - CHECK(!api_object.IsEmpty()); - CcTest::CollectGarbage(i::OLD_SPACE); - CHECK(tracer.IsRegisteredFromV8(first_and_second_field)); -} - -TEST(EmbedderRegisteringV8Reference) { - // Tests that references that are registered by the embedder heap tracer are - // considered live by V8. - ManualGCScope manual_gc; - CcTest::InitializeVM(); - v8::Isolate* isolate = CcTest::isolate(); - TestEmbedderHeapTracer tracer; - heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer); - v8::HandleScope scope(isolate); - v8::Local<v8::Context> context = v8::Context::New(isolate); - v8::Context::Scope context_scope(context); - - auto handle = std::make_unique<v8::TracedReference<v8::Value>>(); - { - v8::HandleScope inner_scope(isolate); - v8::Local<v8::Value> o = - v8::Local<v8::Object>::New(isolate, v8::Object::New(isolate)); - handle->Reset(isolate, o); - } - tracer.AddReferenceForTracing(handle.get()); - CcTest::CollectGarbage(i::OLD_SPACE); - CHECK(!handle->IsEmpty()); -} - -namespace { - -void ResurrectingFinalizer( - const v8::WeakCallbackInfo<v8::Global<v8::Object>>& data) { - data.GetParameter()->ClearWeak(); -} - -} // namespace - -TEST(TracingInRevivedSubgraph) { - // Tests that wrappers are traced when they are contained with in a subgraph - // that is revived by a finalizer. - ManualGCScope manual_gc; - CcTest::InitializeVM(); - v8::Isolate* isolate = CcTest::isolate(); - TestEmbedderHeapTracer tracer; - heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer); - v8::HandleScope scope(isolate); - v8::Local<v8::Context> context = v8::Context::New(isolate); - v8::Context::Scope context_scope(context); - - v8::Global<v8::Object> g; - void* first_and_second_field = reinterpret_cast<void*>(0x4); - { - v8::HandleScope inner_scope(isolate); - v8::Local<v8::Object> api_object = ConstructTraceableJSApiObject( - context, first_and_second_field, first_and_second_field); - CHECK(!api_object.IsEmpty()); - v8::Local<v8::Object> o = - v8::Local<v8::Object>::New(isolate, v8::Object::New(isolate)); - o->Set(context, v8_str("link"), api_object).FromJust(); - g.Reset(isolate, o); - g.SetWeak(&g, ResurrectingFinalizer, v8::WeakCallbackType::kFinalizer); - } - CcTest::CollectGarbage(i::OLD_SPACE); - CHECK(tracer.IsRegisteredFromV8(first_and_second_field)); -} - -TEST(TracingInEphemerons) { - // Tests that wrappers that are part of ephemerons are traced. - ManualGCScope manual_gc; - CcTest::InitializeVM(); - v8::Isolate* isolate = CcTest::isolate(); - TestEmbedderHeapTracer tracer; - heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer); - v8::HandleScope scope(isolate); - v8::Local<v8::Context> context = v8::Context::New(isolate); - v8::Context::Scope context_scope(context); - - v8::Local<v8::Object> key = - v8::Local<v8::Object>::New(isolate, v8::Object::New(isolate)); - void* first_and_second_field = reinterpret_cast<void*>(0x8); - i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); - Handle<JSWeakMap> weak_map = i_isolate->factory()->NewJSWeakMap(); - { - v8::HandleScope inner_scope(isolate); - v8::Local<v8::Object> api_object = ConstructTraceableJSApiObject( - context, first_and_second_field, first_and_second_field); - CHECK(!api_object.IsEmpty()); - Handle<JSObject> js_key = - handle(JSObject::cast(*v8::Utils::OpenHandle(*key)), i_isolate); - Handle<JSReceiver> js_api_object = v8::Utils::OpenHandle(*api_object); - int32_t hash = js_key->GetOrCreateHash(i_isolate).value(); - JSWeakCollection::Set(weak_map, js_key, js_api_object, hash); - } - CcTest::CollectGarbage(i::OLD_SPACE); - CHECK(tracer.IsRegisteredFromV8(first_and_second_field)); -} - -TEST(FinalizeTracingIsNoopWhenNotMarking) { - ManualGCScope manual_gc; - CcTest::InitializeVM(); - v8::Isolate* isolate = CcTest::isolate(); - Isolate* i_isolate = CcTest::i_isolate(); - TestEmbedderHeapTracer tracer; - heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer); - - // Finalize a potentially running garbage collection. - i_isolate->heap()->CollectGarbage(OLD_SPACE, - GarbageCollectionReason::kTesting); - CHECK(i_isolate->heap()->incremental_marking()->IsStopped()); - - int gc_counter = i_isolate->heap()->gc_count(); - tracer.FinalizeTracing(); - CHECK(i_isolate->heap()->incremental_marking()->IsStopped()); - CHECK_EQ(gc_counter, i_isolate->heap()->gc_count()); -} - -TEST(FinalizeTracingWhenMarking) { - if (!FLAG_incremental_marking) return; - ManualGCScope manual_gc; - CcTest::InitializeVM(); - v8::Isolate* isolate = CcTest::isolate(); - Heap* heap = CcTest::i_isolate()->heap(); - TestEmbedderHeapTracer tracer; - heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer); - - // Finalize a potentially running garbage collection. - heap->CollectGarbage(OLD_SPACE, GarbageCollectionReason::kTesting); - if (heap->mark_compact_collector()->sweeping_in_progress()) { - heap->mark_compact_collector()->EnsureSweepingCompleted( - MarkCompactCollector::SweepingForcedFinalizationMode::kV8Only); - } - heap->tracer()->StopCycleIfNeeded(); - CHECK(heap->incremental_marking()->IsStopped()); - - i::IncrementalMarking* marking = heap->incremental_marking(); - { - SafepointScope scope(heap); - heap->tracer()->StartCycle( - GarbageCollector::MARK_COMPACTOR, GarbageCollectionReason::kTesting, - "collector cctest", GCTracer::MarkingType::kIncremental); - marking->Start(GarbageCollectionReason::kTesting); - } - - // Sweeping is not runing so we should immediately start marking. - CHECK(marking->IsMarking()); - tracer.FinalizeTracing(); - CHECK(marking->IsStopped()); -} - -namespace { - -void ConstructJSObject(v8::Isolate* isolate, v8::Local<v8::Context> context, - v8::TracedReference<v8::Object>* handle) { - v8::HandleScope scope(isolate); - v8::Local<v8::Object> object(v8::Object::New(isolate)); - CHECK(!object.IsEmpty()); - *handle = v8::TracedReference<v8::Object>(isolate, object); - CHECK(!handle->IsEmpty()); -} - -template <typename T> -void ConstructJSApiObject(v8::Isolate* isolate, v8::Local<v8::Context> context, - T* global) { - v8::HandleScope scope(isolate); - v8::Local<v8::Object> object( - ConstructTraceableJSApiObject(context, nullptr, nullptr)); - CHECK(!object.IsEmpty()); - *global = T(isolate, object); - CHECK(!global->IsEmpty()); -} - -enum class SurvivalMode { kSurvives, kDies }; - -template <typename ModifierFunction, typename ConstructTracedReferenceFunction> -void TracedReferenceTest(v8::Isolate* isolate, - ConstructTracedReferenceFunction construct_function, - ModifierFunction modifier_function, - void (*gc_function)(), SurvivalMode survives) { - v8::HandleScope scope(isolate); - v8::Local<v8::Context> context = v8::Context::New(isolate); - v8::Context::Scope context_scope(context); - auto* global_handles = - reinterpret_cast<i::Isolate*>(isolate)->global_handles(); - - const size_t initial_count = global_handles->handles_count(); - auto handle = std::make_unique<v8::TracedReference<v8::Object>>(); - construct_function(isolate, context, handle.get()); - CHECK(InCorrectGeneration(isolate, *handle)); - modifier_function(*handle); - const size_t after_modification_count = global_handles->handles_count(); - gc_function(); - // Cannot check the handle as it is not explicitly cleared by the GC. Instead - // check the handles count. - CHECK_IMPLIES(survives == SurvivalMode::kSurvives, - after_modification_count == global_handles->handles_count()); - CHECK_IMPLIES(survives == SurvivalMode::kDies, - initial_count == global_handles->handles_count()); -} - -} // namespace - -TEST(TracedReferenceReset) { - CcTest::InitializeVM(); - v8::Isolate* isolate = CcTest::isolate(); - v8::HandleScope scope(isolate); - - v8::TracedReference<v8::Object> handle; - ConstructJSObject(isolate, isolate->GetCurrentContext(), &handle); - CHECK(!handle.IsEmpty()); - handle.Reset(); - CHECK(handle.IsEmpty()); -} - -TEST(TracedReferenceCopyReferences) { - ManualGCScope manual_gc; - CcTest::InitializeVM(); - v8::Isolate* isolate = CcTest::isolate(); - v8::HandleScope outer_scope(isolate); - i::GlobalHandles* global_handles = CcTest::i_isolate()->global_handles(); - - const size_t initial_count = global_handles->handles_count(); - auto handle1 = std::make_unique<v8::TracedReference<v8::Value>>(); - { - v8::HandleScope scope(isolate); - handle1->Reset(isolate, v8::Object::New(isolate)); - } - auto handle2 = std::make_unique<v8::TracedReference<v8::Value>>(*handle1); - auto handle3 = std::make_unique<v8::TracedReference<v8::Value>>(); - *handle3 = *handle2; - CHECK_EQ(initial_count + 3, global_handles->handles_count()); - CHECK(!handle1->IsEmpty()); - CHECK_EQ(*handle1, *handle2); - CHECK_EQ(*handle2, *handle3); - { - v8::HandleScope scope(isolate); - auto tmp = v8::Local<v8::Value>::New(isolate, *handle3); - CHECK(!tmp.IsEmpty()); - InvokeMarkSweep(); - } - CHECK_EQ(initial_count + 3, global_handles->handles_count()); - CHECK(!handle1->IsEmpty()); - CHECK_EQ(*handle1, *handle2); - CHECK_EQ(*handle2, *handle3); - InvokeMarkSweep(); - CHECK_EQ(initial_count, global_handles->handles_count()); -} - -TEST(TracedReferenceToUnmodifiedJSObjectDiesOnMarkSweep) { - // When stressing incremental marking, a write barrier may keep the object - // alive. - if (FLAG_stress_incremental_marking) return; - - CcTest::InitializeVM(); - TracedReferenceTest( - CcTest::isolate(), ConstructJSObject, - [](const TracedReference<v8::Object>&) {}, [] { InvokeMarkSweep(); }, - SurvivalMode::kDies); -} - -TEST(TracedReferenceToUnmodifiedJSObjectSurvivesMarkSweepWhenHeldAlive) { - CcTest::InitializeVM(); - v8::Isolate* isolate = CcTest::isolate(); - v8::Global<v8::Object> strong_global; - TracedReferenceTest( - CcTest::isolate(), ConstructJSObject, - [isolate, &strong_global](const TracedReference<v8::Object>& handle) { - v8::HandleScope scope(isolate); - strong_global = v8::Global<v8::Object>(isolate, handle.Get(isolate)); - }, - []() { InvokeMarkSweep(); }, SurvivalMode::kSurvives); -} - -TEST(TracedReferenceToUnmodifiedJSObjectSurvivesScavenge) { - if (FLAG_single_generation) return; - ManualGCScope manual_gc; - CcTest::InitializeVM(); - TracedReferenceTest( - CcTest::isolate(), ConstructJSObject, - [](const TracedReference<v8::Object>&) {}, []() { InvokeScavenge(); }, - SurvivalMode::kSurvives); -} - -TEST(TracedReferenceToUnmodifiedJSObjectSurvivesScavengeWhenExcludedFromRoots) { - if (FLAG_single_generation) return; - ManualGCScope manual_gc; - CcTest::InitializeVM(); - v8::Isolate* isolate = CcTest::isolate(); - TestEmbedderHeapTracer tracer; - heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer); - TracedReferenceTest( - CcTest::isolate(), ConstructJSObject, - [&tracer](const TracedReference<v8::Object>& handle) { - tracer.DoNotConsiderAsRootForScavenge(&handle.As<v8::Value>()); - }, - []() { InvokeScavenge(); }, SurvivalMode::kSurvives); -} - -TEST(TracedReferenceToUnmodifiedJSApiObjectSurvivesScavengePerDefault) { - if (FLAG_single_generation) return; - ManualGCScope manual_gc; - CcTest::InitializeVM(); - v8::Isolate* isolate = CcTest::isolate(); - TestEmbedderHeapTracer tracer; - heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer); - TracedReferenceTest( - CcTest::isolate(), ConstructJSApiObject<TracedReference<v8::Object>>, - [](const TracedReference<v8::Object>&) {}, []() { InvokeScavenge(); }, - SurvivalMode::kSurvives); -} - -TEST( - TracedReferenceToUnmodifiedJSApiObjectDiesOnScavengeWhenExcludedFromRoots) { - if (FLAG_single_generation) return; - ManualGCScope manual_gc; - CcTest::InitializeVM(); - v8::Isolate* isolate = CcTest::isolate(); - TestEmbedderHeapTracer tracer; - heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer); - TracedReferenceTest( - CcTest::isolate(), ConstructJSApiObject<TracedReference<v8::Object>>, - [&tracer](const TracedReference<v8::Object>& handle) { - tracer.DoNotConsiderAsRootForScavenge(&handle.As<v8::Value>()); - }, - []() { InvokeScavenge(); }, SurvivalMode::kDies); -} - -TEST(TracedReferenceWrapperClassId) { - ManualGCScope manual_gc; - CcTest::InitializeVM(); - v8::Isolate* isolate = CcTest::isolate(); - v8::HandleScope scope(isolate); - TestEmbedderHeapTracer tracer; - heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer); - - v8::TracedReference<v8::Object> traced; - ConstructJSObject(isolate, isolate->GetCurrentContext(), &traced); - CHECK_EQ(0, traced.WrapperClassId()); - traced.SetWrapperClassId(17); - CHECK_EQ(17, traced.WrapperClassId()); -} - -TEST(TracedReferenceHandlesMarking) { - ManualGCScope manual_gc; - CcTest::InitializeVM(); - v8::Isolate* isolate = CcTest::isolate(); - v8::HandleScope scope(isolate); - auto live = std::make_unique<v8::TracedReference<v8::Value>>(); - auto dead = std::make_unique<v8::TracedReference<v8::Value>>(); - live->Reset(isolate, v8::Undefined(isolate)); - dead->Reset(isolate, v8::Undefined(isolate)); - i::GlobalHandles* global_handles = CcTest::i_isolate()->global_handles(); - { - TestEmbedderHeapTracer tracer; - heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer); - tracer.AddReferenceForTracing(live.get()); - const size_t initial_count = global_handles->handles_count(); - InvokeMarkSweep(); - const size_t final_count = global_handles->handles_count(); - // Handles are black allocated, so the first GC does not collect them. - CHECK_EQ(initial_count, final_count); - } - - { - TestEmbedderHeapTracer tracer; - heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer); - tracer.AddReferenceForTracing(live.get()); - const size_t initial_count = global_handles->handles_count(); - InvokeMarkSweep(); - const size_t final_count = global_handles->handles_count(); - CHECK_EQ(initial_count, final_count + 1); - } -} - -TEST(TracedReferenceHandlesDoNotLeak) { - // TracedReference handles are not cleared by the destructor of the embedder - // object. To avoid leaks we need to mark these handles during GC. - // This test checks that unmarked handles do not leak. - ManualGCScope manual_gc; - CcTest::InitializeVM(); - v8::Isolate* isolate = CcTest::isolate(); - v8::HandleScope scope(isolate); - auto ref = std::make_unique<v8::TracedReference<v8::Value>>(); - ref->Reset(isolate, v8::Undefined(isolate)); - i::GlobalHandles* global_handles = CcTest::i_isolate()->global_handles(); - const size_t initial_count = global_handles->handles_count(); - // We need two GCs because handles are black allocated. - InvokeMarkSweep(); - InvokeMarkSweep(); - const size_t final_count = global_handles->handles_count(); - CHECK_EQ(initial_count, final_count + 1); -} - -namespace { - -class TracedReferenceVisitor final - : public v8::EmbedderHeapTracer::TracedGlobalHandleVisitor { - public: - ~TracedReferenceVisitor() override = default; - - void VisitTracedReference(const TracedReference<Value>& value) final { - if (value.WrapperClassId() == 57) { - count_++; - } - } - - size_t count() const { return count_; } - - private: - size_t count_ = 0; -}; - -} // namespace - -TEST(TracedReferenceIteration) { - ManualGCScope manual_gc; - CcTest::InitializeVM(); - v8::Isolate* isolate = CcTest::isolate(); - v8::HandleScope scope(isolate); - TestEmbedderHeapTracer tracer; - heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer); - - auto handle = std::make_unique<v8::TracedReference<v8::Object>>(); - ConstructJSObject(isolate, isolate->GetCurrentContext(), handle.get()); - CHECK(!handle->IsEmpty()); - handle->SetWrapperClassId(57); - TracedReferenceVisitor visitor; - { - v8::HandleScope new_scope(isolate); - tracer.IterateTracedGlobalHandles(&visitor); - } - CHECK_EQ(1, visitor.count()); -} - -TEST(TracePrologueCallingIntoV8WriteBarrier) { - // Regression test: https://crbug.com/940003 - if (!FLAG_incremental_marking) return; - ManualGCScope manual_gc; - CcTest::InitializeVM(); - v8::Isolate* isolate = CcTest::isolate(); - v8::HandleScope scope(isolate); - v8::Global<v8::Array> global; - { - v8::HandleScope new_scope(isolate); - auto local = v8::Array::New(isolate, 10); - global.Reset(isolate, local); - } - TestEmbedderHeapTracer tracer(TracePrologueBehavior::kCallV8WriteBarrier, - std::move(global)); - heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer); - SimulateIncrementalMarking(CcTest::i_isolate()->heap()); - // Finish GC to avoid removing the tracer while GC is running which may end up - // in an infinite loop because of unprocessed objects. - heap::InvokeMarkSweep(); -} - -TEST(BasicTracedReference) { - ManualGCScope manual_gc; - CcTest::InitializeVM(); - v8::Isolate* isolate = CcTest::isolate(); - v8::HandleScope scope(isolate); - TestEmbedderHeapTracer tracer; - heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer); - i::GlobalHandles* global_handles = CcTest::i_isolate()->global_handles(); - - const size_t initial_count = global_handles->handles_count(); - char* memory = new char[sizeof(v8::TracedReference<v8::Value>)]; - auto* traced = new (memory) v8::TracedReference<v8::Value>(); - { - v8::HandleScope new_scope(isolate); - v8::Local<v8::Value> object(ConstructTraceableJSApiObject( - isolate->GetCurrentContext(), nullptr, nullptr)); - CHECK(traced->IsEmpty()); - *traced = v8::TracedReference<v8::Value>(isolate, object); - CHECK(!traced->IsEmpty()); - CHECK_EQ(initial_count + 1, global_handles->handles_count()); - } - traced->~TracedReference<v8::Value>(); - CHECK_EQ(initial_count + 1, global_handles->handles_count()); - // GC should clear the handle. - heap::InvokeMarkSweep(); - CHECK_EQ(initial_count, global_handles->handles_count()); - delete[] memory; -} - -namespace { - -class EmptyEmbedderHeapTracer : public v8::EmbedderHeapTracer { - public: - void RegisterV8References( - const std::vector<std::pair<void*, void*>>& embedder_fields) final {} - - bool AdvanceTracing(double deadline_in_ms) final { return true; } - bool IsTracingDone() final { return true; } - void TracePrologue(EmbedderHeapTracer::TraceFlags) final {} - void TraceEpilogue(TraceSummary*) final {} - void EnterFinalPause(EmbedderStackState) final {} -}; - -// EmbedderHeapTracer that can optimize Scavenger handling when used with -// TracedReference. -class EmbedderHeapTracerNoDestructorNonTracingClearing final - : public EmptyEmbedderHeapTracer { - public: - explicit EmbedderHeapTracerNoDestructorNonTracingClearing( - uint16_t class_id_to_optimize) - : class_id_to_optimize_(class_id_to_optimize) {} - - bool IsRootForNonTracingGC( - const v8::TracedReference<v8::Value>& handle) final { - return handle.WrapperClassId() != class_id_to_optimize_; - } - - void ResetHandleInNonTracingGC( - const v8::TracedReference<v8::Value>& handle) final { - if (handle.WrapperClassId() != class_id_to_optimize_) return; - - // Convention (for test): Objects that are optimized have their first field - // set as a back pointer. - BasicTracedReference<v8::Value>* original_handle = - reinterpret_cast<BasicTracedReference<v8::Value>*>( - v8::Object::GetAlignedPointerFromInternalField( - handle.As<v8::Object>(), 0)); - original_handle->Reset(); - } - - private: - uint16_t class_id_to_optimize_; -}; - -template <typename T> -void SetupOptimizedAndNonOptimizedHandle(v8::Isolate* isolate, - uint16_t optimized_class_id, - T* optimized_handle, - T* non_optimized_handle) { - v8::HandleScope scope(isolate); - - v8::Local<v8::Object> optimized_object(ConstructTraceableJSApiObject( - isolate->GetCurrentContext(), optimized_handle, nullptr)); - CHECK(optimized_handle->IsEmpty()); - *optimized_handle = T(isolate, optimized_object); - CHECK(!optimized_handle->IsEmpty()); - optimized_handle->SetWrapperClassId(optimized_class_id); - - v8::Local<v8::Object> non_optimized_object(ConstructTraceableJSApiObject( - isolate->GetCurrentContext(), nullptr, nullptr)); - CHECK(non_optimized_handle->IsEmpty()); - *non_optimized_handle = T(isolate, non_optimized_object); - CHECK(!non_optimized_handle->IsEmpty()); -} - -} // namespace - -TEST(TracedReferenceNoDestructorReclaimedOnScavenge) { - if (FLAG_single_generation) return; - ManualGCScope manual_gc; - CcTest::InitializeVM(); - v8::Isolate* isolate = CcTest::isolate(); - v8::HandleScope scope(isolate); - constexpr uint16_t kClassIdToOptimize = 23; - EmbedderHeapTracerNoDestructorNonTracingClearing tracer(kClassIdToOptimize); - heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer); - i::GlobalHandles* global_handles = CcTest::i_isolate()->global_handles(); - - const size_t initial_count = global_handles->handles_count(); - auto* optimized_handle = new v8::TracedReference<v8::Value>(); - auto* non_optimized_handle = new v8::TracedReference<v8::Value>(); - SetupOptimizedAndNonOptimizedHandle(isolate, kClassIdToOptimize, - optimized_handle, non_optimized_handle); - CHECK_EQ(initial_count + 2, global_handles->handles_count()); - heap::InvokeScavenge(); - CHECK_EQ(initial_count + 1, global_handles->handles_count()); - CHECK(optimized_handle->IsEmpty()); - delete optimized_handle; - CHECK(!non_optimized_handle->IsEmpty()); - non_optimized_handle->Reset(); - delete non_optimized_handle; - CHECK_EQ(initial_count, global_handles->handles_count()); -} - -namespace { - -template <typename T> -V8_NOINLINE void OnStackTest(TestEmbedderHeapTracer* tracer) { - v8::Isolate* isolate = CcTest::isolate(); - v8::Global<v8::Object> observer; - T stack_ref; - { - v8::HandleScope scope(isolate); - v8::Local<v8::Object> object(ConstructTraceableJSApiObject( - isolate->GetCurrentContext(), nullptr, nullptr)); - stack_ref.Reset(isolate, object); - observer.Reset(isolate, object); - observer.SetWeak(); - } - CHECK(!observer.IsEmpty()); - heap::InvokeMarkSweep(); - CHECK(!observer.IsEmpty()); -} - -V8_NOINLINE void CreateTracedReferenceInDeepStack( - v8::Isolate* isolate, v8::Global<v8::Object>* observer) { - v8::TracedReference<v8::Value> stack_ref; - v8::HandleScope scope(isolate); - v8::Local<v8::Object> object(ConstructTraceableJSApiObject( - isolate->GetCurrentContext(), nullptr, nullptr)); - stack_ref.Reset(isolate, object); - observer->Reset(isolate, object); - observer->SetWeak(); -} - -V8_NOINLINE void TracedReferenceNotifyEmptyStackTest( - TestEmbedderHeapTracer* tracer) { - v8::Isolate* isolate = CcTest::isolate(); - v8::Global<v8::Object> observer; - CreateTracedReferenceInDeepStack(isolate, &observer); - CHECK(!observer.IsEmpty()); - reinterpret_cast<i::Isolate*>(isolate) - ->heap() - ->local_embedder_heap_tracer() - ->NotifyEmptyEmbedderStack(); - heap::InvokeMarkSweep(); - CHECK(observer.IsEmpty()); -} - -enum class Operation { - kCopy, - kMove, -}; - -template <typename T> -void PerformOperation(Operation op, T* lhs, T* rhs) { - switch (op) { - case Operation::kMove: - *lhs = std::move(*rhs); - break; - case Operation::kCopy: - *lhs = *rhs; - rhs->Reset(); - break; - } -} - -enum class TargetHandling { - kNonInitialized, - kInitializedYoungGen, - kInitializedOldGen -}; - -V8_NOINLINE void StackToHeapTest(TestEmbedderHeapTracer* tracer, Operation op, - TargetHandling target_handling) { - v8::Isolate* isolate = CcTest::isolate(); - v8::Global<v8::Object> observer; - v8::TracedReference<v8::Value> stack_handle; - v8::TracedReference<v8::Value>* heap_handle = - new v8::TracedReference<v8::Value>(); - if (target_handling != TargetHandling::kNonInitialized) { - v8::HandleScope scope(isolate); - v8::Local<v8::Object> to_object(ConstructTraceableJSApiObject( - isolate->GetCurrentContext(), nullptr, nullptr)); - CHECK(InCorrectGeneration(*v8::Utils::OpenHandle(*to_object))); - if (!FLAG_single_generation && - target_handling == TargetHandling::kInitializedOldGen) { - heap::InvokeScavenge(); - heap::InvokeScavenge(); - CHECK(!i::Heap::InYoungGeneration(*v8::Utils::OpenHandle(*to_object))); - } - heap_handle->Reset(isolate, to_object); - } - { - v8::HandleScope scope(isolate); - v8::Local<v8::Object> object(ConstructTraceableJSApiObject( - isolate->GetCurrentContext(), nullptr, nullptr)); - stack_handle.Reset(isolate, object); - observer.Reset(isolate, object); - observer.SetWeak(); - } - CHECK(!observer.IsEmpty()); - tracer->AddReferenceForTracing(heap_handle); - heap::InvokeMarkSweep(); - CHECK(!observer.IsEmpty()); - tracer->AddReferenceForTracing(heap_handle); - PerformOperation(op, heap_handle, &stack_handle); - heap::InvokeMarkSweep(); - CHECK(!observer.IsEmpty()); - heap::InvokeMarkSweep(); - CHECK(observer.IsEmpty()); - delete heap_handle; -} - -V8_NOINLINE void HeapToStackTest(TestEmbedderHeapTracer* tracer, Operation op, - TargetHandling target_handling) { - v8::Isolate* isolate = CcTest::isolate(); - v8::Global<v8::Object> observer; - v8::TracedReference<v8::Value> stack_handle; - v8::TracedReference<v8::Value>* heap_handle = - new v8::TracedReference<v8::Value>(); - if (target_handling != TargetHandling::kNonInitialized) { - v8::HandleScope scope(isolate); - v8::Local<v8::Object> to_object(ConstructTraceableJSApiObject( - isolate->GetCurrentContext(), nullptr, nullptr)); - CHECK(InCorrectGeneration(*v8::Utils::OpenHandle(*to_object))); - if (!FLAG_single_generation && - target_handling == TargetHandling::kInitializedOldGen) { - heap::InvokeScavenge(); - heap::InvokeScavenge(); - CHECK(!i::Heap::InYoungGeneration(*v8::Utils::OpenHandle(*to_object))); - } - stack_handle.Reset(isolate, to_object); - } - { - v8::HandleScope scope(isolate); - v8::Local<v8::Object> object(ConstructTraceableJSApiObject( - isolate->GetCurrentContext(), nullptr, nullptr)); - heap_handle->Reset(isolate, object); - observer.Reset(isolate, object); - observer.SetWeak(); - } - CHECK(!observer.IsEmpty()); - tracer->AddReferenceForTracing(heap_handle); - heap::InvokeMarkSweep(); - CHECK(!observer.IsEmpty()); - PerformOperation(op, &stack_handle, heap_handle); - heap::InvokeMarkSweep(); - CHECK(!observer.IsEmpty()); - stack_handle.Reset(); - heap::InvokeMarkSweep(); - CHECK(observer.IsEmpty()); - delete heap_handle; -} - -V8_NOINLINE void StackToStackTest(TestEmbedderHeapTracer* tracer, Operation op, - TargetHandling target_handling) { - v8::Isolate* isolate = CcTest::isolate(); - v8::Global<v8::Object> observer; - v8::TracedReference<v8::Value> stack_handle1; - v8::TracedReference<v8::Value> stack_handle2; - if (target_handling != TargetHandling::kNonInitialized) { - v8::HandleScope scope(isolate); - v8::Local<v8::Object> to_object(ConstructTraceableJSApiObject( - isolate->GetCurrentContext(), nullptr, nullptr)); - CHECK(InCorrectGeneration(*v8::Utils::OpenHandle(*to_object))); - if (!FLAG_single_generation && - target_handling == TargetHandling::kInitializedOldGen) { - heap::InvokeScavenge(); - heap::InvokeScavenge(); - CHECK(!i::Heap::InYoungGeneration(*v8::Utils::OpenHandle(*to_object))); - } - stack_handle2.Reset(isolate, to_object); - } - { - v8::HandleScope scope(isolate); - v8::Local<v8::Object> object(ConstructTraceableJSApiObject( - isolate->GetCurrentContext(), nullptr, nullptr)); - stack_handle1.Reset(isolate, object); - observer.Reset(isolate, object); - observer.SetWeak(); - } - CHECK(!observer.IsEmpty()); - heap::InvokeMarkSweep(); - CHECK(!observer.IsEmpty()); - PerformOperation(op, &stack_handle2, &stack_handle1); - heap::InvokeMarkSweep(); - CHECK(!observer.IsEmpty()); - stack_handle2.Reset(); - heap::InvokeMarkSweep(); - CHECK(observer.IsEmpty()); -} - -V8_NOINLINE void TracedReferenceCleanedTest(TestEmbedderHeapTracer* tracer) { - v8::Isolate* isolate = CcTest::isolate(); - v8::HandleScope scope(isolate); - v8::Local<v8::Object> object(ConstructTraceableJSApiObject( - isolate->GetCurrentContext(), nullptr, nullptr)); - const size_t before = - CcTest::i_isolate()->global_handles()->NumberOfOnStackHandlesForTesting(); - for (int i = 0; i < 100; i++) { - v8::TracedReference<v8::Value> stack_handle; - stack_handle.Reset(isolate, object); - } - CHECK_EQ(before + 1, CcTest::i_isolate() - ->global_handles() - ->NumberOfOnStackHandlesForTesting()); -} - -} // namespace - -TEST(TracedReferenceOnStack) { - ManualGCScope manual_gc; - CcTest::InitializeVM(); - TestEmbedderHeapTracer tracer; - heap::TemporaryEmbedderHeapTracerScope tracer_scope(CcTest::isolate(), - &tracer); - tracer.SetStackStart(&manual_gc); - OnStackTest<v8::TracedReference<v8::Value>>(&tracer); -} - -TEST(TracedReferenceCleaned) { - ManualGCScope manual_gc; - CcTest::InitializeVM(); - TestEmbedderHeapTracer tracer; - heap::TemporaryEmbedderHeapTracerScope tracer_scope(CcTest::isolate(), - &tracer); - tracer.SetStackStart(&manual_gc); - TracedReferenceCleanedTest(&tracer); -} - -TEST(TracedReferenceMove) { - ManualGCScope manual_gc; - CcTest::InitializeVM(); - TestEmbedderHeapTracer tracer; - heap::TemporaryEmbedderHeapTracerScope tracer_scope(CcTest::isolate(), - &tracer); - tracer.SetStackStart(&manual_gc); - StackToHeapTest(&tracer, Operation::kMove, TargetHandling::kNonInitialized); - StackToHeapTest(&tracer, Operation::kMove, - TargetHandling::kInitializedYoungGen); - StackToHeapTest(&tracer, Operation::kMove, - TargetHandling::kInitializedOldGen); - HeapToStackTest(&tracer, Operation::kMove, TargetHandling::kNonInitialized); - HeapToStackTest(&tracer, Operation::kMove, - TargetHandling::kInitializedYoungGen); - HeapToStackTest(&tracer, Operation::kMove, - TargetHandling::kInitializedOldGen); - StackToStackTest(&tracer, Operation::kMove, TargetHandling::kNonInitialized); - StackToStackTest(&tracer, Operation::kMove, - TargetHandling::kInitializedYoungGen); - StackToStackTest(&tracer, Operation::kMove, - TargetHandling::kInitializedOldGen); -} - -TEST(TracedReferenceCopy) { - ManualGCScope manual_gc; - CcTest::InitializeVM(); - TestEmbedderHeapTracer tracer; - heap::TemporaryEmbedderHeapTracerScope tracer_scope(CcTest::isolate(), - &tracer); - tracer.SetStackStart(&manual_gc); - StackToHeapTest(&tracer, Operation::kCopy, TargetHandling::kNonInitialized); - StackToHeapTest(&tracer, Operation::kCopy, - TargetHandling::kInitializedYoungGen); - StackToHeapTest(&tracer, Operation::kCopy, - TargetHandling::kInitializedOldGen); - HeapToStackTest(&tracer, Operation::kCopy, TargetHandling::kNonInitialized); - HeapToStackTest(&tracer, Operation::kCopy, - TargetHandling::kInitializedYoungGen); - HeapToStackTest(&tracer, Operation::kCopy, - TargetHandling::kInitializedOldGen); - StackToStackTest(&tracer, Operation::kCopy, TargetHandling::kNonInitialized); - StackToStackTest(&tracer, Operation::kCopy, - TargetHandling::kInitializedYoungGen); - StackToStackTest(&tracer, Operation::kCopy, - TargetHandling::kInitializedOldGen); -} - -TEST(NotifyEmptyStack) { - ManualGCScope manual_gc; - CcTest::InitializeVM(); - TestEmbedderHeapTracer tracer; - heap::TemporaryEmbedderHeapTracerScope tracer_scope(CcTest::isolate(), - &tracer); - tracer.SetStackStart(&manual_gc); - TracedReferenceNotifyEmptyStackTest(&tracer); -} - -} // namespace heap -} // namespace internal -} // namespace v8 - -END_ALLOW_USE_DEPRECATED() diff --git a/deps/v8/test/cctest/heap/test-heap.cc b/deps/v8/test/cctest/heap/test-heap.cc index f90922b8a5..e74e560e7a 100644 --- a/deps/v8/test/cctest/heap/test-heap.cc +++ b/deps/v8/test/cctest/heap/test-heap.cc @@ -48,6 +48,7 @@ #include "src/heap/incremental-marking.h" #include "src/heap/large-spaces.h" #include "src/heap/mark-compact.h" +#include "src/heap/marking-barrier.h" #include "src/heap/memory-chunk.h" #include "src/heap/memory-reducer.h" #include "src/heap/parked-scope.h" @@ -1561,7 +1562,8 @@ TEST(TestInternalWeakLists) { // Some flags turn Scavenge collections into Mark-sweep collections // and hence are incompatible with this test case. if (FLAG_gc_global || FLAG_stress_compaction || - FLAG_stress_incremental_marking || FLAG_single_generation) + FLAG_stress_incremental_marking || FLAG_single_generation || + FLAG_separate_gc_phases) return; FLAG_retain_maps_for_n_gc = 0; @@ -5450,8 +5452,9 @@ AllocationResult HeapTester::AllocateByteArrayForTest( } bool HeapTester::CodeEnsureLinearAllocationArea(Heap* heap, int size_in_bytes) { - bool result = heap->code_space()->EnsureLabMain(size_in_bytes, - AllocationOrigin::kRuntime); + bool result = heap->code_space()->EnsureAllocation( + size_in_bytes, AllocationAlignment::kTaggedAligned, + AllocationOrigin::kRuntime, nullptr); heap->code_space()->UpdateInlineAllocationLimit(0); return result; } @@ -5709,6 +5712,7 @@ TEST(Regress598319) { StepOrigin::kV8); if (marking->IsReadyToOverApproximateWeakClosure()) { SafepointScope safepoint_scope(heap); + MarkingBarrier::PublishAll(heap); marking->FinalizeIncrementally(); } } @@ -5828,7 +5832,7 @@ class StaticOneByteResource : public v8::String::ExternalOneByteStringResource { }; TEST(Regress631969) { - if (!FLAG_incremental_marking) return; + if (!FLAG_incremental_marking || FLAG_separate_gc_phases) return; FLAG_manual_evacuation_candidates_selection = true; FLAG_parallel_compaction = false; ManualGCScope manual_gc_scope; @@ -6255,7 +6259,7 @@ TEST(RememberedSet_InsertInLargePage) { } TEST(RememberedSet_InsertOnPromotingObjectToOld) { - if (FLAG_single_generation) return; + if (FLAG_single_generation || FLAG_stress_incremental_marking) return; FLAG_stress_concurrent_allocation = false; // For SealCurrentObjects. CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); @@ -6281,11 +6285,12 @@ TEST(RememberedSet_InsertOnPromotingObjectToOld) { CcTest::CollectGarbage(i::NEW_SPACE); CHECK(heap->InOldSpace(*arr)); + CHECK(heap->InYoungGeneration(arr->get(0))); CHECK_EQ(1, GetRememberedSetSize<OLD_TO_NEW>(*arr)); } TEST(RememberedSet_RemoveStaleOnScavenge) { - if (FLAG_single_generation) return; + if (FLAG_single_generation || FLAG_stress_incremental_marking) return; FLAG_stress_concurrent_allocation = false; // For SealCurrentObjects. CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); @@ -6457,7 +6462,7 @@ HEAP_TEST(Regress670675) { collector->EnsureSweepingCompleted( MarkCompactCollector::SweepingForcedFinalizationMode::kV8Only); } - heap->tracer()->StopCycleIfNeeded(); + heap->tracer()->StopFullCycleIfNeeded(); i::IncrementalMarking* marking = CcTest::heap()->incremental_marking(); if (marking->IsStopped()) { SafepointScope safepoint_scope(heap); @@ -6560,7 +6565,7 @@ Isolate* oom_isolate = nullptr; void OOMCallback(const char* location, bool is_heap_oom) { Heap* heap = oom_isolate->heap(); - size_t kSlack = heap->new_space() ? heap->new_space()->Capacity() : 0; + size_t kSlack = heap->new_space() ? heap->MaxSemiSpaceSize() : 0; CHECK_LE(heap->OldGenerationCapacity(), kHeapLimit + kSlack); CHECK_LE(heap->memory_allocator()->Size(), heap->MaxReserved() + kSlack); base::OS::ExitProcess(0); @@ -6765,9 +6770,9 @@ UNINITIALIZED_TEST(OutOfMemorySmallObjects) { } } CHECK_LE(state.old_generation_capacity_at_oom, - kOldGenerationLimit + state.new_space_capacity_at_oom); - CHECK_LE(kOldGenerationLimit, state.old_generation_capacity_at_oom + - state.new_space_capacity_at_oom); + kOldGenerationLimit + heap->MaxSemiSpaceSize()); + CHECK_LE(kOldGenerationLimit, + state.old_generation_capacity_at_oom + heap->MaxSemiSpaceSize()); CHECK_LE( state.memory_allocator_size_at_oom, MemoryAllocatorSizeFromHeapCapacity(state.old_generation_capacity_at_oom + @@ -6987,7 +6992,7 @@ TEST(CodeObjectRegistry) { TEST(Regress9701) { ManualGCScope manual_gc_scope; - if (!FLAG_incremental_marking) return; + if (!FLAG_incremental_marking || FLAG_separate_gc_phases) return; CcTest::InitializeVM(); Heap* heap = CcTest::heap(); // Start with an empty new space. diff --git a/deps/v8/test/cctest/heap/test-incremental-marking.cc b/deps/v8/test/cctest/heap/test-incremental-marking.cc index 702d66560e..7bda4c808a 100644 --- a/deps/v8/test/cctest/heap/test-incremental-marking.cc +++ b/deps/v8/test/cctest/heap/test-incremental-marking.cc @@ -35,16 +35,10 @@ namespace heap { class MockPlatform : public TestPlatform { public: - MockPlatform() - : taskrunner_(new MockTaskRunner()), - old_platform_(i::V8::GetCurrentPlatform()) { - // Now that it's completely constructed, make this the current platform. - i::V8::SetPlatformForTesting(this); - } + MockPlatform() : taskrunner_(new MockTaskRunner()) {} ~MockPlatform() override { - i::V8::SetPlatformForTesting(old_platform_); for (auto& task : worker_tasks_) { - old_platform_->CallOnWorkerThread(std::move(task)); + CcTest::default_platform()->CallOnWorkerThread(std::move(task)); } worker_tasks_.clear(); } @@ -106,17 +100,13 @@ class MockPlatform : public TestPlatform { std::shared_ptr<MockTaskRunner> taskrunner_; std::vector<std::unique_ptr<Task>> worker_tasks_; - v8::Platform* old_platform_; }; -UNINITIALIZED_TEST(IncrementalMarkingUsingTasks) { +TEST_WITH_PLATFORM(IncrementalMarkingUsingTasks, MockPlatform) { if (!i::FLAG_incremental_marking) return; FLAG_stress_concurrent_allocation = false; // For SimulateFullSpace. FLAG_stress_incremental_marking = false; - MockPlatform platform; - v8::Isolate::CreateParams create_params; - create_params.array_buffer_allocator = CcTest::array_buffer_allocator(); - v8::Isolate* isolate = v8::Isolate::New(create_params); + v8::Isolate* isolate = CcTest::isolate(); { v8::HandleScope handle_scope(isolate); v8::Local<v8::Context> context = CcTest::NewContext(isolate); @@ -140,7 +130,6 @@ UNINITIALIZED_TEST(IncrementalMarkingUsingTasks) { } CHECK(marking->IsStopped()); } - isolate->Dispose(); } } // namespace heap diff --git a/deps/v8/test/cctest/heap/test-lab.cc b/deps/v8/test/cctest/heap/test-lab.cc deleted file mode 100644 index 1ca4699c1c..0000000000 --- a/deps/v8/test/cctest/heap/test-lab.cc +++ /dev/null @@ -1,289 +0,0 @@ -// Copyright 2015 the V8 project authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <vector> - -#include "src/common/globals.h" -#include "src/heap/heap-inl.h" -#include "src/heap/spaces-inl.h" -#include "src/objects/objects.h" -#include "test/cctest/cctest.h" - -namespace v8 { -namespace internal { -namespace heap { - -static Address AllocateLabBackingStore(Heap* heap, intptr_t size_in_bytes) { - AllocationResult result = heap->old_space()->AllocateRawAligned( - static_cast<int>(size_in_bytes), kDoubleAligned); - Address adr = result.ToObjectChecked().address(); - return adr; -} - - -static void VerifyIterable(v8::internal::Address base, - v8::internal::Address limit, - std::vector<intptr_t> expected_size) { - CHECK_LE(base, limit); - HeapObject object; - size_t counter = 0; - while (base < limit) { - object = HeapObject::FromAddress(base); - CHECK(object.IsFreeSpaceOrFiller()); - CHECK_LT(counter, expected_size.size()); - CHECK_EQ(expected_size[counter], object.Size()); - base += object.Size(); - counter++; - } -} - -static bool AllocateFromLab(Heap* heap, LocalAllocationBuffer* lab, - intptr_t size_in_bytes, - AllocationAlignment alignment = kTaggedAligned) { - HeapObject obj; - AllocationResult result = - lab->AllocateRawAligned(static_cast<int>(size_in_bytes), alignment); - if (result.To(&obj)) { - heap->CreateFillerObjectAt(obj.address(), static_cast<int>(size_in_bytes), - ClearRecordedSlots::kNo); - return true; - } - return false; -} - -TEST(InvalidLab) { - LocalAllocationBuffer lab = LocalAllocationBuffer::InvalidBuffer(); - CHECK(!lab.IsValid()); -} - - -TEST(UnusedLabImplicitClose) { - CcTest::InitializeVM(); - Heap* heap = CcTest::heap(); - const int kLabSize = 4 * KB; - Address base = AllocateLabBackingStore(heap, kLabSize); - Address limit = base + kLabSize; - intptr_t expected_sizes_raw[1] = {kLabSize}; - std::vector<intptr_t> expected_sizes(expected_sizes_raw, - expected_sizes_raw + 1); - { - AllocationResult lab_backing_store = - AllocationResult::FromObject(HeapObject::FromAddress(base)); - LocalAllocationBuffer lab = - LocalAllocationBuffer::FromResult(heap, lab_backing_store, kLabSize); - CHECK(lab.IsValid()); - } - VerifyIterable(base, limit, expected_sizes); -} - - -TEST(SimpleAllocate) { - CcTest::InitializeVM(); - Heap* heap = CcTest::heap(); - const int kLabSize = 4 * KB; - Address base = AllocateLabBackingStore(heap, kLabSize); - Address limit = base + kLabSize; - intptr_t sizes_raw[1] = {128}; - intptr_t expected_sizes_raw[2] = {128, kLabSize - 128}; - std::vector<intptr_t> sizes(sizes_raw, sizes_raw + 1); - std::vector<intptr_t> expected_sizes(expected_sizes_raw, - expected_sizes_raw + 2); - { - AllocationResult lab_backing_store = - AllocationResult::FromObject(HeapObject::FromAddress(base)); - LocalAllocationBuffer lab = - LocalAllocationBuffer::FromResult(heap, lab_backing_store, kLabSize); - CHECK(lab.IsValid()); - for (auto size : sizes) { - AllocateFromLab(heap, &lab, size); - } - } - VerifyIterable(base, limit, expected_sizes); -} - - -TEST(AllocateUntilLabOOM) { - CcTest::InitializeVM(); - Heap* heap = CcTest::heap(); - const int kLabSize = 2 * KB; - Address base = AllocateLabBackingStore(heap, kLabSize); - Address limit = base + kLabSize; - // The following objects won't fit in {kLabSize}. - intptr_t sizes_raw[5] = {512, 512, 128, 512, 512}; - intptr_t expected_sizes_raw[5] = {512, 512, 128, 512, 384 /* left over */}; - std::vector<intptr_t> sizes(sizes_raw, sizes_raw + 5); - std::vector<intptr_t> expected_sizes(expected_sizes_raw, - expected_sizes_raw + 5); - intptr_t sum = 0; - { - AllocationResult lab_backing_store = - AllocationResult::FromObject(HeapObject::FromAddress(base)); - LocalAllocationBuffer lab = - LocalAllocationBuffer::FromResult(heap, lab_backing_store, kLabSize); - CHECK(lab.IsValid()); - for (auto size : sizes) { - if (AllocateFromLab(heap, &lab, size)) { - sum += size; - } - } - CHECK_EQ(kLabSize - sum, 384); - } - VerifyIterable(base, limit, expected_sizes); -} - - -TEST(AllocateExactlyUntilLimit) { - CcTest::InitializeVM(); - Heap* heap = CcTest::heap(); - const int kLabSize = 2 * KB; - Address base = AllocateLabBackingStore(heap, kLabSize); - Address limit = base + kLabSize; - intptr_t sizes_raw[4] = {512, 512, 512, 512}; - intptr_t expected_sizes_raw[5] = {512, 512, 512, 512, 0}; - std::vector<intptr_t> sizes(sizes_raw, sizes_raw + 4); - std::vector<intptr_t> expected_sizes(expected_sizes_raw, - expected_sizes_raw + 5); - { - AllocationResult lab_backing_store = - AllocationResult::FromObject(HeapObject::FromAddress(base)); - LocalAllocationBuffer lab = - LocalAllocationBuffer::FromResult(heap, lab_backing_store, kLabSize); - CHECK(lab.IsValid()); - intptr_t sum = 0; - for (auto size : sizes) { - if (AllocateFromLab(heap, &lab, size)) { - sum += size; - } else { - break; - } - } - CHECK_EQ(kLabSize - sum, 0); - } - VerifyIterable(base, limit, expected_sizes); -} - - -TEST(MergeSuccessful) { - CcTest::InitializeVM(); - Heap* heap = CcTest::heap(); - const int kLabSize = 2 * KB; - Address base1 = AllocateLabBackingStore(heap, 2 * kLabSize); - Address limit1 = base1 + kLabSize; - Address base2 = limit1; - Address limit2 = base2 + kLabSize; - - intptr_t sizes1_raw[4] = {512, 512, 512, 256}; - intptr_t expected_sizes1_raw[5] = {512, 512, 512, 256, 256}; - std::vector<intptr_t> sizes1(sizes1_raw, sizes1_raw + 4); - std::vector<intptr_t> expected_sizes1(expected_sizes1_raw, - expected_sizes1_raw + 5); - - intptr_t sizes2_raw[5] = {256, 512, 512, 512, 512}; - intptr_t expected_sizes2_raw[10] = {512, 512, 512, 256, 256, - 512, 512, 512, 512, 0}; - std::vector<intptr_t> sizes2(sizes2_raw, sizes2_raw + 5); - std::vector<intptr_t> expected_sizes2(expected_sizes2_raw, - expected_sizes2_raw + 10); - - { - AllocationResult lab_backing_store1 = - AllocationResult::FromObject(HeapObject::FromAddress(base1)); - LocalAllocationBuffer lab1 = - LocalAllocationBuffer::FromResult(heap, lab_backing_store1, kLabSize); - CHECK(lab1.IsValid()); - intptr_t sum = 0; - for (auto size : sizes1) { - if (AllocateFromLab(heap, &lab1, size)) { - sum += size; - } else { - break; - } - } - - AllocationResult lab_backing_store2 = - AllocationResult::FromObject(HeapObject::FromAddress(base2)); - LocalAllocationBuffer lab2 = - LocalAllocationBuffer::FromResult(heap, lab_backing_store2, kLabSize); - CHECK(lab2.IsValid()); - CHECK(lab2.TryMerge(&lab1)); - CHECK(!lab1.IsValid()); - for (auto size : sizes2) { - if (AllocateFromLab(heap, &lab2, size)) { - sum += size; - } else { - break; - } - } - CHECK_EQ(2 * kLabSize - sum, 0); - } - VerifyIterable(base1, limit1, expected_sizes1); - VerifyIterable(base1, limit2, expected_sizes2); -} - - -TEST(MergeFailed) { - CcTest::InitializeVM(); - Heap* heap = CcTest::heap(); - const int kLabSize = 2 * KB; - Address base1 = AllocateLabBackingStore(heap, 3 * kLabSize); - Address base2 = base1 + kLabSize; - Address base3 = base2 + kLabSize; - - { - AllocationResult lab_backing_store1 = - AllocationResult::FromObject(HeapObject::FromAddress(base1)); - LocalAllocationBuffer lab1 = - LocalAllocationBuffer::FromResult(heap, lab_backing_store1, kLabSize); - CHECK(lab1.IsValid()); - - AllocationResult lab_backing_store2 = - AllocationResult::FromObject(HeapObject::FromAddress(base2)); - LocalAllocationBuffer lab2 = - LocalAllocationBuffer::FromResult(heap, lab_backing_store2, kLabSize); - CHECK(lab2.IsValid()); - - AllocationResult lab_backing_store3 = - AllocationResult::FromObject(HeapObject::FromAddress(base3)); - LocalAllocationBuffer lab3 = - LocalAllocationBuffer::FromResult(heap, lab_backing_store3, kLabSize); - CHECK(lab3.IsValid()); - - CHECK(!lab3.TryMerge(&lab1)); - } -} - -TEST(AllocateAligned) { - // The test works only for configurations with 32-bit tagged values. - if (kTaggedSize != kUInt32Size) return; - CcTest::InitializeVM(); - Heap* heap = CcTest::heap(); - const int kLabSize = 2 * KB; - Address base = AllocateLabBackingStore(heap, kLabSize); - Address limit = base + kLabSize; - std::pair<intptr_t, AllocationAlignment> sizes_raw[2] = { - std::make_pair(116, kTaggedAligned), std::make_pair(64, kDoubleAligned)}; - std::vector<std::pair<intptr_t, AllocationAlignment>> sizes(sizes_raw, - sizes_raw + 2); - intptr_t expected_sizes_raw[4] = {116, 4, 64, 1864}; - std::vector<intptr_t> expected_sizes(expected_sizes_raw, - expected_sizes_raw + 4); - - { - AllocationResult lab_backing_store = - AllocationResult::FromObject(HeapObject::FromAddress(base)); - LocalAllocationBuffer lab = - LocalAllocationBuffer::FromResult(heap, lab_backing_store, kLabSize); - CHECK(lab.IsValid()); - for (auto pair : sizes) { - if (!AllocateFromLab(heap, &lab, pair.first, pair.second)) { - break; - } - } - } - VerifyIterable(base, limit, expected_sizes); -} - -} // namespace heap -} // namespace internal -} // namespace v8 diff --git a/deps/v8/test/cctest/heap/test-memory-measurement.cc b/deps/v8/test/cctest/heap/test-memory-measurement.cc index a5a0e6b645..8ad4247514 100644 --- a/deps/v8/test/cctest/heap/test-memory-measurement.cc +++ b/deps/v8/test/cctest/heap/test-memory-measurement.cc @@ -132,10 +132,7 @@ namespace { class MockPlatform : public TestPlatform { public: - MockPlatform() : TestPlatform(), mock_task_runner_(new MockTaskRunner()) { - // Now that it's completely constructed, make this the current platform. - i::V8::SetPlatformForTesting(this); - } + MockPlatform() : mock_task_runner_(new MockTaskRunner()) {} std::shared_ptr<v8::TaskRunner> GetForegroundTaskRunner( v8::Isolate*) override { @@ -199,14 +196,10 @@ class MockMeasureMemoryDelegate : public v8::MeasureMemoryDelegate { } // namespace -TEST(RandomizedTimeout) { - MockPlatform platform; +TEST_WITH_PLATFORM(RandomizedTimeout, MockPlatform) { v8::Isolate::CreateParams create_params; create_params.array_buffer_allocator = CcTest::array_buffer_allocator(); - // We have to create the isolate manually here. Using CcTest::isolate() would - // lead to the situation when the isolate outlives MockPlatform which may lead - // to UAF on the background thread. - v8::Isolate* isolate = v8::Isolate::New(create_params); + v8::Isolate* isolate = CcTest::isolate(); std::vector<double> delays; for (int i = 0; i < 10; i++) { isolate->MeasureMemory(std::make_unique<MockMeasureMemoryDelegate>()); @@ -214,7 +207,6 @@ TEST(RandomizedTimeout) { platform.PerformTask(); } std::sort(delays.begin(), delays.end()); - isolate->Dispose(); CHECK_LT(delays[0], delays.back()); } diff --git a/deps/v8/test/cctest/heap/test-spaces.cc b/deps/v8/test/cctest/heap/test-spaces.cc index 9cc24525e2..37261c4cc0 100644 --- a/deps/v8/test/cctest/heap/test-spaces.cc +++ b/deps/v8/test/cctest/heap/test-spaces.cc @@ -27,6 +27,8 @@ #include <stdlib.h> +#include <memory> + #include "include/v8-initialization.h" #include "include/v8-platform.h" #include "src/base/bounded-page-allocator.h" @@ -113,9 +115,8 @@ class V8_NODISCARD TestCodePageAllocatorScope { static void VerifyMemoryChunk(Isolate* isolate, Heap* heap, v8::PageAllocator* code_page_allocator, - size_t reserve_area_size, size_t commit_area_size, - Executability executable, PageSize page_size, - Space* space) { + size_t area_size, Executability executable, + PageSize page_size, LargeObjectSpace* space) { TestMemoryAllocatorScope test_allocator_scope(isolate, heap->MaxReserved()); MemoryAllocator* memory_allocator = test_allocator_scope.allocator(); TestCodePageAllocatorScope test_code_page_allocator_scope( @@ -129,23 +130,23 @@ static void VerifyMemoryChunk(Isolate* isolate, Heap* heap, size_t guard_size = (executable == EXECUTABLE) ? MemoryChunkLayout::CodePageGuardSize() : 0; - MemoryChunk* memory_chunk = memory_allocator->AllocateChunk( - reserve_area_size, commit_area_size, executable, page_size, space); + MemoryChunk* memory_chunk = + memory_allocator->AllocateLargePage(space, area_size, executable); size_t reserved_size = ((executable == EXECUTABLE)) ? allocatable_memory_area_offset + - RoundUp(reserve_area_size, page_allocator->CommitPageSize()) + + RoundUp(area_size, page_allocator->CommitPageSize()) + guard_size - : RoundUp(allocatable_memory_area_offset + reserve_area_size, + : RoundUp(allocatable_memory_area_offset + area_size, page_allocator->CommitPageSize()); CHECK(memory_chunk->size() == reserved_size); CHECK(memory_chunk->area_start() < memory_chunk->address() + memory_chunk->size()); CHECK(memory_chunk->area_end() <= memory_chunk->address() + memory_chunk->size()); - CHECK(static_cast<size_t>(memory_chunk->area_size()) == commit_area_size); + CHECK(static_cast<size_t>(memory_chunk->area_size()) == area_size); - memory_allocator->Free(MemoryAllocator::kImmediately, memory_chunk); + memory_allocator->Free(MemoryAllocator::FreeMode::kImmediately, memory_chunk); } static unsigned int PseudorandomAreaSize() { @@ -160,12 +161,10 @@ TEST(MemoryChunk) { Heap* heap = isolate->heap(); v8::PageAllocator* page_allocator = GetPlatformPageAllocator(); - - size_t reserve_area_size = 1 * MB; - size_t initial_commit_area_size; + size_t area_size; for (int i = 0; i < 100; i++) { - initial_commit_area_size = + area_size = RoundUp(PseudorandomAreaSize(), page_allocator->CommitPageSize()); // With CodeRange. @@ -179,13 +178,11 @@ TEST(MemoryChunk) { code_range_reservation.size(), MemoryChunk::kAlignment, base::PageInitializationMode::kAllocatedPagesCanBeUninitialized); - VerifyMemoryChunk(isolate, heap, &code_page_allocator, reserve_area_size, - initial_commit_area_size, EXECUTABLE, PageSize::kLarge, - heap->code_space()); + VerifyMemoryChunk(isolate, heap, &code_page_allocator, area_size, + EXECUTABLE, PageSize::kLarge, heap->code_lo_space()); - VerifyMemoryChunk(isolate, heap, &code_page_allocator, reserve_area_size, - initial_commit_area_size, NOT_EXECUTABLE, - PageSize::kLarge, heap->old_space()); + VerifyMemoryChunk(isolate, heap, &code_page_allocator, area_size, + NOT_EXECUTABLE, PageSize::kLarge, heap->lo_space()); } } @@ -203,7 +200,7 @@ TEST(MemoryAllocator) { CHECK(!faked_space.first_page()); CHECK(!faked_space.last_page()); Page* first_page = memory_allocator->AllocatePage( - MemoryAllocator::kRegular, faked_space.AreaSize(), + MemoryAllocator::AllocationMode::kRegular, static_cast<PagedSpace*>(&faked_space), NOT_EXECUTABLE); faked_space.memory_chunk_list().PushBack(first_page); @@ -216,7 +213,7 @@ TEST(MemoryAllocator) { // Again, we should get n or n - 1 pages. Page* other = memory_allocator->AllocatePage( - MemoryAllocator::kRegular, faked_space.AreaSize(), + MemoryAllocator::AllocationMode::kRegular, static_cast<PagedSpace*>(&faked_space), NOT_EXECUTABLE); total_pages++; faked_space.memory_chunk_list().PushBack(other); @@ -280,18 +277,19 @@ TEST(NewSpace) { MemoryAllocator* memory_allocator = test_allocator_scope.allocator(); LinearAllocationArea allocation_info; - NewSpace new_space(heap, memory_allocator->data_page_allocator(), - CcTest::heap()->InitialSemiSpaceSize(), - CcTest::heap()->InitialSemiSpaceSize(), &allocation_info); - CHECK(new_space.MaximumCapacity()); + std::unique_ptr<NewSpace> new_space = std::make_unique<NewSpace>( + heap, memory_allocator->data_page_allocator(), + CcTest::heap()->InitialSemiSpaceSize(), + CcTest::heap()->InitialSemiSpaceSize(), &allocation_info); + CHECK(new_space->MaximumCapacity()); - while (new_space.Available() >= kMaxRegularHeapObjectSize) { - CHECK(new_space.Contains( - new_space.AllocateRaw(kMaxRegularHeapObjectSize, kTaggedAligned) + while (new_space->Available() >= kMaxRegularHeapObjectSize) { + CHECK(new_space->Contains( + new_space->AllocateRaw(kMaxRegularHeapObjectSize, kTaggedAligned) .ToObjectChecked())); } - new_space.TearDown(); + new_space.reset(); memory_allocator->unmapper()->EnsureUnmappingCompleted(); } @@ -813,7 +811,7 @@ TEST(NoMemoryForNewPage) { LinearAllocationArea allocation_info; OldSpace faked_space(heap, &allocation_info); Page* page = memory_allocator->AllocatePage( - MemoryAllocator::kRegular, faked_space.AreaSize(), + MemoryAllocator::AllocationMode::kRegular, static_cast<PagedSpace*>(&faked_space), NOT_EXECUTABLE); CHECK_NULL(page); diff --git a/deps/v8/test/cctest/heap/test-unmapper.cc b/deps/v8/test/cctest/heap/test-unmapper.cc index 164de7571c..2297409f2d 100644 --- a/deps/v8/test/cctest/heap/test-unmapper.cc +++ b/deps/v8/test/cctest/heap/test-unmapper.cc @@ -20,16 +20,9 @@ namespace heap { class MockPlatformForUnmapper : public TestPlatform { public: - MockPlatformForUnmapper() - : task_(nullptr), old_platform_(i::V8::GetCurrentPlatform()) { - // Now that it's completely constructed, make this the current platform. - i::V8::SetPlatformForTesting(this); - } ~MockPlatformForUnmapper() override { - delete task_; - i::V8::SetPlatformForTesting(old_platform_); for (auto& task : worker_tasks_) { - old_platform_->CallOnWorkerThread(std::move(task)); + CcTest::default_platform()->CallOnWorkerThread(std::move(task)); } worker_tasks_.clear(); } @@ -40,14 +33,8 @@ class MockPlatformForUnmapper : public TestPlatform { bool IdleTasksEnabled(v8::Isolate* isolate) override { return false; } - int NumberOfWorkerThreads() override { - return old_platform_->NumberOfWorkerThreads(); - } - private: - Task* task_; std::vector<std::unique_ptr<Task>> worker_tasks_; - v8::Platform* old_platform_; }; UNINITIALIZED_TEST(EagerUnmappingInCollectAllAvailableGarbage) { diff --git a/deps/v8/test/cctest/heap/test-weak-references.cc b/deps/v8/test/cctest/heap/test-weak-references.cc index 3ead9c48be..1cfb4715d3 100644 --- a/deps/v8/test/cctest/heap/test-weak-references.cc +++ b/deps/v8/test/cctest/heap/test-weak-references.cc @@ -176,7 +176,8 @@ TEST(WeakReferencesOldToCleared) { } TEST(ObjectMovesBeforeClearingWeakField) { - if (!FLAG_incremental_marking || FLAG_single_generation) { + if (!FLAG_incremental_marking || FLAG_single_generation || + FLAG_separate_gc_phases) { return; } ManualGCScope manual_gc_scope; @@ -277,7 +278,7 @@ TEST(ObjectWithWeakReferencePromoted) { } TEST(ObjectWithClearedWeakReferencePromoted) { - if (FLAG_single_generation) return; + if (FLAG_single_generation || FLAG_stress_incremental_marking) return; CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); Factory* factory = isolate->factory(); diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/ClassAndSuperClass.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/ClassAndSuperClass.golden index 7581b0f391..f45da46455 100644 --- a/deps/v8/test/cctest/interpreter/bytecode_expectations/ClassAndSuperClass.golden +++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/ClassAndSuperClass.golden @@ -20,18 +20,14 @@ snippet: " test(); })(); " -frame size: 5 +frame size: 1 parameter count: 1 -bytecode array length: 24 +bytecode array length: 16 bytecodes: [ /* 104 S> */ B(LdaImmutableCurrentContextSlot), U8(2), - B(Star3), - B(LdaConstant), U8(0), - B(Star4), - B(Mov), R(this), R(2), - /* 117 E> */ B(CallRuntime), U16(Runtime::kLoadFromSuper), R(2), U8(3), + /* 117 E> */ B(GetNamedPropertyFromSuper), R(this), U8(0), U8(1), B(Star0), - /* 117 E> */ B(CallAnyReceiver), R(0), R(this), U8(1), U8(1), + /* 117 E> */ B(CallAnyReceiver), R(0), R(this), U8(1), U8(3), /* 126 E> */ B(AddSmi), I8(1), U8(0), /* 130 S> */ B(Return), ] @@ -58,7 +54,7 @@ snippet: " " frame size: 4 parameter count: 1 -bytecode array length: 32 +bytecode array length: 24 bytecodes: [ /* 130 S> */ B(LdaImmutableCurrentContextSlot), U8(2), B(Star1), @@ -69,11 +65,7 @@ bytecodes: [ B(Mov), R(this), R(0), /* 138 E> */ B(CallRuntime), U16(Runtime::kStoreToSuper), R(0), U8(4), /* 143 S> */ B(LdaImmutableCurrentContextSlot), U8(2), - B(Star1), - B(LdaConstant), U8(0), - B(Star2), - B(Mov), R(this), R(0), - /* 156 E> */ B(CallRuntime), U16(Runtime::kLoadFromSuper), R(0), U8(3), + /* 156 E> */ B(GetNamedPropertyFromSuper), R(this), U8(0), U8(0), /* 158 S> */ B(Return), ] constant pool: [ diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/CompareBoolean.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/CompareBoolean.golden new file mode 100644 index 0000000000..76646494bd --- /dev/null +++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/CompareBoolean.golden @@ -0,0 +1,368 @@ +# +# Autogenerated by generate-bytecode-expectations. +# + +--- +wrap: yes + +--- +snippet: " + var a = 1; + return a === true; +" +frame size: 1 +parameter count: 1 +bytecode array length: 7 +bytecodes: [ + /* 42 S> */ B(LdaSmi), I8(1), + B(Star0), + /* 45 S> */ B(LdaTrue), + B(TestReferenceEqual), R(0), + /* 63 S> */ B(Return), +] +constant pool: [ +] +handlers: [ +] + +--- +snippet: " + var a = true; + return true === a; +" +frame size: 1 +parameter count: 1 +bytecode array length: 6 +bytecodes: [ + /* 42 S> */ B(LdaTrue), + B(Star0), + /* 48 S> */ B(LdaTrue), + B(TestReferenceEqual), R(0), + /* 66 S> */ B(Return), +] +constant pool: [ +] +handlers: [ +] + +--- +snippet: " + var a = false; + return true !== a; +" +frame size: 1 +parameter count: 1 +bytecode array length: 7 +bytecodes: [ + /* 42 S> */ B(LdaFalse), + B(Star0), + /* 49 S> */ B(LdaTrue), + B(TestReferenceEqual), R(0), + /* 61 E> */ B(LogicalNot), + /* 67 S> */ B(Return), +] +constant pool: [ +] +handlers: [ +] + +--- +snippet: " + var a = 1; + return true === a ? 1 : 2; +" +frame size: 1 +parameter count: 1 +bytecode array length: 14 +bytecodes: [ + /* 42 S> */ B(LdaSmi), I8(1), + B(Star0), + /* 45 S> */ B(JumpIfTrue), U8(4), + B(Jump), U8(6), + B(LdaSmi), I8(1), + B(Jump), U8(4), + B(LdaSmi), I8(2), + /* 71 S> */ B(Return), +] +constant pool: [ +] +handlers: [ +] + +--- +snippet: " + var a = true; + return false === a ? 1 : 2; +" +frame size: 1 +parameter count: 1 +bytecode array length: 13 +bytecodes: [ + /* 42 S> */ B(LdaTrue), + B(Star0), + /* 48 S> */ B(JumpIfFalse), U8(4), + B(Jump), U8(6), + B(LdaSmi), I8(1), + B(Jump), U8(4), + B(LdaSmi), I8(2), + /* 75 S> */ B(Return), +] +constant pool: [ +] +handlers: [ +] + +--- +snippet: " + var a = 1; + return true !== a ? 1 : 2; +" +frame size: 1 +parameter count: 1 +bytecode array length: 12 +bytecodes: [ + /* 42 S> */ B(LdaSmi), I8(1), + B(Star0), + /* 45 S> */ B(JumpIfTrue), U8(6), + B(LdaSmi), I8(1), + B(Jump), U8(4), + B(LdaSmi), I8(2), + /* 71 S> */ B(Return), +] +constant pool: [ +] +handlers: [ +] + +--- +snippet: " + var a = false; + return false !== null ? 1 : 2; +" +frame size: 1 +parameter count: 1 +bytecode array length: 12 +bytecodes: [ + /* 42 S> */ B(LdaFalse), + B(Star0), + /* 49 S> */ B(LdaNull), + B(JumpIfFalse), U8(6), + B(LdaSmi), I8(1), + B(Jump), U8(4), + B(LdaSmi), I8(2), + /* 79 S> */ B(Return), +] +constant pool: [ +] +handlers: [ +] + +--- +snippet: " + var a = 0; + if (a !== true) { + return 1; + } +" +frame size: 1 +parameter count: 1 +bytecode array length: 9 +bytecodes: [ + /* 42 S> */ B(LdaZero), + B(Star0), + /* 45 S> */ B(JumpIfTrue), U8(5), + /* 65 S> */ B(LdaSmi), I8(1), + /* 74 S> */ B(Return), + B(LdaUndefined), + /* 77 S> */ B(Return), +] +constant pool: [ +] +handlers: [ +] + +--- +snippet: " + var a = true; + var b = 0; + while (a !== true) { + b++; + } +" +frame size: 2 +parameter count: 1 +bytecode array length: 18 +bytecodes: [ + /* 42 S> */ B(LdaTrue), + B(Star0), + /* 56 S> */ B(LdaZero), + B(Star1), + /* 68 S> */ B(Ldar), R(0), + B(JumpIfTrue), U8(10), + /* 82 S> */ B(Ldar), R(1), + B(Inc), U8(0), + B(Star1), + /* 59 E> */ B(JumpLoop), U8(9), I8(0), + B(LdaUndefined), + /* 89 S> */ B(Return), +] +constant pool: [ +] +handlers: [ +] + +--- +snippet: " + (0 === true) ? 1 : 2; +" +frame size: 0 +parameter count: 1 +bytecode array length: 13 +bytecodes: [ + /* 34 S> */ B(LdaZero), + B(JumpIfTrue), U8(4), + B(Jump), U8(6), + B(LdaSmi), I8(1), + B(Jump), U8(4), + B(LdaSmi), I8(2), + B(LdaUndefined), + /* 56 S> */ B(Return), +] +constant pool: [ +] +handlers: [ +] + +--- +snippet: " + (0 !== true) ? 1 : 2; +" +frame size: 0 +parameter count: 1 +bytecode array length: 11 +bytecodes: [ + /* 34 S> */ B(LdaZero), + B(JumpIfTrue), U8(6), + B(LdaSmi), I8(1), + B(Jump), U8(4), + B(LdaSmi), I8(2), + B(LdaUndefined), + /* 56 S> */ B(Return), +] +constant pool: [ +] +handlers: [ +] + +--- +snippet: " + (false === 0) ? 1 : 2; +" +frame size: 0 +parameter count: 1 +bytecode array length: 13 +bytecodes: [ + /* 34 S> */ B(LdaZero), + B(JumpIfFalse), U8(4), + B(Jump), U8(6), + B(LdaSmi), I8(1), + B(Jump), U8(4), + B(LdaSmi), I8(2), + B(LdaUndefined), + /* 57 S> */ B(Return), +] +constant pool: [ +] +handlers: [ +] + +--- +snippet: " + (0 === true || 0 === false) ? 1 : 2; +" +frame size: 0 +parameter count: 1 +bytecode array length: 16 +bytecodes: [ + /* 34 S> */ B(LdaZero), + B(JumpIfTrue), U8(7), + B(LdaZero), + B(JumpIfFalse), U8(4), + B(Jump), U8(6), + B(LdaSmi), I8(1), + B(Jump), U8(4), + B(LdaSmi), I8(2), + B(LdaUndefined), + /* 71 S> */ B(Return), +] +constant pool: [ +] +handlers: [ +] + +--- +snippet: " + if (0 === true || 0 === false) return 1; +" +frame size: 0 +parameter count: 1 +bytecode array length: 13 +bytecodes: [ + /* 34 S> */ B(LdaZero), + B(JumpIfTrue), U8(7), + B(LdaZero), + B(JumpIfFalse), U8(4), + B(Jump), U8(5), + /* 65 S> */ B(LdaSmi), I8(1), + /* 74 S> */ B(Return), + B(LdaUndefined), + /* 75 S> */ B(Return), +] +constant pool: [ +] +handlers: [ +] + +--- +snippet: " + if (!('false' === false)) return 1; +" +frame size: 0 +parameter count: 1 +bytecode array length: 9 +bytecodes: [ + /* 34 S> */ B(LdaConstant), U8(0), + B(JumpIfFalse), U8(5), + /* 60 S> */ B(LdaSmi), I8(1), + /* 69 S> */ B(Return), + B(LdaUndefined), + /* 70 S> */ B(Return), +] +constant pool: [ + ONE_BYTE_INTERNALIZED_STRING_TYPE ["false"], +] +handlers: [ +] + +--- +snippet: " + if (!('false' !== false)) return 1; +" +frame size: 0 +parameter count: 1 +bytecode array length: 11 +bytecodes: [ + /* 34 S> */ B(LdaConstant), U8(0), + B(JumpIfFalse), U8(4), + B(Jump), U8(5), + /* 60 S> */ B(LdaSmi), I8(1), + /* 69 S> */ B(Return), + B(LdaUndefined), + /* 70 S> */ B(Return), +] +constant pool: [ + ONE_BYTE_INTERNALIZED_STRING_TYPE ["false"], +] +handlers: [ +] + diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/PrivateAccessorAccess.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/PrivateAccessorAccess.golden index 00cf22fb7b..4451dfbbb4 100644 --- a/deps/v8/test/cctest/interpreter/bytecode_expectations/PrivateAccessorAccess.golden +++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/PrivateAccessorAccess.golden @@ -83,7 +83,7 @@ bytecodes: [ /* 48 E> */ B(DefineKeyedOwnProperty), R(this), R(0), U8(0), /* 53 S> */ B(LdaImmutableCurrentContextSlot), U8(3), /* 58 E> */ B(GetKeyedProperty), R(this), U8(2), - B(Wide), B(LdaSmi), I16(296), + B(Wide), B(LdaSmi), I16(297), B(Star2), B(LdaConstant), U8(0), B(Star3), @@ -115,7 +115,7 @@ bytecodes: [ /* 41 E> */ B(DefineKeyedOwnProperty), R(this), R(0), U8(0), /* 46 S> */ B(LdaImmutableCurrentContextSlot), U8(3), /* 51 E> */ B(GetKeyedProperty), R(this), U8(2), - B(Wide), B(LdaSmi), I16(295), + B(Wide), B(LdaSmi), I16(296), B(Star2), B(LdaConstant), U8(0), B(Star3), @@ -137,21 +137,23 @@ snippet: " var test = D; new test; " -frame size: 4 +frame size: 5 parameter count: 1 -bytecode array length: 28 +bytecode array length: 31 bytecodes: [ B(LdaImmutableCurrentContextSlot), U8(3), B(Star0), B(Ldar), R(context), /* 48 E> */ B(DefineKeyedOwnProperty), R(this), R(0), U8(0), - /* 53 S> */ B(LdaImmutableCurrentContextSlot), U8(3), - /* 58 E> */ B(GetKeyedProperty), R(this), U8(2), - B(Wide), B(LdaSmi), I16(296), + /* 53 S> */ B(LdaImmutableCurrentContextSlot), U8(2), B(Star2), - B(LdaConstant), U8(0), + B(LdaImmutableCurrentContextSlot), U8(3), + /* 58 E> */ B(GetKeyedProperty), R(this), U8(2), + B(Wide), B(LdaSmi), I16(297), B(Star3), - B(CallRuntime), U16(Runtime::kNewTypeError), R(2), U8(2), + B(LdaConstant), U8(0), + B(Star4), + B(CallRuntime), U16(Runtime::kNewTypeError), R(3), U8(2), B(Throw), ] constant pool: [ @@ -179,7 +181,7 @@ bytecodes: [ /* 41 E> */ B(DefineKeyedOwnProperty), R(this), R(0), U8(0), /* 46 S> */ B(LdaImmutableCurrentContextSlot), U8(3), /* 51 E> */ B(GetKeyedProperty), R(this), U8(2), - B(Wide), B(LdaSmi), I16(295), + B(Wide), B(LdaSmi), I16(296), B(Star2), B(LdaConstant), U8(0), B(Star3), diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/PrivateMethodAccess.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/PrivateMethodAccess.golden index a26dd54cf9..f783f4a443 100644 --- a/deps/v8/test/cctest/interpreter/bytecode_expectations/PrivateMethodAccess.golden +++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/PrivateMethodAccess.golden @@ -46,21 +46,23 @@ snippet: " var test = B; new test; " -frame size: 4 +frame size: 5 parameter count: 1 -bytecode array length: 28 +bytecode array length: 31 bytecodes: [ B(LdaImmutableCurrentContextSlot), U8(3), B(Star0), B(Ldar), R(context), /* 44 E> */ B(DefineKeyedOwnProperty), R(this), R(0), U8(0), - /* 49 S> */ B(LdaImmutableCurrentContextSlot), U8(3), - /* 54 E> */ B(GetKeyedProperty), R(this), U8(2), - B(Wide), B(LdaSmi), I16(294), + /* 49 S> */ B(LdaImmutableCurrentContextSlot), U8(2), B(Star2), - B(LdaConstant), U8(0), + B(LdaImmutableCurrentContextSlot), U8(3), + /* 54 E> */ B(GetKeyedProperty), R(this), U8(2), + B(Wide), B(LdaSmi), I16(295), B(Star3), - B(CallRuntime), U16(Runtime::kNewTypeError), R(2), U8(2), + B(LdaConstant), U8(0), + B(Star4), + B(CallRuntime), U16(Runtime::kNewTypeError), R(3), U8(2), B(Throw), ] constant pool: [ @@ -89,7 +91,7 @@ bytecodes: [ /* 44 E> */ B(DefineKeyedOwnProperty), R(this), R(0), U8(0), /* 49 S> */ B(LdaImmutableCurrentContextSlot), U8(3), /* 54 E> */ B(GetKeyedProperty), R(this), U8(2), - B(Wide), B(LdaSmi), I16(294), + B(Wide), B(LdaSmi), I16(295), B(Star2), B(LdaConstant), U8(0), B(Star3), diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/StaticPrivateMethodAccess.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/StaticPrivateMethodAccess.golden index 846fe89559..3c2e1706f6 100644 --- a/deps/v8/test/cctest/interpreter/bytecode_expectations/StaticPrivateMethodAccess.golden +++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/StaticPrivateMethodAccess.golden @@ -24,7 +24,7 @@ bytecodes: [ B(TestReferenceEqual), R(this), B(Mov), R(this), R(1), B(JumpIfTrue), U8(16), - B(Wide), B(LdaSmi), I16(288), + B(Wide), B(LdaSmi), I16(289), B(Star2), B(LdaConstant), U8(0), B(Star3), @@ -51,25 +51,27 @@ snippet: " var test = B.test; test(); " -frame size: 3 +frame size: 4 parameter count: 1 -bytecode array length: 37 +bytecode array length: 40 bytecodes: [ - /* 56 S> */ B(LdaCurrentContextSlot), U8(3), + /* 56 S> */ B(LdaImmutableCurrentContextSlot), U8(2), + B(Star1), + B(LdaCurrentContextSlot), U8(3), B(TestReferenceEqual), R(this), B(Mov), R(this), R(0), B(JumpIfTrue), U8(16), - B(Wide), B(LdaSmi), I16(288), - B(Star1), - B(LdaConstant), U8(0), + B(Wide), B(LdaSmi), I16(289), B(Star2), - /* 61 E> */ B(CallRuntime), U16(Runtime::kNewTypeError), R(1), U8(2), + B(LdaConstant), U8(0), + B(Star3), + /* 61 E> */ B(CallRuntime), U16(Runtime::kNewTypeError), R(2), U8(2), B(Throw), - B(Wide), B(LdaSmi), I16(294), - B(Star1), - B(LdaConstant), U8(1), + B(Wide), B(LdaSmi), I16(295), B(Star2), - B(CallRuntime), U16(Runtime::kNewTypeError), R(1), U8(2), + B(LdaConstant), U8(1), + B(Star3), + B(CallRuntime), U16(Runtime::kNewTypeError), R(2), U8(2), B(Throw), ] constant pool: [ @@ -97,13 +99,13 @@ bytecodes: [ B(TestReferenceEqual), R(this), B(Mov), R(this), R(0), B(JumpIfTrue), U8(16), - B(Wide), B(LdaSmi), I16(288), + B(Wide), B(LdaSmi), I16(289), B(Star1), B(LdaConstant), U8(0), B(Star2), /* 61 E> */ B(CallRuntime), U16(Runtime::kNewTypeError), R(1), U8(2), B(Throw), - B(Wide), B(LdaSmi), I16(294), + B(Wide), B(LdaSmi), I16(295), B(Star1), B(LdaConstant), U8(1), B(Star2), @@ -143,7 +145,7 @@ bytecodes: [ B(TestReferenceEqual), R(this), B(Mov), R(this), R(0), B(JumpIfTrue), U8(16), - B(Wide), B(LdaSmi), I16(288), + B(Wide), B(LdaSmi), I16(289), B(Star2), B(LdaConstant), U8(0), B(Star3), @@ -165,7 +167,7 @@ bytecodes: [ B(TestReferenceEqual), R(this), B(Mov), R(this), R(0), B(JumpIfTrue), U8(16), - B(Wide), B(LdaSmi), I16(288), + B(Wide), B(LdaSmi), I16(289), B(Star3), B(LdaConstant), U8(0), B(Star4), @@ -180,7 +182,7 @@ bytecodes: [ B(TestReferenceEqual), R(this), B(Mov), R(this), R(0), B(JumpIfTrue), U8(16), - B(Wide), B(LdaSmi), I16(288), + B(Wide), B(LdaSmi), I16(289), B(Star2), B(LdaConstant), U8(0), B(Star3), @@ -214,13 +216,13 @@ bytecodes: [ B(TestReferenceEqual), R(this), B(Mov), R(this), R(0), B(JumpIfTrue), U8(16), - B(Wide), B(LdaSmi), I16(288), + B(Wide), B(LdaSmi), I16(289), B(Star1), B(LdaConstant), U8(0), B(Star2), /* 65 E> */ B(CallRuntime), U16(Runtime::kNewTypeError), R(1), U8(2), B(Throw), - B(Wide), B(LdaSmi), I16(296), + B(Wide), B(LdaSmi), I16(297), B(Star1), B(LdaConstant), U8(1), B(Star2), @@ -251,13 +253,13 @@ bytecodes: [ B(TestReferenceEqual), R(this), B(Mov), R(this), R(0), B(JumpIfTrue), U8(16), - B(Wide), B(LdaSmi), I16(288), + B(Wide), B(LdaSmi), I16(289), B(Star1), B(LdaConstant), U8(0), B(Star2), /* 58 E> */ B(CallRuntime), U16(Runtime::kNewTypeError), R(1), U8(2), B(Throw), - B(Wide), B(LdaSmi), I16(295), + B(Wide), B(LdaSmi), I16(296), B(Star1), B(LdaConstant), U8(1), B(Star2), @@ -280,25 +282,27 @@ snippet: " var test = G.test; test(); " -frame size: 3 +frame size: 4 parameter count: 1 -bytecode array length: 37 +bytecode array length: 40 bytecodes: [ - /* 60 S> */ B(LdaCurrentContextSlot), U8(3), + /* 60 S> */ B(LdaImmutableCurrentContextSlot), U8(2), + B(Star1), + B(LdaCurrentContextSlot), U8(3), B(TestReferenceEqual), R(this), B(Mov), R(this), R(0), B(JumpIfTrue), U8(16), - B(Wide), B(LdaSmi), I16(288), - B(Star1), - B(LdaConstant), U8(0), + B(Wide), B(LdaSmi), I16(289), B(Star2), - /* 65 E> */ B(CallRuntime), U16(Runtime::kNewTypeError), R(1), U8(2), + B(LdaConstant), U8(0), + B(Star3), + /* 65 E> */ B(CallRuntime), U16(Runtime::kNewTypeError), R(2), U8(2), B(Throw), - B(Wide), B(LdaSmi), I16(296), - B(Star1), - B(LdaConstant), U8(1), + B(Wide), B(LdaSmi), I16(297), B(Star2), - B(CallRuntime), U16(Runtime::kNewTypeError), R(1), U8(2), + B(LdaConstant), U8(1), + B(Star3), + B(CallRuntime), U16(Runtime::kNewTypeError), R(2), U8(2), B(Throw), ] constant pool: [ @@ -323,7 +327,7 @@ bytecode array length: 19 bytecodes: [ /* 46 S> */ B(LdaImmutableCurrentContextSlot), U8(3), /* 51 E> */ B(GetKeyedProperty), R(this), U8(0), - B(Wide), B(LdaSmi), I16(295), + B(Wide), B(LdaSmi), I16(296), B(Star1), B(LdaConstant), U8(0), B(Star2), diff --git a/deps/v8/test/cctest/interpreter/test-bytecode-generator.cc b/deps/v8/test/cctest/interpreter/test-bytecode-generator.cc index 09e2926059..2a31638d33 100644 --- a/deps/v8/test/cctest/interpreter/test-bytecode-generator.cc +++ b/deps/v8/test/cctest/interpreter/test-bytecode-generator.cc @@ -1161,6 +1161,62 @@ TEST(CompareTypeOf) { LoadGolden("CompareTypeOf.golden"))); } +TEST(CompareBoolean) { + InitializedIgnitionHandleScope scope; + BytecodeExpectationsPrinter printer(CcTest::isolate()); + + std::string snippets[] = { + "var a = 1;\n" + "return a === true;\n", + + "var a = true;\n" + "return true === a;\n", + + "var a = false;\n" + "return true !== a;\n", + + "var a = 1;\n" + "return true === a ? 1 : 2;\n", + + "var a = true;\n" + "return false === a ? 1 : 2;\n", + + "var a = 1;\n" + "return true !== a ? 1 : 2;\n", + + "var a = false;\n" + "return false !== null ? 1 : 2;\n", + + "var a = 0;\n" + "if (a !== true) {\n" + " return 1;\n" + "}\n", + + "var a = true;\n" + "var b = 0;\n" + "while (a !== true) {\n" + " b++;\n" + "}\n", + + "(0 === true) ? 1 : 2;\n", + + "(0 !== true) ? 1 : 2;\n", + + "(false === 0) ? 1 : 2;\n", + + "(0 === true || 0 === false) ? 1 : 2;\n", + + "if (0 === true || 0 === false) return 1;\n", + + "if (!('false' === false)) return 1;\n", + + "if (!('false' !== false)) return 1;\n", + }; + + CHECK(CompareTexts(BuildActual(printer, snippets), + LoadGolden("CompareBoolean.golden"))); +} + TEST(CompareNil) { InitializedIgnitionHandleScope scope; BytecodeExpectationsPrinter printer(CcTest::isolate()); diff --git a/deps/v8/test/cctest/test-allocation.cc b/deps/v8/test/cctest/test-allocation.cc index 2078aeb02a..0081e8e29c 100644 --- a/deps/v8/test/cctest/test-allocation.cc +++ b/deps/v8/test/cctest/test-allocation.cc @@ -32,12 +32,7 @@ namespace { // Implementation of v8::Platform that can register OOM callbacks. class AllocationPlatform : public TestPlatform { public: - AllocationPlatform() { - current_platform = this; - // Now that it's completely constructed, make this the current platform. - i::V8::SetPlatformForTesting(this); - } - ~AllocationPlatform() override = default; + AllocationPlatform() { current_platform = this; } void OnCriticalMemoryPressure() override { oom_callback_called = true; } @@ -95,8 +90,7 @@ void OnAlignedAllocOOM(const char* location, const char* message) { } // namespace -TEST(AccountingAllocatorOOM) { - AllocationPlatform platform; +TEST_WITH_PLATFORM(AccountingAllocatorOOM, AllocationPlatform) { v8::internal::AccountingAllocator allocator; CHECK(!platform.oom_callback_called); const bool support_compression = false; @@ -106,8 +100,7 @@ TEST(AccountingAllocatorOOM) { CHECK_EQ(result == nullptr, platform.oom_callback_called); } -TEST(AccountingAllocatorCurrentAndMax) { - AllocationPlatform platform; +TEST_WITH_PLATFORM(AccountingAllocatorCurrentAndMax, AllocationPlatform) { v8::internal::AccountingAllocator allocator; static constexpr size_t kAllocationSizes[] = {51, 231, 27}; std::vector<v8::internal::Segment*> segments; @@ -135,8 +128,7 @@ TEST(AccountingAllocatorCurrentAndMax) { CHECK(!platform.oom_callback_called); } -TEST(MallocedOperatorNewOOM) { - AllocationPlatform platform; +TEST_WITH_PLATFORM(MallocedOperatorNewOOM, AllocationPlatform) { CHECK(!platform.oom_callback_called); CcTest::isolate()->SetFatalErrorHandler(OnMallocedOperatorNewOOM); // On failure, this won't return, since a Malloced::New failure is fatal. @@ -146,8 +138,7 @@ TEST(MallocedOperatorNewOOM) { CHECK_EQ(result == nullptr, platform.oom_callback_called); } -TEST(NewArrayOOM) { - AllocationPlatform platform; +TEST_WITH_PLATFORM(NewArrayOOM, AllocationPlatform) { CHECK(!platform.oom_callback_called); CcTest::isolate()->SetFatalErrorHandler(OnNewArrayOOM); // On failure, this won't return, since a NewArray failure is fatal. @@ -157,8 +148,7 @@ TEST(NewArrayOOM) { CHECK_EQ(result == nullptr, platform.oom_callback_called); } -TEST(AlignedAllocOOM) { - AllocationPlatform platform; +TEST_WITH_PLATFORM(AlignedAllocOOM, AllocationPlatform) { CHECK(!platform.oom_callback_called); CcTest::isolate()->SetFatalErrorHandler(OnAlignedAllocOOM); // On failure, this won't return, since an AlignedAlloc failure is fatal. @@ -169,8 +159,7 @@ TEST(AlignedAllocOOM) { CHECK_EQ(result == nullptr, platform.oom_callback_called); } -TEST(AllocVirtualMemoryOOM) { - AllocationPlatform platform; +TEST_WITH_PLATFORM(AllocVirtualMemoryOOM, AllocationPlatform) { CHECK(!platform.oom_callback_called); v8::internal::VirtualMemory result(v8::internal::GetPlatformPageAllocator(), GetHugeMemoryAmount(), nullptr); @@ -178,8 +167,7 @@ TEST(AllocVirtualMemoryOOM) { CHECK_IMPLIES(!result.IsReserved(), platform.oom_callback_called); } -TEST(AlignedAllocVirtualMemoryOOM) { - AllocationPlatform platform; +TEST_WITH_PLATFORM(AlignedAllocVirtualMemoryOOM, AllocationPlatform) { CHECK(!platform.oom_callback_called); v8::internal::VirtualMemory result(v8::internal::GetPlatformPageAllocator(), GetHugeMemoryAmount(), nullptr, diff --git a/deps/v8/test/cctest/test-api-accessors.cc b/deps/v8/test/cctest/test-api-accessors.cc index 7c1799da6a..8ed8dd6afe 100644 --- a/deps/v8/test/cctest/test-api-accessors.cc +++ b/deps/v8/test/cctest/test-api-accessors.cc @@ -814,3 +814,64 @@ TEST(BindFunctionTemplateSetNativeDataProperty) { CHECK(try_catch.HasCaught()); } } + +namespace { +v8::MaybeLocal<v8::Context> TestHostCreateShadowRealmContextCallback( + v8::Local<v8::Context> initiator_context) { + v8::Isolate* isolate = initiator_context->GetIsolate(); + v8::Local<v8::FunctionTemplate> global_constructor = + v8::FunctionTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> global_template = + global_constructor->InstanceTemplate(); + + // Check that getter is called on Function.prototype.bind. + global_template->SetNativeDataProperty( + v8_str("func1"), [](v8::Local<v8::String> property, + const v8::PropertyCallbackInfo<v8::Value>& info) { + v8::Isolate* isolate = info.GetIsolate(); + v8::Local<v8::FunctionTemplate> templ = + v8::FunctionTemplate::New(isolate); + templ->SetNativeDataProperty(v8_str("name"), FunctionNativeGetter); + info.GetReturnValue().Set( + templ->GetFunction(isolate->GetCurrentContext()).ToLocalChecked()); + }); + + // Check that getter is called on Function.prototype.bind. + global_template->SetNativeDataProperty( + v8_str("func2"), [](v8::Local<v8::String> property, + const v8::PropertyCallbackInfo<v8::Value>& info) { + v8::Isolate* isolate = info.GetIsolate(); + v8::Local<v8::FunctionTemplate> templ = + v8::FunctionTemplate::New(isolate); + templ->SetNativeDataProperty(v8_str("length"), FunctionNativeGetter); + info.GetReturnValue().Set( + templ->GetFunction(isolate->GetCurrentContext()).ToLocalChecked()); + }); + + return v8::Context::New(isolate, nullptr, global_template); +} +} // namespace + +TEST(WrapFunctionTemplateSetNativeDataProperty) { + i::FLAG_harmony_shadow_realm = true; + LocalContext env; + v8::Isolate* isolate = env->GetIsolate(); + isolate->SetHostCreateShadowRealmContextCallback( + TestHostCreateShadowRealmContextCallback); + + v8::HandleScope scope(isolate); + // Check that getter is called on WrappedFunctionCreate. + { + v8::TryCatch try_catch(isolate); + CHECK( + CompileRun("new ShadowRealm().evaluate('globalThis.func1')").IsEmpty()); + CHECK(try_catch.HasCaught()); + } + // Check that getter is called on WrappedFunctionCreate. + { + v8::TryCatch try_catch(isolate); + CHECK( + CompileRun("new ShadowRealm().evaluate('globalThis.func2')").IsEmpty()); + CHECK(try_catch.HasCaught()); + } +} diff --git a/deps/v8/test/cctest/test-api.cc b/deps/v8/test/cctest/test-api.cc index 3c57428651..92f549ad96 100644 --- a/deps/v8/test/cctest/test-api.cc +++ b/deps/v8/test/cctest/test-api.cc @@ -33,6 +33,8 @@ #include <memory> #include <string> +#include "test/cctest/cctest.h" + #if V8_OS_POSIX #include <unistd.h> #endif @@ -7895,6 +7897,7 @@ static void ResetUseValueAndSetFlag( } void v8::internal::heap::HeapTester::ResetWeakHandle(bool global_gc) { + if (FLAG_stress_incremental_marking) return; using v8::Context; using v8::Local; using v8::Object; @@ -23102,14 +23105,8 @@ TEST(ThrowOnJavascriptExecution) { namespace { -class MockPlatform : public TestPlatform { +class MockPlatform final : public TestPlatform { public: - MockPlatform() : old_platform_(i::V8::GetCurrentPlatform()) { - // Now that it's completely constructed, make this the current platform. - i::V8::SetPlatformForTesting(this); - } - ~MockPlatform() override { i::V8::SetPlatformForTesting(old_platform_); } - bool dump_without_crashing_called() const { return dump_without_crashing_called_; } @@ -23117,15 +23114,12 @@ class MockPlatform : public TestPlatform { void DumpWithoutCrashing() override { dump_without_crashing_called_ = true; } private: - v8::Platform* old_platform_; bool dump_without_crashing_called_ = false; }; } // namespace -TEST(DumpOnJavascriptExecution) { - MockPlatform platform; - +TEST_WITH_PLATFORM(DumpOnJavascriptExecution, MockPlatform) { LocalContext context; v8::Isolate* isolate = context->GetIsolate(); v8::HandleScope scope(isolate); @@ -29498,38 +29492,6 @@ TEST(CodeLikeFunction) { ExpectInt32("new Function(new CodeLike())()", 7); } -UNINITIALIZED_TEST(SingleThreadedDefaultPlatform) { - v8::V8::SetFlagsFromString("--single-threaded"); - auto old_platform = i::V8::GetCurrentPlatform(); - std::unique_ptr<v8::Platform> new_platform( - v8::platform::NewSingleThreadedDefaultPlatform()); - i::V8::SetPlatformForTesting(new_platform.get()); - v8::Isolate::CreateParams create_params; - create_params.array_buffer_allocator = CcTest::array_buffer_allocator(); - v8::Isolate* isolate = v8::Isolate::New(create_params); - isolate->Enter(); - i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); - { - i::HandleScope scope(i_isolate); - v8::Local<Context> env = Context::New(isolate); - env->Enter(); - - CompileRunChecked(isolate, - "function f() {" - " for (let i = 0; i < 10; i++)" - " (new Array(10)).fill(0);" - " return 0;" - "}" - "f();"); - env->Exit(); - } - CcTest::CollectGarbage(i::NEW_SPACE, i_isolate); - CcTest::CollectAllAvailableGarbage(i_isolate); - isolate->Exit(); - isolate->Dispose(); - i::V8::SetPlatformForTesting(old_platform); -} - THREADED_TEST(MicrotaskQueueOfContext) { auto microtask_queue = v8::MicrotaskQueue::New(CcTest::isolate()); v8::HandleScope scope(CcTest::isolate()); diff --git a/deps/v8/test/cctest/test-assembler-arm64.cc b/deps/v8/test/cctest/test-assembler-arm64.cc index fea98df487..897a4a70f9 100644 --- a/deps/v8/test/cctest/test-assembler-arm64.cc +++ b/deps/v8/test/cctest/test-assembler-arm64.cc @@ -12381,7 +12381,7 @@ static void PushPopSimpleHelper(int reg_count, int reg_size, } break; case PushPopRegList: - __ PushSizeRegList<TurboAssembler::kDontStoreLR>(list, reg_size); + __ PushSizeRegList(list, reg_size); break; } @@ -12406,7 +12406,7 @@ static void PushPopSimpleHelper(int reg_count, int reg_size, } break; case PushPopRegList: - __ PopSizeRegList<TurboAssembler::kDontLoadLR>(list, reg_size); + __ PopSizeRegList(list, reg_size); break; } } @@ -12740,8 +12740,8 @@ TEST(push_pop) { __ PopXRegList({}); // Don't push/pop x18 (platform register) or lr RegList all_regs = RegList::FromBits(0xFFFFFFFF) - RegList{x18, lr}; - __ PushXRegList<TurboAssembler::kDontStoreLR>(all_regs); - __ PopXRegList<TurboAssembler::kDontLoadLR>(all_regs); + __ PushXRegList(all_regs); + __ PopXRegList(all_regs); __ Drop(12); END(); diff --git a/deps/v8/test/cctest/test-assembler-ia32.cc b/deps/v8/test/cctest/test-assembler-ia32.cc index f4ca7e83cf..131a52a396 100644 --- a/deps/v8/test/cctest/test-assembler-ia32.cc +++ b/deps/v8/test/cctest/test-assembler-ia32.cc @@ -1522,8 +1522,6 @@ TEST(Regress621926) { } TEST(DeoptExitSizeIsFixed) { - CHECK(Deoptimizer::kSupportsFixedDeoptExitSizes); - Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); v8::internal::byte buffer[256]; @@ -1539,9 +1537,8 @@ TEST(DeoptExitSizeIsFixed) { masm.CallForDeoptimization(target, 42, &before_exit, kind, &before_exit, nullptr); CHECK_EQ(masm.SizeOfCodeGeneratedSince(&before_exit), - kind == DeoptimizeKind::kLazy - ? Deoptimizer::kLazyDeoptExitSize - : Deoptimizer::kNonLazyDeoptExitSize); + kind == DeoptimizeKind::kLazy ? Deoptimizer::kLazyDeoptExitSize + : Deoptimizer::kEagerDeoptExitSize); } } diff --git a/deps/v8/test/cctest/test-assembler-x64.cc b/deps/v8/test/cctest/test-assembler-x64.cc index 11ef08fb89..4d823e4f0a 100644 --- a/deps/v8/test/cctest/test-assembler-x64.cc +++ b/deps/v8/test/cctest/test-assembler-x64.cc @@ -2827,6 +2827,53 @@ TEST(AssemblerX64Integer256bit) { CHECK_EQ(0, memcmp(expected, desc.buffer, sizeof(expected))); } +TEST(AssemblerX64CmpOperations256bit) { + if (!CpuFeatures::IsSupported(AVX)) return; + CcTest::InitializeVM(); + v8::HandleScope scope(CcTest::isolate()); + auto buffer = AllocateAssemblerBuffer(); + Isolate* isolate = CcTest::i_isolate(); + Assembler masm(AssemblerOptions{}, buffer->CreateView()); + CpuFeatureScope fscope(&masm, AVX); + + __ vcmpeqps(ymm1, ymm2, ymm4); + __ vcmpltpd(ymm4, ymm7, Operand(rcx, rdx, times_4, 10000)); + __ vcmpleps(ymm9, ymm8, Operand(r8, r11, times_8, 10000)); + __ vcmpunordpd(ymm3, ymm7, ymm8); + __ vcmpneqps(ymm3, ymm5, ymm9); + __ vcmpnltpd(ymm10, ymm12, Operand(r12, r11, times_4, 10000)); + __ vcmpnleps(ymm9, ymm11, Operand(r10, r9, times_8, 10000)); + __ vcmpgepd(ymm13, ymm3, ymm12); + + CodeDesc desc; + masm.GetCode(isolate, &desc); +#ifdef OBJECT_PRINT + Handle<Code> code = + Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING).Build(); + StdoutStream os; + code->Print(os); +#endif + + byte expected[] = { + // vcmpeqps ymm1, ymm2, ymm4 + 0xC5, 0xEC, 0xC2, 0xCC, 0x00, + // vcmpltpd ymm4, ymm7, YMMWORD PTR [rcx+rdx*4+0x2710] + 0xC5, 0xC5, 0xC2, 0xA4, 0x91, 0x10, 0x27, 0x00, 0x00, 0x01, + // vcmpleps ymm9, ymm8, YMMWORD PTR [r8+r11*8+0x2710] + 0xC4, 0x01, 0x3C, 0xC2, 0x8C, 0xD8, 0x10, 0x27, 0x00, 0x00, 0x02, + // vcmpunordpd ymm3, ymm7, ymm8 + 0xC4, 0xC1, 0x45, 0xC2, 0xD8, 0x03, + // vcmpneqps ymm3, ymm5, ymm9 + 0xC4, 0xC1, 0x54, 0xC2, 0xD9, 0x04, + // vcmpnltpd ymm10, ymm12, YMMWORD PTR [r12+r11*4+0x2710] + 0xC4, 0x01, 0x1D, 0xC2, 0x94, 0x9C, 0x10, 0x27, 0x00, 0x00, 0x05, + // vcmpnleps ymm9, ymm11, YMMWORD PTR [r10+r9*8+0x2710] + 0xC4, 0x01, 0x24, 0xC2, 0x8C, 0xCA, 0x10, 0x27, 0x00, 0x00, 0x06, + // vcmpgepd ymm13, ymm3, ymm12 + 0xC4, 0x41, 0x65, 0xC2, 0xEC, 0x0D}; + CHECK_EQ(0, memcmp(expected, desc.buffer, sizeof(expected))); +} + TEST(CpuFeatures_ProbeImpl) { // Support for a newer extension implies support for the older extensions. CHECK_IMPLIES(CpuFeatures::IsSupported(FMA3), CpuFeatures::IsSupported(AVX)); diff --git a/deps/v8/test/cctest/test-debug.cc b/deps/v8/test/cctest/test-debug.cc index 28600996f5..4c70451d59 100644 --- a/deps/v8/test/cctest/test-debug.cc +++ b/deps/v8/test/cctest/test-debug.cc @@ -4565,6 +4565,48 @@ TEST(DebugEvaluateNoSideEffect) { DisableDebugger(env->GetIsolate()); } +TEST(DebugEvaluateGlobalSharedCrossOrigin) { + LocalContext env; + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); + v8::TryCatch tryCatch(isolate); + tryCatch.SetCaptureMessage(true); + v8::MaybeLocal<v8::Value> result = + v8::debug::EvaluateGlobal(isolate, v8_str(isolate, "throw new Error()"), + v8::debug::EvaluateGlobalMode::kDefault); + CHECK(result.IsEmpty()); + CHECK(tryCatch.HasCaught()); + CHECK(tryCatch.Message()->IsSharedCrossOrigin()); +} + +TEST(DebugEvaluateLocalSharedCrossOrigin) { + struct BreakProgramDelegate : public v8::debug::DebugDelegate { + void BreakProgramRequested(v8::Local<v8::Context> context, + std::vector<v8::debug::BreakpointId> const&, + v8::debug::BreakReasons) final { + v8::Isolate* isolate = context->GetIsolate(); + v8::TryCatch tryCatch(isolate); + tryCatch.SetCaptureMessage(true); + std::unique_ptr<v8::debug::StackTraceIterator> it = + v8::debug::StackTraceIterator::Create(isolate); + v8::MaybeLocal<v8::Value> result = + it->Evaluate(v8_str(isolate, "throw new Error()"), false); + CHECK(result.IsEmpty()); + CHECK(tryCatch.HasCaught()); + CHECK(tryCatch.Message()->IsSharedCrossOrigin()); + } + } delegate; + LocalContext env; + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); + v8::debug::SetDebugDelegate(isolate, &delegate); + v8::Script::Compile(env.local(), v8_str(isolate, "debugger;")) + .ToLocalChecked() + ->Run(env.local()) + .ToLocalChecked(); + v8::debug::SetDebugDelegate(isolate, nullptr); +} + namespace { i::MaybeHandle<i::Script> FindScript( i::Isolate* isolate, const std::vector<i::Handle<i::Script>>& scripts, @@ -5722,7 +5764,7 @@ TEST(AwaitCleansUpGlobalPromiseStack) { "})();\n"); CompileRun(source); - CHECK_EQ(CcTest::i_isolate()->thread_local_top()->promise_on_stack_, nullptr); + CHECK(CcTest::i_isolate()->IsPromiseStackEmpty()); v8::debug::SetDebugDelegate(env->GetIsolate(), nullptr); CheckDebuggerUnloaded(); diff --git a/deps/v8/test/cctest/test-disasm-x64.cc b/deps/v8/test/cctest/test-disasm-x64.cc index 2b2aa963ee..45c7aebe5a 100644 --- a/deps/v8/test/cctest/test-disasm-x64.cc +++ b/deps/v8/test/cctest/test-disasm-x64.cc @@ -780,6 +780,8 @@ UNINITIALIZED_TEST(DisasmX64CheckOutputSSE) { COMPARE("440f178c8b10270000 movhps [rbx+rcx*4+0x2710],xmm9", movhps(Operand(rbx, rcx, times_4, 10000), xmm9)); COMPARE("410fc6c100 shufps xmm0, xmm9, 0", shufps(xmm0, xmm9, 0x0)); + COMPARE("f30fc2c100 cmpeqss xmm0,xmm1", cmpeqss(xmm0, xmm1)); + COMPARE("f20fc2c100 cmpeqsd xmm0,xmm1", cmpeqsd(xmm0, xmm1)); COMPARE("0f2ec1 ucomiss xmm0,xmm1", ucomiss(xmm0, xmm1)); COMPARE("0f2e848b10270000 ucomiss xmm0,[rbx+rcx*4+0x2710]", ucomiss(xmm0, Operand(rbx, rcx, times_4, 10000))); @@ -1027,8 +1029,12 @@ UNINITIALIZED_TEST(DisasmX64CheckOutputSSE4_1) { roundpd(xmm8, xmm3, kRoundToNearest)); COMPARE("66440f3a0ac309 roundss xmm8,xmm3,0x1", roundss(xmm8, xmm3, kRoundDown)); + COMPARE("66440f3a0a420b09 roundss xmm8,[rdx+0xb],0x1", + roundss(xmm8, Operand(rdx, 11), kRoundDown)); COMPARE("66440f3a0bc309 roundsd xmm8,xmm3,0x1", roundsd(xmm8, xmm3, kRoundDown)); + COMPARE("66440f3a0b420b09 roundsd xmm8,[rdx+0xb],0x1", + roundsd(xmm8, Operand(rdx, 11), kRoundDown)); #define COMPARE_SSE4_1_INSTR(instruction, _, __, ___, ____) \ exp = #instruction " xmm5,xmm1"; \ @@ -1167,6 +1173,10 @@ UNINITIALIZED_TEST(DisasmX64CheckOutputAVX) { vmovss(xmm9, Operand(r11, rcx, times_8, -10000))); COMPARE("c4a17a118c8b10270000 vmovss [rbx+r9*4+0x2710],xmm1", vmovss(Operand(rbx, r9, times_4, 10000), xmm1)); + COMPARE("c532c2c900 vcmpss xmm9,xmm9,xmm1, (eq)", + vcmpeqss(xmm9, xmm1)); + COMPARE("c533c2c900 vcmpsd xmm9,xmm9,xmm1, (eq)", + vcmpeqsd(xmm9, xmm1)); COMPARE("c5782ec9 vucomiss xmm9,xmm1", vucomiss(xmm9, xmm1)); COMPARE("c5782e8453e52a0000 vucomiss xmm8,[rbx+rdx*2+0x2ae5]", vucomiss(xmm8, Operand(rbx, rdx, times_2, 10981))); @@ -1415,9 +1425,26 @@ UNINITIALIZED_TEST(DisasmX64YMMRegister) { COMPARE("c5ff12a48b10270000 vmovddup ymm4,[rbx+rcx*4+0x2710]", vmovddup(ymm4, Operand(rbx, rcx, times_4, 10000))); COMPARE("c5fe16ca vmovshdup ymm1,ymm2", vmovshdup(ymm1, ymm2)); - COMPARE("c5f4c6da73 vshufps ymm3,ymm1,ymm2,0x73", vshufps(ymm3, ymm1, ymm2, 115)); + + // vcmp + COMPARE("c5dcc2e900 vcmpps ymm5,ymm4,ymm1, (eq)", + vcmpeqps(ymm5, ymm4, ymm1)); + COMPARE("c5ddc2ac8b1027000001 vcmppd ymm5,ymm4,[rbx+rcx*4+0x2710], (lt)", + vcmpltpd(ymm5, ymm4, Operand(rbx, rcx, times_4, 10000))); + COMPARE("c5ddc2e902 vcmppd ymm5,ymm4,ymm1, (le)", + vcmplepd(ymm5, ymm4, ymm1)); + COMPARE("c5dcc2ac8b1027000003 vcmpps ymm5,ymm4,[rbx+rcx*4+0x2710], (unord)", + vcmpunordps(ymm5, ymm4, Operand(rbx, rcx, times_4, 10000))); + COMPARE("c5dcc2e904 vcmpps ymm5,ymm4,ymm1, (neq)", + vcmpneqps(ymm5, ymm4, ymm1)); + COMPARE("c5ddc2ac8b1027000005 vcmppd ymm5,ymm4,[rbx+rcx*4+0x2710], (nlt)", + vcmpnltpd(ymm5, ymm4, Operand(rbx, rcx, times_4, 10000))); + COMPARE("c5ddc2ac8b1027000006 vcmppd ymm5,ymm4,[rbx+rcx*4+0x2710], (nle)", + vcmpnlepd(ymm5, ymm4, Operand(rbx, rcx, times_4, 10000))); + COMPARE("c5dcc2e90d vcmpps ymm5,ymm4,ymm1, (ge)", + vcmpgeps(ymm5, ymm4, ymm1)); } if (!CpuFeatures::IsSupported(AVX2)) return; diff --git a/deps/v8/test/cctest/test-field-type-tracking.cc b/deps/v8/test/cctest/test-field-type-tracking.cc index 1bee88aa4d..90e3341806 100644 --- a/deps/v8/test/cctest/test-field-type-tracking.cc +++ b/deps/v8/test/cctest/test-field-type-tracking.cc @@ -70,7 +70,7 @@ static void CheckMigrationTarget(Isolate* isolate, Map old_map, Map new_map) { if (target.is_null()) return; CHECK_EQ(new_map, target); CHECK_EQ(MapUpdater::TryUpdateNoLock(isolate, old_map, - ConcurrencyMode::kNotConcurrent), + ConcurrencyMode::kSynchronous), target); } @@ -1836,7 +1836,7 @@ static void TestReconfigureElementsKind_GeneralizeFieldInPlace( MapHandles map_list; map_list.push_back(updated_map); Map transitioned_map = map2->FindElementsKindTransitionedMap( - isolate, map_list, ConcurrencyMode::kNotConcurrent); + isolate, map_list, ConcurrencyMode::kSynchronous); CHECK_EQ(*updated_map, transitioned_map); } } diff --git a/deps/v8/test/cctest/test-heap-profiler.cc b/deps/v8/test/cctest/test-heap-profiler.cc index d39629ecec..7d1fd5de99 100644 --- a/deps/v8/test/cctest/test-heap-profiler.cc +++ b/deps/v8/test/cctest/test-heap-profiler.cc @@ -465,7 +465,7 @@ TEST(HeapSnapshotCodeObjects) { for (int i = 0, count = compiled_sfi->GetChildrenCount(); i < count; ++i) { const v8::HeapGraphEdge* prop = compiled_sfi->GetChild(i); const v8::HeapGraphNode* node = prop->GetToNode(); - if (node->GetType() == v8::HeapGraphNode::kHidden && + if (node->GetType() == v8::HeapGraphNode::kCode && !strcmp("system / ScopeInfo", GetName(node))) { if (HasString(env->GetIsolate(), node, "x")) { compiled_references_x = true; @@ -476,7 +476,7 @@ TEST(HeapSnapshotCodeObjects) { for (int i = 0, count = lazy_sfi->GetChildrenCount(); i < count; ++i) { const v8::HeapGraphEdge* prop = lazy_sfi->GetChild(i); const v8::HeapGraphNode* node = prop->GetToNode(); - if (node->GetType() == v8::HeapGraphNode::kHidden && + if (node->GetType() == v8::HeapGraphNode::kCode && !strcmp("system / ScopeInfo", GetName(node))) { if (HasString(env->GetIsolate(), node, "x")) { lazy_references_x = true; @@ -2680,7 +2680,7 @@ TEST(AllocationSitesAreVisible) { CHECK(feedback_cell); const v8::HeapGraphNode* vector = GetProperty( env->GetIsolate(), feedback_cell, v8::HeapGraphEdge::kInternal, "value"); - CHECK_EQ(v8::HeapGraphNode::kHidden, vector->GetType()); + CHECK_EQ(v8::HeapGraphNode::kCode, vector->GetType()); CHECK_EQ(4, vector->GetChildrenCount()); // The last value in the feedback vector should be the boilerplate, @@ -2698,7 +2698,7 @@ TEST(AllocationSitesAreVisible) { GetProperty(env->GetIsolate(), transition_info, v8::HeapGraphEdge::kInternal, "elements"); CHECK(elements); - CHECK_EQ(v8::HeapGraphNode::kArray, elements->GetType()); + CHECK_EQ(v8::HeapGraphNode::kCode, elements->GetType()); CHECK_EQ(v8::internal::FixedArray::SizeFor(3), static_cast<int>(elements->GetShallowSize())); @@ -4139,9 +4139,9 @@ TEST(WeakReference) { // to the FOR_TESTING code kind). fv->set_maybe_optimized_code(i::HeapObjectReference::Weak(ToCodeT(*code)), v8::kReleaseStore); - fv->set_flags(i::FeedbackVector::MaybeHasOptimizedCodeBit::encode(true) | - i::FeedbackVector::OptimizationMarkerBits::encode( - i::OptimizationMarker::kNone)); + fv->set_flags( + i::FeedbackVector::MaybeHasOptimizedCodeBit::encode(true) | + i::FeedbackVector::TieringStateBits::encode(i::TieringState::kNone)); v8::HeapProfiler* heap_profiler = isolate->GetHeapProfiler(); const v8::HeapSnapshot* snapshot = heap_profiler->TakeHeapSnapshot(); diff --git a/deps/v8/test/cctest/test-js-to-wasm.cc b/deps/v8/test/cctest/test-js-to-wasm.cc index ecb481ee23..ff18adf51c 100644 --- a/deps/v8/test/cctest/test-js-to-wasm.cc +++ b/deps/v8/test/cctest/test-js-to-wasm.cc @@ -271,6 +271,7 @@ class FastJSWasmCallTester { i::FLAG_allow_natives_syntax = true; i::FLAG_turbo_inline_js_wasm_calls = true; i::FLAG_stress_background_compile = false; + i::FLAG_concurrent_osr = false; // Seems to mess with %ObserveNode. } void DeclareCallback(const char* name, FunctionSig* signature, diff --git a/deps/v8/test/cctest/test-js-weak-refs.cc b/deps/v8/test/cctest/test-js-weak-refs.cc index 8974bdf6db..a2c3a3e504 100644 --- a/deps/v8/test/cctest/test-js-weak-refs.cc +++ b/deps/v8/test/cctest/test-js-weak-refs.cc @@ -925,7 +925,8 @@ TEST(JSWeakRefScavengedInWorklist) { } TEST(JSWeakRefTenuredInWorklist) { - if (!FLAG_incremental_marking || FLAG_single_generation) { + if (!FLAG_incremental_marking || FLAG_single_generation || + FLAG_separate_gc_phases) { return; } diff --git a/deps/v8/test/cctest/test-log.cc b/deps/v8/test/cctest/test-log.cc index e57c5a6198..0abce98009 100644 --- a/deps/v8/test/cctest/test-log.cc +++ b/deps/v8/test/cctest/test-log.cc @@ -513,7 +513,6 @@ UNINITIALIZED_TEST(LogAll) { SETUP_FLAGS(); i::FLAG_log_all = true; i::FLAG_log_deopt = true; - i::FLAG_log_api = true; i::FLAG_turbo_inlining = false; i::FLAG_log_internal_timer_events = true; i::FLAG_allow_natives_syntax = true; @@ -551,11 +550,9 @@ UNINITIALIZED_TEST(LogAll) { logger.StopLogging(); // We should find at least one code-creation even for testAddFn(); - CHECK(logger.ContainsLine({"api,v8::Context::New"})); CHECK(logger.ContainsLine({"timer-event-start", "V8.CompileCode"})); CHECK(logger.ContainsLine({"timer-event-end", "V8.CompileCode"})); CHECK(logger.ContainsLine({"code-creation,Script", ":1:1"})); - CHECK(logger.ContainsLine({"api,v8::Script::Run"})); CHECK(logger.ContainsLine({"code-creation,LazyCompile,", "testAddFn"})); if (i::FLAG_opt && !i::FLAG_always_opt) { diff --git a/deps/v8/test/cctest/test-macro-assembler-arm.cc b/deps/v8/test/cctest/test-macro-assembler-arm.cc index 251cd5f705..23b5b2d4e8 100644 --- a/deps/v8/test/cctest/test-macro-assembler-arm.cc +++ b/deps/v8/test/cctest/test-macro-assembler-arm.cc @@ -311,8 +311,6 @@ TEST(ReplaceLane) { } TEST(DeoptExitSizeIsFixed) { - CHECK(Deoptimizer::kSupportsFixedDeoptExitSizes); - Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); auto buffer = AllocateAssemblerBuffer(); @@ -328,9 +326,8 @@ TEST(DeoptExitSizeIsFixed) { masm.CallForDeoptimization(target, 42, &before_exit, kind, &before_exit, nullptr); CHECK_EQ(masm.SizeOfCodeGeneratedSince(&before_exit), - kind == DeoptimizeKind::kLazy - ? Deoptimizer::kLazyDeoptExitSize - : Deoptimizer::kNonLazyDeoptExitSize); + kind == DeoptimizeKind::kLazy ? Deoptimizer::kLazyDeoptExitSize + : Deoptimizer::kEagerDeoptExitSize); } } diff --git a/deps/v8/test/cctest/test-macro-assembler-arm64.cc b/deps/v8/test/cctest/test-macro-assembler-arm64.cc index d96fc3551f..eec16c0529 100644 --- a/deps/v8/test/cctest/test-macro-assembler-arm64.cc +++ b/deps/v8/test/cctest/test-macro-assembler-arm64.cc @@ -94,8 +94,6 @@ TEST(EmbeddedObj) { } TEST(DeoptExitSizeIsFixed) { - CHECK(Deoptimizer::kSupportsFixedDeoptExitSizes); - Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); auto buffer = AllocateAssemblerBuffer(); @@ -117,9 +115,8 @@ TEST(DeoptExitSizeIsFixed) { masm.CallForDeoptimization(target, 42, &before_exit, kind, &before_exit, &before_exit); CHECK_EQ(masm.SizeOfCodeGeneratedSince(&before_exit), - kind == DeoptimizeKind::kLazy - ? Deoptimizer::kLazyDeoptExitSize - : Deoptimizer::kNonLazyDeoptExitSize); + kind == DeoptimizeKind::kLazy ? Deoptimizer::kLazyDeoptExitSize + : Deoptimizer::kEagerDeoptExitSize); } } diff --git a/deps/v8/test/cctest/test-macro-assembler-loong64.cc b/deps/v8/test/cctest/test-macro-assembler-loong64.cc index 63730abbc2..eac64947e9 100644 --- a/deps/v8/test/cctest/test-macro-assembler-loong64.cc +++ b/deps/v8/test/cctest/test-macro-assembler-loong64.cc @@ -2879,8 +2879,6 @@ TEST(Popcnt) { } TEST(DeoptExitSizeIsFixed) { - CHECK(Deoptimizer::kSupportsFixedDeoptExitSizes); - Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); auto buffer = AllocateAssemblerBuffer(); @@ -2895,9 +2893,8 @@ TEST(DeoptExitSizeIsFixed) { masm.CallForDeoptimization(target, 42, &before_exit, kind, &before_exit, nullptr); CHECK_EQ(masm.SizeOfCodeGeneratedSince(&before_exit), - kind == DeoptimizeKind::kLazy - ? Deoptimizer::kLazyDeoptExitSize - : Deoptimizer::kNonLazyDeoptExitSize); + kind == DeoptimizeKind::kLazy ? Deoptimizer::kLazyDeoptExitSize + : Deoptimizer::kEagerDeoptExitSize); } } diff --git a/deps/v8/test/cctest/test-macro-assembler-mips.cc b/deps/v8/test/cctest/test-macro-assembler-mips.cc index 9e5fdabd15..c4926af159 100644 --- a/deps/v8/test/cctest/test-macro-assembler-mips.cc +++ b/deps/v8/test/cctest/test-macro-assembler-mips.cc @@ -1337,8 +1337,6 @@ TEST(macro_float_minmax_f64) { } TEST(DeoptExitSizeIsFixed) { - CHECK(Deoptimizer::kSupportsFixedDeoptExitSizes); - Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); auto buffer = AllocateAssemblerBuffer(); @@ -1353,9 +1351,8 @@ TEST(DeoptExitSizeIsFixed) { masm.CallForDeoptimization(target, 42, &before_exit, kind, &before_exit, nullptr); CHECK_EQ(masm.SizeOfCodeGeneratedSince(&before_exit), - kind == DeoptimizeKind::kLazy - ? Deoptimizer::kLazyDeoptExitSize - : Deoptimizer::kNonLazyDeoptExitSize); + kind == DeoptimizeKind::kLazy ? Deoptimizer::kLazyDeoptExitSize + : Deoptimizer::kEagerDeoptExitSize); } } diff --git a/deps/v8/test/cctest/test-macro-assembler-mips64.cc b/deps/v8/test/cctest/test-macro-assembler-mips64.cc index 09664f0170..2d87fb7750 100644 --- a/deps/v8/test/cctest/test-macro-assembler-mips64.cc +++ b/deps/v8/test/cctest/test-macro-assembler-mips64.cc @@ -1690,8 +1690,6 @@ TEST(macro_float_minmax_f64) { } TEST(DeoptExitSizeIsFixed) { - CHECK(Deoptimizer::kSupportsFixedDeoptExitSizes); - Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); auto buffer = AllocateAssemblerBuffer(); @@ -1706,9 +1704,8 @@ TEST(DeoptExitSizeIsFixed) { masm.CallForDeoptimization(target, 42, &before_exit, kind, &before_exit, nullptr); CHECK_EQ(masm.SizeOfCodeGeneratedSince(&before_exit), - kind == DeoptimizeKind::kLazy - ? Deoptimizer::kLazyDeoptExitSize - : Deoptimizer::kNonLazyDeoptExitSize); + kind == DeoptimizeKind::kLazy ? Deoptimizer::kLazyDeoptExitSize + : Deoptimizer::kEagerDeoptExitSize); } } diff --git a/deps/v8/test/cctest/test-macro-assembler-riscv64.cc b/deps/v8/test/cctest/test-macro-assembler-riscv64.cc index a98c10933e..0bf9b5b363 100644 --- a/deps/v8/test/cctest/test-macro-assembler-riscv64.cc +++ b/deps/v8/test/cctest/test-macro-assembler-riscv64.cc @@ -1519,8 +1519,6 @@ TEST(Move) { } TEST(DeoptExitSizeIsFixed) { - CHECK(Deoptimizer::kSupportsFixedDeoptExitSizes); - Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); auto buffer = AllocateAssemblerBuffer(); @@ -1541,9 +1539,8 @@ TEST(DeoptExitSizeIsFixed) { masm.CallForDeoptimization(target, 42, &before_exit, kind, &before_exit, &before_exit); CHECK_EQ(masm.SizeOfCodeGeneratedSince(&before_exit), - kind == DeoptimizeKind::kLazy - ? Deoptimizer::kLazyDeoptExitSize - : Deoptimizer::kNonLazyDeoptExitSize); + kind == DeoptimizeKind::kLazy ? Deoptimizer::kLazyDeoptExitSize + : Deoptimizer::kEagerDeoptExitSize); } } diff --git a/deps/v8/test/cctest/test-macro-assembler-x64.cc b/deps/v8/test/cctest/test-macro-assembler-x64.cc index 7e1388bd52..1bc04263e8 100644 --- a/deps/v8/test/cctest/test-macro-assembler-x64.cc +++ b/deps/v8/test/cctest/test-macro-assembler-x64.cc @@ -1050,8 +1050,6 @@ TEST(AreAliased) { } TEST(DeoptExitSizeIsFixed) { - CHECK(Deoptimizer::kSupportsFixedDeoptExitSizes); - Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); auto buffer = AllocateAssemblerBuffer(); @@ -1067,9 +1065,8 @@ TEST(DeoptExitSizeIsFixed) { masm.CallForDeoptimization(target, 42, &before_exit, kind, &before_exit, nullptr); CHECK_EQ(masm.SizeOfCodeGeneratedSince(&before_exit), - kind == DeoptimizeKind::kLazy - ? Deoptimizer::kLazyDeoptExitSize - : Deoptimizer::kNonLazyDeoptExitSize); + kind == DeoptimizeKind::kLazy ? Deoptimizer::kLazyDeoptExitSize + : Deoptimizer::kEagerDeoptExitSize); } } diff --git a/deps/v8/test/cctest/test-profile-generator.cc b/deps/v8/test/cctest/test-profile-generator.cc index de1c42cb16..204cba7e4e 100644 --- a/deps/v8/test/cctest/test-profile-generator.cc +++ b/deps/v8/test/cctest/test-profile-generator.cc @@ -536,6 +536,32 @@ TEST(SampleIds_StopProfilingByProfilerId) { CHECK_NE(profile, nullptr); } +TEST(CpuProfilesCollectionDuplicateId) { + CpuProfilesCollection collection(CcTest::i_isolate()); + CpuProfiler profiler(CcTest::i_isolate()); + collection.set_cpu_profiler(&profiler); + + auto profile_result = collection.StartProfiling(); + CHECK_EQ(CpuProfilingStatus::kStarted, profile_result.status); + CHECK_EQ(CpuProfilingStatus::kAlreadyStarted, + collection.StartProfilingForTesting(profile_result.id).status); + + collection.StopProfiling(profile_result.id); +} + +TEST(CpuProfilesCollectionDuplicateTitle) { + CpuProfilesCollection collection(CcTest::i_isolate()); + CpuProfiler profiler(CcTest::i_isolate()); + collection.set_cpu_profiler(&profiler); + + auto profile_result = collection.StartProfiling("duplicate"); + CHECK_EQ(CpuProfilingStatus::kStarted, profile_result.status); + CHECK_EQ(CpuProfilingStatus::kAlreadyStarted, + collection.StartProfiling("duplicate").status); + + collection.StopProfiling(profile_result.id); +} + namespace { class DiscardedSamplesDelegateImpl : public v8::DiscardedSamplesDelegate { public: @@ -543,17 +569,9 @@ class DiscardedSamplesDelegateImpl : public v8::DiscardedSamplesDelegate { void Notify() override { CHECK_GT(GetId(), 0); } }; -class MockPlatform : public TestPlatform { +class MockPlatform final : public TestPlatform { public: - MockPlatform() - : old_platform_(i::V8::GetCurrentPlatform()), - mock_task_runner_(new MockTaskRunner()) { - // Now that it's completely constructed, make this the current platform. - i::V8::SetPlatformForTesting(this); - } - - // When done, explicitly revert to old_platform_. - ~MockPlatform() override { i::V8::SetPlatformForTesting(old_platform_); } + MockPlatform() : mock_task_runner_(new MockTaskRunner()) {} std::shared_ptr<v8::TaskRunner> GetForegroundTaskRunner( v8::Isolate*) override { @@ -581,6 +599,8 @@ class MockPlatform : public TestPlatform { } bool IdleTasksEnabled() override { return false; } + bool NonNestableTasksEnabled() const override { return true; } + bool NonNestableDelayedTasksEnabled() const override { return true; } int posted_count() { return posted_count_; } @@ -590,17 +610,15 @@ class MockPlatform : public TestPlatform { std::unique_ptr<Task> task_; }; - v8::Platform* old_platform_; std::shared_ptr<MockTaskRunner> mock_task_runner_; }; } // namespace -TEST(MaxSamplesCallback) { +TEST_WITH_PLATFORM(MaxSamplesCallback, MockPlatform) { i::Isolate* isolate = CcTest::i_isolate(); CpuProfilesCollection profiles(isolate); CpuProfiler profiler(isolate); profiles.set_cpu_profiler(&profiler); - MockPlatform* mock_platform = new MockPlatform(); std::unique_ptr<DiscardedSamplesDelegateImpl> impl = std::make_unique<DiscardedSamplesDelegateImpl>( DiscardedSamplesDelegateImpl()); @@ -624,7 +642,7 @@ TEST(MaxSamplesCallback) { profiles.AddPathToCurrentProfiles( sample1.timestamp, symbolized.stack_trace, symbolized.src_line, true, base::TimeDelta(), StateTag::JS, EmbedderStateTag::EMPTY); - CHECK_EQ(0, mock_platform->posted_count()); + CHECK_EQ(0, platform.posted_count()); TickSample sample2; sample2.timestamp = v8::base::TimeTicks::Now(); sample2.pc = ToPointer(0x1925); @@ -634,7 +652,7 @@ TEST(MaxSamplesCallback) { profiles.AddPathToCurrentProfiles( sample2.timestamp, symbolized.stack_trace, symbolized.src_line, true, base::TimeDelta(), StateTag::JS, EmbedderStateTag::EMPTY); - CHECK_EQ(1, mock_platform->posted_count()); + CHECK_EQ(1, platform.posted_count()); TickSample sample3; sample3.timestamp = v8::base::TimeTicks::Now(); sample3.pc = ToPointer(0x1510); @@ -643,11 +661,10 @@ TEST(MaxSamplesCallback) { profiles.AddPathToCurrentProfiles( sample3.timestamp, symbolized.stack_trace, symbolized.src_line, true, base::TimeDelta(), StateTag::JS, EmbedderStateTag::EMPTY); - CHECK_EQ(1, mock_platform->posted_count()); + CHECK_EQ(1, platform.posted_count()); // Teardown profiles.StopProfiling(id); - delete mock_platform; } TEST(NoSamples) { @@ -758,7 +775,6 @@ TEST(Issue51919) { i::DeleteArray(titles[i]); } - static const v8::CpuProfileNode* PickChild(const v8::CpuProfileNode* parent, const char* name) { for (int i = 0; i < parent->GetChildrenCount(); ++i) { diff --git a/deps/v8/test/cctest/test-roots.cc b/deps/v8/test/cctest/test-roots.cc index 33f0873530..21bc365ab7 100644 --- a/deps/v8/test/cctest/test-roots.cc +++ b/deps/v8/test/cctest/test-roots.cc @@ -56,6 +56,7 @@ bool IsInitiallyMutable(Factory* factory, Address object_address) { V(retaining_path_targets) \ V(serialized_global_proxy_sizes) \ V(serialized_objects) \ + IF_WASM(V, wasm_canonical_rtts) \ V(weak_refs_keep_during_job) #define TEST_CAN_BE_READ_ONLY(name) \ diff --git a/deps/v8/test/cctest/test-serialize.cc b/deps/v8/test/cctest/test-serialize.cc index 9c19b399df..8c4d6b4722 100644 --- a/deps/v8/test/cctest/test-serialize.cc +++ b/deps/v8/test/cctest/test-serialize.cc @@ -2670,7 +2670,7 @@ TEST(CodeSerializerAfterExecute) { Handle<SharedFunctionInfo> sfi = v8::Utils::OpenHandle(*script); CHECK(sfi->HasBytecodeArray()); BytecodeArray bytecode = sfi->GetBytecodeArray(i_isolate2); - CHECK_EQ(bytecode.osr_loop_nesting_level(), 0); + CHECK_EQ(bytecode.osr_urgency(), 0); { DisallowCompilation no_compile_expected(i_isolate2); diff --git a/deps/v8/test/cctest/test-trace-event.cc b/deps/v8/test/cctest/test-trace-event.cc index 2e2dd3d2cb..1f25a9a212 100644 --- a/deps/v8/test/cctest/test-trace-event.cc +++ b/deps/v8/test/cctest/test-trace-event.cc @@ -6,6 +6,7 @@ #include <string.h> #include "include/v8-function.h" +#include "include/v8-platform.h" #include "src/init/v8.h" #include "src/tracing/trace-event.h" #include "test/cctest/cctest.h" @@ -86,12 +87,6 @@ class MockTracingController : public v8::TracingController { class MockTracingPlatform : public TestPlatform { public: - MockTracingPlatform() { - // Now that it's completely constructed, make this the current platform. - i::V8::SetPlatformForTesting(this); - } - ~MockTracingPlatform() override = default; - v8::TracingController* GetTracingController() override { return &tracing_controller_; } @@ -110,18 +105,14 @@ class MockTracingPlatform : public TestPlatform { } // namespace -TEST(TraceEventDisabledCategory) { - MockTracingPlatform platform; - +TEST_WITH_PLATFORM(TraceEventDisabledCategory, MockTracingPlatform) { // Disabled category, will not add events. TRACE_EVENT_BEGIN0("cat", "e1"); TRACE_EVENT_END0("cat", "e1"); CHECK_EQ(0, platform.NumberOfTraceObjects()); } -TEST(TraceEventNoArgs) { - MockTracingPlatform platform; - +TEST_WITH_PLATFORM(TraceEventNoArgs, MockTracingPlatform) { // Enabled category will add 2 events. TRACE_EVENT_BEGIN0("v8-cat", "e1"); TRACE_EVENT_END0("v8-cat", "e1"); @@ -136,9 +127,7 @@ TEST(TraceEventNoArgs) { CHECK_EQ(0, platform.GetTraceObject(1)->num_args); } -TEST(TraceEventWithOneArg) { - MockTracingPlatform platform; - +TEST_WITH_PLATFORM(TraceEventWithOneArg, MockTracingPlatform) { TRACE_EVENT_BEGIN1("v8-cat", "e1", "arg1", 42); TRACE_EVENT_END1("v8-cat", "e1", "arg1", 42); TRACE_EVENT_BEGIN1("v8-cat", "e2", "arg1", "abc"); @@ -152,9 +141,7 @@ TEST(TraceEventWithOneArg) { CHECK_EQ(1, platform.GetTraceObject(3)->num_args); } -TEST(TraceEventWithTwoArgs) { - MockTracingPlatform platform; - +TEST_WITH_PLATFORM(TraceEventWithTwoArgs, MockTracingPlatform) { TRACE_EVENT_BEGIN2("v8-cat", "e1", "arg1", 42, "arg2", "abc"); TRACE_EVENT_END2("v8-cat", "e1", "arg1", 42, "arg2", "abc"); TRACE_EVENT_BEGIN2("v8-cat", "e2", "arg1", "abc", "arg2", 43); @@ -168,9 +155,7 @@ TEST(TraceEventWithTwoArgs) { CHECK_EQ(2, platform.GetTraceObject(3)->num_args); } -TEST(ScopedTraceEvent) { - MockTracingPlatform platform; - +TEST_WITH_PLATFORM(ScopedTraceEvent, MockTracingPlatform) { { TRACE_EVENT0("v8-cat", "e"); } CHECK_EQ(1, platform.NumberOfTraceObjects()); @@ -187,9 +172,7 @@ TEST(ScopedTraceEvent) { CHECK_EQ(2, platform.GetTraceObject(2)->num_args); } -TEST(TestEventWithFlow) { - MockTracingPlatform platform; - +TEST_WITH_PLATFORM(TestEventWithFlow, MockTracingPlatform) { static uint64_t bind_id = 21; { TRACE_EVENT_WITH_FLOW0("v8-cat", "f1", bind_id, TRACE_EVENT_FLAG_FLOW_OUT); @@ -211,9 +194,7 @@ TEST(TestEventWithFlow) { CHECK_EQ(TRACE_EVENT_FLAG_FLOW_IN, platform.GetTraceObject(2)->flags); } -TEST(TestEventWithId) { - MockTracingPlatform platform; - +TEST_WITH_PLATFORM(TestEventWithId, MockTracingPlatform) { static uint64_t event_id = 21; TRACE_EVENT_ASYNC_BEGIN0("v8-cat", "a1", event_id); TRACE_EVENT_ASYNC_END0("v8-cat", "a1", event_id); @@ -225,9 +206,7 @@ TEST(TestEventWithId) { CHECK_EQ(event_id, platform.GetTraceObject(1)->id); } -TEST(TestEventWithTimestamp) { - MockTracingPlatform platform; - +TEST_WITH_PLATFORM(TestEventWithTimestamp, MockTracingPlatform) { TRACE_EVENT_INSTANT_WITH_TIMESTAMP0("v8-cat", "0arg", TRACE_EVENT_SCOPE_GLOBAL, 1729); TRACE_EVENT_INSTANT_WITH_TIMESTAMP1("v8-cat", "1arg", @@ -254,9 +233,8 @@ TEST(TestEventWithTimestamp) { CHECK_EQ(32832, platform.GetTraceObject(4)->timestamp); } -TEST(BuiltinsIsTraceCategoryEnabled) { +TEST_WITH_PLATFORM(BuiltinsIsTraceCategoryEnabled, MockTracingPlatform) { CcTest::InitializeVM(); - MockTracingPlatform platform; v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope handle_scope(isolate); @@ -302,9 +280,8 @@ TEST(BuiltinsIsTraceCategoryEnabled) { } } -TEST(BuiltinsTrace) { +TEST_WITH_PLATFORM(BuiltinsTrace, MockTracingPlatform) { CcTest::InitializeVM(); - MockTracingPlatform platform; v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope handle_scope(isolate); diff --git a/deps/v8/test/cctest/test-unwinder-code-pages.cc b/deps/v8/test/cctest/test-unwinder-code-pages.cc index 182a13bba0..595cda98d7 100644 --- a/deps/v8/test/cctest/test-unwinder-code-pages.cc +++ b/deps/v8/test/cctest/test-unwinder-code-pages.cc @@ -126,7 +126,7 @@ void CheckCalleeSavedRegisters(const RegisterState& register_state) { static const void* fake_stack_base = nullptr; TEST(Unwind_BadState_Fail_CodePagesAPI) { - JSEntryStubs entry_stubs; // Fields are intialized to nullptr. + JSEntryStubs entry_stubs; // Fields are initialized to nullptr. RegisterState register_state; size_t pages_length = 0; MemoryRange* code_pages = nullptr; diff --git a/deps/v8/test/cctest/test-weakmaps.cc b/deps/v8/test/cctest/test-weakmaps.cc index 9866e22bc6..5ecdab31aa 100644 --- a/deps/v8/test/cctest/test-weakmaps.cc +++ b/deps/v8/test/cctest/test-weakmaps.cc @@ -191,7 +191,7 @@ TEST(WeakMapPromotionMarkCompact) { } TEST(WeakMapScavenge) { - if (i::FLAG_single_generation) return; + if (i::FLAG_single_generation || i::FLAG_stress_incremental_marking) return; LocalContext context; Isolate* isolate = GetIsolateFrom(&context); Factory* factory = isolate->factory(); diff --git a/deps/v8/test/cctest/wasm/test-gc.cc b/deps/v8/test/cctest/wasm/test-gc.cc index 04c73c55c2..4835f56278 100644 --- a/deps/v8/test/cctest/wasm/test-gc.cc +++ b/deps/v8/test/cctest/wasm/test-gc.cc @@ -5,6 +5,7 @@ #include <stdint.h> #include "src/base/vector.h" +#include "src/codegen/signature.h" #include "src/utils/utils.h" #include "src/wasm/module-decoder.h" #include "src/wasm/struct-types.h" @@ -39,6 +40,11 @@ class WasmGCTester { execution_tier == TestExecutionTier::kLiftoff), flag_liftoff_only(&v8::internal::FLAG_liftoff_only, execution_tier == TestExecutionTier::kLiftoff), + flag_wasm_dynamic_tiering(&v8::internal::FLAG_wasm_dynamic_tiering, + v8::internal::FLAG_liftoff_only != true), + // Test both setups with canonicalization and without. + flag_canonicalization(&v8::internal::FLAG_wasm_type_canonicalization, + execution_tier == TestExecutionTier::kTurbofan), flag_tierup(&v8::internal::FLAG_wasm_tier_up, false), zone_(&allocator, ZONE_NAME), builder_(&zone_), @@ -169,6 +175,19 @@ class WasmGCTester { CheckHasThrownImpl(function_index, sig, &packer, expected); } + bool HasSimdSupport(TestExecutionTier tier) const { +#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_IA32 + // Liftoff does not have a fallback for executing SIMD instructions if + // SSE4_1 is not available. + if (tier == TestExecutionTier::kLiftoff && + !CpuFeatures::IsSupported(SSE4_1)) { + return false; + } +#endif + USE(tier); + return true; + } + Handle<WasmInstanceObject> instance() { return instance_; } Isolate* isolate() { return isolate_; } WasmModuleBuilder* builder() { return &builder_; } @@ -181,6 +200,8 @@ class WasmGCTester { const FlagScope<bool> flag_typedfuns; const FlagScope<bool> flag_liftoff; const FlagScope<bool> flag_liftoff_only; + const FlagScope<bool> flag_wasm_dynamic_tiering; + const FlagScope<bool> flag_canonicalization; const FlagScope<bool> flag_tierup; byte DefineFunctionImpl(WasmFunctionBuilder* fun, @@ -474,6 +495,28 @@ WASM_COMPILED_EXEC_TEST(RefCast) { {F(kWasmI32, true), F(kWasmF32, false)}, supertype_index); const byte subtype2_index = tester.DefineStruct( {F(kWasmI32, true), F(kWasmI64, false)}, supertype_index); + auto super_sig = FixedSizeSignature<ValueType>::Params( + ValueType::Ref(subtype1_index, kNullable)) + .Returns(ValueType::Ref(supertype_index, kNullable)); + auto sub_sig1 = FixedSizeSignature<ValueType>::Params( + ValueType::Ref(supertype_index, kNullable)) + .Returns(ValueType::Ref(subtype1_index, kNullable)); + auto sub_sig2 = FixedSizeSignature<ValueType>::Params( + ValueType::Ref(supertype_index, kNullable)) + .Returns(ValueType::Ref(subtype2_index, kNullable)); + const byte function_type_index = tester.DefineSignature(&super_sig); + const byte function_subtype1_index = + tester.DefineSignature(&sub_sig1, function_type_index); + const byte function_subtype2_index = + tester.DefineSignature(&sub_sig2, function_type_index); + const byte function_index = tester.DefineFunction( + function_subtype1_index, {}, + {WASM_STRUCT_NEW_DEFAULT_WITH_RTT(subtype1_index, + WASM_RTT_CANON(subtype1_index)), + WASM_END}); + // Just so this function counts as "declared". + tester.AddGlobal(ValueType::Ref(function_type_index, kNullable), false, + WasmInitExpr::RefFuncConst(function_index)); const byte kTestSuccessful = tester.DefineFunction( tester.sigs.i_v(), {ValueType::Ref(supertype_index, kNullable)}, @@ -493,9 +536,32 @@ WASM_COMPILED_EXEC_TEST(RefCast) { WASM_REF_CAST(WASM_LOCAL_GET(0), WASM_RTT_CANON(subtype2_index))), WASM_END}); + const byte kFuncTestSuccessfulSuper = tester.DefineFunction( + tester.sigs.i_v(), {ValueType::Ref(function_type_index, kNullable)}, + {WASM_LOCAL_SET(0, WASM_REF_FUNC(function_index)), + WASM_REF_CAST(WASM_LOCAL_GET(0), WASM_RTT_CANON(function_type_index)), + WASM_DROP, WASM_I32V(0), WASM_END}); + + const byte kFuncTestSuccessfulSub = tester.DefineFunction( + tester.sigs.i_v(), {ValueType::Ref(function_type_index, kNullable)}, + {WASM_LOCAL_SET(0, WASM_REF_FUNC(function_index)), + WASM_REF_CAST(WASM_LOCAL_GET(0), + WASM_RTT_CANON(function_subtype1_index)), + WASM_DROP, WASM_I32V(0), WASM_END}); + + const byte kFuncTestFailed = tester.DefineFunction( + tester.sigs.i_v(), {ValueType::Ref(function_type_index, kNullable)}, + {WASM_LOCAL_SET(0, WASM_REF_FUNC(function_index)), + WASM_REF_CAST(WASM_LOCAL_GET(0), + WASM_RTT_CANON(function_subtype2_index)), + WASM_DROP, WASM_I32V(1), WASM_END}); + tester.CompileModule(); tester.CheckResult(kTestSuccessful, 0); tester.CheckHasThrown(kTestFailed); + tester.CheckResult(kFuncTestSuccessfulSuper, 0); + tester.CheckResult(kFuncTestSuccessfulSub, 0); + tester.CheckHasThrown(kFuncTestFailed); } WASM_COMPILED_EXEC_TEST(RefCastStatic) { @@ -916,6 +982,7 @@ TEST(WasmLetInstruction) { WASM_COMPILED_EXEC_TEST(WasmBasicArray) { WasmGCTester tester(execution_tier); + if (!tester.HasSimdSupport(execution_tier)) return; const byte type_index = tester.DefineArray(wasm::kWasmI32, true); const byte fp_type_index = tester.DefineArray(wasm::kWasmF64, true); @@ -1304,11 +1371,15 @@ WASM_COMPILED_EXEC_TEST(WasmArrayCopy) { tester.CheckResult(kZeroLength, 0); // Does not throw. } -/* TODO(7748): This test requires for recursive groups. WASM_COMPILED_EXEC_TEST(NewDefault) { WasmGCTester tester(execution_tier); + if (!tester.HasSimdSupport(execution_tier)) return; + + tester.builder()->StartRecursiveTypeGroup(); const byte struct_type = tester.DefineStruct( {F(wasm::kWasmI32, true), F(wasm::kWasmF64, true), F(optref(0), true)}); + tester.builder()->EndRecursiveTypeGroup(); + const byte array_type = tester.DefineArray(wasm::kWasmI32, true); // Returns: struct[0] + f64_to_i32(struct[1]) + (struct[2].is_null ^ 1) == 0. const byte allocate_struct = tester.DefineFunction( @@ -1338,7 +1409,6 @@ WASM_COMPILED_EXEC_TEST(NewDefault) { tester.CheckResult(allocate_struct, 0); tester.CheckResult(allocate_array, 0); } -*/ WASM_COMPILED_EXEC_TEST(BasicRtt) { WasmGCTester tester(execution_tier); diff --git a/deps/v8/test/cctest/wasm/test-streaming-compilation.cc b/deps/v8/test/cctest/wasm/test-streaming-compilation.cc index a6fc58f5d1..b30d8983f4 100644 --- a/deps/v8/test/cctest/wasm/test-streaming-compilation.cc +++ b/deps/v8/test/cctest/wasm/test-streaming-compilation.cc @@ -29,10 +29,7 @@ namespace wasm { class MockPlatform final : public TestPlatform { public: - MockPlatform() : task_runner_(std::make_shared<MockTaskRunner>()) { - // Now that it's completely constructed, make this the current platform. - i::V8::SetPlatformForTesting(this); - } + MockPlatform() : task_runner_(std::make_shared<MockTaskRunner>()) {} ~MockPlatform() { for (auto* job_handle : job_handles_) job_handle->ResetPlatform(); @@ -239,25 +236,18 @@ class StreamTester { }; } // namespace -#define RUN_STREAM(name) \ - MockPlatform mock_platform; \ - CHECK_EQ(V8::GetCurrentPlatform(), &mock_platform); \ - v8::Isolate::CreateParams create_params; \ - create_params.array_buffer_allocator = CcTest::array_buffer_allocator(); \ - v8::Isolate* isolate = v8::Isolate::New(create_params); \ - { \ - v8::HandleScope handle_scope(isolate); \ - v8::Local<v8::Context> context = v8::Context::New(isolate); \ - v8::Context::Scope context_scope(context); \ - RunStream_##name(&mock_platform, isolate); \ - } \ - isolate->Dispose(); +#define RUN_STREAM(name) \ + v8::Isolate* isolate = CcTest::isolate(); \ + v8::HandleScope handle_scope(isolate); \ + v8::Local<v8::Context> context = v8::Context::New(isolate); \ + v8::Context::Scope context_scope(context); \ + RunStream_##name(&platform, isolate); #define STREAM_TEST(name) \ void RunStream_##name(MockPlatform*, v8::Isolate*); \ - UNINITIALIZED_TEST(Async##name) { RUN_STREAM(name); } \ + TEST_WITH_PLATFORM(Async##name, MockPlatform) { RUN_STREAM(name); } \ \ - UNINITIALIZED_TEST(SingleThreaded##name) { \ + TEST_WITH_PLATFORM(SingleThreaded##name, MockPlatform) { \ i::FlagScope<bool> single_threaded_scope(&i::FLAG_single_threaded, true); \ RUN_STREAM(name); \ } \ diff --git a/deps/v8/test/cctest/wasm/test-wasm-metrics.cc b/deps/v8/test/cctest/wasm/test-wasm-metrics.cc index abb3dc9520..6e54c0535f 100644 --- a/deps/v8/test/cctest/wasm/test-wasm-metrics.cc +++ b/deps/v8/test/cctest/wasm/test-wasm-metrics.cc @@ -6,6 +6,7 @@ #include "include/libplatform/libplatform.h" #include "include/v8-metrics.h" +#include "include/v8-platform.h" #include "src/api/api-inl.h" #include "src/base/platform/time.h" #include "src/wasm/wasm-engine.h" @@ -24,10 +25,7 @@ namespace { class MockPlatform final : public TestPlatform { public: - MockPlatform() : task_runner_(std::make_shared<MockTaskRunner>()) { - // Now that it's completely constructed, make this the current platform. - i::V8::SetPlatformForTesting(this); - } + MockPlatform() : task_runner_(std::make_shared<MockTaskRunner>()) {} ~MockPlatform() override { for (auto* job_handle : job_handles_) job_handle->ResetPlatform(); @@ -208,32 +206,24 @@ class TestCompileResolver : public CompilationResultResolver { } // namespace -#define RUN_COMPILE(name) \ - MockPlatform mock_platform; \ - CHECK_EQ(V8::GetCurrentPlatform(), &mock_platform); \ - v8::Isolate::CreateParams create_params; \ - create_params.array_buffer_allocator = CcTest::array_buffer_allocator(); \ - v8::Isolate* isolate = v8::Isolate::New(create_params); \ - { \ - v8::HandleScope handle_scope(isolate); \ - v8::Local<v8::Context> context = v8::Context::New(isolate); \ - v8::Context::Scope context_scope(context); \ - Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); \ - testing::SetupIsolateForWasmModule(i_isolate); \ - RunCompile_##name(&mock_platform, i_isolate); \ - } \ - isolate->Dispose(); +#define RUN_COMPILE(name) \ + v8::HandleScope handle_scope(CcTest::isolate()); \ + v8::Local<v8::Context> context = v8::Context::New(CcTest::isolate()); \ + v8::Context::Scope context_scope(context); \ + Isolate* i_isolate = CcTest::i_isolate(); \ + testing::SetupIsolateForWasmModule(i_isolate); \ + RunCompile_##name(&platform, i_isolate); #define COMPILE_TEST(name) \ void RunCompile_##name(MockPlatform*, i::Isolate*); \ - UNINITIALIZED_TEST(Sync##name) { \ + TEST_WITH_PLATFORM(Sync##name, MockPlatform) { \ i::FlagScope<bool> sync_scope(&i::FLAG_wasm_async_compilation, false); \ RUN_COMPILE(name); \ } \ \ - UNINITIALIZED_TEST(Async##name) { RUN_COMPILE(name); } \ + TEST_WITH_PLATFORM(Async##name, MockPlatform) { RUN_COMPILE(name); } \ \ - UNINITIALIZED_TEST(Streaming##name) { \ + TEST_WITH_PLATFORM(Streaming##name, MockPlatform) { \ i::FlagScope<bool> streaming_scope(&i::FLAG_wasm_test_streaming, true); \ RUN_COMPILE(name); \ } \ diff --git a/deps/v8/test/cctest/wasm/wasm-run-utils.cc b/deps/v8/test/cctest/wasm/wasm-run-utils.cc index 142ba2d8e2..71a1e77e3d 100644 --- a/deps/v8/test/cctest/wasm/wasm-run-utils.cc +++ b/deps/v8/test/cctest/wasm/wasm-run-utils.cc @@ -348,7 +348,7 @@ CompilationEnv TestingModuleBuilder::CreateCompilationEnv() { } const WasmGlobal* TestingModuleBuilder::AddGlobal(ValueType type) { - byte size = type.element_size_bytes(); + byte size = type.value_kind_size(); global_offset = (global_offset + size - 1) & ~(size - 1); // align test_module_->globals.push_back( {type, true, {}, {global_offset}, false, false}); diff --git a/deps/v8/test/cctest/wasm/wasm-run-utils.h b/deps/v8/test/cctest/wasm/wasm-run-utils.h index f5a3ce2389..5adfe39f84 100644 --- a/deps/v8/test/cctest/wasm/wasm-run-utils.h +++ b/deps/v8/test/cctest/wasm/wasm-run-utils.h @@ -186,7 +186,7 @@ class TestingModuleBuilder { memset(raw, 0, mem_size_); } - // Pseudo-randomly intialize the memory. + // Pseudo-randomly initialize the memory. void RandomizeMemory(unsigned int seed = 88) { byte* raw = raw_mem_start<byte>(); byte* end = raw_mem_end<byte>(); |