Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(137)

Side by Side Diff: vm/intrinsifier.cc

Issue 12096105: Instead of setting up the can intrinsify state lazily setup eagerly (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/runtime/
Patch Set: Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « vm/intrinsifier.h ('k') | vm/object.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/intrinsifier.h" 6 #include "vm/intrinsifier.h"
7 #include "vm/flags.h" 7 #include "vm/flags.h"
8 #include "vm/object.h" 8 #include "vm/object.h"
9 #include "vm/symbols.h"
9 10
10 namespace dart { 11 namespace dart {
11 12
12 DEFINE_FLAG(bool, intrinsify, true, "Instrinsify when possible"); 13 DEFINE_FLAG(bool, intrinsify, true, "Instrinsify when possible");
13 14
14 15
15 static bool CompareNames(const char* test_name, const char* name) { 16 static bool CompareNames(const Library& lib,
17 const char* test_name,
18 const char* name) {
16 static const char* kPrivateGetterPrefix = "get:_"; 19 static const char* kPrivateGetterPrefix = "get:_";
17 static const char* kPrivateSetterPrefix = "set:_"; 20 static const char* kPrivateSetterPrefix = "set:_";
18 21
19 if (test_name[0] == '_') { 22 if (test_name[0] == '_') {
20 if (name[0] != '_') { 23 if (name[0] != '_') {
21 return false; 24 return false;
22 } 25 }
23 } else if (strncmp(test_name, 26 } else if (strncmp(test_name,
24 kPrivateGetterPrefix, 27 kPrivateGetterPrefix,
25 strlen(kPrivateGetterPrefix)) == 0) { 28 strlen(kPrivateGetterPrefix)) == 0) {
26 if (strncmp(name, 29 if (strncmp(name,
27 kPrivateGetterPrefix, 30 kPrivateGetterPrefix,
28 strlen(kPrivateGetterPrefix)) != 0) { 31 strlen(kPrivateGetterPrefix)) != 0) {
29 return false; 32 return false;
30 } 33 }
31 } else if (strncmp(test_name, 34 } else if (strncmp(test_name,
32 kPrivateSetterPrefix, 35 kPrivateSetterPrefix,
33 strlen(kPrivateSetterPrefix)) == 0) { 36 strlen(kPrivateSetterPrefix)) == 0) {
34 if (strncmp(name, 37 if (strncmp(name,
35 kPrivateSetterPrefix, 38 kPrivateSetterPrefix,
36 strlen(kPrivateSetterPrefix)) != 0) { 39 strlen(kPrivateSetterPrefix)) != 0) {
37 return false; 40 return false;
38 } 41 }
39 } else { 42 } else {
40 return (strcmp(test_name, name) == 0); 43 return (strcmp(test_name, name) == 0);
41 } 44 }
42 45
43 // Check if the private class is member of core or scalarlist and matches 46 // Check if the private class is member of the library and matches
44 // the test_class_name. 47 // the test_class_name.
45 const Library& core_lib = Library::Handle(Library::CoreLibrary()); 48 const String& test_str = String::Handle(String::New(test_name));
46 const Library& scalarlist_lib = 49 const String& test_str_with_key = String::Handle(
47 Library::Handle(Library::ScalarlistLibrary()); 50 String::Concat(test_str, String::Handle(lib.private_key())));
48 String& test_str = String::Handle(String::New(test_name));
49 String& test_str_with_key = String::Handle();
50 test_str_with_key =
51 String::Concat(test_str, String::Handle(core_lib.private_key()));
52 if (strcmp(test_str_with_key.ToCString(), name) == 0) {
53 return true;
54 }
55 test_str_with_key =
56 String::Concat(test_str, String::Handle(scalarlist_lib.private_key()));
57 if (strcmp(test_str_with_key.ToCString(), name) == 0) { 51 if (strcmp(test_str_with_key.ToCString(), name) == 0) {
58 return true; 52 return true;
59 } 53 }
60 54
61 return false; 55 return false;
62 } 56 }
63 57
64 58
65 // Returns true if the function matches function_name and class_name, with 59 // Returns true if the function matches function_name and class_name, with
66 // special recognition of corelib private classes. 60 // special recognition of corelib private classes.
67 static bool TestFunction(const Function& function, 61 static bool TestFunction(const Library& lib,
62 const Function& function,
68 const char* function_class_name, 63 const char* function_class_name,
69 const char* function_name, 64 const char* function_name,
70 const char* test_class_name, 65 const char* test_class_name,
71 const char* test_function_name) { 66 const char* test_function_name) {
72 // If test_function_name starts with a '.' we use that to indicate 67 return CompareNames(lib, test_class_name, function_class_name) &&
73 // that it is a named constructor in the class. Therefore, if 68 CompareNames(lib, test_function_name, function_name);
74 // the class matches and the rest of the method name starting with
75 // the dot matches, we have found a match.
76 if (test_function_name[0] == '.') {
77 function_name = strstr(function_name, ".");
78 if (function_name == NULL) {
79 return false;
80 }
81 }
82 return CompareNames(test_class_name, function_class_name) &&
83 CompareNames(test_function_name, function_name);
84 } 69 }
85 70
86 71
87 bool Intrinsifier::CanIntrinsify(const Function& function) { 72 bool Intrinsifier::CanIntrinsify(const Function& function) {
88 if (!FLAG_intrinsify) return false; 73 if (!FLAG_intrinsify) return false;
89 if (function.IsClosureFunction()) return false; 74 if (function.IsClosureFunction()) return false;
90 // Can occur because of compile-all flag. 75 // Can occur because of compile-all flag.
91 if (function.is_external()) return false; 76 if (function.is_external()) return false;
92 // Intrinsic kind is set lazily below. 77 return function.is_intrinsic();
93 if (function.intrinsic_kind() == Function::kIsIntrinsic) return true; 78 }
94 if (function.intrinsic_kind() == Function::kIsNotIntrinsic) return false; 79
95 // Closure functions may have different arguments. 80
96 const char* function_name = String::Handle(function.name()).ToCString(); 81 void Intrinsifier::InitializeState() {
97 const Class& function_class = Class::Handle(function.Owner()); 82 Library& lib = Library::Handle();
98 // Only core, math and scalarlist library methods can be intrinsified. 83 Class& cls = Class::Handle();
99 if ((function_class.library() != Library::CoreLibrary()) && 84 Function& func = Function::Handle();
100 (function_class.library() != Library::MathLibrary()) && 85 String& str = String::Handle();
101 (function_class.library() != Library::ScalarlistLibrary())) { 86
102 return false; 87 #define SETUP_FUNCTION(class_name, function_name, destination, fp) \
103 } 88 if (strcmp(#class_name, "::") == 0) { \
104 const char* class_name = String::Handle(function_class.Name()).ToCString(); 89 str = String::New(#function_name); \
105 #define FIND_INTRINSICS(test_class_name, test_function_name, destination, fp) \ 90 func = lib.LookupFunctionAllowPrivate(str); \
106 if (TestFunction(function, \ 91 } else { \
107 class_name, function_name, \ 92 str = String::New(#class_name); \
108 #test_class_name, #test_function_name)) { \ 93 cls = lib.LookupClassAllowPrivate(str); \
109 function.set_intrinsic_kind(Function::kIsIntrinsic); \ 94 ASSERT(!cls.IsNull()); \
110 return true; \ 95 str = String::New(#function_name); \
96 func = cls.LookupFunctionAllowPrivate(str); \
111 } \ 97 } \
98 ASSERT(!func.IsNull()); \
99 func.set_is_intrinsic(true); \
112 100
113 INTRINSIC_LIST(FIND_INTRINSICS); 101 // Set up all core lib functions that can be intrisified.
114 #undef FIND_INTRINSICS 102 lib = Library::CoreLibrary();
115 function.set_intrinsic_kind(Function::kIsNotIntrinsic); 103 CORE_LIB_INTRINSIC_LIST(SETUP_FUNCTION);
116 return false; 104
105 // Set up all math lib functions that can be intrisified.
106 lib = Library::MathLibrary();
107 MATH_LIB_INTRINSIC_LIST(SETUP_FUNCTION);
108
109 // Set up all scalar list lib functions that can be intrisified.
110 lib = Library::ScalarlistLibrary();
111 SCALARLIST_LIB_INTRINSIC_LIST(SETUP_FUNCTION);
112
113 #undef SETUP_FUNCTION
117 } 114 }
118 115
119 116
120 bool Intrinsifier::Intrinsify(const Function& function, Assembler* assembler) { 117 bool Intrinsifier::Intrinsify(const Function& function, Assembler* assembler) {
121 if (!CanIntrinsify(function)) return false; 118 if (!CanIntrinsify(function)) return false;
119
122 const char* function_name = String::Handle(function.name()).ToCString(); 120 const char* function_name = String::Handle(function.name()).ToCString();
123 const Class& function_class = Class::Handle(function.Owner()); 121 const Class& function_class = Class::Handle(function.Owner());
124 const char* class_name = String::Handle(function_class.Name()).ToCString(); 122 const char* class_name = String::Handle(function_class.Name()).ToCString();
123 const Library& lib = Library::Handle(function_class.library());
124
125 #define FIND_INTRINSICS(test_class_name, test_function_name, destination, fp) \ 125 #define FIND_INTRINSICS(test_class_name, test_function_name, destination, fp) \
126 if (TestFunction(function, \ 126 if (TestFunction(lib, function, \
127 class_name, function_name, \ 127 class_name, function_name, \
128 #test_class_name, #test_function_name)) { \ 128 #test_class_name, #test_function_name)) { \
129 ASSERT(function.CheckSourceFingerprint(fp)); \ 129 ASSERT(function.CheckSourceFingerprint(fp)); \
130 return destination(assembler); \ 130 return destination(assembler); \
131 } \ 131 } \
132 132
133 INTRINSIC_LIST(FIND_INTRINSICS); 133 if (lib.raw() == Library::CoreLibrary()) {
134 CORE_LIB_INTRINSIC_LIST(FIND_INTRINSICS);
135 } else if (lib.raw() == Library::ScalarlistLibrary()) {
136 SCALARLIST_LIB_INTRINSIC_LIST(FIND_INTRINSICS);
137 } else if (lib.raw() == Library::MathLibrary()) {
138 MATH_LIB_INTRINSIC_LIST(FIND_INTRINSICS);
139 }
140 return false;
141
134 #undef FIND_INTRINSICS 142 #undef FIND_INTRINSICS
135 return false;
136 } 143 }
137 144
138 } // namespace dart 145 } // namespace dart
OLDNEW
« no previous file with comments | « vm/intrinsifier.h ('k') | vm/object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698