28 #include "memory/oopFactory.hpp" |
28 #include "memory/oopFactory.hpp" |
29 #include "memory/resourceArea.hpp" |
29 #include "memory/resourceArea.hpp" |
30 #include "oops/klass.hpp" |
30 #include "oops/klass.hpp" |
31 #include "oops/methodOop.hpp" |
31 #include "oops/methodOop.hpp" |
32 #include "oops/oop.inline.hpp" |
32 #include "oops/oop.inline.hpp" |
33 #include "oops/symbolOop.hpp" |
33 #include "oops/symbol.hpp" |
34 #include "runtime/handles.inline.hpp" |
34 #include "runtime/handles.inline.hpp" |
35 #include "runtime/jniHandles.hpp" |
35 #include "runtime/jniHandles.hpp" |
36 |
36 |
37 class MethodMatcher : public CHeapObj { |
37 class MethodMatcher : public CHeapObj { |
38 public: |
38 public: |
44 Any, |
44 Any, |
45 Unknown = -1 |
45 Unknown = -1 |
46 }; |
46 }; |
47 |
47 |
48 protected: |
48 protected: |
49 jobject _class_name; |
49 Symbol* _class_name; |
|
50 Symbol* _method_name; |
|
51 Symbol* _signature; |
50 Mode _class_mode; |
52 Mode _class_mode; |
51 jobject _method_name; |
|
52 Mode _method_mode; |
53 Mode _method_mode; |
53 jobject _signature; |
|
54 MethodMatcher* _next; |
54 MethodMatcher* _next; |
55 |
55 |
56 static bool match(symbolHandle candidate, symbolHandle match, Mode match_mode); |
56 static bool match(Symbol* candidate, Symbol* match, Mode match_mode); |
57 |
57 |
58 symbolHandle class_name() const { return (symbolOop)JNIHandles::resolve_non_null(_class_name); } |
58 Symbol* class_name() const { return _class_name; } |
59 symbolHandle method_name() const { return (symbolOop)JNIHandles::resolve_non_null(_method_name); } |
59 Symbol* method_name() const { return _method_name; } |
60 symbolHandle signature() const { return (symbolOop)JNIHandles::resolve(_signature); } |
60 Symbol* signature() const { return _signature; } |
61 |
61 |
62 public: |
62 public: |
63 MethodMatcher(symbolHandle class_name, Mode class_mode, |
63 MethodMatcher(Symbol* class_name, Mode class_mode, |
64 symbolHandle method_name, Mode method_mode, |
64 Symbol* method_name, Mode method_mode, |
65 symbolHandle signature, MethodMatcher* next); |
65 Symbol* signature, MethodMatcher* next); |
66 MethodMatcher(symbolHandle class_name, symbolHandle method_name, MethodMatcher* next); |
66 MethodMatcher(Symbol* class_name, Symbol* method_name, MethodMatcher* next); |
67 |
67 |
68 // utility method |
68 // utility method |
69 MethodMatcher* find(methodHandle method) { |
69 MethodMatcher* find(methodHandle method) { |
70 symbolHandle class_name = Klass::cast(method->method_holder())->name(); |
70 Symbol* class_name = Klass::cast(method->method_holder())->name(); |
71 symbolHandle method_name = method->name(); |
71 Symbol* method_name = method->name(); |
72 for (MethodMatcher* current = this; current != NULL; current = current->_next) { |
72 for (MethodMatcher* current = this; current != NULL; current = current->_next) { |
73 if (match(class_name, current->class_name(), current->_class_mode) && |
73 if (match(class_name, current->class_name(), current->_class_mode) && |
74 match(method_name, current->method_name(), current->_method_mode) && |
74 match(method_name, current->method_name(), current->_method_mode) && |
75 (current->signature().is_null() || current->signature()() == method->signature())) { |
75 (current->signature() == NULL || current->signature() == method->signature())) { |
76 return current; |
76 return current; |
77 } |
77 } |
78 } |
78 } |
79 return NULL; |
79 return NULL; |
80 } |
80 } |
83 return find(method) != NULL; |
83 return find(method) != NULL; |
84 } |
84 } |
85 |
85 |
86 MethodMatcher* next() const { return _next; } |
86 MethodMatcher* next() const { return _next; } |
87 |
87 |
88 static void print_symbol(symbolHandle h, Mode mode) { |
88 static void print_symbol(Symbol* h, Mode mode) { |
89 ResourceMark rm; |
89 ResourceMark rm; |
90 |
90 |
91 if (mode == Suffix || mode == Substring || mode == Any) { |
91 if (mode == Suffix || mode == Substring || mode == Any) { |
92 tty->print("*"); |
92 tty->print("*"); |
93 } |
93 } |
94 if (mode != Any) { |
94 if (mode != Any) { |
95 h()->print_symbol_on(tty); |
95 h->print_symbol_on(tty); |
96 } |
96 } |
97 if (mode == Prefix || mode == Substring) { |
97 if (mode == Prefix || mode == Substring) { |
98 tty->print("*"); |
98 tty->print("*"); |
99 } |
99 } |
100 } |
100 } |
101 |
101 |
102 void print_base() { |
102 void print_base() { |
103 print_symbol(class_name(), _class_mode); |
103 print_symbol(class_name(), _class_mode); |
104 tty->print("."); |
104 tty->print("."); |
105 print_symbol(method_name(), _method_mode); |
105 print_symbol(method_name(), _method_mode); |
106 if (!signature().is_null()) { |
106 if (signature() != NULL) { |
107 tty->print(" "); |
107 tty->print(" "); |
108 signature()->print_symbol_on(tty); |
108 signature()->print_symbol_on(tty); |
109 } |
109 } |
110 } |
110 } |
111 |
111 |
113 print_base(); |
113 print_base(); |
114 tty->cr(); |
114 tty->cr(); |
115 } |
115 } |
116 }; |
116 }; |
117 |
117 |
118 MethodMatcher::MethodMatcher(symbolHandle class_name, symbolHandle method_name, MethodMatcher* next) { |
118 MethodMatcher::MethodMatcher(Symbol* class_name, Symbol* method_name, MethodMatcher* next) { |
119 _class_name = JNIHandles::make_global(class_name); |
119 _class_name = class_name; |
120 _method_name = JNIHandles::make_global(method_name); |
120 _method_name = method_name; |
121 _next = next; |
121 _next = next; |
122 _class_mode = MethodMatcher::Exact; |
122 _class_mode = MethodMatcher::Exact; |
123 _method_mode = MethodMatcher::Exact; |
123 _method_mode = MethodMatcher::Exact; |
124 _signature = NULL; |
124 _signature = NULL; |
125 } |
125 } |
126 |
126 |
127 |
127 |
128 MethodMatcher::MethodMatcher(symbolHandle class_name, Mode class_mode, |
128 MethodMatcher::MethodMatcher(Symbol* class_name, Mode class_mode, |
129 symbolHandle method_name, Mode method_mode, |
129 Symbol* method_name, Mode method_mode, |
130 symbolHandle signature, MethodMatcher* next): |
130 Symbol* signature, MethodMatcher* next): |
131 _class_mode(class_mode) |
131 _class_mode(class_mode) |
132 , _method_mode(method_mode) |
132 , _method_mode(method_mode) |
133 , _next(next) |
133 , _next(next) |
134 , _class_name(JNIHandles::make_global(class_name())) |
134 , _class_name(class_name) |
135 , _method_name(JNIHandles::make_global(method_name())) |
135 , _method_name(method_name) |
136 , _signature(JNIHandles::make_global(signature())) { |
136 , _signature(signature) { |
137 } |
137 } |
138 |
138 |
139 bool MethodMatcher::match(symbolHandle candidate, symbolHandle match, Mode match_mode) { |
139 bool MethodMatcher::match(Symbol* candidate, Symbol* match, Mode match_mode) { |
140 if (match_mode == Any) { |
140 if (match_mode == Any) { |
141 return true; |
141 return true; |
142 } |
142 } |
143 |
143 |
144 if (match_mode == Exact) { |
144 if (match_mode == Exact) { |
145 return candidate() == match(); |
145 return candidate == match; |
146 } |
146 } |
147 |
147 |
148 ResourceMark rm; |
148 ResourceMark rm; |
149 const char * candidate_string = candidate->as_C_string(); |
149 const char * candidate_string = candidate->as_C_string(); |
150 const char * match_string = match->as_C_string(); |
150 const char * match_string = match->as_C_string(); |
169 |
169 |
170 |
170 |
171 class MethodOptionMatcher: public MethodMatcher { |
171 class MethodOptionMatcher: public MethodMatcher { |
172 const char * option; |
172 const char * option; |
173 public: |
173 public: |
174 MethodOptionMatcher(symbolHandle class_name, Mode class_mode, |
174 MethodOptionMatcher(Symbol* class_name, Mode class_mode, |
175 symbolHandle method_name, Mode method_mode, |
175 Symbol* method_name, Mode method_mode, |
176 symbolHandle signature, const char * opt, MethodMatcher* next): |
176 Symbol* signature, const char * opt, MethodMatcher* next): |
177 MethodMatcher(class_name, class_mode, method_name, method_mode, signature, next) { |
177 MethodMatcher(class_name, class_mode, method_name, method_mode, signature, next) { |
178 option = opt; |
178 option = opt; |
179 } |
179 } |
180 |
180 |
181 bool match(methodHandle method, const char* opt) { |
181 bool match(methodHandle method, const char* opt) { |
254 lists[command]->match(method)); |
254 lists[command]->match(method)); |
255 } |
255 } |
256 |
256 |
257 |
257 |
258 static MethodMatcher* add_predicate(OracleCommand command, |
258 static MethodMatcher* add_predicate(OracleCommand command, |
259 symbolHandle class_name, MethodMatcher::Mode c_mode, |
259 Symbol* class_name, MethodMatcher::Mode c_mode, |
260 symbolHandle method_name, MethodMatcher::Mode m_mode, |
260 Symbol* method_name, MethodMatcher::Mode m_mode, |
261 symbolHandle signature) { |
261 Symbol* signature) { |
262 assert(command != OptionCommand, "must use add_option_string"); |
262 assert(command != OptionCommand, "must use add_option_string"); |
263 if (command == LogCommand && !LogCompilation && lists[LogCommand] == NULL) |
263 if (command == LogCommand && !LogCompilation && lists[LogCommand] == NULL) |
264 tty->print_cr("Warning: +LogCompilation must be enabled in order for individual methods to be logged."); |
264 tty->print_cr("Warning: +LogCompilation must be enabled in order for individual methods to be logged."); |
265 lists[command] = new MethodMatcher(class_name, c_mode, method_name, m_mode, signature, lists[command]); |
265 lists[command] = new MethodMatcher(class_name, c_mode, method_name, m_mode, signature, lists[command]); |
266 return lists[command]; |
266 return lists[command]; |
267 } |
267 } |
268 |
268 |
269 |
269 |
270 |
270 |
271 static MethodMatcher* add_option_string(symbolHandle class_name, MethodMatcher::Mode c_mode, |
271 static MethodMatcher* add_option_string(Symbol* class_name, MethodMatcher::Mode c_mode, |
272 symbolHandle method_name, MethodMatcher::Mode m_mode, |
272 Symbol* method_name, MethodMatcher::Mode m_mode, |
273 symbolHandle signature, |
273 Symbol* signature, |
274 const char* option) { |
274 const char* option) { |
275 lists[OptionCommand] = new MethodOptionMatcher(class_name, c_mode, method_name, m_mode, |
275 lists[OptionCommand] = new MethodOptionMatcher(class_name, c_mode, method_name, m_mode, |
276 signature, option, lists[OptionCommand]); |
276 signature, option, lists[OptionCommand]); |
277 return lists[OptionCommand]; |
277 return lists[OptionCommand]; |
278 } |
278 } |
495 const char* error_msg = NULL; |
495 const char* error_msg = NULL; |
496 MethodMatcher* match = NULL; |
496 MethodMatcher* match = NULL; |
497 |
497 |
498 if (scan_line(line, class_name, &c_match, method_name, &m_match, &bytes_read, error_msg)) { |
498 if (scan_line(line, class_name, &c_match, method_name, &m_match, &bytes_read, error_msg)) { |
499 EXCEPTION_MARK; |
499 EXCEPTION_MARK; |
500 symbolHandle c_name = oopFactory::new_symbol_handle(class_name, CHECK); |
500 Symbol* c_name = SymbolTable::new_symbol(class_name, CHECK); |
501 symbolHandle m_name = oopFactory::new_symbol_handle(method_name, CHECK); |
501 Symbol* m_name = SymbolTable::new_symbol(method_name, CHECK); |
502 symbolHandle signature; |
502 Symbol* signature = NULL; |
503 |
503 |
504 line += bytes_read; |
504 line += bytes_read; |
505 // there might be a signature following the method. |
505 // there might be a signature following the method. |
506 // signatures always begin with ( so match that by hand |
506 // signatures always begin with ( so match that by hand |
507 if (1 == sscanf(line, "%*[ \t](%254[[);/" RANGEBASE "]%n", sig + 1, &bytes_read)) { |
507 if (1 == sscanf(line, "%*[ \t](%254[[);/" RANGEBASE "]%n", sig + 1, &bytes_read)) { |
508 sig[0] = '('; |
508 sig[0] = '('; |
509 line += bytes_read; |
509 line += bytes_read; |
510 signature = oopFactory::new_symbol_handle(sig, CHECK); |
510 signature = SymbolTable::new_symbol(sig, CHECK); |
511 } |
511 } |
512 |
512 |
513 if (command == OptionCommand) { |
513 if (command == OptionCommand) { |
514 // Look for trailing options to support |
514 // Look for trailing options to support |
515 // ciMethod::has_option("string") to control features in the |
515 // ciMethod::has_option("string") to control features in the |
712 m_match = MethodMatcher::Any; |
712 m_match = MethodMatcher::Any; |
713 } |
713 } |
714 } |
714 } |
715 |
715 |
716 EXCEPTION_MARK; |
716 EXCEPTION_MARK; |
717 symbolHandle c_name = oopFactory::new_symbol_handle(className, CHECK); |
717 Symbol* c_name = SymbolTable::new_symbol(className, CHECK); |
718 symbolHandle m_name = oopFactory::new_symbol_handle(methodName, CHECK); |
718 Symbol* m_name = SymbolTable::new_symbol(methodName, CHECK); |
719 symbolHandle signature; |
719 Symbol* signature = NULL; |
720 |
720 |
721 add_predicate(CompileOnlyCommand, c_name, c_match, m_name, m_match, signature); |
721 add_predicate(CompileOnlyCommand, c_name, c_match, m_name, m_match, signature); |
722 if (PrintVMOptions) { |
722 if (PrintVMOptions) { |
723 tty->print("CompileOnly: compileonly "); |
723 tty->print("CompileOnly: compileonly "); |
724 lists[CompileOnlyCommand]->print(); |
724 lists[CompileOnlyCommand]->print(); |