[heap] Update SharedStringInClientGlobalHandle test for --shared-space
This test had to be updated for --shared-space because the main isolate is always parked when the client isolate requests a GC. In such cases the GC isn't performed and therefore the weak handle not reset. The CL moves the client isolate into a proper thread which allows the main isolate to remain in the running state. In addition this CL adds the BasicMemoryChunk::ComputeMarkBit methods. These methods make it easy during debugging to compute the MarkBit (cell + mask) for an object. Bug: v8:13267 Change-Id: I6680d8d1d8b36d86b22c43399abbd4325f64ccb2 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4054622 Auto-Submit: Dominik Inführ <dinfuehr@chromium.org> Commit-Queue: Dominik Inführ <dinfuehr@chromium.org> Reviewed-by: Michael Lippautz <mlippautz@chromium.org> Cr-Commit-Position: refs/heads/main@{#84488}
This commit is contained in:
parent
c970d03449
commit
2507b38af2
@ -84,6 +84,19 @@ void BasicMemoryChunk::SynchronizedHeapLoad() const {
|
||||
}
|
||||
#endif
|
||||
|
||||
// static
|
||||
MarkBit BasicMemoryChunk::ComputeMarkBit(HeapObject object) {
|
||||
return BasicMemoryChunk::ComputeMarkBit(object.address());
|
||||
}
|
||||
|
||||
// static
|
||||
MarkBit BasicMemoryChunk::ComputeMarkBit(Address address) {
|
||||
BasicMemoryChunk* chunk = BasicMemoryChunk::FromAddress(address);
|
||||
int index = chunk->AddressToMarkbitIndex(address);
|
||||
return chunk->marking_bitmap<AccessMode::NON_ATOMIC>()->MarkBitFromIndex(
|
||||
index);
|
||||
}
|
||||
|
||||
class BasicMemoryChunkValidator {
|
||||
// Computed offsets should match the compiler generated ones.
|
||||
static_assert(BasicMemoryChunk::kSizeOffset ==
|
||||
|
@ -350,6 +350,10 @@ class BasicMemoryChunk {
|
||||
void SynchronizedHeapLoad() const;
|
||||
#endif
|
||||
|
||||
// Computes position of object in marking bitmap. Useful for debugging.
|
||||
V8_ALLOW_UNUSED static MarkBit ComputeMarkBit(HeapObject object);
|
||||
V8_ALLOW_UNUSED static MarkBit ComputeMarkBit(Address address);
|
||||
|
||||
protected:
|
||||
// Overall size of the chunk, including the header and guards.
|
||||
size_t size_;
|
||||
|
@ -1807,36 +1807,75 @@ UNINITIALIZED_TEST(SharedStringInGlobalHandle) {
|
||||
CHECK(!gh_shared_string.IsEmpty());
|
||||
}
|
||||
|
||||
class WakeupTask : public CancelableTask {
|
||||
public:
|
||||
explicit WakeupTask(Isolate* isolate) : CancelableTask(isolate) {}
|
||||
|
||||
private:
|
||||
// v8::internal::CancelableTask overrides.
|
||||
void RunInternal() override {}
|
||||
};
|
||||
|
||||
class WorkerIsolateThread : public v8::base::Thread {
|
||||
public:
|
||||
WorkerIsolateThread(const char* name, MultiClientIsolateTest* test,
|
||||
std::atomic<bool>* done)
|
||||
: v8::base::Thread(base::Thread::Options(name)),
|
||||
test_(test),
|
||||
done_(done) {}
|
||||
|
||||
void Run() override {
|
||||
v8::Isolate* client = test_->NewClientIsolate();
|
||||
Isolate* i_client = reinterpret_cast<Isolate*>(client);
|
||||
Factory* factory = i_client->factory();
|
||||
|
||||
v8::Global<v8::String> gh_shared_string;
|
||||
|
||||
{
|
||||
HandleScope handle_scope(i_client);
|
||||
Handle<String> shared_string = factory->NewStringFromAsciiChecked(
|
||||
"foobar", AllocationType::kSharedOld);
|
||||
CHECK(shared_string->InSharedWritableHeap());
|
||||
v8::Local<v8::String> lh_shared_string =
|
||||
Utils::Convert<String, v8::String>(shared_string);
|
||||
gh_shared_string.Reset(test_->main_isolate(), lh_shared_string);
|
||||
gh_shared_string.SetWeak();
|
||||
}
|
||||
|
||||
i_client->heap()->CollectGarbageShared(i_client->main_thread_local_heap(),
|
||||
GarbageCollectionReason::kTesting);
|
||||
CHECK(gh_shared_string.IsEmpty());
|
||||
client->Dispose();
|
||||
|
||||
*done_ = true;
|
||||
|
||||
V8::GetCurrentPlatform()
|
||||
->GetForegroundTaskRunner(test_->main_isolate())
|
||||
->PostTask(std::make_unique<WakeupTask>(test_->i_main_isolate()));
|
||||
}
|
||||
|
||||
private:
|
||||
MultiClientIsolateTest* test_;
|
||||
std::atomic<bool>* done_;
|
||||
};
|
||||
|
||||
UNINITIALIZED_TEST(SharedStringInClientGlobalHandle) {
|
||||
if (!V8_CAN_CREATE_SHARED_HEAP_BOOL) return;
|
||||
|
||||
v8_flags.shared_string_table = true;
|
||||
|
||||
MultiClientIsolateTest test;
|
||||
ParkedScope park_main_isolate(
|
||||
test.i_main_isolate()->main_thread_local_heap());
|
||||
v8::Isolate* client = test.NewClientIsolate();
|
||||
Isolate* i_client = reinterpret_cast<Isolate*>(client);
|
||||
Factory* factory = i_client->factory();
|
||||
std::atomic<bool> done = false;
|
||||
WorkerIsolateThread thread("worker", &test, &done);
|
||||
CHECK(thread.Start());
|
||||
|
||||
v8::Global<v8::String> gh_shared_string;
|
||||
|
||||
{
|
||||
HandleScope handle_scope(i_client);
|
||||
Handle<String> shared_string = factory->NewStringFromAsciiChecked(
|
||||
"foobar", AllocationType::kSharedOld);
|
||||
CHECK(shared_string->InSharedWritableHeap());
|
||||
v8::Local<v8::String> lh_shared_string =
|
||||
Utils::Convert<String, v8::String>(shared_string);
|
||||
gh_shared_string.Reset(test.main_isolate(), lh_shared_string);
|
||||
gh_shared_string.SetWeak();
|
||||
while (!done) {
|
||||
v8::platform::PumpMessageLoop(
|
||||
i::V8::GetCurrentPlatform(), test.main_isolate(),
|
||||
v8::platform::MessageLoopBehavior::kWaitForWork);
|
||||
}
|
||||
|
||||
i_client->heap()->CollectGarbageShared(i_client->main_thread_local_heap(),
|
||||
GarbageCollectionReason::kTesting);
|
||||
|
||||
CHECK(gh_shared_string.IsEmpty());
|
||||
client->Dispose();
|
||||
thread.Join();
|
||||
}
|
||||
|
||||
} // namespace test_shared_strings
|
||||
|
Loading…
Reference in New Issue
Block a user