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