Flutter Engine
The Flutter Engine
weak_table.cc
Go to the documentation of this file.
1// Copyright (c) 2013, 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
6
7#include "platform/assert.h"
8#include "vm/isolate.h"
9#include "vm/raw_object.h"
10
11namespace dart {
12
13intptr_t WeakTable::SizeFor(intptr_t count, intptr_t size) {
14 intptr_t result = size;
15 if (count <= (size / 4)) {
16 // Reduce the capacity.
17 result = size / 2;
18 } else {
19 // Increase the capacity.
20 result = size * 2;
21 if (result < size) {
22 FATAL(
23 "Reached impossible state of having more weak table entries"
24 " than memory available for heap objects.");
25 }
26 }
27 if (result < kMinSize) {
28 result = kMinSize;
29 }
30 return result;
31}
32
34 const intptr_t mask = size() - 1;
35 intptr_t idx = Hash(key) & mask;
36 intptr_t empty_idx = -1;
38
39 while (obj != static_cast<ObjectPtr>(kNoEntry)) {
40 if (obj == key) {
41 SetValueAt(idx, val);
42 return;
43 } else if ((empty_idx < 0) &&
44 (static_cast<intptr_t>(obj) == kDeletedEntry)) {
45 empty_idx = idx; // Insert at this location if not found.
46 }
47 idx = (idx + 1) & mask;
48 obj = ObjectAtExclusive(idx);
49 }
50
51 if (val == 0) {
52 // Do not enter an invalid value. Associating 0 with a key deletes it from
53 // this weak table above in SetValueAt. If the key was not present in the
54 // weak table we are done.
55 return;
56 }
57
58 if (empty_idx >= 0) {
59 // We will be reusing a slot below.
60 set_used(used() - 1);
61 idx = empty_idx;
62 }
63
65 // Set the key and value.
66 SetObjectAt(idx, key);
67 SetValueAt(idx, val);
68 // Update the counts.
69 set_used(used() + 1);
70 set_count(count() + 1);
71
72 // Rehash if needed to ensure that there are empty slots available.
73 if (used_ >= limit()) {
74 Rehash();
75 }
76}
77
79 const intptr_t mask = size() - 1;
80 intptr_t idx = Hash(key) & mask;
81 intptr_t empty_idx = -1;
83
84 while (obj != static_cast<ObjectPtr>(kNoEntry)) {
85 if (obj == key) {
86 return false;
87 } else if ((empty_idx < 0) &&
88 (static_cast<intptr_t>(obj) == kDeletedEntry)) {
89 empty_idx = idx; // Insert at this location if not found.
90 }
91 idx = (idx + 1) & mask;
92 obj = ObjectAtExclusive(idx);
93 }
94
95 ASSERT(val != 0);
96
97 if (empty_idx >= 0) {
98 // We will be reusing a slot below.
99 set_used(used() - 1);
100 idx = empty_idx;
101 }
102
104 // Set the key and value.
105 SetObjectAt(idx, key);
106 SetValueAt(idx, val);
107 // Update the counts.
108 set_used(used() + 1);
109 set_count(count() + 1);
110
111 // Rehash if needed to ensure that there are empty slots available.
112 if (used_ >= limit()) {
113 Rehash();
114 }
115 return true;
116}
117
119 intptr_t* old_data = data_;
120 used_ = 0;
121 count_ = 0;
122 size_ = kMinSize;
123 free(old_data);
124 data_ = reinterpret_cast<intptr_t*>(malloc(size_ * kEntrySize * kWordSize));
125 for (intptr_t i = 0; i < size_; i++) {
126 data_[ObjectIndex(i)] = kNoEntry;
127 data_[ValueIndex(i)] = kNoValue;
128 }
129}
130
132 if (used_ == 0) return;
133
134 for (intptr_t i = 0; i < size_; i++) {
136 visitor->VisitPointer(ObjectPointerAt(i));
137 }
138 }
139
140 Rehash();
141}
142
143#if !defined(PRODUCT) || defined(FORCE_INCLUDE_SAMPLING_HEAP_PROFILER)
146 void* context) {
147 MutexLocker ml(&mutex_);
148 for (intptr_t i = 0; i < size_; i++) {
150 void* data = reinterpret_cast<void*>(data_[ValueIndex(i)]);
151 callback(context, data);
152 }
153 }
154}
155
157 for (intptr_t i = 0; i < size_; i++) {
159 cleanup(reinterpret_cast<void*>(data_[ValueIndex(i)]));
160 }
161 }
162}
163#endif
164
165void WeakTable::Rehash() {
166 intptr_t old_size = size();
167 intptr_t* old_data = data_;
168
169 intptr_t new_size = SizeFor(count(), size());
170 ASSERT(Utils::IsPowerOfTwo(new_size));
171 intptr_t* new_data =
172 reinterpret_cast<intptr_t*>(malloc(new_size * kEntrySize * kWordSize));
173 for (intptr_t i = 0; i < new_size; i++) {
174 new_data[ObjectIndex(i)] = kNoEntry;
175 new_data[ValueIndex(i)] = kNoValue;
176 }
177
178 intptr_t mask = new_size - 1;
179 set_used(0);
180 for (intptr_t i = 0; i < old_size; i++) {
182 // Find the new hash location for this entry.
183 ObjectPtr key = ObjectAtExclusive(i);
184 intptr_t idx = Hash(key) & mask;
185 ObjectPtr obj = static_cast<ObjectPtr>(new_data[ObjectIndex(idx)]);
186 while (obj != static_cast<ObjectPtr>(kNoEntry)) {
187 ASSERT(obj != key); // Duplicate entry is not expected.
188 idx = (idx + 1) & mask;
189 obj = static_cast<ObjectPtr>(new_data[ObjectIndex(idx)]);
190 }
191
192 new_data[ObjectIndex(idx)] = static_cast<intptr_t>(key);
193 new_data[ValueIndex(idx)] = ValueAtExclusive(i);
194 set_used(used() + 1);
195 }
196 }
197 // We should only have used valid entries.
198 ASSERT(used() == count());
199
200 // Switch to using the newly allocated backing store.
201 size_ = new_size;
202 data_ = new_data;
203 free(old_data);
204}
205
206} // namespace dart
int count
Definition: FontMgrTest.cpp:50
void VisitPointer(ObjectPtr *p)
Definition: visitor.h:55
static constexpr bool IsPowerOfTwo(T x)
Definition: utils.h:76
intptr_t used() const
Definition: weak_table.h:50
static constexpr intptr_t kNoValue
Definition: weak_table.h:18
bool MarkValueExclusive(ObjectPtr key, intptr_t val)
Definition: weak_table.cc:78
intptr_t ValueAtExclusive(intptr_t i) const
Definition: weak_table.h:100
void SetValueExclusive(ObjectPtr key, intptr_t val)
Definition: weak_table.cc:33
intptr_t count() const
Definition: weak_table.h:51
bool IsValidEntryAtExclusive(intptr_t i) const
Definition: weak_table.h:80
intptr_t size() const
Definition: weak_table.h:49
void ReportSurvivingAllocations(Dart_HeapSamplingReportCallback callback, void *context)
Definition: weak_table.cc:144
ObjectPtr ObjectAtExclusive(intptr_t i) const
Definition: weak_table.h:94
void Forward(ObjectPointerVisitor *visitor)
Definition: weak_table.cc:131
void CleanupValues(Dart_HeapSamplingDeleteCallback cleanup)
Definition: weak_table.cc:156
void(* Dart_HeapSamplingDeleteCallback)(void *data)
Definition: dart_api.h:1288
void(* Dart_HeapSamplingReportCallback)(void *context, void *data)
Definition: dart_api.h:1281
#define ASSERT(E)
#define FATAL(error)
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
GAsyncResult * result
Definition: dart_vm.cc:33
void * malloc(size_t size)
Definition: allocation.cc:19
constexpr intptr_t kWordSize
Definition: globals.h:509
static int8_t data[kExtLength]
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