| // 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. |
| |
| #ifndef V8_HEAP_CPPGC_HEAP_SPACE_H_ |
| #define V8_HEAP_CPPGC_HEAP_SPACE_H_ |
| |
| #include <vector> |
| |
| #include "src/base/logging.h" |
| #include "src/base/macros.h" |
| #include "src/base/platform/mutex.h" |
| #include "src/heap/cppgc/free-list.h" |
| |
| namespace cppgc { |
| namespace internal { |
| |
| class RawHeap; |
| class BasePage; |
| |
| // BaseSpace is responsible for page management. |
| class V8_EXPORT_PRIVATE BaseSpace { |
| public: |
| using Pages = std::vector<BasePage*>; |
| |
| using iterator = Pages::iterator; |
| using const_iterator = Pages::const_iterator; |
| |
| BaseSpace(const BaseSpace&) = delete; |
| BaseSpace& operator=(const BaseSpace&) = delete; |
| |
| iterator begin() { return pages_.begin(); } |
| const_iterator begin() const { return pages_.begin(); } |
| iterator end() { return pages_.end(); } |
| const_iterator end() const { return pages_.end(); } |
| |
| size_t size() const { return pages_.size(); } |
| |
| bool is_large() const { return type_ == PageType::kLarge; } |
| size_t index() const { return index_; } |
| |
| RawHeap* raw_heap() { return heap_; } |
| const RawHeap* raw_heap() const { return heap_; } |
| |
| // Page manipulation functions. |
| void AddPage(BasePage*); |
| void RemovePage(BasePage*); |
| Pages RemoveAllPages(); |
| |
| bool is_compactable() const { return is_compactable_; } |
| |
| protected: |
| enum class PageType { kNormal, kLarge }; |
| explicit BaseSpace(RawHeap* heap, size_t index, PageType type, |
| bool is_compactable); |
| |
| private: |
| RawHeap* heap_; |
| Pages pages_; |
| v8::base::Mutex pages_mutex_; |
| const size_t index_; |
| const PageType type_; |
| const bool is_compactable_; |
| }; |
| |
| class V8_EXPORT_PRIVATE NormalPageSpace final : public BaseSpace { |
| public: |
| class LinearAllocationBuffer { |
| public: |
| Address Allocate(size_t alloc_size) { |
| DCHECK_GE(size_, alloc_size); |
| Address result = start_; |
| start_ += alloc_size; |
| size_ -= alloc_size; |
| return result; |
| } |
| |
| void Set(Address ptr, size_t size) { |
| start_ = ptr; |
| size_ = size; |
| } |
| |
| Address start() const { return start_; } |
| size_t size() const { return size_; } |
| |
| private: |
| Address start_ = nullptr; |
| size_t size_ = 0; |
| }; |
| |
| static NormalPageSpace* From(BaseSpace* space) { |
| DCHECK(!space->is_large()); |
| return static_cast<NormalPageSpace*>(space); |
| } |
| static const NormalPageSpace* From(const BaseSpace* space) { |
| return From(const_cast<BaseSpace*>(space)); |
| } |
| |
| NormalPageSpace(RawHeap* heap, size_t index, bool is_compactable); |
| |
| LinearAllocationBuffer& linear_allocation_buffer() { return current_lab_; } |
| const LinearAllocationBuffer& linear_allocation_buffer() const { |
| return current_lab_; |
| } |
| |
| FreeList& free_list() { return free_list_; } |
| const FreeList& free_list() const { return free_list_; } |
| |
| private: |
| LinearAllocationBuffer current_lab_; |
| FreeList free_list_; |
| }; |
| |
| class V8_EXPORT_PRIVATE LargePageSpace final : public BaseSpace { |
| public: |
| static LargePageSpace* From(BaseSpace* space) { |
| DCHECK(space->is_large()); |
| return static_cast<LargePageSpace*>(space); |
| } |
| static const LargePageSpace* From(const BaseSpace* space) { |
| return From(const_cast<BaseSpace*>(space)); |
| } |
| |
| LargePageSpace(RawHeap* heap, size_t index); |
| }; |
| |
| } // namespace internal |
| } // namespace cppgc |
| |
| #endif // V8_HEAP_CPPGC_HEAP_SPACE_H_ |