Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
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) {
34 intptr_t size = UntaggedObject::SizeTag::decode(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();
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
122 bool TryAllocateBumpLocked(intptr_t size, uword* result) {
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) {
170 ASSERT(size >= kObjectAlignment);
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};
229
230} // namespace dart
231
232#endif // RUNTIME_VM_HEAP_FREELIST_H_
static float next(float f)
#define DEBUG_ASSERT(cond)
Definition assert.h:321
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 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 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:401
static constexpr uword decode(uword tag)
Definition raw_object.h:205
static constexpr bool IsAligned(T x, uintptr_t alignment, uintptr_t offset=0)
Definition utils.h:77
#define DART_WARN_UNUSED_RESULT
Definition dart_api.h:66
#define ASSERT(E)
uint8_t value
GAsyncResult * result
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_IMPLICIT_CONSTRUCTORS(TypeName)
Definition globals.h:593
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition globals.h:581