Commit b0245183 authored by Anton Bikineev's avatar Anton Bikineev Committed by Commit Bot

heap: Fix misaccounting of allocated-object-size

When shrinking/promptly-freeing/expansion happens, memory occupied by
linear allocation area is already accounted (in SetAllocationPoint()).

Object shrinking case: Expanding the area means that the bytes stay
allocated.
Object expansion case: Just using up space that's accounted for.

Bug: 1029379
Change-Id: I77edced5e71b989d6968f92a5bbf0bd4819aea7a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2051263
Commit-Queue: Anton Bikineev <bikineev@chromium.org>
Reviewed-by: default avatarMichael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#740723}
parent 93e4c7ea
......@@ -413,7 +413,6 @@ NormalPageArena::NormalPageArena(ThreadState* state, int index)
: BaseArena(state, index),
current_allocation_point_(nullptr),
remaining_allocation_size_(0),
last_remaining_allocation_size_(0),
promptly_freed_size_(0) {}
void NormalPageArena::AddToFreeList(Address address, size_t size) {
......@@ -728,7 +727,7 @@ void NormalPageArena::PromptlyFreeObject(HeapObjectHeader* header) {
if (IsObjectAllocatedAtAllocationPoint(header)) {
current_allocation_point_ -= size;
DCHECK_EQ(address, current_allocation_point_);
SetRemainingAllocationSize(remaining_allocation_size_ + size);
remaining_allocation_size_ += size;
SET_MEMORY_INACCESSIBLE(address, size);
// Memory that is part of the allocation point is not allowed to be part
// of the object start bit map.
......@@ -775,7 +774,7 @@ bool NormalPageArena::ExpandObject(HeapObjectHeader* header, size_t new_size) {
expand_size <= remaining_allocation_size_) {
current_allocation_point_ += expand_size;
DCHECK_GE(remaining_allocation_size_, expand_size);
SetRemainingAllocationSize(remaining_allocation_size_ - expand_size);
remaining_allocation_size_ -= expand_size;
// Unpoison the memory used for the object (payload).
SET_MEMORY_ACCESSIBLE(header->PayloadEnd(), expand_size);
header->SetSize(allocation_size);
......@@ -794,7 +793,7 @@ bool NormalPageArena::ShrinkObject(HeapObjectHeader* header, size_t new_size) {
size_t shrink_size = header->size() - allocation_size;
if (IsObjectAllocatedAtAllocationPoint(header)) {
current_allocation_point_ -= shrink_size;
SetRemainingAllocationSize(remaining_allocation_size_ + shrink_size);
remaining_allocation_size_ += shrink_size;
SET_MEMORY_INACCESSIBLE(current_allocation_point_, shrink_size);
header->SetSize(allocation_size);
return true;
......@@ -855,24 +854,6 @@ Address NormalPageArena::LazySweepPages(size_t allocation_size,
return result;
}
void NormalPageArena::SetRemainingAllocationSize(
size_t new_remaining_allocation_size) {
remaining_allocation_size_ = new_remaining_allocation_size;
// Sync recorded allocated-object size using the recorded checkpoint in
// |remaining_allocation_size_|:
// - If checkpoint is larger, the allocated size has increased.
// - The allocated size has decreased, otherwise.
if (last_remaining_allocation_size_ > remaining_allocation_size_) {
GetThreadState()->Heap().stats_collector()->IncreaseAllocatedObjectSize(
last_remaining_allocation_size_ - remaining_allocation_size_);
} else if (last_remaining_allocation_size_ != remaining_allocation_size_) {
GetThreadState()->Heap().stats_collector()->DecreaseAllocatedObjectSize(
remaining_allocation_size_ - last_remaining_allocation_size_);
}
last_remaining_allocation_size_ = remaining_allocation_size_;
}
void NormalPageArena::SetAllocationPoint(Address point, size_t size) {
#if DCHECK_IS_ON()
if (point) {
......@@ -890,7 +871,7 @@ void NormalPageArena::SetAllocationPoint(Address point, size_t size) {
}
// Set up a new linear allocation area.
current_allocation_point_ = point;
last_remaining_allocation_size_ = remaining_allocation_size_ = size;
remaining_allocation_size_ = size;
// Update last allocated region in ThreadHeap. This must also be done if the
// allocation point is set to 0 (before doing GC), so that the last allocated
// region is automatically reset after GC.
......
......@@ -1060,14 +1060,9 @@ class PLATFORM_EXPORT NormalPageArena final : public BaseArena {
}
void SetAllocationPoint(Address, size_t);
// Only use when adjusting the area from allocation and free and not when
// returning it to free list.
void SetRemainingAllocationSize(size_t);
FreeList free_list_;
Address current_allocation_point_;
size_t remaining_allocation_size_;
size_t last_remaining_allocation_size_;
// The size of promptly freed objects in the heap. This counter is set to
// zero before sweeping when clearing the free list and after coalescing.
......
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