Flutter Engine
The Flutter Engine
freelist.h
Go to the documentation of this file.
1// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
5#ifndef RUNTIME_VM_HEAP_FREELIST_H_
6#define RUNTIME_VM_HEAP_FREELIST_H_
7
8#include "platform/assert.h"
9#include "platform/atomic.h"
10#include "vm/allocation.h"
11#include "vm/bit_set.h"
12#include "vm/os_thread.h"
13#include "vm/raw_object.h"
14
15namespace dart {
16
17// FreeListElement describes a freelist element. Smallest FreeListElement is
18// two words in size. Second word of the raw object is used to keep a next_
19// pointer to chain elements of the list together. For objects larger than the
20// object size encodable in tags field, the size of the element is embedded in
21// the element at the address following the next_ field. All words written by
22// the freelist are guaranteed to look like Smis.
23// A FreeListElement never has its header mark bit set.
25 public:
26 FreeListElement* next() const { return next_; }
27 uword next_address() const { return reinterpret_cast<uword>(&next_); }
28
29 void set_next(FreeListElement* next) { next_ = next; }
30
31 intptr_t HeapSize() { return HeapSize(tags_); }
32 intptr_t HeapSize(uword tags) {
35 if (size != 0) return size;
36 return *SizeAddress();
37 }
38
39 static FreeListElement* AsElement(uword addr, intptr_t size);
40 static FreeListElement* AsElementNew(uword addr, intptr_t size);
41
42 static void Init();
43
44 static constexpr intptr_t kLargeHeaderSize = 3 * kWordSize;
45 static intptr_t HeaderSizeFor(intptr_t size);
46
47 // Used to allocate class for free list elements in Object::InitOnce.
49 public:
51 static cpp_vtable vtable() { return 0; }
52 static intptr_t InstanceSize() { return 0; }
53 static intptr_t NextFieldOffset() { return -kWordSize; }
55 static bool IsInstance() { return true; }
56
57 private:
58 DISALLOW_ALLOCATION();
59 DISALLOW_COPY_AND_ASSIGN(FakeInstance);
60 };
61
62 private:
63 // This layout mirrors the layout of UntaggedObject.
66
67 // Returns the address of the embedded size.
68 intptr_t* SizeAddress() const {
69 uword addr = reinterpret_cast<uword>(&next_) + kWordSize;
70 return reinterpret_cast<intptr_t*>(addr);
71 }
72
73 // FreeListElements cannot be allocated. Instead references to them are
74 // created using the AsElement factory method.
75 DISALLOW_ALLOCATION();
76 DISALLOW_IMPLICIT_CONSTRUCTORS(FreeListElement);
77};
78
79class FreeList {
80 public:
81 FreeList();
82 ~FreeList();
83
84 uword TryAllocate(intptr_t size, bool is_protected);
85 void Free(uword addr, intptr_t size);
86
87 void Reset();
88
89 void Print() const;
90
91 Mutex* mutex() { return &mutex_; }
92 uword TryAllocateLocked(intptr_t size, bool is_protected);
93 void FreeLocked(uword addr, intptr_t size);
94
95 // Returns a large element, at least 'minimum_size', or NULL if none exists.
96 FreeListElement* TryAllocateLarge(intptr_t minimum_size);
97 FreeListElement* TryAllocateLargeLocked(intptr_t minimum_size);
98
99 // Allocates locked and unprotected memory, but only from small elements
100 // (i.e., fixed size lists).
103 if (size > last_free_small_size_) {
104 return 0;
105 }
106 int index = IndexForSize(size);
107 if (index != kNumLists && free_map_.Test(index)) {
108 return reinterpret_cast<uword>(DequeueElement(index));
109 }
110 if ((index + 1) < kNumLists) {
111 intptr_t next_index = free_map_.Next(index + 1);
112 if (next_index != -1) {
113 FreeListElement* element = DequeueElement(next_index);
114 SplitElementAfterAndEnqueue(element, size, false);
115 return reinterpret_cast<uword>(element);
116 }
117 }
118 return 0;
119 }
120
121 DART_FORCE_INLINE
124 uword top = top_;
125 uword new_top = top + size;
126 if (new_top <= end_) {
127 top_ = new_top;
128 *result = top;
129 return true;
130 }
131 return false;
132 }
135 intptr_t result = unaccounted_size_;
136 unaccounted_size_ = 0;
137 return result;
138 }
139
140 // Ensures Page::VisitObjects can successful walk over a partially
141 // allocated bump region.
143 if (top_ < end_) {
144 FreeListElement::AsElement(top_, end_ - top_);
145 }
146 }
147 // Returns the bump region to the free list.
150 intptr_t remaining = end_ - top_;
151 if (remaining != 0) {
152 Free(top_, remaining);
153 top_ = 0;
154 end_ = 0;
155 }
156 return remaining;
157 }
158
159 uword top() const { return top_; }
160 uword end() const { return end_; }
161 void set_top(uword value) { top_ = value; }
162 void set_end(uword value) { end_ = value; }
163 void AddUnaccountedSize(intptr_t size) { unaccounted_size_ += size; }
164
165 private:
166 static constexpr int kNumLists = 128;
167 static constexpr intptr_t kInitialFreeListSearchBudget = 1000;
168
169 static intptr_t IndexForSize(intptr_t size) {
172
173 intptr_t index = size >> kObjectAlignmentLog2;
174 if (index >= kNumLists) {
175 index = kNumLists;
176 }
177 return index;
178 }
179
180 intptr_t LengthLocked(int index) const;
181
182 void EnqueueElement(FreeListElement* element, intptr_t index);
183 FreeListElement* DequeueElement(intptr_t index) {
184 FreeListElement* result = free_lists_[index];
185 FreeListElement* next = result->next();
186 if (next == nullptr && index != kNumLists) {
187 intptr_t size = index << kObjectAlignmentLog2;
188 if (size == last_free_small_size_) {
189 // Note: This is -1 * kObjectAlignment if no other small sizes remain.
190 last_free_small_size_ =
192 } else {
193 free_map_.Set(index, false);
194 }
195 }
196 free_lists_[index] = next;
197 return result;
198 }
199
200 void SplitElementAfterAndEnqueue(FreeListElement* element,
201 intptr_t size,
202 bool is_protected);
203
204 void PrintSmall() const;
205 void PrintLarge() const;
206
207 // Bump pointer region.
208 uword top_ = 0;
209 uword end_ = 0;
210
211 // Allocated from the free list, but not yet added to PageSpace::usage_. Used
212 // to avoid expensive atomic adds during parallel scavenge.
213 intptr_t unaccounted_size_ = 0;
214
215 // Lock protecting the free list data structures.
216 mutable Mutex mutex_;
217
218 BitSet<kNumLists> free_map_;
219
220 FreeListElement* free_lists_[kNumLists + 1];
221
222 intptr_t freelist_search_budget_ = kInitialFreeListSearchBudget;
223
224 // The largest available small size in bytes, or negative if there is none.
225 intptr_t last_free_small_size_;
226
228 friend class PrologueTask;
229
231};
232
233} // namespace dart
234
235#endif // RUNTIME_VM_HEAP_FREELIST_H_
static float next(float f)
#define DEBUG_ASSERT(cond)
Definition: assert.h:321
static constexpr ClassIdTagType decode(uword value)
Definition: bitfield.h:171
intptr_t ClearLastAndFindPrevious(intptr_t current_last)
Definition: bit_set.h:67
bool Test(intptr_t i) const
Definition: bit_set.h:31
void Set(intptr_t i, bool value)
Definition: bit_set.h:20
intptr_t Next(intptr_t i) const
Definition: bit_set.h:38
static intptr_t InstanceSize()
Definition: freelist.h:52
static cpp_vtable vtable()
Definition: freelist.h:51
static const ClassId kClassId
Definition: freelist.h:54
static intptr_t NextFieldOffset()
Definition: freelist.h:53
FreeListElement * next() const
Definition: freelist.h:26
intptr_t HeapSize(uword tags)
Definition: freelist.h:32
uword next_address() const
Definition: freelist.h:27
static void Init()
Definition: freelist.cc:66
void set_next(FreeListElement *next)
Definition: freelist.h:29
static FreeListElement * AsElementNew(uword addr, intptr_t size)
Definition: freelist.cc:43
static intptr_t HeaderSizeFor(intptr_t size)
Definition: freelist.cc:71
intptr_t HeapSize()
Definition: freelist.h:31
static constexpr intptr_t kLargeHeaderSize
Definition: freelist.h:44
static FreeListElement * AsElement(uword addr, intptr_t size)
Definition: freelist.cc:16
uword top() const
Definition: freelist.h:159
void set_end(uword value)
Definition: freelist.h:162
void Reset()
Definition: freelist.cc:211
void Print() const
Definition: freelist.cc:315
Mutex * mutex()
Definition: freelist.h:91
void AddUnaccountedSize(intptr_t size)
Definition: freelist.h:163
void FreeLocked(uword addr, intptr_t size)
Definition: freelist.cc:198
DART_FORCE_INLINE bool TryAllocateBumpLocked(intptr_t size, uword *result)
Definition: freelist.h:122
FreeListElement * TryAllocateLarge(intptr_t minimum_size)
Definition: freelist.cc:356
uword TryAllocateLocked(intptr_t size, bool is_protected)
Definition: freelist.cc:87
uword TryAllocate(intptr_t size, bool is_protected)
Definition: freelist.cc:82
void set_top(uword value)
Definition: freelist.h:161
FreeListElement * TryAllocateLargeLocked(intptr_t minimum_size)
Definition: freelist.cc:361
DART_WARN_UNUSED_RESULT intptr_t ReleaseBumpAllocation()
Definition: freelist.h:149
void Free(uword addr, intptr_t size)
Definition: freelist.cc:193
intptr_t TakeUnaccountedSizeLocked()
Definition: freelist.h:133
uword end() const
Definition: freelist.h:160
void MakeIterable()
Definition: freelist.h:142
uword TryAllocateSmallLocked(intptr_t size)
Definition: freelist.h:101
bool IsOwnedByCurrentThread() const
Definition: os_thread.h:402
static constexpr uword decode(uword tag)
Definition: raw_object.h:208
static constexpr bool IsAligned(T x, uintptr_t alignment, uintptr_t offset=0)
Definition: utils.h:92
#define DART_WARN_UNUSED_RESULT
Definition: dart_api.h:66
#define ASSERT(E)
uint8_t value
GAsyncResult * result
Definition: dart_vm.cc:33
uword cpp_vtable
Definition: globals.h:163
ClassId
Definition: class_id.h:212
@ kFreeListElement
Definition: class_id.h:224
uintptr_t uword
Definition: globals.h:501
constexpr intptr_t kWordSize
Definition: globals.h:509
static constexpr intptr_t kObjectAlignment
static constexpr intptr_t kObjectAlignmentLog2
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition: globals.h:581