| 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 |