Chromium Code Reviews| Index: runtime/vm/intermediate_language.cc |
| =================================================================== |
| --- runtime/vm/intermediate_language.cc (revision 39328) |
| +++ runtime/vm/intermediate_language.cc (working copy) |
| @@ -13,6 +13,7 @@ |
| #include "vm/flow_graph_compiler.h" |
| #include "vm/flow_graph_optimizer.h" |
| #include "vm/flow_graph_range_analysis.h" |
| +#include "vm/intrinsifier.h" |
| #include "vm/locations.h" |
| #include "vm/object.h" |
| #include "vm/object_store.h" |
| @@ -477,76 +478,6 @@ |
| } |
| -static bool StartsWith(const String& name, const char* prefix, intptr_t n) { |
| - ASSERT(name.IsOneByteString()); |
| - |
| - if (name.Length() < n) { |
| - return false; |
| - } |
| - |
| - for (intptr_t i = 0; i < n; i++) { |
| - if (name.CharAt(i) != prefix[i]) { |
| - return false; |
| - } |
| - } |
| - |
| - return true; |
| -} |
| - |
| - |
| -static bool CompareNames(const Library& lib, |
| - const char* test_name, |
| - const String& name) { |
| - ASSERT(Library::kPrivateIdentifierStart == '_'); |
| - const char* kPrivateGetterPrefix = "get:_"; |
| - const char* kPrivateSetterPrefix = "set:_"; |
| - |
| - if (test_name[0] == Library::kPrivateIdentifierStart) { |
| - if (name.CharAt(0) != Library::kPrivateIdentifierStart) { |
| - return false; |
| - } |
| - } else if (strncmp(test_name, |
| - kPrivateGetterPrefix, |
| - strlen(kPrivateGetterPrefix)) == 0) { |
| - if (!StartsWith(name, kPrivateGetterPrefix, strlen(kPrivateGetterPrefix))) { |
| - return false; |
| - } |
| - } else if (strncmp(test_name, |
| - kPrivateSetterPrefix, |
| - strlen(kPrivateSetterPrefix)) == 0) { |
| - if (!StartsWith(name, kPrivateSetterPrefix, strlen(kPrivateSetterPrefix))) { |
| - return false; |
| - } |
| - } else { |
| - // Compare without mangling. |
| - return name.Equals(test_name); |
| - } |
| - |
| - // Both names are private. Mangle test_name before comparison. |
| - // Check if this is a constructor (e.g., List,), in which case the mangler |
| - // needs some help (see comment in Library::PrivateName). |
| - String& test_name_symbol = String::Handle(); |
| - if (test_name[strlen(test_name) - 1] == '.') { |
| - test_name_symbol = Symbols::New(test_name, strlen(test_name) - 1); |
| - test_name_symbol = lib.PrivateName(test_name_symbol); |
| - test_name_symbol = String::Concat(test_name_symbol, Symbols::Dot()); |
| - } else { |
| - test_name_symbol = Symbols::New(test_name); |
| - test_name_symbol = lib.PrivateName(test_name_symbol); |
| - } |
| - return test_name_symbol.Equals(name); |
| -} |
| - |
| - |
| -static bool IsRecognizedLibrary(const Library& library) { |
| - // List of libraries where methods can be recognized. |
| - return (library.raw() == Library::CoreLibrary()) |
| - || (library.raw() == Library::MathLibrary()) |
| - || (library.raw() == Library::TypedDataLibrary()) |
| - || (library.raw() == Library::InternalLibrary()); |
| -} |
| - |
| - |
| MethodRecognizer::Kind MethodRecognizer::RecognizeKind( |
| const Function& function) { |
| if (!function.is_recognized()) { |
| @@ -555,12 +486,12 @@ |
| const Class& function_class = Class::Handle(function.Owner()); |
| const Library& lib = Library::Handle(function_class.library()); |
| - const String& function_name = String::Handle(function.name()); |
| - const String& class_name = String::Handle(function_class.Name()); |
| + const char* function_name = String::Handle(function.name()).ToCString(); |
|
srdjan
2014/08/18 18:04:49
ToCString is expensive, should not be used in perf
Florian Schneider
2014/08/18 18:22:57
The reason was that I use the existing comparison
|
| + const char* class_name = String::Handle(function_class.Name()).ToCString(); |
| #define RECOGNIZE_FUNCTION(test_class_name, test_function_name, enum_name, fp) \ |
| - if (CompareNames(lib, #test_function_name, function_name) && \ |
| - CompareNames(lib, #test_class_name, class_name)) { \ |
| + if (Intrinsifier::TestFunction(lib, class_name, function_name, \ |
| + #test_class_name, #test_function_name)) { \ |
| ASSERT(function.CheckSourceFingerprint(fp)); \ |
| return k##enum_name; \ |
| } |
| @@ -571,6 +502,15 @@ |
| } |
| +static bool IsRecognizedLibrary(const Library& library) { |
| + // List of libraries where methods can be recognized. |
| + return (library.raw() == Library::CoreLibrary()) |
| + || (library.raw() == Library::MathLibrary()) |
| + || (library.raw() == Library::TypedDataLibrary()) |
| + || (library.raw() == Library::InternalLibrary()); |
| +} |
| + |
| + |
| bool MethodRecognizer::AlwaysInline(const Function& function) { |
| const Class& function_class = Class::Handle(function.Owner()); |
| const Library& lib = Library::Handle(function_class.library()); |
| @@ -578,12 +518,12 @@ |
| return false; |
| } |
| - const String& function_name = String::Handle(function.name()); |
| - const String& class_name = String::Handle(function_class.Name()); |
| + const char* function_name = String::Handle(function.name()).ToCString(); |
| + const char* class_name = String::Handle(function_class.Name()).ToCString(); |
| #define RECOGNIZE_FUNCTION(test_class_name, test_function_name, enum_name, fp) \ |
| - if (CompareNames(lib, #test_function_name, function_name) && \ |
| - CompareNames(lib, #test_class_name, class_name)) { \ |
| + if (Intrinsifier::TestFunction(lib, class_name, function_name, \ |
| + #test_class_name, #test_function_name)) { \ |
| ASSERT(function.CheckSourceFingerprint(fp)); \ |
| return true; \ |
| } |
| @@ -600,12 +540,12 @@ |
| return false; |
| } |
| - const String& function_name = String::Handle(function.name()); |
| - const String& class_name = String::Handle(function_class.Name()); |
| + const char* function_name = String::Handle(function.name()).ToCString(); |
| + const char* class_name = String::Handle(function_class.Name()).ToCString(); |
| #define RECOGNIZE_FUNCTION(test_class_name, test_function_name, enum_name, fp) \ |
| - if (CompareNames(lib, #test_function_name, function_name) && \ |
| - CompareNames(lib, #test_class_name, class_name)) { \ |
| + if (Intrinsifier::TestFunction(lib, class_name, function_name, \ |
| + #test_class_name, #test_function_name)) { \ |
| ASSERT(function.CheckSourceFingerprint(fp)); \ |
| return true; \ |
| } |
| @@ -2472,9 +2412,16 @@ |
| MethodRecognizer::Kind recognized_kind = |
| MethodRecognizer::RecognizeKind(function()); |
| int num_args_checked = 0; |
| - if ((recognized_kind == MethodRecognizer::kMathMin) || |
| - (recognized_kind == MethodRecognizer::kMathMax)) { |
| - num_args_checked = 2; |
| + switch (recognized_kind) { |
| + case MethodRecognizer::kDoubleFromInteger: |
| + num_args_checked = 1; |
| + break; |
| + case MethodRecognizer::kMathMin: |
| + case MethodRecognizer::kMathMax: |
| + num_args_checked = 2; |
| + break; |
| + default: |
| + break; |
| } |
| call_ic_data = compiler->GetOrAddStaticCallICData(deopt_id(), |
| function(), |