Mercurial > hg > truffle
annotate src/share/vm/compiler/compilerOracle.cpp @ 9126:bc26f978b0ce
HotSpotResolvedObjectType: implement hasFinalizeSubclass() correctly
don't use the (wrong) cached value, but ask the runtime on each request.
Fixes regression on xml.* benchmarks @ specjvm2008. The problem was:
After the constructor of Object was deoptimized due to an assumption violation,
it was recompiled again after some time. However, on recompilation, the value
of hasFinalizeSubclass for the class was not updated and it was compiled again
with a, now wrong, assumption, which then triggers deoptimization again.
This was repeated until it hit the recompilation limit (defined by
PerMethodRecompilationCutoff), and therefore only executed by the interpreter
from now on, causing the performance regression.
author | Bernhard Urban <bernhard.urban@jku.at> |
---|---|
date | Mon, 15 Apr 2013 19:54:58 +0200 |
parents | 89e4d67fdd2a |
children | d8041d695d19 |
rev | line source |
---|---|
0 | 1 /* |
6150
1e76463170b3
7110720: Issue with vm config file loadingIssue with vm config file loading
kamg
parents:
2426
diff
changeset
|
2 * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1155
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1155
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1155
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "compiler/compilerOracle.hpp" | |
27 #include "memory/allocation.inline.hpp" | |
28 #include "memory/oopFactory.hpp" | |
29 #include "memory/resourceArea.hpp" | |
30 #include "oops/klass.hpp" | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6204
diff
changeset
|
31 #include "oops/method.hpp" |
1972 | 32 #include "oops/oop.inline.hpp" |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
33 #include "oops/symbol.hpp" |
1972 | 34 #include "runtime/handles.inline.hpp" |
35 #include "runtime/jniHandles.hpp" | |
0 | 36 |
6197 | 37 class MethodMatcher : public CHeapObj<mtCompiler> { |
0 | 38 public: |
39 enum Mode { | |
40 Exact, | |
41 Prefix = 1, | |
42 Suffix = 2, | |
43 Substring = Prefix | Suffix, | |
44 Any, | |
45 Unknown = -1 | |
46 }; | |
47 | |
48 protected: | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
49 Symbol* _class_name; |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
50 Symbol* _method_name; |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
51 Symbol* _signature; |
0 | 52 Mode _class_mode; |
53 Mode _method_mode; | |
54 MethodMatcher* _next; | |
55 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
56 static bool match(Symbol* candidate, Symbol* match, Mode match_mode); |
0 | 57 |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
58 Symbol* class_name() const { return _class_name; } |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
59 Symbol* method_name() const { return _method_name; } |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
60 Symbol* signature() const { return _signature; } |
0 | 61 |
62 public: | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
63 MethodMatcher(Symbol* class_name, Mode class_mode, |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
64 Symbol* method_name, Mode method_mode, |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
65 Symbol* signature, MethodMatcher* next); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
66 MethodMatcher(Symbol* class_name, Symbol* method_name, MethodMatcher* next); |
0 | 67 |
68 // utility method | |
69 MethodMatcher* find(methodHandle method) { | |
6940
18fb7da42534
8000725: NPG: method_holder() and pool_holder() and pool_holder field should be InstanceKlass
coleenp
parents:
6909
diff
changeset
|
70 Symbol* class_name = method->method_holder()->name(); |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
71 Symbol* method_name = method->name(); |
0 | 72 for (MethodMatcher* current = this; current != NULL; current = current->_next) { |
73 if (match(class_name, current->class_name(), current->_class_mode) && | |
74 match(method_name, current->method_name(), current->_method_mode) && | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
75 (current->signature() == NULL || current->signature() == method->signature())) { |
0 | 76 return current; |
77 } | |
78 } | |
79 return NULL; | |
80 } | |
81 | |
82 bool match(methodHandle method) { | |
83 return find(method) != NULL; | |
84 } | |
85 | |
86 MethodMatcher* next() const { return _next; } | |
87 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
88 static void print_symbol(Symbol* h, Mode mode) { |
0 | 89 ResourceMark rm; |
90 | |
91 if (mode == Suffix || mode == Substring || mode == Any) { | |
92 tty->print("*"); | |
93 } | |
94 if (mode != Any) { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
95 h->print_symbol_on(tty); |
0 | 96 } |
97 if (mode == Prefix || mode == Substring) { | |
98 tty->print("*"); | |
99 } | |
100 } | |
101 | |
102 void print_base() { | |
103 print_symbol(class_name(), _class_mode); | |
104 tty->print("."); | |
105 print_symbol(method_name(), _method_mode); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
106 if (signature() != NULL) { |
0 | 107 tty->print(" "); |
108 signature()->print_symbol_on(tty); | |
109 } | |
110 } | |
111 | |
112 virtual void print() { | |
113 print_base(); | |
114 tty->cr(); | |
115 } | |
116 }; | |
117 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
118 MethodMatcher::MethodMatcher(Symbol* class_name, Symbol* method_name, MethodMatcher* next) { |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
119 _class_name = class_name; |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
120 _method_name = method_name; |
0 | 121 _next = next; |
122 _class_mode = MethodMatcher::Exact; | |
123 _method_mode = MethodMatcher::Exact; | |
124 _signature = NULL; | |
125 } | |
126 | |
127 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
128 MethodMatcher::MethodMatcher(Symbol* class_name, Mode class_mode, |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
129 Symbol* method_name, Mode method_mode, |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
130 Symbol* signature, MethodMatcher* next): |
0 | 131 _class_mode(class_mode) |
132 , _method_mode(method_mode) | |
133 , _next(next) | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
134 , _class_name(class_name) |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
135 , _method_name(method_name) |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
136 , _signature(signature) { |
0 | 137 } |
138 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
139 bool MethodMatcher::match(Symbol* candidate, Symbol* match, Mode match_mode) { |
0 | 140 if (match_mode == Any) { |
141 return true; | |
142 } | |
143 | |
144 if (match_mode == Exact) { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
145 return candidate == match; |
0 | 146 } |
147 | |
148 ResourceMark rm; | |
149 const char * candidate_string = candidate->as_C_string(); | |
150 const char * match_string = match->as_C_string(); | |
151 | |
152 switch (match_mode) { | |
153 case Prefix: | |
154 return strstr(candidate_string, match_string) == candidate_string; | |
155 | |
156 case Suffix: { | |
157 size_t clen = strlen(candidate_string); | |
158 size_t mlen = strlen(match_string); | |
159 return clen >= mlen && strcmp(candidate_string + clen - mlen, match_string) == 0; | |
160 } | |
161 | |
162 case Substring: | |
163 return strstr(candidate_string, match_string) != NULL; | |
164 | |
165 default: | |
166 return false; | |
167 } | |
168 } | |
169 | |
170 | |
171 class MethodOptionMatcher: public MethodMatcher { | |
172 const char * option; | |
173 public: | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
174 MethodOptionMatcher(Symbol* class_name, Mode class_mode, |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
175 Symbol* method_name, Mode method_mode, |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
176 Symbol* signature, const char * opt, MethodMatcher* next): |
0 | 177 MethodMatcher(class_name, class_mode, method_name, method_mode, signature, next) { |
178 option = opt; | |
179 } | |
180 | |
181 bool match(methodHandle method, const char* opt) { | |
182 MethodOptionMatcher* current = this; | |
183 while (current != NULL) { | |
184 current = (MethodOptionMatcher*)current->find(method); | |
185 if (current == NULL) { | |
186 return false; | |
187 } | |
188 if (strcmp(current->option, opt) == 0) { | |
189 return true; | |
190 } | |
191 current = current->next(); | |
192 } | |
193 return false; | |
194 } | |
195 | |
196 MethodOptionMatcher* next() { | |
197 return (MethodOptionMatcher*)_next; | |
198 } | |
199 | |
200 virtual void print() { | |
201 print_base(); | |
202 tty->print(" %s", option); | |
203 tty->cr(); | |
204 } | |
205 }; | |
206 | |
207 | |
208 | |
209 // this must parallel the command_names below | |
210 enum OracleCommand { | |
211 UnknownCommand = -1, | |
212 OracleFirstCommand = 0, | |
213 BreakCommand = OracleFirstCommand, | |
214 PrintCommand, | |
215 ExcludeCommand, | |
216 InlineCommand, | |
217 DontInlineCommand, | |
218 CompileOnlyCommand, | |
219 LogCommand, | |
220 OptionCommand, | |
221 QuietCommand, | |
222 HelpCommand, | |
223 OracleCommandCount | |
224 }; | |
225 | |
226 // this must parallel the enum OracleCommand | |
227 static const char * command_names[] = { | |
228 "break", | |
229 "print", | |
230 "exclude", | |
231 "inline", | |
232 "dontinline", | |
233 "compileonly", | |
234 "log", | |
235 "option", | |
236 "quiet", | |
237 "help" | |
238 }; | |
239 | |
240 class MethodMatcher; | |
241 static MethodMatcher* lists[OracleCommandCount] = { 0, }; | |
242 | |
243 | |
244 static bool check_predicate(OracleCommand command, methodHandle method) { | |
245 return ((lists[command] != NULL) && | |
246 !method.is_null() && | |
247 lists[command]->match(method)); | |
248 } | |
249 | |
250 | |
251 static MethodMatcher* add_predicate(OracleCommand command, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
252 Symbol* class_name, MethodMatcher::Mode c_mode, |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
253 Symbol* method_name, MethodMatcher::Mode m_mode, |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
254 Symbol* signature) { |
0 | 255 assert(command != OptionCommand, "must use add_option_string"); |
256 if (command == LogCommand && !LogCompilation && lists[LogCommand] == NULL) | |
257 tty->print_cr("Warning: +LogCompilation must be enabled in order for individual methods to be logged."); | |
258 lists[command] = new MethodMatcher(class_name, c_mode, method_name, m_mode, signature, lists[command]); | |
259 return lists[command]; | |
260 } | |
261 | |
262 | |
263 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
264 static MethodMatcher* add_option_string(Symbol* class_name, MethodMatcher::Mode c_mode, |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
265 Symbol* method_name, MethodMatcher::Mode m_mode, |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
266 Symbol* signature, |
0 | 267 const char* option) { |
268 lists[OptionCommand] = new MethodOptionMatcher(class_name, c_mode, method_name, m_mode, | |
269 signature, option, lists[OptionCommand]); | |
270 return lists[OptionCommand]; | |
271 } | |
272 | |
273 | |
274 bool CompilerOracle::has_option_string(methodHandle method, const char* option) { | |
275 return lists[OptionCommand] != NULL && | |
276 ((MethodOptionMatcher*)lists[OptionCommand])->match(method, option); | |
277 } | |
278 | |
279 | |
280 bool CompilerOracle::should_exclude(methodHandle method, bool& quietly) { | |
281 quietly = true; | |
282 if (lists[ExcludeCommand] != NULL) { | |
283 if (lists[ExcludeCommand]->match(method)) { | |
284 quietly = _quiet; | |
285 return true; | |
286 } | |
287 } | |
288 | |
289 if (lists[CompileOnlyCommand] != NULL) { | |
290 return !lists[CompileOnlyCommand]->match(method); | |
291 } | |
292 return false; | |
293 } | |
294 | |
295 | |
296 bool CompilerOracle::should_inline(methodHandle method) { | |
297 return (check_predicate(InlineCommand, method)); | |
298 } | |
299 | |
300 | |
301 bool CompilerOracle::should_not_inline(methodHandle method) { | |
302 return (check_predicate(DontInlineCommand, method)); | |
303 } | |
304 | |
305 | |
306 bool CompilerOracle::should_print(methodHandle method) { | |
307 return (check_predicate(PrintCommand, method)); | |
308 } | |
309 | |
310 | |
311 bool CompilerOracle::should_log(methodHandle method) { | |
312 if (!LogCompilation) return false; | |
313 if (lists[LogCommand] == NULL) return true; // by default, log all | |
314 return (check_predicate(LogCommand, method)); | |
315 } | |
316 | |
317 | |
318 bool CompilerOracle::should_break_at(methodHandle method) { | |
319 return check_predicate(BreakCommand, method); | |
320 } | |
321 | |
322 | |
323 static OracleCommand parse_command_name(const char * line, int* bytes_read) { | |
324 assert(ARRAY_SIZE(command_names) == OracleCommandCount, | |
325 "command_names size mismatch"); | |
326 | |
327 *bytes_read = 0; | |
2077
781072b12368
6765546: Wrong sscanf used to parse CompilerOracle command >= 32 characters could lead to crash
never
parents:
1972
diff
changeset
|
328 char command[33]; |
0 | 329 int result = sscanf(line, "%32[a-z]%n", command, bytes_read); |
330 for (uint i = 0; i < ARRAY_SIZE(command_names); i++) { | |
331 if (strcmp(command, command_names[i]) == 0) { | |
332 return (OracleCommand)i; | |
333 } | |
334 } | |
335 return UnknownCommand; | |
336 } | |
337 | |
338 | |
339 static void usage() { | |
340 tty->print_cr(" CompileCommand and the CompilerOracle allows simple control over"); | |
341 tty->print_cr(" what's allowed to be compiled. The standard supported directives"); | |
342 tty->print_cr(" are exclude and compileonly. The exclude directive stops a method"); | |
343 tty->print_cr(" from being compiled and compileonly excludes all methods except for"); | |
344 tty->print_cr(" the ones mentioned by compileonly directives. The basic form of"); | |
345 tty->print_cr(" all commands is a command name followed by the name of the method"); | |
346 tty->print_cr(" in one of two forms: the standard class file format as in"); | |
347 tty->print_cr(" class/name.methodName or the PrintCompilation format"); | |
348 tty->print_cr(" class.name::methodName. The method name can optionally be followed"); | |
349 tty->print_cr(" by a space then the signature of the method in the class file"); | |
350 tty->print_cr(" format. Otherwise the directive applies to all methods with the"); | |
351 tty->print_cr(" same name and class regardless of signature. Leading and trailing"); | |
352 tty->print_cr(" *'s in the class and/or method name allows a small amount of"); | |
353 tty->print_cr(" wildcarding. "); | |
354 tty->cr(); | |
355 tty->print_cr(" Examples:"); | |
356 tty->cr(); | |
357 tty->print_cr(" exclude java/lang/StringBuffer.append"); | |
358 tty->print_cr(" compileonly java/lang/StringBuffer.toString ()Ljava/lang/String;"); | |
359 tty->print_cr(" exclude java/lang/String*.*"); | |
360 tty->print_cr(" exclude *.toString"); | |
361 } | |
362 | |
363 | |
364 // The characters allowed in a class or method name. All characters > 0x7f | |
365 // are allowed in order to handle obfuscated class files (e.g. Volano) | |
366 #define RANGEBASE "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789$_<>" \ | |
367 "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f" \ | |
368 "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f" \ | |
369 "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf" \ | |
370 "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf" \ | |
371 "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf" \ | |
372 "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf" \ | |
373 "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef" \ | |
374 "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff" | |
375 | |
376 #define RANGE0 "[*" RANGEBASE "]" | |
377 #define RANGEDOT "[*" RANGEBASE ".]" | |
378 #define RANGESLASH "[*" RANGEBASE "/]" | |
379 | |
380 | |
381 // Accept several syntaxes for these patterns | |
382 // original syntax | |
383 // cmd java.lang.String foo | |
384 // PrintCompilation syntax | |
385 // cmd java.lang.String::foo | |
386 // VM syntax | |
387 // cmd java/lang/String[. ]foo | |
388 // | |
389 | |
390 static const char* patterns[] = { | |
391 "%*[ \t]%255" RANGEDOT " " "%255" RANGE0 "%n", | |
392 "%*[ \t]%255" RANGEDOT "::" "%255" RANGE0 "%n", | |
393 "%*[ \t]%255" RANGESLASH "%*[ .]" "%255" RANGE0 "%n", | |
394 }; | |
395 | |
396 static MethodMatcher::Mode check_mode(char name[], const char*& error_msg) { | |
397 int match = MethodMatcher::Exact; | |
1155
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
0
diff
changeset
|
398 while (name[0] == '*') { |
0 | 399 match |= MethodMatcher::Suffix; |
400 strcpy(name, name + 1); | |
401 } | |
402 | |
1155
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
0
diff
changeset
|
403 if (strcmp(name, "*") == 0) return MethodMatcher::Any; |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
0
diff
changeset
|
404 |
0 | 405 size_t len = strlen(name); |
1155
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
0
diff
changeset
|
406 while (len > 0 && name[len - 1] == '*') { |
0 | 407 match |= MethodMatcher::Prefix; |
1155
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
0
diff
changeset
|
408 name[--len] = '\0'; |
0 | 409 } |
410 | |
411 if (strstr(name, "*") != NULL) { | |
412 error_msg = " Embedded * not allowed"; | |
413 return MethodMatcher::Unknown; | |
414 } | |
415 return (MethodMatcher::Mode)match; | |
416 } | |
417 | |
418 static bool scan_line(const char * line, | |
419 char class_name[], MethodMatcher::Mode* c_mode, | |
420 char method_name[], MethodMatcher::Mode* m_mode, | |
421 int* bytes_read, const char*& error_msg) { | |
422 *bytes_read = 0; | |
423 error_msg = NULL; | |
424 for (uint i = 0; i < ARRAY_SIZE(patterns); i++) { | |
425 if (2 == sscanf(line, patterns[i], class_name, method_name, bytes_read)) { | |
426 *c_mode = check_mode(class_name, error_msg); | |
427 *m_mode = check_mode(method_name, error_msg); | |
428 return *c_mode != MethodMatcher::Unknown && *m_mode != MethodMatcher::Unknown; | |
429 } | |
430 } | |
431 return false; | |
432 } | |
433 | |
434 | |
435 | |
436 void CompilerOracle::parse_from_line(char* line) { | |
437 if (line[0] == '\0') return; | |
438 if (line[0] == '#') return; | |
439 | |
440 bool have_colon = (strstr(line, "::") != NULL); | |
441 for (char* lp = line; *lp != '\0'; lp++) { | |
442 // Allow '.' to separate the class name from the method name. | |
443 // This is the preferred spelling of methods: | |
444 // exclude java/lang/String.indexOf(I)I | |
445 // Allow ',' for spaces (eases command line quoting). | |
446 // exclude,java/lang/String.indexOf | |
447 // For backward compatibility, allow space as separator also. | |
448 // exclude java/lang/String indexOf | |
449 // exclude,java/lang/String,indexOf | |
450 // For easy cut-and-paste of method names, allow VM output format | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6204
diff
changeset
|
451 // as produced by Method::print_short_name: |
0 | 452 // exclude java.lang.String::indexOf |
453 // For simple implementation convenience here, convert them all to space. | |
454 if (have_colon) { | |
455 if (*lp == '.') *lp = '/'; // dots build the package prefix | |
456 if (*lp == ':') *lp = ' '; | |
457 } | |
458 if (*lp == ',' || *lp == '.') *lp = ' '; | |
459 } | |
460 | |
461 char* original_line = line; | |
462 int bytes_read; | |
463 OracleCommand command = parse_command_name(line, &bytes_read); | |
464 line += bytes_read; | |
465 | |
2077
781072b12368
6765546: Wrong sscanf used to parse CompilerOracle command >= 32 characters could lead to crash
never
parents:
1972
diff
changeset
|
466 if (command == UnknownCommand) { |
781072b12368
6765546: Wrong sscanf used to parse CompilerOracle command >= 32 characters could lead to crash
never
parents:
1972
diff
changeset
|
467 tty->print_cr("CompilerOracle: unrecognized line"); |
781072b12368
6765546: Wrong sscanf used to parse CompilerOracle command >= 32 characters could lead to crash
never
parents:
1972
diff
changeset
|
468 tty->print_cr(" \"%s\"", original_line); |
781072b12368
6765546: Wrong sscanf used to parse CompilerOracle command >= 32 characters could lead to crash
never
parents:
1972
diff
changeset
|
469 return; |
781072b12368
6765546: Wrong sscanf used to parse CompilerOracle command >= 32 characters could lead to crash
never
parents:
1972
diff
changeset
|
470 } |
781072b12368
6765546: Wrong sscanf used to parse CompilerOracle command >= 32 characters could lead to crash
never
parents:
1972
diff
changeset
|
471 |
0 | 472 if (command == QuietCommand) { |
473 _quiet = true; | |
474 return; | |
475 } | |
476 | |
477 if (command == HelpCommand) { | |
478 usage(); | |
479 return; | |
480 } | |
481 | |
482 MethodMatcher::Mode c_match = MethodMatcher::Exact; | |
483 MethodMatcher::Mode m_match = MethodMatcher::Exact; | |
484 char class_name[256]; | |
485 char method_name[256]; | |
486 char sig[1024]; | |
487 char errorbuf[1024]; | |
488 const char* error_msg = NULL; | |
489 MethodMatcher* match = NULL; | |
490 | |
491 if (scan_line(line, class_name, &c_match, method_name, &m_match, &bytes_read, error_msg)) { | |
492 EXCEPTION_MARK; | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
493 Symbol* c_name = SymbolTable::new_symbol(class_name, CHECK); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
494 Symbol* m_name = SymbolTable::new_symbol(method_name, CHECK); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
495 Symbol* signature = NULL; |
0 | 496 |
497 line += bytes_read; | |
498 // there might be a signature following the method. | |
499 // signatures always begin with ( so match that by hand | |
2077
781072b12368
6765546: Wrong sscanf used to parse CompilerOracle command >= 32 characters could lead to crash
never
parents:
1972
diff
changeset
|
500 if (1 == sscanf(line, "%*[ \t](%254[[);/" RANGEBASE "]%n", sig + 1, &bytes_read)) { |
0 | 501 sig[0] = '('; |
502 line += bytes_read; | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
503 signature = SymbolTable::new_symbol(sig, CHECK); |
0 | 504 } |
505 | |
506 if (command == OptionCommand) { | |
507 // Look for trailing options to support | |
508 // ciMethod::has_option("string") to control features in the | |
509 // compiler. Multiple options may follow the method name. | |
510 char option[256]; | |
511 while (sscanf(line, "%*[ \t]%255[a-zA-Z0-9]%n", option, &bytes_read) == 1) { | |
512 if (match != NULL && !_quiet) { | |
513 // Print out the last match added | |
514 tty->print("CompilerOracle: %s ", command_names[command]); | |
515 match->print(); | |
516 } | |
517 match = add_option_string(c_name, c_match, m_name, m_match, signature, strdup(option)); | |
518 line += bytes_read; | |
519 } | |
520 } else { | |
521 bytes_read = 0; | |
522 sscanf(line, "%*[ \t]%n", &bytes_read); | |
523 if (line[bytes_read] != '\0') { | |
524 jio_snprintf(errorbuf, sizeof(errorbuf), " Unrecognized text after command: %s", line); | |
525 error_msg = errorbuf; | |
526 } else { | |
527 match = add_predicate(command, c_name, c_match, m_name, m_match, signature); | |
528 } | |
529 } | |
530 } | |
531 | |
532 if (match != NULL) { | |
533 if (!_quiet) { | |
7421
ad5dd04754ee
8005031: Some cleanup in c2 to prepare for incremental inlining support
roland
parents:
6940
diff
changeset
|
534 ResourceMark rm; |
0 | 535 tty->print("CompilerOracle: %s ", command_names[command]); |
536 match->print(); | |
537 } | |
538 } else { | |
539 tty->print_cr("CompilerOracle: unrecognized line"); | |
540 tty->print_cr(" \"%s\"", original_line); | |
541 if (error_msg != NULL) { | |
542 tty->print_cr(error_msg); | |
543 } | |
544 } | |
545 } | |
546 | |
6196
3759236eea14
7167142: Consider a warning when finding a .hotspotrc or .hotspot_compiler file that isn't used
kamg
parents:
6150
diff
changeset
|
547 static const char* default_cc_file = ".hotspot_compiler"; |
3759236eea14
7167142: Consider a warning when finding a .hotspotrc or .hotspot_compiler file that isn't used
kamg
parents:
6150
diff
changeset
|
548 |
0 | 549 static const char* cc_file() { |
6150
1e76463170b3
7110720: Issue with vm config file loadingIssue with vm config file loading
kamg
parents:
2426
diff
changeset
|
550 #ifdef ASSERT |
0 | 551 if (CompileCommandFile == NULL) |
6196
3759236eea14
7167142: Consider a warning when finding a .hotspotrc or .hotspot_compiler file that isn't used
kamg
parents:
6150
diff
changeset
|
552 return default_cc_file; |
6150
1e76463170b3
7110720: Issue with vm config file loadingIssue with vm config file loading
kamg
parents:
2426
diff
changeset
|
553 #endif |
0 | 554 return CompileCommandFile; |
555 } | |
6150
1e76463170b3
7110720: Issue with vm config file loadingIssue with vm config file loading
kamg
parents:
2426
diff
changeset
|
556 |
1e76463170b3
7110720: Issue with vm config file loadingIssue with vm config file loading
kamg
parents:
2426
diff
changeset
|
557 bool CompilerOracle::has_command_file() { |
1e76463170b3
7110720: Issue with vm config file loadingIssue with vm config file loading
kamg
parents:
2426
diff
changeset
|
558 return cc_file() != NULL; |
1e76463170b3
7110720: Issue with vm config file loadingIssue with vm config file loading
kamg
parents:
2426
diff
changeset
|
559 } |
1e76463170b3
7110720: Issue with vm config file loadingIssue with vm config file loading
kamg
parents:
2426
diff
changeset
|
560 |
0 | 561 bool CompilerOracle::_quiet = false; |
562 | |
563 void CompilerOracle::parse_from_file() { | |
6150
1e76463170b3
7110720: Issue with vm config file loadingIssue with vm config file loading
kamg
parents:
2426
diff
changeset
|
564 assert(has_command_file(), "command file must be specified"); |
0 | 565 FILE* stream = fopen(cc_file(), "rt"); |
566 if (stream == NULL) return; | |
567 | |
568 char token[1024]; | |
569 int pos = 0; | |
570 int c = getc(stream); | |
6901 | 571 while(c != EOF && pos < (int)(sizeof(token)-1)) { |
0 | 572 if (c == '\n') { |
573 token[pos++] = '\0'; | |
574 parse_from_line(token); | |
575 pos = 0; | |
576 } else { | |
577 token[pos++] = c; | |
578 } | |
579 c = getc(stream); | |
580 } | |
581 token[pos++] = '\0'; | |
582 parse_from_line(token); | |
583 | |
584 fclose(stream); | |
585 } | |
586 | |
587 void CompilerOracle::parse_from_string(const char* str, void (*parse_line)(char*)) { | |
588 char token[1024]; | |
589 int pos = 0; | |
590 const char* sp = str; | |
591 int c = *sp++; | |
6901 | 592 while (c != '\0' && pos < (int)(sizeof(token)-1)) { |
0 | 593 if (c == '\n') { |
594 token[pos++] = '\0'; | |
595 parse_line(token); | |
596 pos = 0; | |
597 } else { | |
598 token[pos++] = c; | |
599 } | |
600 c = *sp++; | |
601 } | |
602 token[pos++] = '\0'; | |
603 parse_line(token); | |
604 } | |
605 | |
606 void CompilerOracle::append_comment_to_file(const char* message) { | |
6150
1e76463170b3
7110720: Issue with vm config file loadingIssue with vm config file loading
kamg
parents:
2426
diff
changeset
|
607 assert(has_command_file(), "command file must be specified"); |
0 | 608 fileStream stream(fopen(cc_file(), "at")); |
609 stream.print("# "); | |
610 for (int index = 0; message[index] != '\0'; index++) { | |
611 stream.put(message[index]); | |
612 if (message[index] == '\n') stream.print("# "); | |
613 } | |
614 stream.cr(); | |
615 } | |
616 | |
617 void CompilerOracle::append_exclude_to_file(methodHandle method) { | |
6150
1e76463170b3
7110720: Issue with vm config file loadingIssue with vm config file loading
kamg
parents:
2426
diff
changeset
|
618 assert(has_command_file(), "command file must be specified"); |
0 | 619 fileStream stream(fopen(cc_file(), "at")); |
620 stream.print("exclude "); | |
6940
18fb7da42534
8000725: NPG: method_holder() and pool_holder() and pool_holder field should be InstanceKlass
coleenp
parents:
6909
diff
changeset
|
621 method->method_holder()->name()->print_symbol_on(&stream); |
0 | 622 stream.print("."); |
623 method->name()->print_symbol_on(&stream); | |
624 method->signature()->print_symbol_on(&stream); | |
625 stream.cr(); | |
626 stream.cr(); | |
627 } | |
628 | |
629 | |
630 void compilerOracle_init() { | |
631 CompilerOracle::parse_from_string(CompileCommand, CompilerOracle::parse_from_line); | |
632 CompilerOracle::parse_from_string(CompileOnly, CompilerOracle::parse_compile_only); | |
6150
1e76463170b3
7110720: Issue with vm config file loadingIssue with vm config file loading
kamg
parents:
2426
diff
changeset
|
633 if (CompilerOracle::has_command_file()) { |
1e76463170b3
7110720: Issue with vm config file loadingIssue with vm config file loading
kamg
parents:
2426
diff
changeset
|
634 CompilerOracle::parse_from_file(); |
6196
3759236eea14
7167142: Consider a warning when finding a .hotspotrc or .hotspot_compiler file that isn't used
kamg
parents:
6150
diff
changeset
|
635 } else { |
3759236eea14
7167142: Consider a warning when finding a .hotspotrc or .hotspot_compiler file that isn't used
kamg
parents:
6150
diff
changeset
|
636 struct stat buf; |
3759236eea14
7167142: Consider a warning when finding a .hotspotrc or .hotspot_compiler file that isn't used
kamg
parents:
6150
diff
changeset
|
637 if (os::stat(default_cc_file, &buf) == 0) { |
3759236eea14
7167142: Consider a warning when finding a .hotspotrc or .hotspot_compiler file that isn't used
kamg
parents:
6150
diff
changeset
|
638 warning("%s file is present but has been ignored. " |
3759236eea14
7167142: Consider a warning when finding a .hotspotrc or .hotspot_compiler file that isn't used
kamg
parents:
6150
diff
changeset
|
639 "Run with -XX:CompileCommandFile=%s to load the file.", |
3759236eea14
7167142: Consider a warning when finding a .hotspotrc or .hotspot_compiler file that isn't used
kamg
parents:
6150
diff
changeset
|
640 default_cc_file, default_cc_file); |
3759236eea14
7167142: Consider a warning when finding a .hotspotrc or .hotspot_compiler file that isn't used
kamg
parents:
6150
diff
changeset
|
641 } |
6150
1e76463170b3
7110720: Issue with vm config file loadingIssue with vm config file loading
kamg
parents:
2426
diff
changeset
|
642 } |
1155
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
0
diff
changeset
|
643 if (lists[PrintCommand] != NULL) { |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
0
diff
changeset
|
644 if (PrintAssembly) { |
6196
3759236eea14
7167142: Consider a warning when finding a .hotspotrc or .hotspot_compiler file that isn't used
kamg
parents:
6150
diff
changeset
|
645 warning("CompileCommand and/or %s file contains 'print' commands, but PrintAssembly is also enabled", default_cc_file); |
1155
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
0
diff
changeset
|
646 } else if (FLAG_IS_DEFAULT(DebugNonSafepoints)) { |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
0
diff
changeset
|
647 warning("printing of assembly code is enabled; turning on DebugNonSafepoints to gain additional output"); |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
0
diff
changeset
|
648 DebugNonSafepoints = true; |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
0
diff
changeset
|
649 } |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
0
diff
changeset
|
650 } |
0 | 651 } |
652 | |
653 | |
654 void CompilerOracle::parse_compile_only(char * line) { | |
655 int i; | |
656 char name[1024]; | |
657 const char* className = NULL; | |
658 const char* methodName = NULL; | |
659 | |
660 bool have_colon = (strstr(line, "::") != NULL); | |
661 char method_sep = have_colon ? ':' : '.'; | |
662 | |
663 if (Verbose) { | |
664 tty->print_cr(line); | |
665 } | |
666 | |
667 ResourceMark rm; | |
668 while (*line != '\0') { | |
669 MethodMatcher::Mode c_match = MethodMatcher::Exact; | |
670 MethodMatcher::Mode m_match = MethodMatcher::Exact; | |
671 | |
672 for (i = 0; | |
673 i < 1024 && *line != '\0' && *line != method_sep && *line != ',' && !isspace(*line); | |
674 line++, i++) { | |
675 name[i] = *line; | |
676 if (name[i] == '.') name[i] = '/'; // package prefix uses '/' | |
677 } | |
678 | |
679 if (i > 0) { | |
680 char* newName = NEW_RESOURCE_ARRAY( char, i + 1); | |
681 if (newName == NULL) | |
682 return; | |
683 strncpy(newName, name, i); | |
684 newName[i] = '\0'; | |
685 | |
686 if (className == NULL) { | |
687 className = newName; | |
688 c_match = MethodMatcher::Prefix; | |
689 } else { | |
690 methodName = newName; | |
691 } | |
692 } | |
693 | |
694 if (*line == method_sep) { | |
695 if (className == NULL) { | |
696 className = ""; | |
697 c_match = MethodMatcher::Any; | |
698 } else { | |
699 // foo/bar.blah is an exact match on foo/bar, bar.blah is a suffix match on bar | |
700 if (strchr(className, '/') != NULL) { | |
701 c_match = MethodMatcher::Exact; | |
702 } else { | |
703 c_match = MethodMatcher::Suffix; | |
704 } | |
705 } | |
706 } else { | |
707 // got foo or foo/bar | |
708 if (className == NULL) { | |
709 ShouldNotReachHere(); | |
710 } else { | |
711 // got foo or foo/bar | |
712 if (strchr(className, '/') != NULL) { | |
713 c_match = MethodMatcher::Prefix; | |
714 } else if (className[0] == '\0') { | |
715 c_match = MethodMatcher::Any; | |
716 } else { | |
717 c_match = MethodMatcher::Substring; | |
718 } | |
719 } | |
720 } | |
721 | |
722 // each directive is terminated by , or NUL or . followed by NUL | |
723 if (*line == ',' || *line == '\0' || (line[0] == '.' && line[1] == '\0')) { | |
724 if (methodName == NULL) { | |
725 methodName = ""; | |
726 if (*line != method_sep) { | |
727 m_match = MethodMatcher::Any; | |
728 } | |
729 } | |
730 | |
731 EXCEPTION_MARK; | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
732 Symbol* c_name = SymbolTable::new_symbol(className, CHECK); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
733 Symbol* m_name = SymbolTable::new_symbol(methodName, CHECK); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2077
diff
changeset
|
734 Symbol* signature = NULL; |
0 | 735 |
736 add_predicate(CompileOnlyCommand, c_name, c_match, m_name, m_match, signature); | |
737 if (PrintVMOptions) { | |
738 tty->print("CompileOnly: compileonly "); | |
739 lists[CompileOnlyCommand]->print(); | |
740 } | |
741 | |
742 className = NULL; | |
743 methodName = NULL; | |
744 } | |
745 | |
746 line = *line == '\0' ? line : line + 1; | |
747 } | |
748 } |