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(), |