[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:
Dominik Inführ 2022-11-25 12:42:06 +01:00 committed by V8 LUCI CQ
parent c970d03449
commit 2507b38af2
3 changed files with 77 additions and 21 deletions

View File

@ -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 ==

View File

@ -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_;

View File

@ -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