5bbca548e9
When a background thread fails to allocate, it requests a GC and retries the allocation afterwards. Make second allocation more likely to succeed by allowing those allocations to expand the old space. TLABs of LocalHeaps also need to be invalidated before the GC. Bug: v8:10315 Change-Id: Idaea2c4ee25642d508c72ae274b06d60c6e225e0 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2154193 Commit-Queue: Dominik Inführ <dinfuehr@chromium.org> Reviewed-by: Ulan Degenbaev <ulan@chromium.org> Cr-Commit-Position: refs/heads/master@{#67496}
98 lines
2.9 KiB
C++
98 lines
2.9 KiB
C++
// Copyright 2020 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 <memory>
|
|
|
|
#include "src/api/api.h"
|
|
#include "src/base/platform/condition-variable.h"
|
|
#include "src/base/platform/mutex.h"
|
|
#include "src/base/platform/semaphore.h"
|
|
#include "src/common/globals.h"
|
|
#include "src/handles/handles-inl.h"
|
|
#include "src/handles/local-handles-inl.h"
|
|
#include "src/handles/persistent-handles.h"
|
|
#include "src/heap/concurrent-allocator-inl.h"
|
|
#include "src/heap/heap.h"
|
|
#include "src/heap/local-heap.h"
|
|
#include "src/heap/safepoint.h"
|
|
#include "src/objects/heap-number.h"
|
|
#include "test/cctest/cctest.h"
|
|
#include "test/cctest/heap/heap-utils.h"
|
|
|
|
namespace v8 {
|
|
namespace internal {
|
|
|
|
const int kNumIterations = 2000;
|
|
const int kObjectSize = 10 * kTaggedSize;
|
|
const int kLargeObjectSize = 8 * KB;
|
|
|
|
class ConcurrentAllocationThread final : public v8::base::Thread {
|
|
public:
|
|
explicit ConcurrentAllocationThread(Heap* heap, std::atomic<int>* pending)
|
|
: v8::base::Thread(base::Thread::Options("ThreadWithLocalHeap")),
|
|
heap_(heap),
|
|
pending_(pending) {}
|
|
|
|
void Run() override {
|
|
LocalHeap local_heap(heap_);
|
|
ConcurrentAllocator* allocator = local_heap.old_space_allocator();
|
|
|
|
for (int i = 0; i < kNumIterations; i++) {
|
|
Address address = allocator->AllocateOrFail(
|
|
kObjectSize, AllocationAlignment::kWordAligned,
|
|
AllocationOrigin::kRuntime);
|
|
heap_->CreateFillerObjectAt(address, kObjectSize,
|
|
ClearRecordedSlots::kNo);
|
|
address = allocator->AllocateOrFail(kLargeObjectSize,
|
|
AllocationAlignment::kWordAligned,
|
|
AllocationOrigin::kRuntime);
|
|
heap_->CreateFillerObjectAt(address, kLargeObjectSize,
|
|
ClearRecordedSlots::kNo);
|
|
}
|
|
|
|
pending_->fetch_sub(1);
|
|
}
|
|
|
|
Heap* heap_;
|
|
std::atomic<int>* pending_;
|
|
};
|
|
|
|
UNINITIALIZED_TEST(ConcurrentAllocationInOldSpace) {
|
|
FLAG_max_old_space_size = 8;
|
|
FLAG_concurrent_allocation = true;
|
|
|
|
v8::Isolate::CreateParams create_params;
|
|
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
|
|
v8::Isolate* isolate = v8::Isolate::New(create_params);
|
|
Isolate* i_isolate = reinterpret_cast<Isolate*>(isolate);
|
|
|
|
FLAG_local_heaps = true;
|
|
|
|
std::vector<std::unique_ptr<ConcurrentAllocationThread>> threads;
|
|
|
|
const int kThreads = 4;
|
|
|
|
std::atomic<int> pending(kThreads);
|
|
|
|
for (int i = 0; i < kThreads; i++) {
|
|
auto thread = std::make_unique<ConcurrentAllocationThread>(
|
|
i_isolate->heap(), &pending);
|
|
CHECK(thread->Start());
|
|
threads.push_back(std::move(thread));
|
|
}
|
|
|
|
while (pending > 0) {
|
|
v8::platform::PumpMessageLoop(i::V8::GetCurrentPlatform(), isolate);
|
|
}
|
|
|
|
for (auto& thread : threads) {
|
|
thread->Join();
|
|
}
|
|
|
|
isolate->Dispose();
|
|
}
|
|
|
|
} // namespace internal
|
|
} // namespace v8
|