Flutter Engine
The Flutter Engine
Public Types | Static Public Member Functions | List of all members
dart::MethodRecognizer Class Reference

#include <method_recognizer.h>

Inheritance diagram for dart::MethodRecognizer:
dart::AllStatic

Public Types

enum  Kind { kUnknown , kNumRecognizedMethods }
 

Static Public Member Functions

static intptr_t NumArgsCheckedForStaticCall (const Function &function)
 
static intptr_t ResultCidFromPragma (const Object &function_or_field)
 
static intptr_t MethodKindToReceiverCid (Kind kind)
 
static const char * KindToCString (Kind kind)
 
static const char * KindToFunctionNameCString (Kind kind)
 
static bool IsMarkedAsRecognized (const Function &function, const char *kind=nullptr)
 
static void InitializeState ()
 

Detailed Description

Definition at line 25 of file method_recognizer.h.

Member Enumeration Documentation

◆ Kind

Enumerator
kUnknown 
kNumRecognizedMethods 

Definition at line 27 of file method_recognizer.h.

27 {
29#define DEFINE_ENUM_LIST(class_name, function_name, enum_name, fp) k##enum_name,
31#undef DEFINE_ENUM_LIST
33 };
#define DEFINE_ENUM_LIST(class_name, function_name, enum_name, fp)
#define RECOGNIZED_LIST(V)

Member Function Documentation

◆ InitializeState()

void dart::MethodRecognizer::InitializeState ( )
static

Definition at line 163 of file method_recognizer.cc.

163 {
164 GrowableArray<Library*> libs(3);
165 Libraries(&libs);
166 Function& func = Function::Handle();
167 bool fingerprints_match = true;
168
169 for (intptr_t i = 1; i < MethodRecognizer::kNumRecognizedMethods; i++) {
170 const MethodRecognizer::Kind kind = static_cast<MethodRecognizer::Kind>(i);
173 if (!func.IsNull()) {
174 fingerprints_match =
175 func.CheckSourceFingerprint(recognized_methods[i].fp) &&
176 fingerprints_match;
177 func.set_recognized_kind(kind);
178 switch (kind) {
179#define RECOGNIZE_METHOD(class_name, function_name, enum_name, fp) \
180 case MethodRecognizer::k##enum_name: \
181 func.reset_unboxed_parameters_and_return(); \
182 break;
184#undef RECOGNIZE_METHOD
185 default:
186 break;
187 }
188 } else if (!FLAG_precompiled_mode) {
189 fingerprints_match = false;
190 OS::PrintErr("Missing %s::%s\n", recognized_methods[i].class_name,
192 }
193 }
194
195#define SET_FUNCTION_BIT(class_name, function_name, dest, fp, setter, value) \
196 func = Library::GetFunction(libs, #class_name, #function_name); \
197 if (!func.IsNull()) { \
198 fingerprints_match = \
199 func.CheckSourceFingerprint(fp) && fingerprints_match; \
200 func.setter(value); \
201 } else if (!FLAG_precompiled_mode) { \
202 OS::PrintErr("Missing %s::%s\n", #class_name, #function_name); \
203 fingerprints_match = false; \
204 }
205
206#define SET_IS_POLYMORPHIC_TARGET(class_name, function_name, dest, fp) \
207 SET_FUNCTION_BIT(class_name, function_name, dest, fp, \
208 set_is_polymorphic_target, true)
209
211
212#undef SET_RECOGNIZED_KIND
213#undef SET_IS_POLYMORPHIC_TARGET
214#undef SET_FUNCTION_BIT
215
216 if (!fingerprints_match) {
217 // Private names are mangled. Mangling depends on Library::private_key_.
218 // If registering a new bootstrap library, add at the end.
219 FATAL(
220 "FP mismatch while recognizing methods. If the behavior of "
221 "these functions has changed, then changes are also needed in "
222 "the VM's compiler. Otherwise the fingerprint can simply be "
223 "updated in recognized_methods_list.h\n");
224 }
225}
static FunctionPtr GetFunction(const GrowableArray< Library * > &libs, const char *class_name, const char *function_name)
Definition: object.cc:15305
static void static void PrintErr(const char *format,...) PRINTF_ATTRIBUTE(1
static Object & Handle()
Definition: object.h:407
#define FATAL(error)
#define SET_IS_POLYMORPHIC_TARGET(class_name, function_name, dest, fp)
#define RECOGNIZE_METHOD(class_name, function_name, enum_name, fp)
const char *const class_name
const uint32_t fp
static const struct dart::@132 recognized_methods[MethodRecognizer::kNumRecognizedMethods]
const char *const function_name
#define ALL_INTRINSICS_LIST(V)
#define POLYMORPHIC_TARGET_LIST(V)

◆ IsMarkedAsRecognized()

bool dart::MethodRecognizer::IsMarkedAsRecognized ( const Function function,
const char *  kind = nullptr 
)
static

Definition at line 143 of file method_recognizer.cc.

144 {
145 const Function* functionp =
146 function.IsDynamicInvocationForwarder()
147 ? &Function::Handle(function.ForwardingTarget())
148 : &function;
149 Object& options = Object::Handle();
150 bool is_recognized = Library::FindPragma(
151 Thread::Current(), /*only_core=*/true, *functionp,
152 Symbols::vm_recognized(), /*multiple=*/false, &options);
153 if (!is_recognized) return false;
154 if (kind == nullptr) return true;
155
156 ASSERT(options.IsString());
157 ASSERT(String::Cast(options).Equals("asm-intrinsic") ||
158 String::Cast(options).Equals("graph-intrinsic") ||
159 String::Cast(options).Equals("other"));
160 return String::Cast(options).Equals(kind);
161}
const char * options
static bool FindPragma(Thread *T, bool only_core, const Object &object, const String &pragma_name, bool multiple=false, Object *options=nullptr)
Definition: object.cc:4151
static Thread * Current()
Definition: thread.h:362
#define ASSERT(E)
Dart_NativeFunction function
Definition: fuchsia.cc:51
static bool Equals(const Object &expected, const Object &actual)

◆ KindToCString()

const char * dart::MethodRecognizer::KindToCString ( Kind  kind)
static

Definition at line 130 of file method_recognizer.cc.

130 {
131 if (kind >= kUnknown && kind < kNumRecognizedMethods)
132 return recognized_methods[kind].enum_name;
133 return "?";
134}

◆ KindToFunctionNameCString()

const char * dart::MethodRecognizer::KindToFunctionNameCString ( Kind  kind)
static

Definition at line 136 of file method_recognizer.cc.

136 {
137 if (kind >= kUnknown && kind < kNumRecognizedMethods)
138 return recognized_methods[kind].function_name;
139 return "?";
140}

◆ MethodKindToReceiverCid()

intptr_t dart::MethodRecognizer::MethodKindToReceiverCid ( Kind  kind)
static

Definition at line 80 of file method_recognizer.cc.

80 {
81 switch (kind) {
82 case kObjectArrayGetIndexed:
83 case kObjectArraySetIndexed:
84 case kObjectArraySetIndexedUnchecked:
85 return kArrayCid;
86
87 case kGrowableArrayGetIndexed:
88 case kGrowableArraySetIndexed:
89 case kGrowableArraySetIndexedUnchecked:
90 return kGrowableObjectArrayCid;
91
92#define TYPED_DATA_GET_SET_INDEXED_CASES(clazz) \
93 case k##clazz##ArrayGetIndexed: \
94 case k##clazz##ArraySetIndexed: \
95 return kTypedData##clazz##ArrayCid; \
96 case kExternal##clazz##ArrayGetIndexed: \
97 return kExternalTypedData##clazz##ArrayCid; \
98 case k##clazz##ArrayViewGetIndexed: \
99 return kTypedData##clazz##ArrayViewCid;
100
102#undef TYPED_DATA_GET_SET_INDEXED_CASES
103
104 case kExternalUint8ArraySetIndexed:
105 return kExternalTypedDataUint8ArrayCid;
106
107 case kExternalUint8ClampedArraySetIndexed:
108 return kExternalTypedDataUint8ClampedArrayCid;
109
110 default:
111 break;
112 }
113 UNREACHABLE();
114 return kIllegalCid;
115}
#define UNREACHABLE()
Definition: assert.h:248
#define DART_CLASS_LIST_TYPED_DATA(V)
Definition: class_id.h:177
#define TYPED_DATA_GET_SET_INDEXED_CASES(clazz)
@ kIllegalCid
Definition: class_id.h:214

◆ NumArgsCheckedForStaticCall()

intptr_t dart::MethodRecognizer::NumArgsCheckedForStaticCall ( const Function function)
static

Definition at line 14 of file method_recognizer.cc.

15 {
16 switch (function.recognized_kind()) {
17 case MethodRecognizer::kDoubleFromInteger:
18 case MethodRecognizer::kMathMin:
19 case MethodRecognizer::kMathMax:
20 return 2;
21 default:
22 return 0;
23 }
24}

◆ ResultCidFromPragma()

intptr_t dart::MethodRecognizer::ResultCidFromPragma ( const Object function_or_field)
static

Definition at line 26 of file method_recognizer.cc.

27 {
28 auto T = Thread::Current();
29 auto Z = T->zone();
30 auto& option = Object::Handle(Z);
31 if (Library::FindPragma(T, /*only_core=*/true, function_or_field,
32 Symbols::vm_exact_result_type(),
33 /*multiple=*/false, &option)) {
34 if (option.IsType()) {
35 return Type::Cast(option).type_class_id();
36 } else if (option.IsString()) {
37 auto& str = String::Cast(option);
38 // 'str' should match the pattern '([^#]+)#([^#\?]+)' where group 1
39 // is the library URI and group 2 is the class name.
40 bool parse_failure = false;
41 intptr_t library_end = -1;
42 for (intptr_t i = 0; i < str.Length(); ++i) {
43 if (str.CharAt(i) == '#') {
44 if (library_end != -1) {
45 parse_failure = true;
46 break;
47 } else {
48 library_end = i;
49 }
50 }
51 }
52 if (!parse_failure && library_end > 0) {
53 auto& tmp =
54 String::Handle(String::SubString(str, 0, library_end, Heap::kOld));
55 const auto& library = Library::Handle(Library::LookupLibrary(T, tmp));
56 if (!library.IsNull()) {
57 tmp = String::SubString(str, library_end + 1,
58 str.Length() - library_end - 1, Heap::kOld);
59 const auto& klass =
60 Class::Handle(library.LookupClassAllowPrivate(tmp));
61 if (!klass.IsNull()) {
62 return klass.id();
63 }
64 }
65 }
66 } else if (option.IsArray()) {
67 const Array& array = Array::Cast(option);
68 if (array.Length() > 0) {
69 const Object& type = Object::Handle(Array::Cast(option).At(0));
70 if (type.IsType()) {
71 return Type::Cast(type).type_class_id();
72 }
73 }
74 }
75 }
76
77 return kDynamicCid;
78}
#define Z
GLenum type
@ kOld
Definition: heap.h:39
static LibraryPtr LookupLibrary(Thread *thread, const String &url)
Definition: object.cc:14599
static StringPtr SubString(const String &str, intptr_t begin_index, Heap::Space space=Heap::kNew)
Definition: object.cc:24080
@ kDynamicCid
Definition: class_id.h:253
#define T
Definition: precompiler.cc:65

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