Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Static Public Member Functions | List of all members
dart::ClosureFunctionsCache Class Reference

#include <closure_functions_cache.h>

Inheritance diagram for dart::ClosureFunctionsCache:
dart::AllStatic

Static Public Member Functions

static FunctionPtr LookupClosureFunction (const Function &member_function, intptr_t kernel_offset)
 
static FunctionPtr LookupClosureFunctionLocked (const Function &member_function, intptr_t kernel_offset)
 
static void AddClosureFunctionLocked (const Function &function, bool allow_implicit_closure_functions=false)
 
static intptr_t FindClosureIndex (const Function &needle)
 
static FunctionPtr ClosureFunctionFromIndex (intptr_t idx)
 
static void ForAllClosureFunctions (std::function< bool(const Function &)> callback)
 

Detailed Description

Definition at line 34 of file closure_functions_cache.h.

Member Function Documentation

◆ AddClosureFunctionLocked()

void dart::ClosureFunctionsCache::AddClosureFunctionLocked ( const Function function,
bool  allow_implicit_closure_functions = false 
)
static

Definition at line 66 of file closure_functions_cache.cc.

68 {
70
71 auto thread = Thread::Current();
72 auto zone = thread->zone();
73 auto object_store = thread->isolate_group()->object_store();
74
76 thread->isolate_group()->program_lock()->IsCurrentThreadWriter());
77
78 auto& closures =
79 GrowableObjectArray::Handle(zone, object_store->closure_functions());
80 if (closures.IsNull()) {
81 closures = GrowableObjectArray::New();
82 object_store->set_closure_functions(closures);
83 }
84
85 ASSERT(allow_implicit_closure_functions ||
86 function.IsNonImplicitClosureFunction());
87 closures.Add(function, Heap::kOld);
88
89 if (allow_implicit_closure_functions) {
90 return;
91 }
92
93 const Function& member_function =
94 Function::Handle(zone, function.GetOutermostFunction());
95 ASSERT(function.kernel_offset() > 0);
96
97 auto& map_array =
98 Array::Handle(zone, object_store->closure_functions_table());
99 if (map_array.IsNull()) {
100 map_array = HashTables::New<FunctionHashMap>(16, Heap::kOld);
101 }
102 FunctionHashMap map(zone, map_array.ptr());
103 map_array ^= map.GetOrNull(member_function);
104 if (map_array.IsNull()) {
105 map_array = HashTables::New<IntHashMap>(4, Heap::kOld);
106 }
107 IntHashMap map2(zone, map_array.ptr());
108 map2.UpdateOrInsert(Smi::Handle(zone, Smi::New(function.kernel_offset())),
109 function);
110 map.UpdateOrInsert(member_function, map2.Release());
111 object_store->set_closure_functions_table(map.Release());
112}
#define DEBUG_ASSERT(cond)
Definition assert.h:321
static bool IsBackgroundCompilation()
Definition compiler.cc:299
static GrowableObjectArrayPtr New(Heap::Space space=Heap::kNew)
Definition object.h:11118
@ kOld
Definition heap.h:39
static Object & Handle()
Definition object.h:407
static SmiPtr New(intptr_t value)
Definition object.h:9985
static Thread * Current()
Definition thread.h:361
#define ASSERT(E)
Dart_NativeFunction function
Definition fuchsia.cc:51
UnorderedHashMap< SmiTraits > IntHashMap
Definition hash_table.h:902
UnorderedHashMap< FunctionHashMapTraits > FunctionHashMap
SI auto map(std::index_sequence< I... >, Fn &&fn, const Args &... args) -> skvx::Vec< sizeof...(I), decltype(fn(args[0]...))>
Definition SkVx.h:680

◆ ClosureFunctionFromIndex()

FunctionPtr dart::ClosureFunctionsCache::ClosureFunctionFromIndex ( intptr_t  idx)
static

Definition at line 134 of file closure_functions_cache.cc.

134 {
135 auto thread = Thread::Current();
136 auto zone = thread->zone();
137 auto object_store = thread->isolate_group()->object_store();
138
139 SafepointReadRwLocker ml(thread, thread->isolate_group()->program_lock());
140
141 const auto& closures_array =
142 GrowableObjectArray::Handle(zone, object_store->closure_functions());
143 if (idx < 0 || closures_array.IsNull() || idx >= closures_array.Length()) {
144 return Function::null();
145 }
146 return Function::RawCast(closures_array.At(idx));
147}
static ObjectPtr null()
Definition object.h:433
static ObjectPtr RawCast(ObjectPtr obj)
Definition object.h:325

◆ FindClosureIndex()

intptr_t dart::ClosureFunctionsCache::FindClosureIndex ( const Function needle)
static

Definition at line 114 of file closure_functions_cache.cc.

114 {
115 auto thread = Thread::Current();
116 auto zone = thread->zone();
117 auto object_store = thread->isolate_group()->object_store();
118
119 SafepointReadRwLocker ml(thread, thread->isolate_group()->program_lock());
120
121 const auto& closures_array =
122 GrowableObjectArray::Handle(zone, object_store->closure_functions());
123 if (!closures_array.IsNull()) {
124 intptr_t num_closures = closures_array.Length();
125 for (intptr_t i = 0; i < num_closures; i++) {
126 if (closures_array.At(i) == needle.ptr()) {
127 return i;
128 }
129 }
130 }
131 return -1;
132}

◆ ForAllClosureFunctions()

void dart::ClosureFunctionsCache::ForAllClosureFunctions ( std::function< bool(const Function &)>  callback)
static

Definition at line 149 of file closure_functions_cache.cc.

150 {
151 auto thread = Thread::Current();
152 auto zone = thread->zone();
153 auto object_store = thread->isolate_group()->object_store();
154
155 auto& current_data = Array::Handle(zone);
156 auto& entry = Function::Handle(zone);
157
158 // NOTE: Inner functions may get added to the closures array while iterating -
159 // we guarantee that any closure functions added on this thread by a
160 // [callback] call will be visited as well.
161 //
162 // We avoid holding a lock while accessing the closures array, since often
163 // times [callback] will do very heavy things (e.g. compiling the function).
164 //
165 // This means we can possibly miss a concurrently added closure function -
166 // which the caller should be ok with (or it guarantees that this cannot
167 // happen).
168 const auto& closures =
169 GrowableObjectArray::Handle(zone, object_store->closure_functions());
170 if (closures.IsNull()) {
171 return;
172 }
173
174 if (!thread->IsInStoppedMutatorsScope()) {
175 // The empty read locker scope will implicitly issue an acquire memory
176 // fence, which means any closure functions added so far will be visible and
177 // iterated further down.
178 SafepointReadRwLocker ml(thread, thread->isolate_group()->program_lock());
179 }
180
181 // We have an outer loop to ensure any new closure functions added by
182 // [callback] will be iterated as well.
183 intptr_t i = 0;
184 while (true) {
185 intptr_t current_length = closures.Length();
186 if (i == current_length) break;
187
188 current_data = closures.data();
189 if (current_data.Length() < current_length) {
190 current_length = current_data.Length();
191 }
192
193 for (; i < current_length; ++i) {
194 entry ^= current_data.At(i);
195 if (!callback(entry)) {
196 return; // Stop iteration.
197 }
198 }
199 }
200}
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback

◆ LookupClosureFunction()

FunctionPtr dart::ClosureFunctionsCache::LookupClosureFunction ( const Function member_function,
intptr_t  kernel_offset 
)
static

Definition at line 26 of file closure_functions_cache.cc.

28 {
29 auto thread = Thread::Current();
30 SafepointReadRwLocker ml(thread, thread->isolate_group()->program_lock());
31 return LookupClosureFunctionLocked(member_function, kernel_offset);
32}
static FunctionPtr LookupClosureFunctionLocked(const Function &member_function, intptr_t kernel_offset)

◆ LookupClosureFunctionLocked()

FunctionPtr dart::ClosureFunctionsCache::LookupClosureFunctionLocked ( const Function member_function,
intptr_t  kernel_offset 
)
static

Definition at line 34 of file closure_functions_cache.cc.

36 {
37 auto thread = Thread::Current();
38 auto zone = thread->zone();
39 auto object_store = thread->isolate_group()->object_store();
40
42 thread->isolate_group()->program_lock()->IsCurrentThreadReader());
43
44 auto& map_array =
45 Array::Handle(zone, object_store->closure_functions_table());
46 if (map_array.IsNull()) {
47 return Function::null();
48 }
49
50 FunctionHashMap map(zone, map_array.ptr());
51 map_array ^= map.GetOrNull(member_function);
52 map.Release();
53
54 if (map_array.IsNull()) {
55 return Function::null();
56 }
57
58 auto& result = Function::Handle(zone);
59 IntHashMap map2(zone, map_array.ptr());
60 result ^= map2.GetOrNull(Smi::Handle(zone, Smi::New(kernel_offset)));
61 map2.Release();
62
63 return result.ptr();
64}
GAsyncResult * result

The documentation for this class was generated from the following files: