72 if (
size == 0)
return 0;
93 int index = IndexForSize(
size);
94 if ((index != kNumLists) && free_map_.
Test(index)) {
100 return reinterpret_cast<uword>(element);
103 if ((index + 1) < kNumLists) {
104 intptr_t next_index = free_map_.
Next(index + 1);
105 if (next_index != -1) {
116 intptr_t region_size =
121 SplitElementAfterAndEnqueue(element,
size, is_protected);
122 return reinterpret_cast<uword>(element);
138 while (current !=
nullptr) {
143 intptr_t region_size =
153 if (previous ==
nullptr) {
154 free_lists_[kNumLists] = current->
next();
159 bool target_is_protected =
false;
160 uword target_address = 0
L;
162 uword writable_start =
reinterpret_cast<uword>(current);
163 uword writable_end = writable_start + region_size - 1;
165 target_is_protected =
169 if (target_is_protected) {
174 if (target_is_protected) {
179 SplitElementAfterAndEnqueue(current,
size, is_protected);
180 freelist_search_budget_ =
182 return reinterpret_cast<uword>(current);
183 }
else if (tries_left-- < 0) {
184 freelist_search_budget_ = kInitialFreeListSearchBudget;
188 current = current->
next();
205 intptr_t index = IndexForSize(
size);
207 EnqueueElement(element, index);
214 last_free_small_size_ = -1;
215 for (
int i = 0;
i < (kNumLists + 1);
i++) {
216 free_lists_[
i] =
nullptr;
220void FreeList::EnqueueElement(
FreeListElement* element, intptr_t index) {
222 if (
next ==
nullptr && index != kNumLists) {
223 free_map_.
Set(index,
true);
224 last_free_small_size_ =
228 free_lists_[index] = element;
231intptr_t FreeList::LengthLocked(
int index)
const {
234 ASSERT(index < kNumLists);
236 FreeListElement* element = free_lists_[index];
237 while (element !=
nullptr) {
239 element = element->next();
244void FreeList::PrintSmall()
const {
245 intptr_t small_bytes = 0;
246 for (
int i = 0;
i < kNumLists; ++
i) {
247 if (free_lists_[
i] ==
nullptr) {
250 intptr_t list_length = LengthLocked(
i);
252 small_bytes += list_bytes;
254 "small %3d [%8d bytes] : "
255 "%8" Pd " objs; %8.1f KB; %8.1f cum KB\n",
257 list_bytes /
static_cast<double>(
KB),
258 small_bytes /
static_cast<double>(
KB));
268 intptr_t
first()
const {
return first_; }
269 intptr_t
second()
const {
return second_; }
273 return (first_ == other.first_) && (second_ == other.second_);
277 return (first_ != other.first_) || (second_ != other.second_);
285void FreeList::PrintLarge()
const {
286 intptr_t large_bytes = 0;
287 MallocDirectChainedHashMap<NumbersKeyValueTrait<IntptrPair> >
map;
288 FreeListElement* node;
289 for (node = free_lists_[kNumLists]; node !=
nullptr; node = node->next()) {
290 IntptrPair* pair =
map.Lookup(node->HeapSize());
291 if (pair ==
nullptr) {
292 map.Insert(IntptrPair(node->HeapSize(), 1));
294 pair->set_second(pair->second() + 1);
298 MallocDirectChainedHashMap<NumbersKeyValueTrait<IntptrPair> >::Iterator it =
301 while ((pair = it.Next()) !=
nullptr) {
302 intptr_t
size = pair->first();
303 intptr_t list_length = pair->second();
304 intptr_t list_bytes = list_length *
size;
305 large_bytes += list_bytes;
308 "%8" Pd " objs; %8.1f KB; %8.1f cum KB\n",
310 list_bytes /
static_cast<double>(
KB),
311 large_bytes /
static_cast<double>(
KB));
328 if (remainder_size == 0)
return;
330 uword remainder_address =
reinterpret_cast<uword>(element) +
size;
332 intptr_t remainder_index = IndexForSize(remainder_size);
333 EnqueueElement(element, remainder_index);
341 const uword remainder_header_size =
344 remainder_address - 1,
345 remainder_address + remainder_header_size - 1)) {
347 reinterpret_cast<void*
>(
349 remainder_address + remainder_header_size -
367 intptr_t tries_left =
369 while (current !=
nullptr) {
371 if (current->
HeapSize() >= minimum_size) {
372 if (previous ==
nullptr) {
373 free_lists_[kNumLists] =
next;
377 freelist_search_budget_ =
380 }
else if (tries_left-- < 0) {
381 freelist_search_budget_ = kInitialFreeListSearchBudget;
static float next(float f)
#define DEBUG_ASSERT(cond)
static constexpr uword update(ClassIdTagType value, uword original)
bool Test(intptr_t i) const
void Set(intptr_t i, bool value)
intptr_t Next(intptr_t i) const
FreeListElement * next() const
uword next_address() const
void set_next(FreeListElement *next)
static FreeListElement * AsElementNew(uword addr, intptr_t size)
static intptr_t HeaderSizeFor(intptr_t size)
static FreeListElement * AsElement(uword addr, intptr_t size)
void FreeLocked(uword addr, intptr_t size)
FreeListElement * TryAllocateLarge(intptr_t minimum_size)
uword TryAllocateLocked(intptr_t size, bool is_protected)
uword TryAllocate(intptr_t size, bool is_protected)
FreeListElement * TryAllocateLargeLocked(intptr_t minimum_size)
void Free(uword addr, intptr_t size)
bool operator!=(const IntptrPair &other)
void set_second(intptr_t s)
bool operator==(const IntptrPair &other)
IntptrPair(intptr_t first, intptr_t second)
bool IsOwnedByCurrentThread() const
static void static void PrintErr(const char *format,...) PRINTF_ATTRIBUTE(1
static intptr_t tags_offset()
static constexpr uword update(intptr_t size, uword tag)
static constexpr intptr_t kMaxSizeTag
static constexpr T Maximum(T x, T y)
static T Minimum(T x, T y)
static constexpr T RoundUp(T x, uintptr_t alignment, uintptr_t offset=0)
static constexpr bool IsAligned(T x, uintptr_t alignment, uintptr_t offset=0)
static void Protect(void *address, intptr_t size, Protection mode)
static intptr_t PageSize()
static bool InSamePage(uword address0, uword address1)
static constexpr intptr_t kOldObjectAlignmentOffset
static constexpr intptr_t kNewObjectAlignmentOffset
constexpr intptr_t kWordSizeLog2
constexpr intptr_t kWordSize
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
SI auto map(std::index_sequence< I... >, Fn &&fn, const Args &... args) -> skvx::Vec< sizeof...(I), decltype(fn(args[0]...))>
#define OFFSET_OF(type, field)