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