Mercurial > hg > truffle
annotate src/share/vm/classfile/vmSymbols.cpp @ 6972:bd7a7ce2e264
6830717: replay of compilations would help with debugging
Summary: When java process crashed in compiler thread, repeat the compilation process will help finding root cause. This is done with using SA dump application class data and replay data from core dump, then use debug version of jvm to recompile the problematic java method.
Reviewed-by: kvn, twisti, sspitsyn
Contributed-by: yumin.qi@oracle.com
author | minqi |
---|---|
date | Mon, 12 Nov 2012 14:03:53 -0800 |
parents | 18fb7da42534 |
children | f2aebc22372a |
rev | line source |
---|---|
0 | 1 /* |
5979
fc9d8850ab8b
7150058: Allocate symbols from null boot loader to an arena for NMT
coleenp
parents:
2356
diff
changeset
|
2 * Copyright (c) 1997, 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:
1138
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1138
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:
1138
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "classfile/vmSymbols.hpp" | |
27 #include "memory/oopFactory.hpp" | |
28 #include "oops/oop.inline.hpp" | |
29 #include "runtime/handles.inline.hpp" | |
30 #include "utilities/xmlstream.hpp" | |
0 | 31 |
32 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
33 Symbol* vmSymbols::_symbols[vmSymbols::SID_LIMIT]; |
0 | 34 |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
35 Symbol* vmSymbols::_type_signatures[T_VOID+1] = { NULL /*, NULL...*/ }; |
0 | 36 |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
37 inline int compare_symbol(Symbol* a, Symbol* b) { |
0 | 38 if (a == b) return 0; |
39 // follow the natural address order: | |
40 return (address)a > (address)b ? +1 : -1; | |
41 } | |
42 | |
43 static vmSymbols::SID vm_symbol_index[vmSymbols::SID_LIMIT]; | |
44 extern "C" { | |
45 static int compare_vmsymbol_sid(const void* void_a, const void* void_b) { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
46 Symbol* a = vmSymbols::symbol_at(*((vmSymbols::SID*) void_a)); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
47 Symbol* b = vmSymbols::symbol_at(*((vmSymbols::SID*) void_b)); |
0 | 48 return compare_symbol(a, b); |
49 } | |
50 } | |
51 | |
52 #ifndef PRODUCT | |
53 #define VM_SYMBOL_ENUM_NAME_BODY(name, string) #name "\0" | |
54 static const char* vm_symbol_enum_names = | |
55 VM_SYMBOLS_DO(VM_SYMBOL_ENUM_NAME_BODY, VM_ALIAS_IGNORE) | |
56 "\0"; | |
57 static const char* vm_symbol_enum_name(vmSymbols::SID sid) { | |
58 const char* string = &vm_symbol_enum_names[0]; | |
59 int skip = (int)sid - (int)vmSymbols::FIRST_SID; | |
60 for (; skip != 0; skip--) { | |
61 size_t skiplen = strlen(string); | |
62 if (skiplen == 0) return "<unknown>"; // overflow | |
63 string += skiplen+1; | |
64 } | |
65 return string; | |
66 } | |
67 #endif //PRODUCT | |
68 | |
69 // Put all the VM symbol strings in one place. | |
70 // Makes for a more compact libjvm. | |
71 #define VM_SYMBOL_BODY(name, string) string "\0" | |
72 static const char* vm_symbol_bodies = VM_SYMBOLS_DO(VM_SYMBOL_BODY, VM_ALIAS_IGNORE); | |
73 | |
74 void vmSymbols::initialize(TRAPS) { | |
75 assert((int)SID_LIMIT <= (1<<log2_SID_LIMIT), "must fit in this bitfield"); | |
76 assert((int)SID_LIMIT*5 > (1<<log2_SID_LIMIT), "make the bitfield smaller, please"); | |
1133
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
77 assert(vmIntrinsics::FLAG_LIMIT <= (1 << vmIntrinsics::log2_FLAG_LIMIT), "must fit in this bitfield"); |
0 | 78 |
79 if (!UseSharedSpaces) { | |
80 const char* string = &vm_symbol_bodies[0]; | |
81 for (int index = (int)FIRST_SID; index < (int)SID_LIMIT; index++) { | |
5979
fc9d8850ab8b
7150058: Allocate symbols from null boot loader to an arena for NMT
coleenp
parents:
2356
diff
changeset
|
82 Symbol* sym = SymbolTable::new_permanent_symbol(string, CHECK); |
0 | 83 _symbols[index] = sym; |
84 string += strlen(string); // skip string body | |
85 string += 1; // skip trailing null | |
86 } | |
87 | |
88 _type_signatures[T_BYTE] = byte_signature(); | |
89 _type_signatures[T_CHAR] = char_signature(); | |
90 _type_signatures[T_DOUBLE] = double_signature(); | |
91 _type_signatures[T_FLOAT] = float_signature(); | |
92 _type_signatures[T_INT] = int_signature(); | |
93 _type_signatures[T_LONG] = long_signature(); | |
94 _type_signatures[T_SHORT] = short_signature(); | |
95 _type_signatures[T_BOOLEAN] = bool_signature(); | |
96 _type_signatures[T_VOID] = void_signature(); | |
97 // no single signatures for T_OBJECT or T_ARRAY | |
98 } | |
99 | |
100 #ifdef ASSERT | |
101 // Check for duplicates: | |
102 for (int i1 = (int)FIRST_SID; i1 < (int)SID_LIMIT; i1++) { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
103 Symbol* sym = symbol_at((SID)i1); |
0 | 104 for (int i2 = (int)FIRST_SID; i2 < i1; i2++) { |
105 if (symbol_at((SID)i2) == sym) { | |
106 tty->print("*** Duplicate VM symbol SIDs %s(%d) and %s(%d): \"", | |
107 vm_symbol_enum_name((SID)i2), i2, | |
108 vm_symbol_enum_name((SID)i1), i1); | |
109 sym->print_symbol_on(tty); | |
110 tty->print_cr("\""); | |
111 } | |
112 } | |
113 } | |
114 #endif //ASSERT | |
115 | |
116 // Create an index for find_id: | |
117 { | |
118 for (int index = (int)FIRST_SID; index < (int)SID_LIMIT; index++) { | |
119 vm_symbol_index[index] = (SID)index; | |
120 } | |
121 int num_sids = SID_LIMIT-FIRST_SID; | |
122 qsort(&vm_symbol_index[FIRST_SID], num_sids, sizeof(vm_symbol_index[0]), | |
123 compare_vmsymbol_sid); | |
124 } | |
125 | |
126 #ifdef ASSERT | |
127 { | |
128 // Spot-check correspondence between strings, symbols, and enums: | |
129 assert(_symbols[NO_SID] == NULL, "must be"); | |
130 const char* str = "java/lang/Object"; | |
5979
fc9d8850ab8b
7150058: Allocate symbols from null boot loader to an arena for NMT
coleenp
parents:
2356
diff
changeset
|
131 TempNewSymbol jlo = SymbolTable::new_permanent_symbol(str, CHECK); |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
132 assert(strncmp(str, (char*)jlo->base(), jlo->utf8_length()) == 0, ""); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
133 assert(jlo == java_lang_Object(), ""); |
0 | 134 SID sid = VM_SYMBOL_ENUM_NAME(java_lang_Object); |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
135 assert(find_sid(jlo) == sid, ""); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
136 assert(symbol_at(sid) == jlo, ""); |
0 | 137 |
138 // Make sure find_sid produces the right answer in each case. | |
139 for (int index = (int)FIRST_SID; index < (int)SID_LIMIT; index++) { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
140 Symbol* sym = symbol_at((SID)index); |
0 | 141 sid = find_sid(sym); |
142 assert(sid == (SID)index, "symbol index works"); | |
143 // Note: If there are duplicates, this assert will fail. | |
144 // A "Duplicate VM symbol" message will have already been printed. | |
145 } | |
146 | |
147 // The string "format" happens (at the moment) not to be a vmSymbol, | |
148 // though it is a method name in java.lang.String. | |
149 str = "format"; | |
5979
fc9d8850ab8b
7150058: Allocate symbols from null boot loader to an arena for NMT
coleenp
parents:
2356
diff
changeset
|
150 TempNewSymbol fmt = SymbolTable::new_permanent_symbol(str, CHECK); |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
151 sid = find_sid(fmt); |
0 | 152 assert(sid == NO_SID, "symbol index works (negative test)"); |
153 } | |
154 #endif | |
155 } | |
156 | |
157 | |
158 #ifndef PRODUCT | |
159 const char* vmSymbols::name_for(vmSymbols::SID sid) { | |
160 if (sid == NO_SID) | |
161 return "NO_SID"; | |
162 const char* string = &vm_symbol_bodies[0]; | |
163 for (int index = (int)FIRST_SID; index < (int)SID_LIMIT; index++) { | |
164 if (index == (int)sid) | |
165 return string; | |
166 string += strlen(string); // skip string body | |
167 string += 1; // skip trailing null | |
168 } | |
169 return "BAD_SID"; | |
170 } | |
171 #endif | |
172 | |
173 | |
174 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
175 void vmSymbols::symbols_do(SymbolClosure* f) { |
0 | 176 for (int index = (int)FIRST_SID; index < (int)SID_LIMIT; index++) { |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
177 f->do_symbol(&_symbols[index]); |
0 | 178 } |
179 for (int i = 0; i < T_VOID+1; i++) { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
180 f->do_symbol(&_type_signatures[i]); |
0 | 181 } |
182 } | |
183 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
184 void vmSymbols::serialize(SerializeClosure* soc) { |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
185 soc->do_region((u_char*)&_symbols[FIRST_SID], |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
186 (SID_LIMIT - FIRST_SID) * sizeof(_symbols[0])); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
187 soc->do_region((u_char*)_type_signatures, sizeof(_type_signatures)); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
188 } |
0 | 189 |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
190 |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
191 BasicType vmSymbols::signature_type(Symbol* s) { |
0 | 192 assert(s != NULL, "checking"); |
193 for (int i = T_BOOLEAN; i < T_VOID+1; i++) { | |
194 if (s == _type_signatures[i]) { | |
195 return (BasicType)i; | |
196 } | |
197 } | |
198 return T_OBJECT; | |
199 } | |
200 | |
201 | |
202 static int mid_hint = (int)vmSymbols::FIRST_SID+1; | |
203 | |
204 #ifndef PRODUCT | |
205 static int find_sid_calls, find_sid_probes; | |
206 // (Typical counts are calls=7000 and probes=17000.) | |
207 #endif | |
208 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
209 vmSymbols::SID vmSymbols::find_sid(Symbol* symbol) { |
0 | 210 // Handle the majority of misses by a bounds check. |
211 // Then, use a binary search over the index. | |
212 // Expected trip count is less than log2_SID_LIMIT, about eight. | |
213 // This is slow but acceptable, given that calls are not | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
214 // dynamically common. (Method*::intrinsic_id has a cache.) |
0 | 215 NOT_PRODUCT(find_sid_calls++); |
216 int min = (int)FIRST_SID, max = (int)SID_LIMIT - 1; | |
217 SID sid = NO_SID, sid1; | |
218 int cmp1; | |
219 sid1 = vm_symbol_index[min]; | |
220 cmp1 = compare_symbol(symbol, symbol_at(sid1)); | |
221 if (cmp1 <= 0) { // before the first | |
222 if (cmp1 == 0) sid = sid1; | |
223 } else { | |
224 sid1 = vm_symbol_index[max]; | |
225 cmp1 = compare_symbol(symbol, symbol_at(sid1)); | |
226 if (cmp1 >= 0) { // after the last | |
227 if (cmp1 == 0) sid = sid1; | |
228 } else { | |
229 // After checking the extremes, do a binary search. | |
230 ++min; --max; // endpoints are done | |
231 int mid = mid_hint; // start at previous success | |
232 while (max >= min) { | |
233 assert(mid >= min && mid <= max, ""); | |
234 NOT_PRODUCT(find_sid_probes++); | |
235 sid1 = vm_symbol_index[mid]; | |
236 cmp1 = compare_symbol(symbol, symbol_at(sid1)); | |
237 if (cmp1 == 0) { | |
238 mid_hint = mid; | |
239 sid = sid1; | |
240 break; | |
241 } | |
242 if (cmp1 < 0) | |
243 max = mid - 1; // symbol < symbol_at(sid) | |
244 else | |
245 min = mid + 1; | |
246 | |
247 // Pick a new probe point: | |
248 mid = (max + min) / 2; | |
249 } | |
250 } | |
251 } | |
252 | |
253 #ifdef ASSERT | |
254 // Perform the exhaustive self-check the first 1000 calls, | |
255 // and every 100 calls thereafter. | |
256 static int find_sid_check_count = -2000; | |
257 if ((uint)++find_sid_check_count > (uint)100) { | |
258 if (find_sid_check_count > 0) find_sid_check_count = 0; | |
259 | |
260 // Make sure this is the right answer, using linear search. | |
261 // (We have already proven that there are no duplicates in the list.) | |
262 SID sid2 = NO_SID; | |
263 for (int index = (int)FIRST_SID; index < (int)SID_LIMIT; index++) { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
264 Symbol* sym2 = symbol_at((SID)index); |
0 | 265 if (sym2 == symbol) { |
266 sid2 = (SID)index; | |
267 break; | |
268 } | |
269 } | |
270 // Unless it's a duplicate, assert that the sids are the same. | |
271 if (_symbols[sid] != _symbols[sid2]) { | |
272 assert(sid == sid2, "binary same as linear search"); | |
273 } | |
274 } | |
275 #endif //ASSERT | |
276 | |
277 return sid; | |
278 } | |
279 | |
2356
72dee110246f
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
2177
diff
changeset
|
280 vmSymbols::SID vmSymbols::find_sid(const char* symbol_name) { |
72dee110246f
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
2177
diff
changeset
|
281 Symbol* symbol = SymbolTable::probe(symbol_name, (int) strlen(symbol_name)); |
72dee110246f
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
2177
diff
changeset
|
282 if (symbol == NULL) return NO_SID; |
72dee110246f
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
2177
diff
changeset
|
283 return find_sid(symbol); |
72dee110246f
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
2177
diff
changeset
|
284 } |
72dee110246f
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
2177
diff
changeset
|
285 |
1133
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
286 static vmIntrinsics::ID wrapper_intrinsic(BasicType type, bool unboxing) { |
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
287 #define TYPE2(type, unboxing) ((int)(type)*2 + ((unboxing) ? 1 : 0)) |
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
288 switch (TYPE2(type, unboxing)) { |
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
289 #define BASIC_TYPE_CASE(type, box, unbox) \ |
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
290 case TYPE2(type, false): return vmIntrinsics::box; \ |
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
291 case TYPE2(type, true): return vmIntrinsics::unbox |
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
292 BASIC_TYPE_CASE(T_BOOLEAN, _Boolean_valueOf, _booleanValue); |
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
293 BASIC_TYPE_CASE(T_BYTE, _Byte_valueOf, _byteValue); |
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
294 BASIC_TYPE_CASE(T_CHAR, _Character_valueOf, _charValue); |
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
295 BASIC_TYPE_CASE(T_SHORT, _Short_valueOf, _shortValue); |
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
296 BASIC_TYPE_CASE(T_INT, _Integer_valueOf, _intValue); |
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
297 BASIC_TYPE_CASE(T_LONG, _Long_valueOf, _longValue); |
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
298 BASIC_TYPE_CASE(T_FLOAT, _Float_valueOf, _floatValue); |
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
299 BASIC_TYPE_CASE(T_DOUBLE, _Double_valueOf, _doubleValue); |
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
300 #undef BASIC_TYPE_CASE |
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
301 } |
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
302 #undef TYPE2 |
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
303 return vmIntrinsics::_none; |
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
304 } |
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
305 |
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
306 vmIntrinsics::ID vmIntrinsics::for_boxing(BasicType type) { |
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
307 return wrapper_intrinsic(type, false); |
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
308 } |
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
309 vmIntrinsics::ID vmIntrinsics::for_unboxing(BasicType type) { |
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
310 return wrapper_intrinsic(type, true); |
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
311 } |
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
312 |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1133
diff
changeset
|
313 vmIntrinsics::ID vmIntrinsics::for_raw_conversion(BasicType src, BasicType dest) { |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1133
diff
changeset
|
314 #define SRC_DEST(s,d) (((int)(s) << 4) + (int)(d)) |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1133
diff
changeset
|
315 switch (SRC_DEST(src, dest)) { |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1133
diff
changeset
|
316 case SRC_DEST(T_INT, T_FLOAT): return vmIntrinsics::_intBitsToFloat; |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1133
diff
changeset
|
317 case SRC_DEST(T_FLOAT, T_INT): return vmIntrinsics::_floatToRawIntBits; |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1133
diff
changeset
|
318 |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1133
diff
changeset
|
319 case SRC_DEST(T_LONG, T_DOUBLE): return vmIntrinsics::_longBitsToDouble; |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1133
diff
changeset
|
320 case SRC_DEST(T_DOUBLE, T_LONG): return vmIntrinsics::_doubleToRawLongBits; |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1133
diff
changeset
|
321 } |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1133
diff
changeset
|
322 #undef SRC_DEST |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1133
diff
changeset
|
323 |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1133
diff
changeset
|
324 return vmIntrinsics::_none; |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1133
diff
changeset
|
325 } |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1133
diff
changeset
|
326 |
0 | 327 |
328 #define VM_INTRINSIC_INITIALIZE(id, klass, name, sig, flags) #id "\0" | |
329 static const char* vm_intrinsic_name_bodies = | |
330 VM_INTRINSICS_DO(VM_INTRINSIC_INITIALIZE, | |
331 VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_ALIAS_IGNORE); | |
332 | |
333 static const char* vm_intrinsic_name_table[vmIntrinsics::ID_LIMIT]; | |
334 | |
335 const char* vmIntrinsics::name_at(vmIntrinsics::ID id) { | |
336 const char** nt = &vm_intrinsic_name_table[0]; | |
337 if (nt[_none] == NULL) { | |
338 char* string = (char*) &vm_intrinsic_name_bodies[0]; | |
339 for (int index = FIRST_ID; index < ID_LIMIT; index++) { | |
340 nt[index] = string; | |
341 string += strlen(string); // skip string body | |
342 string += 1; // skip trailing null | |
343 } | |
344 assert(!strcmp(nt[_hashCode], "_hashCode"), "lined up"); | |
345 nt[_none] = "_none"; | |
346 } | |
347 if ((uint)id < (uint)ID_LIMIT) | |
348 return vm_intrinsic_name_table[(uint)id]; | |
349 else | |
350 return "(unknown intrinsic)"; | |
351 } | |
352 | |
353 // These are flag-matching functions: | |
354 inline bool match_F_R(jshort flags) { | |
355 const int req = 0; | |
356 const int neg = JVM_ACC_STATIC | JVM_ACC_SYNCHRONIZED; | |
357 return (flags & (req | neg)) == req; | |
358 } | |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
196
diff
changeset
|
359 inline bool match_F_Y(jshort flags) { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
196
diff
changeset
|
360 const int req = JVM_ACC_SYNCHRONIZED; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
196
diff
changeset
|
361 const int neg = JVM_ACC_STATIC; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
196
diff
changeset
|
362 return (flags & (req | neg)) == req; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
196
diff
changeset
|
363 } |
0 | 364 inline bool match_F_RN(jshort flags) { |
365 const int req = JVM_ACC_NATIVE; | |
366 const int neg = JVM_ACC_STATIC | JVM_ACC_SYNCHRONIZED; | |
367 return (flags & (req | neg)) == req; | |
368 } | |
369 inline bool match_F_S(jshort flags) { | |
370 const int req = JVM_ACC_STATIC; | |
371 const int neg = JVM_ACC_SYNCHRONIZED; | |
372 return (flags & (req | neg)) == req; | |
373 } | |
374 inline bool match_F_SN(jshort flags) { | |
375 const int req = JVM_ACC_STATIC | JVM_ACC_NATIVE; | |
376 const int neg = JVM_ACC_SYNCHRONIZED; | |
377 return (flags & (req | neg)) == req; | |
378 } | |
45
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
379 inline bool match_F_RNY(jshort flags) { |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
380 const int req = JVM_ACC_NATIVE | JVM_ACC_SYNCHRONIZED; |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
381 const int neg = JVM_ACC_STATIC; |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
382 return (flags & (req | neg)) == req; |
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
383 } |
0 | 384 |
385 // These are for forming case labels: | |
1133
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
386 #define ID3(x, y, z) (( jlong)(z) + \ |
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
387 ((jlong)(y) << vmSymbols::log2_SID_LIMIT) + \ |
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
388 ((jlong)(x) << (2*vmSymbols::log2_SID_LIMIT)) ) |
0 | 389 #define SID_ENUM(n) vmSymbols::VM_SYMBOL_ENUM_NAME(n) |
390 | |
1133
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
391 vmIntrinsics::ID vmIntrinsics::find_id_impl(vmSymbols::SID holder, |
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
392 vmSymbols::SID name, |
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
393 vmSymbols::SID sig, |
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
394 jshort flags) { |
0 | 395 assert((int)vmSymbols::SID_LIMIT <= (1<<vmSymbols::log2_SID_LIMIT), "must fit"); |
396 | |
397 // Let the C compiler build the decision tree. | |
398 | |
399 #define VM_INTRINSIC_CASE(id, klass, name, sig, fcode) \ | |
400 case ID3(SID_ENUM(klass), SID_ENUM(name), SID_ENUM(sig)): \ | |
401 if (!match_##fcode(flags)) break; \ | |
402 return id; | |
403 | |
404 switch (ID3(holder, name, sig)) { | |
405 VM_INTRINSICS_DO(VM_INTRINSIC_CASE, | |
406 VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_ALIAS_IGNORE); | |
407 } | |
408 return vmIntrinsics::_none; | |
409 | |
410 #undef VM_INTRINSIC_CASE | |
411 } | |
412 | |
413 | |
414 const char* vmIntrinsics::short_name_as_C_string(vmIntrinsics::ID id, char* buf, int buflen) { | |
415 const char* str = name_at(id); | |
416 #ifndef PRODUCT | |
417 const char* kname = vmSymbols::name_for(class_for(id)); | |
418 const char* mname = vmSymbols::name_for(name_for(id)); | |
419 const char* sname = vmSymbols::name_for(signature_for(id)); | |
420 const char* fname = ""; | |
421 switch (flags_for(id)) { | |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
196
diff
changeset
|
422 case F_Y: fname = "synchronized "; break; |
0 | 423 case F_RN: fname = "native "; break; |
424 case F_SN: fname = "native static "; break; | |
425 case F_S: fname = "static "; break; | |
45
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
426 case F_RNY:fname = "native synchronized "; break; |
0 | 427 } |
428 const char* kptr = strrchr(kname, '/'); | |
429 if (kptr != NULL) kname = kptr + 1; | |
430 int len = jio_snprintf(buf, buflen, "%s: %s%s.%s%s", | |
431 str, fname, kname, mname, sname); | |
432 if (len < buflen) | |
433 str = buf; | |
434 #endif //PRODUCT | |
435 return str; | |
436 } | |
437 | |
438 | |
1133
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
439 // These are to get information about intrinsics. |
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
440 |
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
441 #define ID4(x, y, z, f) ((ID3(x, y, z) << vmIntrinsics::log2_FLAG_LIMIT) | (jlong) (f)) |
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
442 |
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
443 static const jlong intrinsic_info_array[vmIntrinsics::ID_LIMIT+1] = { |
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
444 #define VM_INTRINSIC_INFO(ignore_id, klass, name, sig, fcode) \ |
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
445 ID4(SID_ENUM(klass), SID_ENUM(name), SID_ENUM(sig), vmIntrinsics::fcode), |
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
446 |
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
447 0, VM_INTRINSICS_DO(VM_INTRINSIC_INFO, |
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
448 VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_ALIAS_IGNORE) |
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
449 0 |
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
450 #undef VM_INTRINSIC_INFO |
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
451 }; |
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
452 |
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
453 inline jlong intrinsic_info(vmIntrinsics::ID id) { |
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
454 return intrinsic_info_array[vmIntrinsics::ID_from((int)id)]; |
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
455 } |
0 | 456 |
457 vmSymbols::SID vmIntrinsics::class_for(vmIntrinsics::ID id) { | |
1133
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
458 jlong info = intrinsic_info(id); |
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
459 int shift = 2*vmSymbols::log2_SID_LIMIT + log2_FLAG_LIMIT, mask = right_n_bits(vmSymbols::log2_SID_LIMIT); |
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
460 assert(((ID4(1021,1022,1023,15) >> shift) & mask) == 1021, ""); |
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
461 return vmSymbols::SID( (info >> shift) & mask ); |
0 | 462 } |
463 | |
464 vmSymbols::SID vmIntrinsics::name_for(vmIntrinsics::ID id) { | |
1133
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
465 jlong info = intrinsic_info(id); |
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
466 int shift = vmSymbols::log2_SID_LIMIT + log2_FLAG_LIMIT, mask = right_n_bits(vmSymbols::log2_SID_LIMIT); |
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
467 assert(((ID4(1021,1022,1023,15) >> shift) & mask) == 1022, ""); |
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
468 return vmSymbols::SID( (info >> shift) & mask ); |
0 | 469 } |
470 | |
471 vmSymbols::SID vmIntrinsics::signature_for(vmIntrinsics::ID id) { | |
1133
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
472 jlong info = intrinsic_info(id); |
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
473 int shift = log2_FLAG_LIMIT, mask = right_n_bits(vmSymbols::log2_SID_LIMIT); |
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
474 assert(((ID4(1021,1022,1023,15) >> shift) & mask) == 1023, ""); |
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
475 return vmSymbols::SID( (info >> shift) & mask ); |
0 | 476 } |
477 | |
478 vmIntrinsics::Flags vmIntrinsics::flags_for(vmIntrinsics::ID id) { | |
1133
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
479 jlong info = intrinsic_info(id); |
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
480 int shift = 0, mask = right_n_bits(log2_FLAG_LIMIT); |
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
481 assert(((ID4(1021,1022,1023,15) >> shift) & mask) == 15, ""); |
aa62b9388fce
6894206: JVM needs a way to traverse method handle structures
twisti
parents:
1080
diff
changeset
|
482 return Flags( (info >> shift) & mask ); |
0 | 483 } |
484 | |
485 | |
486 #ifndef PRODUCT | |
487 // verify_method performs an extra check on a matched intrinsic method | |
488 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
489 static bool match_method(Method* m, Symbol* n, Symbol* s) { |
0 | 490 return (m->name() == n && |
491 m->signature() == s); | |
492 } | |
493 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
494 static vmIntrinsics::ID match_method_with_klass(Method* m, Symbol* mk) { |
0 | 495 #define VM_INTRINSIC_MATCH(id, klassname, namepart, sigpart, flags) \ |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
496 { Symbol* k = vmSymbols::klassname(); \ |
0 | 497 if (mk == k) { \ |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
498 Symbol* n = vmSymbols::namepart(); \ |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
499 Symbol* s = vmSymbols::sigpart(); \ |
0 | 500 if (match_method(m, n, s)) \ |
501 return vmIntrinsics::id; \ | |
502 } } | |
503 VM_INTRINSICS_DO(VM_INTRINSIC_MATCH, | |
504 VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_ALIAS_IGNORE); | |
505 return vmIntrinsics::_none; | |
506 #undef VM_INTRINSIC_MATCH | |
507 } | |
508 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
509 void vmIntrinsics::verify_method(ID actual_id, Method* m) { |
6940
18fb7da42534
8000725: NPG: method_holder() and pool_holder() and pool_holder field should be InstanceKlass
coleenp
parents:
6847
diff
changeset
|
510 Symbol* mk = m->method_holder()->name(); |
0 | 511 ID declared_id = match_method_with_klass(m, mk); |
512 | |
513 if (declared_id == actual_id) return; // success | |
514 | |
515 if (declared_id == _none && actual_id != _none && mk == vmSymbols::java_lang_StrictMath()) { | |
516 // Here are a few special cases in StrictMath not declared in vmSymbols.hpp. | |
517 switch (actual_id) { | |
518 case _min: | |
519 case _max: | |
520 case _dsqrt: | |
521 declared_id = match_method_with_klass(m, vmSymbols::java_lang_Math()); | |
522 if (declared_id == actual_id) return; // acceptable alias | |
523 break; | |
524 } | |
525 } | |
526 | |
527 const char* declared_name = name_at(declared_id); | |
528 const char* actual_name = name_at(actual_id); | |
529 methodHandle mh = m; | |
530 m = NULL; | |
531 ttyLocker ttyl; | |
532 if (xtty != NULL) { | |
533 xtty->begin_elem("intrinsic_misdeclared actual='%s' declared='%s'", | |
534 actual_name, declared_name); | |
535 xtty->method(mh); | |
536 xtty->end_elem(""); | |
537 } | |
538 if (PrintMiscellaneous && (WizardMode || Verbose)) { | |
539 tty->print_cr("*** misidentified method; %s(%d) should be %s(%d):", | |
540 declared_name, declared_id, actual_name, actual_id); | |
45
48a3fa21394b
6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents:
0
diff
changeset
|
541 mh()->print_short_name(tty); |
0 | 542 tty->cr(); |
543 } | |
544 } | |
545 #endif //PRODUCT |