| Index: src/heap/spaces.h
|
| diff --git a/src/heap/spaces.h b/src/heap/spaces.h
|
| index 7a9b6915e7654211b8f4302b8165014930eed230..19708dcb782315ab9ce2974137db96e86bf0601a 100644
|
| --- a/src/heap/spaces.h
|
| +++ b/src/heap/spaces.h
|
| @@ -1472,7 +1472,13 @@ class PageIterator BASE_EMBEDDED {
|
| // space.
|
| class AllocationInfo {
|
| public:
|
| - AllocationInfo() : top_(NULL), limit_(NULL) {}
|
| + AllocationInfo() : top_(nullptr), limit_(nullptr) {}
|
| + AllocationInfo(Address top, Address limit) : top_(top), limit_(limit) {}
|
| +
|
| + void Reset(Address top, Address limit) {
|
| + set_top(top);
|
| + set_limit(limit);
|
| + }
|
|
|
| INLINE(void set_top(Address top)) {
|
| SLOW_DCHECK(top == NULL ||
|
| @@ -1869,6 +1875,60 @@ class AllocationResult {
|
| STATIC_ASSERT(sizeof(AllocationResult) == kPointerSize);
|
|
|
|
|
| +// LocalAllocationBuffer represents a linear allocation area that is created
|
| +// from a given {AllocationResult} and can be used to allocate memory without
|
| +// synchronization.
|
| +//
|
| +// The buffer is properly closed upon destruction and reassignment.
|
| +// Example:
|
| +// {
|
| +// AllocationResult result = ...;
|
| +// LocalAllocationBuffer a(heap, result, size);
|
| +// LocalAllocationBuffer b = a;
|
| +// CHECK(!a.IsValid());
|
| +// CHECK(b.IsValid());
|
| +// // {a} is invalid now and cannot be used for further allocations.
|
| +// }
|
| +// // Since {b} went out of scope, the LAB is closed, resulting in creating a
|
| +// // filler object for the remaining area.
|
| +class LocalAllocationBuffer {
|
| + public:
|
| + // Indicates that a buffer cannot be used for allocations anymore. Can result
|
| + // from either reassigning a buffer, or trying to construct it from an
|
| + // invalid {AllocationResult}.
|
| + static inline LocalAllocationBuffer InvalidBuffer();
|
| +
|
| + // Creates a new LAB from a given {AllocationResult}. Results in
|
| + // InvalidBuffer if the result indicates a retry.
|
| + static inline LocalAllocationBuffer FromResult(Heap* heap,
|
| + AllocationResult result,
|
| + intptr_t size);
|
| +
|
| + ~LocalAllocationBuffer() { Close(); }
|
| +
|
| + // Convert to C++11 move-semantics once allowed by the style guide.
|
| + LocalAllocationBuffer(const LocalAllocationBuffer& other);
|
| + LocalAllocationBuffer& operator=(const LocalAllocationBuffer& other);
|
| +
|
| + MUST_USE_RESULT inline AllocationResult AllocateRawAligned(
|
| + int size_in_bytes, AllocationAlignment alignment);
|
| +
|
| + inline bool IsValid() { return allocation_info_.top() != nullptr; }
|
| +
|
| + // Try to merge LABs, which is only possible when they are adjacent in memory.
|
| + // Returns true if the merge was successful, false otherwise.
|
| + inline bool TryMerge(LocalAllocationBuffer* other);
|
| +
|
| + private:
|
| + LocalAllocationBuffer(Heap* heap, AllocationInfo allocation_info);
|
| +
|
| + void Close();
|
| +
|
| + Heap* heap_;
|
| + AllocationInfo allocation_info_;
|
| +};
|
| +
|
| +
|
| class PagedSpace : public Space {
|
| public:
|
| static const intptr_t kCompactionMemoryWanted = 500 * KB;
|
| @@ -1999,8 +2059,7 @@ class PagedSpace : public Space {
|
| DCHECK(top == limit ||
|
| Page::FromAddress(top) == Page::FromAddress(limit - 1));
|
| MemoryChunk::UpdateHighWaterMark(allocation_info_.top());
|
| - allocation_info_.set_top(top);
|
| - allocation_info_.set_limit(limit);
|
| + allocation_info_.Reset(top, limit);
|
| }
|
|
|
| // Empty space allocation info, returning unused area to free list.
|
| @@ -2741,6 +2800,9 @@ class NewSpace : public Space {
|
| MUST_USE_RESULT INLINE(AllocationResult AllocateRaw(
|
| int size_in_bytes, AllocationAlignment alignment));
|
|
|
| + MUST_USE_RESULT inline AllocationResult AllocateRawSynchronized(
|
| + int size_in_bytes, AllocationAlignment alignment);
|
| +
|
| // Reset the allocation pointer to the beginning of the active semispace.
|
| void ResetAllocationInfo();
|
|
|
| @@ -2790,6 +2852,7 @@ class NewSpace : public Space {
|
| // are no pages, or the current page is already empty), or true
|
| // if successful.
|
| bool AddFreshPage();
|
| + bool AddFreshPageSynchronized();
|
|
|
| #ifdef VERIFY_HEAP
|
| // Verify the active semispace.
|
| @@ -2833,6 +2896,8 @@ class NewSpace : public Space {
|
| // Update allocation info to match the current to-space page.
|
| void UpdateAllocationInfo();
|
|
|
| + base::Mutex mutex_;
|
| +
|
| Address chunk_base_;
|
| uintptr_t chunk_size_;
|
|
|
|
|