• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2021 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef V8_HEAP_LINEAR_ALLOCATION_AREA_H_
6 #define V8_HEAP_LINEAR_ALLOCATION_AREA_H_
7 
8 // This header file is included outside of src/heap/.
9 // Avoid including src/heap/ internals.
10 #include "include/v8-internal.h"
11 #include "src/common/checks.h"
12 
13 namespace v8 {
14 namespace internal {
15 
16 // A linear allocation area to allocate objects from.
17 //
18 // Invariant that must hold at all times:
19 //   start <= top <= limit
20 class LinearAllocationArea final {
21  public:
22   LinearAllocationArea() = default;
LinearAllocationArea(Address top,Address limit)23   LinearAllocationArea(Address top, Address limit)
24       : start_(top), top_(top), limit_(limit) {
25     Verify();
26   }
27 
Reset(Address top,Address limit)28   void Reset(Address top, Address limit) {
29     start_ = top;
30     top_ = top;
31     limit_ = limit;
32     Verify();
33   }
34 
ResetStart()35   void ResetStart() { start_ = top_; }
36 
CanIncrementTop(size_t bytes)37   V8_INLINE bool CanIncrementTop(size_t bytes) {
38     Verify();
39     return (top_ + bytes) <= limit_;
40   }
41 
IncrementTop(size_t bytes)42   V8_INLINE Address IncrementTop(size_t bytes) {
43     Address old_top = top_;
44     top_ += bytes;
45     Verify();
46     return old_top;
47   }
48 
DecrementTopIfAdjacent(Address new_top,size_t bytes)49   V8_INLINE bool DecrementTopIfAdjacent(Address new_top, size_t bytes) {
50     Verify();
51     if ((new_top + bytes) == top_) {
52       top_ = new_top;
53       if (start_ > top_) {
54         ResetStart();
55       }
56       Verify();
57       return true;
58     }
59     return false;
60   }
61 
MergeIfAdjacent(LinearAllocationArea & other)62   V8_INLINE bool MergeIfAdjacent(LinearAllocationArea& other) {
63     Verify();
64     other.Verify();
65     if (top_ == other.limit_) {
66       top_ = other.top_;
67       start_ = other.start_;
68       other.Reset(kNullAddress, kNullAddress);
69       Verify();
70       return true;
71     }
72     return false;
73   }
74 
SetLimit(Address limit)75   V8_INLINE void SetLimit(Address limit) {
76     limit_ = limit;
77     Verify();
78   }
79 
start()80   V8_INLINE Address start() const {
81     Verify();
82     return start_;
83   }
top()84   V8_INLINE Address top() const {
85     Verify();
86     return top_;
87   }
limit()88   V8_INLINE Address limit() const {
89     Verify();
90     return limit_;
91   }
top_address()92   const Address* top_address() const { return &top_; }
top_address()93   Address* top_address() { return &top_; }
limit_address()94   const Address* limit_address() const { return &limit_; }
limit_address()95   Address* limit_address() { return &limit_; }
96 
Verify()97   void Verify() const {
98 #ifdef DEBUG
99     SLOW_DCHECK(start_ <= top_);
100     SLOW_DCHECK(top_ <= limit_);
101     SLOW_DCHECK(top_ == kNullAddress || (top_ & kHeapObjectTagMask) == 0);
102 #endif  // DEBUG
103   }
104 
105   static constexpr int kSize = 3 * kSystemPointerSize;
106 
107  private:
108   // The start of the LAB. Initially coincides with `top_`. As top is moved
109   // ahead, the area [start_, top_[ denotes a range of new objects. This range
110   // is reset with `ResetStart()`.
111   Address start_ = kNullAddress;
112   // The top of the LAB that is used for allocation.
113   Address top_ = kNullAddress;
114   // Limit of the LAB the denotes the end of the valid range for allocation.
115   Address limit_ = kNullAddress;
116 };
117 
118 static_assert(sizeof(LinearAllocationArea) == LinearAllocationArea::kSize,
119               "LinearAllocationArea's size must be small because it "
120               "is included in IsolateData.");
121 
122 }  // namespace internal
123 }  // namespace v8
124 
125 #endif  // V8_HEAP_LINEAR_ALLOCATION_AREA_H_
126