Flutter Engine
The Flutter Engine
type_testing_stubs.h
Go to the documentation of this file.
1// Copyright (c) 2018, 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_TYPE_TESTING_STUBS_H_
6#define RUNTIME_VM_TYPE_TESTING_STUBS_H_
7
8#include "vm/object.h"
9
10#if !defined(DART_PRECOMPILED_RUNTIME)
14#endif // !defined(DART_PRECOMPILED_RUNTIME)
15
16namespace dart {
17
19 public:
21
22 // Simple helper for stringifying a [type] and prefix it with the type
23 // testing
24 //
25 // (only during dart_bootstrap).
26 const char* StubNameForType(const AbstractType& type) const;
28 const AbstractType& type) const;
29
30 private:
31 void StringifyTypeTo(BaseTextBuffer* buffer, const AbstractType& type) const;
32 // Converts the contents of the buffer to an assembly-safe name.
33 static void MakeNameAssemblerSafe(BaseTextBuffer* buffer);
34
35 Library& lib_;
36 Class& klass_;
37 AbstractType& type_;
38 String& string_;
39 mutable intptr_t nonce_ = 0;
40};
41
43 public:
44 // During bootstrapping it will return `null` for |void| and |dynamic| types,
45 // otherwise it will return a default stub which tail-calls
46 // subtypingtest/runtime code.
47 static CodePtr DefaultCodeForType(const AbstractType& type,
48 bool lazy_specialize = true);
49
50#if !defined(DART_PRECOMPILED_RUNTIME)
51 static CodePtr SpecializeStubFor(Thread* thread, const AbstractType& type);
52#endif
53
55
56 // Creates new stub for [type] (and registers the tuple in object store
57 // array) or returns default stub.
59
60 private:
61#if !defined(TARGET_ARCH_IA32)
62#if !defined(DART_PRECOMPILED_RUNTIME)
63 CodePtr BuildCodeForType(const AbstractType& type);
64 static void BuildOptimizedTypeTestStub(
65 compiler::Assembler* assembler,
67 const Code& slow_type_test_stub,
68 HierarchyInfo* hi,
69 const AbstractType& type);
70
71 static void BuildOptimizedTypeTestStubFastCases(
72 compiler::Assembler* assembler,
73 HierarchyInfo* hi,
74 const AbstractType& type);
75
76 static bool BuildOptimizedSubtypeRangeCheck(compiler::Assembler* assembler,
77 const CidRangeVector& ranges,
78 Register class_id_reg,
79 compiler::Label* check_succeeded,
80 compiler::Label* check_failed);
81
82 static void BuildOptimizedSubclassRangeCheckWithTypeArguments(
83 compiler::Assembler* assembler,
84 HierarchyInfo* hi,
85 const Type& type,
86 const Class& type_class);
87
88 static void BuildOptimizedRecordSubtypeRangeCheck(
89 compiler::Assembler* assembler,
90 HierarchyInfo* hi,
91 const RecordType& type);
92
93 // Returns whether any cid ranges require type argument checking.
94 //
95 // If any do, then returns from the stub if any checks that do not need
96 // type argument checking succeed, falls through or jumps to load_succeeded if
97 // loading the type arguments succeeds, and otherwise jumps to load_failed.
98 // That is, code that uses the type arguments should follow immediately.
99 //
100 // If none do, then falls through or jumps to load_failed if the checks fail,
101 // else returns from the stub if the checks are successful. That is, code
102 // that handles the failure case (like calling the slow stub) should follow.
103 static bool BuildLoadInstanceTypeArguments(
104 compiler::Assembler* assembler,
105 HierarchyInfo* hi,
106 const Type& type,
107 const Class& type_class,
108 const Register class_id_reg,
109 const Register instance_type_args_reg,
110 compiler::Label* load_succeeded,
111 compiler::Label* load_failed);
112
113 static void BuildOptimizedTypeParameterArgumentValueCheck(
114 compiler::Assembler* assembler,
115 HierarchyInfo* hi,
116 const TypeParameter& type_param,
117 intptr_t type_param_value_offset_i,
118 compiler::Label* check_failed);
119
120 static void BuildOptimizedTypeArgumentValueCheck(
121 compiler::Assembler* assembler,
122 HierarchyInfo* hi,
123 const Type& type,
124 intptr_t type_param_value_offset_i,
125 compiler::Label* check_failed);
126
127#endif // !defined(DART_PRECOMPILED_RUNTIME)
128#endif // !defined(TARGET_ARCH_IA32)
129
131 ObjectStore* object_store_;
132};
133
134template <typename T>
136 public:
137 explicit ReusableHandleStack(Zone* zone) : zone_(zone), handles_count_(0) {}
138
139 private:
140 T* Obtain() {
141 T* handle;
142 if (handles_count_ < handles_.length()) {
143 handle = handles_[handles_count_];
144 } else {
145 handle = &T::ZoneHandle(zone_);
146 handles_.Add(handle);
147 }
148 handles_count_++;
149 return handle;
150 }
151
152 void Release(T* handle) {
153 handles_count_--;
154 ASSERT(handles_count_ >= 0);
155 ASSERT(handles_[handles_count_] == handle);
156 }
157
158 Zone* zone_;
159
160 intptr_t handles_count_;
161 MallocGrowableArray<T*> handles_;
162
163 template <typename U>
164 friend class ScopedHandle;
165};
166
167template <typename T>
169 public:
171 : stack_(stack), handle_(stack_->Obtain()) {}
172
173 ~ScopedHandle() { stack_->Release(handle_); }
174
175 T& operator*() { return *handle_; }
176 T* operator->() { return handle_; }
177
178 private:
180 T* handle_;
181};
182
183// Collects data on how [Type] objects are used in generated code.
185 public:
186 explicit TypeUsageInfo(Thread* thread);
188
191 const TypeArguments& ta);
192
193 // Finalize the collected type usage information.
195
196 // Query if [type] is very likely used in a type test (can give
197 // false-positives and false-negatives, but tries to make a very good guess)
199
200 private:
201 template <typename T>
202 class ObjectSetTrait {
203 public:
204 // Typedefs needed for the DirectChainedHashMap template.
205 typedef const T* Key;
206 typedef const T* Value;
207 typedef const T* Pair;
208
209 static Key KeyOf(Pair kv) { return kv; }
210 static Value ValueOf(Pair kv) { return kv; }
211 static inline uword Hash(Key key) { return key->Hash(); }
212 };
213
214 class TypeSetTrait : public ObjectSetTrait<const AbstractType> {
215 public:
216 static inline bool IsKeyEqual(const AbstractType* pair,
217 const AbstractType* key) {
218 return pair->Equals(*key);
219 }
220 };
221
222 class TypeArgumentsSetTrait : public ObjectSetTrait<const TypeArguments> {
223 public:
224 static inline bool IsKeyEqual(const TypeArguments* pair,
225 const TypeArguments* key) {
226 return pair->ptr() == key->ptr();
227 }
228 };
229
230 class TypeParameterSetTrait : public ObjectSetTrait<const TypeParameter> {
231 public:
232 static inline bool IsKeyEqual(const TypeParameter* pair,
233 const TypeParameter* key) {
234 return pair->ptr() == key->ptr();
235 }
236 };
237
241
242 // Collects all type parameters we are doing assert assignable checks against.
243 void CollectTypeParametersUsedInAssertAssignable(TypeParameterSet* set);
244
245 // All types which flow into any of the type parameters in [set] will be added
246 // to the set of types we test against.
247 void UpdateAssertAssignableTypes(ClassTable* class_table,
248 intptr_t cid_count,
250
251 void AddToSetIfParameter(TypeParameterSet* set,
252 const AbstractType* type,
253 TypeParameter* param);
254 void AddTypeToSet(TypeSet* set, const AbstractType* type);
255
256 Zone* zone_;
257 TypeSet assert_assignable_types_;
258 TypeArgumentsSet* instance_creation_arguments_;
259
260 Class& klass_;
261};
262
263#if !defined(DART_PRECOMPILED_RUNTIME)
265 TypeUsageInfo* type_usage_info,
266 const Class& klass,
267 Definition* type_arguments);
268#endif
269
270#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
271
273
274#endif // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
275
276} // namespace dart
277
278#endif // RUNTIME_VM_TYPE_TESTING_STUBS_H_
TArray< uint32_t > Key
GLenum type
virtual bool Equals(const Instance &other) const
Definition: object.h:9094
void Add(const T &value)
intptr_t length() const
ObjectPtr ptr() const
Definition: object.h:332
ScopedHandle(ReusableHandleStack< T > *stack)
static CodePtr DefaultCodeForType(const AbstractType &type, bool lazy_specialize=true)
CodePtr OptimizedCodeForType(const AbstractType &type)
static CodePtr SpecializeStubFor(Thread *thread, const AbstractType &type)
void WriteStubNameForTypeTo(BaseTextBuffer *buffer, const AbstractType &type) const
const char * StubNameForType(const AbstractType &type) const
bool IsUsedInTypeTest(const AbstractType &type)
TypeUsageInfo(Thread *thread)
void UseTypeArgumentsInInstanceCreation(const Class &klass, const TypeArguments &ta)
void UseTypeInAssertAssignable(const AbstractType &type)
Definition: il.h:75
#define ASSERT(E)
Dart_NativeFunction function
Definition: fuchsia.cc:51
Definition: dart_vm.cc:33
void DeoptimizeTypeTestingStubs()
uintptr_t uword
Definition: globals.h:501
void RegisterTypeArgumentsUse(const Function &function, TypeUsageInfo *type_usage_info, const Class &klass, Definition *type_arguments)
static uint32_t Hash(uint32_t key)
Definition: hashmap_test.cc:65
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace buffer
Definition: switches.h:126
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not set
Definition: switches.h:76
#define T
Definition: precompiler.cc:65