Commit c9e47e74 authored by Dominik Inführ's avatar Dominik Inführ Committed by Commit Bot

[heap] Make old_generation_allocation_limit_ atomic

Updating old_generation_allocation_limit_ in Heap::NotifyContextDisposed
races with concurrent allocation. Fix race by making field atomic.

Bug: v8:11064, v8:10315
Change-Id: I030b7f90b2f5b344cdcea5185340dc54dc10298c
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2521153
Commit-Queue: Dominik Inführ <dinfuehr@chromium.org>
Reviewed-by: 's avatarUlan Degenbaev <ulan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#71008}
parent e6f18daf
......@@ -1706,7 +1706,7 @@ int Heap::NotifyContextDisposed(bool dependant_context) {
if (!dependant_context) {
tracer()->ResetSurvivalEvents();
old_generation_size_configured_ = false;
old_generation_allocation_limit_ = initial_old_generation_size_;
set_old_generation_allocation_limit(initial_old_generation_size_);
MemoryReducer::Event event;
event.type = MemoryReducer::kPossibleGarbage;
event.time_ms = MonotonicallyIncreasingTimeInMs();
......@@ -2071,11 +2071,11 @@ void Heap::RecomputeLimits(GarbageCollector collector) {
if (collector == MARK_COMPACTOR) {
external_memory_.ResetAfterGC();
old_generation_allocation_limit_ =
set_old_generation_allocation_limit(
MemoryController<V8HeapTrait>::CalculateAllocationLimit(
this, old_gen_size, min_old_generation_size_,
max_old_generation_size(), new_space_capacity, v8_growing_factor,
mode);
mode));
if (UseGlobalMemoryScheduling()) {
DCHECK_GT(global_growing_factor, 0);
global_allocation_limit_ =
......@@ -2093,8 +2093,8 @@ void Heap::RecomputeLimits(GarbageCollector collector) {
this, old_gen_size, min_old_generation_size_,
max_old_generation_size(), new_space_capacity, v8_growing_factor,
mode);
if (new_old_generation_limit < old_generation_allocation_limit_) {
old_generation_allocation_limit_ = new_old_generation_limit;
if (new_old_generation_limit < old_generation_allocation_limit()) {
set_old_generation_allocation_limit(new_old_generation_limit);
}
if (UseGlobalMemoryScheduling()) {
DCHECK_GT(global_growing_factor, 0);
......@@ -2801,11 +2801,11 @@ void Heap::ConfigureInitialOldGenerationSize() {
const size_t new_old_generation_allocation_limit =
Max(OldGenerationSizeOfObjects() + minimum_growing_step,
static_cast<size_t>(
static_cast<double>(old_generation_allocation_limit_) *
static_cast<double>(old_generation_allocation_limit()) *
(tracer()->AverageSurvivalRatio() / 100)));
if (new_old_generation_allocation_limit <
old_generation_allocation_limit_) {
old_generation_allocation_limit_ = new_old_generation_allocation_limit;
old_generation_allocation_limit()) {
set_old_generation_allocation_limit(new_old_generation_allocation_limit);
} else {
old_generation_size_configured_ = true;
}
......@@ -4634,9 +4634,9 @@ void Heap::ConfigureHeap(const v8::ResourceConstraints& constraints) {
FLAG_semi_space_growth_factor = 2;
}
old_generation_allocation_limit_ = initial_old_generation_size_;
set_old_generation_allocation_limit(initial_old_generation_size_);
global_allocation_limit_ =
GlobalMemorySizeFromV8Size(old_generation_allocation_limit_);
GlobalMemorySizeFromV8Size(old_generation_allocation_limit());
initial_max_old_generation_size_ = max_old_generation_size();
// We rely on being able to allocate new arrays in paged spaces.
......@@ -4745,8 +4745,8 @@ bool Heap::AllocationLimitOvershotByLargeMargin() {
uint64_t size_now =
OldGenerationSizeOfObjects() + AllocatedExternalMemorySinceMarkCompact();
const size_t v8_overshoot = old_generation_allocation_limit_ < size_now
? size_now - old_generation_allocation_limit_
const size_t v8_overshoot = old_generation_allocation_limit() < size_now
? size_now - old_generation_allocation_limit()
: 0;
const size_t global_overshoot =
global_allocation_limit_ < GlobalSizeOfObjects()
......@@ -4762,8 +4762,8 @@ bool Heap::AllocationLimitOvershotByLargeMargin() {
// Overshoot margin is 50% of allocation limit or half-way to the max heap
// with special handling of small heaps.
const size_t v8_margin =
Min(Max(old_generation_allocation_limit_ / 2, kMarginForSmallHeaps),
(max_old_generation_size() - old_generation_allocation_limit_) / 2);
Min(Max(old_generation_allocation_limit() / 2, kMarginForSmallHeaps),
(max_old_generation_size() - old_generation_allocation_limit()) / 2);
const size_t global_margin =
Min(Max(global_allocation_limit_ / 2, kMarginForSmallHeaps),
(max_global_memory_size_ - global_allocation_limit_) / 2);
......@@ -4859,7 +4859,7 @@ double Heap::PercentToOldGenerationLimit() {
double size_now =
OldGenerationSizeOfObjects() + AllocatedExternalMemorySinceMarkCompact();
double current_bytes = size_now - size_at_gc;
double total_bytes = old_generation_allocation_limit_ - size_at_gc;
double total_bytes = old_generation_allocation_limit() - size_at_gc;
return total_bytes > 0 ? (current_bytes / total_bytes) * 100.0 : 0;
}
......@@ -4868,7 +4868,7 @@ double Heap::PercentToGlobalMemoryLimit() {
double size_now =
OldGenerationSizeOfObjects() + AllocatedExternalMemorySinceMarkCompact();
double current_bytes = size_now - size_at_gc;
double total_bytes = old_generation_allocation_limit_ - size_at_gc;
double total_bytes = old_generation_allocation_limit() - size_at_gc;
return total_bytes > 0 ? (current_bytes / total_bytes) * 100.0 : 0;
}
......
......@@ -1845,8 +1845,8 @@ class Heap {
uint64_t bytes = OldGenerationSizeOfObjects() +
AllocatedExternalMemorySinceMarkCompact();
if (old_generation_allocation_limit_ <= bytes) return 0;
return old_generation_allocation_limit_ - static_cast<size_t>(bytes);
if (old_generation_allocation_limit() <= bytes) return 0;
return old_generation_allocation_limit() - static_cast<size_t>(bytes);
}
void UpdateTotalGCTime(double duration);
......@@ -1879,7 +1879,11 @@ class Heap {
bool ShouldOptimizeForLoadTime();
size_t old_generation_allocation_limit() const {
return old_generation_allocation_limit_;
return old_generation_allocation_limit_.load(std::memory_order_relaxed);
}
void set_old_generation_allocation_limit(size_t newlimit) {
old_generation_allocation_limit_.store(newlimit, std::memory_order_relaxed);
}
size_t global_allocation_limit() const { return global_allocation_limit_; }
......@@ -2139,7 +2143,7 @@ class Heap {
// is checked when we have already decided to do a GC to help determine
// which collector to invoke, before expanding a paged space in the old
// generation and on every allocation in large object space.
size_t old_generation_allocation_limit_ = 0;
std::atomic<size_t> old_generation_allocation_limit_{0};
size_t global_allocation_limit_ = 0;
// Indicates that inline bump-pointer allocation has been globally disabled
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment