OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
4 // Class for intrinsifying functions. | 4 // Class for intrinsifying functions. |
5 | 5 |
6 #include "vm/assembler.h" | 6 #include "vm/assembler.h" |
7 #include "vm/intrinsifier.h" | 7 #include "vm/intrinsifier.h" |
8 #include "vm/flags.h" | 8 #include "vm/flags.h" |
9 #include "vm/object.h" | 9 #include "vm/object.h" |
10 #include "vm/symbols.h" | 10 #include "vm/symbols.h" |
(...skipping 28 matching lines...) Expand all Loading... |
39 kPrivateSetterPrefix, | 39 kPrivateSetterPrefix, |
40 strlen(kPrivateSetterPrefix)) != 0) { | 40 strlen(kPrivateSetterPrefix)) != 0) { |
41 return false; | 41 return false; |
42 } | 42 } |
43 } else { | 43 } else { |
44 return (strcmp(test_name, name) == 0); | 44 return (strcmp(test_name, name) == 0); |
45 } | 45 } |
46 | 46 |
47 // Check if the private class is member of the library and matches | 47 // Check if the private class is member of the library and matches |
48 // the test_class_name. | 48 // the test_class_name. |
49 const String& test_str = String::Handle(String::New(test_name)); | 49 // Check if this is a constructor (e.g., List,), in which case the mangler |
50 const String& test_str_with_key = String::Handle( | 50 // needs some help (see comment in Library::PrivateName). |
51 String::Concat(test_str, String::Handle(lib.private_key()))); | 51 String& test_str = String::Handle(); |
52 if (strcmp(test_str_with_key.ToCString(), name) == 0) { | 52 if (test_name[strlen(test_name) - 1] == '.') { |
| 53 test_str = String::FromUTF8(reinterpret_cast<const uint8_t*>(test_name), |
| 54 strlen(test_name) - 1); |
| 55 test_str = lib.PrivateName(test_str); |
| 56 test_str = String::Concat(test_str, Symbols::Dot()); |
| 57 |
| 58 } else { |
| 59 test_str = String::New(test_name); |
| 60 test_str = String::Concat(test_str, String::Handle(lib.private_key())); |
| 61 } |
| 62 |
| 63 if (strcmp(test_str.ToCString(), name) == 0) { |
53 return true; | 64 return true; |
54 } | 65 } |
55 | 66 |
56 return false; | 67 return false; |
57 } | 68 } |
58 | 69 |
59 | 70 |
60 // Returns true if the function matches function_name and class_name, with | 71 // Returns true if the function matches function_name and class_name, with |
61 // special recognition of corelib private classes. | 72 // special recognition of corelib private classes. |
62 static bool TestFunction(const Library& lib, | 73 bool Intrinsifier::TestFunction(const Library& lib, |
63 const Function& function, | 74 const char* class_name, |
64 const char* function_class_name, | 75 const char* function_name, |
65 const char* function_name, | 76 const char* test_class_name, |
66 const char* test_class_name, | 77 const char* test_function_name) { |
67 const char* test_function_name) { | |
68 // If test_function_name starts with a '.' we use that to indicate | 78 // If test_function_name starts with a '.' we use that to indicate |
69 // that it is a named constructor in the class. Therefore, if | 79 // that it is a named constructor in the class. Therefore, if |
70 // the class matches and the rest of the method name starting with | 80 // the class matches and the rest of the method name starting with |
71 // the dot matches, we have found a match. | 81 // the dot matches, we have found a match. |
72 // We do not store the entire factory constructor name with the class | 82 // We do not store the entire factory constructor name with the class |
73 // (e.g: _GrowableList.withData) because the actual function name | 83 // (e.g: _GrowableList.withData) because the actual function name |
74 // that we see here includes the private key. | 84 // that we see here includes the private key. |
75 if (test_function_name[0] == '.') { | 85 if (test_function_name[0] == '.') { |
76 function_name = strstr(function_name, "."); | 86 function_name = strstr(function_name, "."); |
77 if (function_name == NULL) { | 87 if (function_name == NULL) { |
78 return false; | 88 return false; |
79 } | 89 } |
80 } | 90 } |
81 return CompareNames(lib, test_class_name, function_class_name) && | 91 return CompareNames(lib, test_class_name, class_name) && |
82 CompareNames(lib, test_function_name, function_name); | 92 CompareNames(lib, test_function_name, function_name); |
83 } | 93 } |
84 | 94 |
85 | 95 |
86 bool Intrinsifier::CanIntrinsify(const Function& function) { | 96 bool Intrinsifier::CanIntrinsify(const Function& function) { |
87 if (!FLAG_intrinsify) return false; | 97 if (!FLAG_intrinsify) return false; |
88 if (function.IsClosureFunction()) return false; | 98 if (function.IsClosureFunction()) return false; |
89 // Can occur because of compile-all flag. | 99 // Can occur because of compile-all flag. |
90 if (function.is_external()) return false; | 100 if (function.is_external()) return false; |
91 return function.is_intrinsic(); | 101 return function.is_intrinsic(); |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
155 | 165 |
156 void Intrinsifier::Intrinsify(const Function& function, Assembler* assembler) { | 166 void Intrinsifier::Intrinsify(const Function& function, Assembler* assembler) { |
157 if (!CanIntrinsify(function)) return; | 167 if (!CanIntrinsify(function)) return; |
158 | 168 |
159 const char* function_name = String::Handle(function.name()).ToCString(); | 169 const char* function_name = String::Handle(function.name()).ToCString(); |
160 const Class& function_class = Class::Handle(function.Owner()); | 170 const Class& function_class = Class::Handle(function.Owner()); |
161 const char* class_name = String::Handle(function_class.Name()).ToCString(); | 171 const char* class_name = String::Handle(function_class.Name()).ToCString(); |
162 const Library& lib = Library::Handle(function_class.library()); | 172 const Library& lib = Library::Handle(function_class.library()); |
163 | 173 |
164 #define FIND_INTRINSICS(test_class_name, test_function_name, destination, fp) \ | 174 #define FIND_INTRINSICS(test_class_name, test_function_name, destination, fp) \ |
165 if (TestFunction(lib, function, \ | 175 if (TestFunction(lib, \ |
166 class_name, function_name, \ | 176 class_name, function_name, \ |
167 #test_class_name, #test_function_name)) { \ | 177 #test_class_name, #test_function_name)) { \ |
168 ASSERT(function.CheckSourceFingerprint(fp)); \ | 178 ASSERT(function.CheckSourceFingerprint(fp)); \ |
169 assembler->Comment("Intrinsic"); \ | 179 assembler->Comment("Intrinsic"); \ |
170 destination(assembler); \ | 180 destination(assembler); \ |
171 return; \ | 181 return; \ |
172 } \ | 182 } \ |
173 | 183 |
174 if (lib.raw() == Library::CoreLibrary()) { | 184 if (lib.raw() == Library::CoreLibrary()) { |
175 CORE_LIB_INTRINSIC_LIST(FIND_INTRINSICS); | 185 CORE_LIB_INTRINSIC_LIST(FIND_INTRINSICS); |
176 if (!FLAG_throw_on_javascript_int_overflow || (Smi::kBits < 32)) { | 186 if (!FLAG_throw_on_javascript_int_overflow || (Smi::kBits < 32)) { |
177 CORE_INTEGER_LIB_INTRINSIC_LIST(FIND_INTRINSICS); | 187 CORE_INTEGER_LIB_INTRINSIC_LIST(FIND_INTRINSICS); |
178 } | 188 } |
179 } else if (lib.raw() == Library::TypedDataLibrary()) { | 189 } else if (lib.raw() == Library::TypedDataLibrary()) { |
180 TYPED_DATA_LIB_INTRINSIC_LIST(FIND_INTRINSICS); | 190 TYPED_DATA_LIB_INTRINSIC_LIST(FIND_INTRINSICS); |
181 } else if (lib.raw() == Library::MathLibrary()) { | 191 } else if (lib.raw() == Library::MathLibrary()) { |
182 MATH_LIB_INTRINSIC_LIST(FIND_INTRINSICS); | 192 MATH_LIB_INTRINSIC_LIST(FIND_INTRINSICS); |
183 } else if (lib.raw() == Library::ProfilerLibrary()) { | 193 } else if (lib.raw() == Library::ProfilerLibrary()) { |
184 PROFILER_LIB_INTRINSIC_LIST(FIND_INTRINSICS); | 194 PROFILER_LIB_INTRINSIC_LIST(FIND_INTRINSICS); |
185 } | 195 } |
186 #undef FIND_INTRINSICS | 196 #undef FIND_INTRINSICS |
187 } | 197 } |
188 | 198 |
189 } // namespace dart | 199 } // namespace dart |
OLD | NEW |