Mercurial > hg > graal-compiler
annotate src/share/vm/interpreter/rewriter.cpp @ 3992:d1bdeef3e3e2
7098282: G1: assert(interval >= 0) failed: Sanity check, referencePolicy.cpp: 76
Summary: There is a race between one thread successfully forwarding and copying the klass mirror for the SoftReference class (including the static master clock) and another thread attempting to use the master clock while attempting to discover a soft reference object. Maintain a shadow copy of the soft reference master clock and use the shadow during reference discovery and reference processing.
Reviewed-by: tonyp, brutisso, ysr
author | johnc |
---|---|
date | Wed, 12 Oct 2011 10:25:51 -0700 |
parents | d3b9f2be46ab |
children | be4ca325525a 1d7922586cf6 |
rev | line source |
---|---|
0 | 1 /* |
2142 | 2 * Copyright (c) 1998, 2011, 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 "interpreter/bytecodes.hpp" | |
27 #include "interpreter/interpreter.hpp" | |
28 #include "interpreter/rewriter.hpp" | |
29 #include "memory/gcLocker.hpp" | |
30 #include "memory/oopFactory.hpp" | |
31 #include "memory/resourceArea.hpp" | |
32 #include "oops/generateOopMap.hpp" | |
33 #include "oops/objArrayOop.hpp" | |
34 #include "oops/oop.inline.hpp" | |
35 #include "prims/methodComparator.hpp" | |
0 | 36 |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
37 // Computes a CPC map (new_index -> original_index) for constant pool entries |
0 | 38 // that are referred to by the interpreter at runtime via the constant pool cache. |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
39 // Also computes a CP map (original_index -> new_index). |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
40 // Marks entries in CP which require additional processing. |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
41 void Rewriter::compute_index_maps() { |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
42 const int length = _pool->length(); |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
43 init_cp_map(length); |
1660
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1602
diff
changeset
|
44 jint tag_mask = 0; |
0 | 45 for (int i = 0; i < length; i++) { |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
46 int tag = _pool->tag_at(i).value(); |
1660
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1602
diff
changeset
|
47 tag_mask |= (1 << tag); |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
48 switch (tag) { |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
49 case JVM_CONSTANT_InterfaceMethodref: |
0 | 50 case JVM_CONSTANT_Fieldref : // fall through |
51 case JVM_CONSTANT_Methodref : // fall through | |
1602 | 52 case JVM_CONSTANT_MethodHandle : // fall through |
53 case JVM_CONSTANT_MethodType : // fall through | |
1660
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1602
diff
changeset
|
54 case JVM_CONSTANT_InvokeDynamic : // fall through |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
55 add_cp_cache_entry(i); |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
56 break; |
0 | 57 } |
58 } | |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
59 |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
60 guarantee((int)_cp_cache_map.length()-1 <= (int)((u2)-1), |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
61 "all cp cache indexes fit in a u2"); |
1660
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1602
diff
changeset
|
62 |
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1602
diff
changeset
|
63 _have_invoke_dynamic = ((tag_mask & (1 << JVM_CONSTANT_InvokeDynamic)) != 0); |
0 | 64 } |
65 | |
3748 | 66 // Unrewrite the bytecodes if an error occurs. |
67 void Rewriter::restore_bytecodes() { | |
68 int len = _methods->length(); | |
69 | |
70 for (int i = len-1; i >= 0; i--) { | |
71 methodOop method = (methodOop)_methods->obj_at(i); | |
72 scan_method(method, true); | |
73 } | |
74 } | |
0 | 75 |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
76 // Creates a constant pool cache given a CPC map |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
77 void Rewriter::make_constant_pool_cache(TRAPS) { |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
78 const int length = _cp_cache_map.length(); |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
79 constantPoolCacheOop cache = |
2226
c5a923563727
6912621: iCMS: Error: assert(_markBitMap.isMarked(addr + 1),"Missing Printezis bit?")
ysr
parents:
2142
diff
changeset
|
80 oopFactory::new_constantPoolCache(length, CHECK); |
c5a923563727
6912621: iCMS: Error: assert(_markBitMap.isMarked(addr + 1),"Missing Printezis bit?")
ysr
parents:
2142
diff
changeset
|
81 No_Safepoint_Verifier nsv; |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
82 cache->initialize(_cp_cache_map); |
1660
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1602
diff
changeset
|
83 |
2011
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1972
diff
changeset
|
84 // Don't bother with the next pass if there is no JVM_CONSTANT_InvokeDynamic. |
1660
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1602
diff
changeset
|
85 if (_have_invoke_dynamic) { |
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1602
diff
changeset
|
86 for (int i = 0; i < length; i++) { |
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1602
diff
changeset
|
87 int pool_index = cp_cache_entry_pool_index(i); |
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1602
diff
changeset
|
88 if (pool_index >= 0 && |
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1602
diff
changeset
|
89 _pool->tag_at(pool_index).is_invoke_dynamic()) { |
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1602
diff
changeset
|
90 int bsm_index = _pool->invoke_dynamic_bootstrap_method_ref_index_at(pool_index); |
2460 | 91 assert(_pool->tag_at(bsm_index).is_method_handle(), "must be a MH constant"); |
92 // There is a CP cache entry holding the BSM for these calls. | |
93 int bsm_cache_index = cp_entry_to_cp_cache(bsm_index); | |
94 cache->entry_at(i)->initialize_bootstrap_method_index_in_cache(bsm_cache_index); | |
1660
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1602
diff
changeset
|
95 } |
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1602
diff
changeset
|
96 } |
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1602
diff
changeset
|
97 } |
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1602
diff
changeset
|
98 |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
99 _pool->set_cache(cache); |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
100 cache->set_constant_pool(_pool()); |
0 | 101 } |
102 | |
103 | |
104 | |
105 // The new finalization semantics says that registration of | |
106 // finalizable objects must be performed on successful return from the | |
107 // Object.<init> constructor. We could implement this trivially if | |
108 // <init> were never rewritten but since JVMTI allows this to occur, a | |
109 // more complicated solution is required. A special return bytecode | |
110 // is used only by Object.<init> to signal the finalization | |
111 // registration point. Additionally local 0 must be preserved so it's | |
112 // available to pass to the registration function. For simplicty we | |
113 // require that local 0 is never overwritten so it's available as an | |
114 // argument for registration. | |
115 | |
116 void Rewriter::rewrite_Object_init(methodHandle method, TRAPS) { | |
117 RawBytecodeStream bcs(method); | |
118 while (!bcs.is_last_bytecode()) { | |
119 Bytecodes::Code opcode = bcs.raw_next(); | |
120 switch (opcode) { | |
121 case Bytecodes::_return: *bcs.bcp() = Bytecodes::_return_register_finalizer; break; | |
122 | |
123 case Bytecodes::_istore: | |
124 case Bytecodes::_lstore: | |
125 case Bytecodes::_fstore: | |
126 case Bytecodes::_dstore: | |
127 case Bytecodes::_astore: | |
128 if (bcs.get_index() != 0) continue; | |
129 | |
130 // fall through | |
131 case Bytecodes::_istore_0: | |
132 case Bytecodes::_lstore_0: | |
133 case Bytecodes::_fstore_0: | |
134 case Bytecodes::_dstore_0: | |
135 case Bytecodes::_astore_0: | |
136 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), | |
137 "can't overwrite local 0 in Object.<init>"); | |
138 break; | |
139 } | |
140 } | |
141 } | |
142 | |
143 | |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
144 // Rewrite a classfile-order CP index into a native-order CPC index. |
3748 | 145 void Rewriter::rewrite_member_reference(address bcp, int offset, bool reverse) { |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
146 address p = bcp + offset; |
3748 | 147 if (!reverse) { |
148 int cp_index = Bytes::get_Java_u2(p); | |
149 int cache_index = cp_entry_to_cp_cache(cp_index); | |
150 Bytes::put_native_u2(p, cache_index); | |
151 } else { | |
152 int cache_index = Bytes::get_native_u2(p); | |
153 int pool_index = cp_cache_entry_pool_index(cache_index); | |
154 Bytes::put_Java_u2(p, pool_index); | |
155 } | |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
156 } |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
157 |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
158 |
3748 | 159 void Rewriter::rewrite_invokedynamic(address bcp, int offset, bool reverse) { |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
160 address p = bcp + offset; |
3748 | 161 assert(p[-1] == Bytecodes::_invokedynamic, "not invokedynamic bytecode"); |
162 if (!reverse) { | |
163 int cp_index = Bytes::get_Java_u2(p); | |
164 int cpc = maybe_add_cp_cache_entry(cp_index); // add lazily | |
165 int cpc2 = add_secondary_cp_cache_entry(cpc); | |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
166 |
3748 | 167 // Replace the trailing four bytes with a CPC index for the dynamic |
168 // call site. Unlike other CPC entries, there is one per bytecode, | |
169 // not just one per distinct CP entry. In other words, the | |
170 // CPC-to-CP relation is many-to-one for invokedynamic entries. | |
171 // This means we must use a larger index size than u2 to address | |
172 // all these entries. That is the main reason invokedynamic | |
173 // must have a five-byte instruction format. (Of course, other JVM | |
174 // implementations can use the bytes for other purposes.) | |
175 Bytes::put_native_u4(p, constantPoolCacheOopDesc::encode_secondary_index(cpc2)); | |
176 // Note: We use native_u4 format exclusively for 4-byte indexes. | |
177 } else { | |
178 int cache_index = constantPoolCacheOopDesc::decode_secondary_index( | |
179 Bytes::get_native_u4(p)); | |
180 int secondary_index = cp_cache_secondary_entry_main_index(cache_index); | |
181 int pool_index = cp_cache_entry_pool_index(secondary_index); | |
182 assert(_pool->tag_at(pool_index).is_invoke_dynamic(), "wrong index"); | |
183 // zero out 4 bytes | |
184 Bytes::put_Java_u4(p, 0); | |
185 Bytes::put_Java_u2(p, pool_index); | |
186 } | |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
187 } |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
188 |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
189 |
1602 | 190 // Rewrite some ldc bytecodes to _fast_aldc |
3748 | 191 void Rewriter::maybe_rewrite_ldc(address bcp, int offset, bool is_wide, |
192 bool reverse) { | |
193 if (!reverse) { | |
194 assert((*bcp) == (is_wide ? Bytecodes::_ldc_w : Bytecodes::_ldc), "not ldc bytecode"); | |
195 address p = bcp + offset; | |
196 int cp_index = is_wide ? Bytes::get_Java_u2(p) : (u1)(*p); | |
197 constantTag tag = _pool->tag_at(cp_index).value(); | |
198 if (tag.is_method_handle() || tag.is_method_type()) { | |
199 int cache_index = cp_entry_to_cp_cache(cp_index); | |
200 if (is_wide) { | |
201 (*bcp) = Bytecodes::_fast_aldc_w; | |
202 assert(cache_index == (u2)cache_index, "index overflow"); | |
203 Bytes::put_native_u2(p, cache_index); | |
204 } else { | |
205 (*bcp) = Bytecodes::_fast_aldc; | |
206 assert(cache_index == (u1)cache_index, "index overflow"); | |
207 (*p) = (u1)cache_index; | |
208 } | |
209 } | |
210 } else { | |
211 Bytecodes::Code rewritten_bc = | |
212 (is_wide ? Bytecodes::_fast_aldc_w : Bytecodes::_fast_aldc); | |
213 if ((*bcp) == rewritten_bc) { | |
214 address p = bcp + offset; | |
215 int cache_index = is_wide ? Bytes::get_native_u2(p) : (u1)(*p); | |
216 int pool_index = cp_cache_entry_pool_index(cache_index); | |
217 if (is_wide) { | |
218 (*bcp) = Bytecodes::_ldc_w; | |
219 assert(pool_index == (u2)pool_index, "index overflow"); | |
220 Bytes::put_Java_u2(p, pool_index); | |
221 } else { | |
222 (*bcp) = Bytecodes::_ldc; | |
223 assert(pool_index == (u1)pool_index, "index overflow"); | |
224 (*p) = (u1)pool_index; | |
225 } | |
1602 | 226 } |
227 } | |
228 } | |
229 | |
230 | |
0 | 231 // Rewrites a method given the index_map information |
3748 | 232 void Rewriter::scan_method(methodOop method, bool reverse) { |
0 | 233 |
234 int nof_jsrs = 0; | |
235 bool has_monitor_bytecodes = false; | |
236 | |
237 { | |
238 // We cannot tolerate a GC in this block, because we've | |
239 // cached the bytecodes in 'code_base'. If the methodOop | |
240 // moves, the bytecodes will also move. | |
241 No_Safepoint_Verifier nsv; | |
242 Bytecodes::Code c; | |
243 | |
244 // Bytecodes and their length | |
245 const address code_base = method->code_base(); | |
246 const int code_length = method->code_size(); | |
247 | |
248 int bc_length; | |
249 for (int bci = 0; bci < code_length; bci += bc_length) { | |
250 address bcp = code_base + bci; | |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
251 int prefix_length = 0; |
0 | 252 c = (Bytecodes::Code)(*bcp); |
253 | |
254 // Since we have the code, see if we can get the length | |
255 // directly. Some more complicated bytecodes will report | |
256 // a length of zero, meaning we need to make another method | |
257 // call to calculate the length. | |
258 bc_length = Bytecodes::length_for(c); | |
259 if (bc_length == 0) { | |
2142 | 260 bc_length = Bytecodes::length_at(method, bcp); |
0 | 261 |
262 // length_at will put us at the bytecode after the one modified | |
263 // by 'wide'. We don't currently examine any of the bytecodes | |
264 // modified by wide, but in case we do in the future... | |
265 if (c == Bytecodes::_wide) { | |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
266 prefix_length = 1; |
0 | 267 c = (Bytecodes::Code)bcp[1]; |
268 } | |
269 } | |
270 | |
271 assert(bc_length != 0, "impossible bytecode length"); | |
272 | |
273 switch (c) { | |
274 case Bytecodes::_lookupswitch : { | |
275 #ifndef CC_INTERP | |
2142 | 276 Bytecode_lookupswitch bc(method, bcp); |
1565 | 277 (*bcp) = ( |
2142 | 278 bc.number_of_pairs() < BinarySwitchThreshold |
0 | 279 ? Bytecodes::_fast_linearswitch |
280 : Bytecodes::_fast_binaryswitch | |
281 ); | |
282 #endif | |
283 break; | |
284 } | |
3748 | 285 case Bytecodes::_fast_linearswitch: |
286 case Bytecodes::_fast_binaryswitch: { | |
287 #ifndef CC_INTERP | |
288 (*bcp) = Bytecodes::_lookupswitch; | |
289 #endif | |
290 break; | |
291 } | |
0 | 292 case Bytecodes::_getstatic : // fall through |
293 case Bytecodes::_putstatic : // fall through | |
294 case Bytecodes::_getfield : // fall through | |
295 case Bytecodes::_putfield : // fall through | |
296 case Bytecodes::_invokevirtual : // fall through | |
297 case Bytecodes::_invokespecial : // fall through | |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
298 case Bytecodes::_invokestatic : |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
299 case Bytecodes::_invokeinterface: |
3748 | 300 rewrite_member_reference(bcp, prefix_length+1, reverse); |
0 | 301 break; |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
302 case Bytecodes::_invokedynamic: |
3748 | 303 rewrite_invokedynamic(bcp, prefix_length+1, reverse); |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
304 break; |
1602 | 305 case Bytecodes::_ldc: |
3748 | 306 case Bytecodes::_fast_aldc: |
307 maybe_rewrite_ldc(bcp, prefix_length+1, false, reverse); | |
1602 | 308 break; |
309 case Bytecodes::_ldc_w: | |
3748 | 310 case Bytecodes::_fast_aldc_w: |
311 maybe_rewrite_ldc(bcp, prefix_length+1, true, reverse); | |
1602 | 312 break; |
0 | 313 case Bytecodes::_jsr : // fall through |
314 case Bytecodes::_jsr_w : nof_jsrs++; break; | |
315 case Bytecodes::_monitorenter : // fall through | |
316 case Bytecodes::_monitorexit : has_monitor_bytecodes = true; break; | |
317 } | |
318 } | |
319 } | |
320 | |
321 // Update access flags | |
322 if (has_monitor_bytecodes) { | |
323 method->set_has_monitor_bytecodes(); | |
324 } | |
325 | |
326 // The present of a jsr bytecode implies that the method might potentially | |
327 // have to be rewritten, so we run the oopMapGenerator on the method | |
328 if (nof_jsrs > 0) { | |
329 method->set_has_jsrs(); | |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
330 // Second pass will revisit this method. |
3748 | 331 assert(method->has_jsrs(), "didn't we just set this?"); |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
332 } |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
333 } |
0 | 334 |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
335 // After constant pool is created, revisit methods containing jsrs. |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
336 methodHandle Rewriter::rewrite_jsrs(methodHandle method, TRAPS) { |
3748 | 337 ResourceMark rm(THREAD); |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
338 ResolveOopMapConflicts romc(method); |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
339 methodHandle original_method = method; |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
340 method = romc.do_potential_rewrite(CHECK_(methodHandle())); |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
341 if (method() != original_method()) { |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
342 // Insert invalid bytecode into original methodOop and set |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
343 // interpreter entrypoint, so that a executing this method |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
344 // will manifest itself in an easy recognizable form. |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
345 address bcp = original_method->bcp_from(0); |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
346 *bcp = (u1)Bytecodes::_shouldnotreachhere; |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
347 int kind = Interpreter::method_kind(original_method); |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
348 original_method->set_interpreter_kind(kind); |
0 | 349 } |
350 | |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
351 // Update monitor matching info. |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
352 if (romc.monitor_safe()) { |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
353 method->set_guaranteed_monitor_matching(); |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
354 } |
0 | 355 |
356 return method; | |
357 } | |
358 | |
359 void Rewriter::rewrite(instanceKlassHandle klass, TRAPS) { | |
360 ResourceMark rm(THREAD); | |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1059
diff
changeset
|
361 Rewriter rw(klass, klass->constants(), klass->methods(), CHECK); |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
362 // (That's all, folks.) |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
363 } |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
364 |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1059
diff
changeset
|
365 |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1059
diff
changeset
|
366 void Rewriter::rewrite(instanceKlassHandle klass, constantPoolHandle cpool, objArrayHandle methods, TRAPS) { |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1059
diff
changeset
|
367 ResourceMark rm(THREAD); |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1059
diff
changeset
|
368 Rewriter rw(klass, cpool, methods, CHECK); |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1059
diff
changeset
|
369 // (That's all, folks.) |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1059
diff
changeset
|
370 } |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1059
diff
changeset
|
371 |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1059
diff
changeset
|
372 |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1059
diff
changeset
|
373 Rewriter::Rewriter(instanceKlassHandle klass, constantPoolHandle cpool, objArrayHandle methods, TRAPS) |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
374 : _klass(klass), |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1059
diff
changeset
|
375 _pool(cpool), |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1059
diff
changeset
|
376 _methods(methods) |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
377 { |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
378 assert(_pool->cache() == NULL, "constant pool cache must not be set yet"); |
0 | 379 |
380 // determine index maps for methodOop rewriting | |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
381 compute_index_maps(); |
0 | 382 |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
383 if (RegisterFinalizersAtInit && _klass->name() == vmSymbols::java_lang_Object()) { |
856
75596850f863
6862576: vmIntrinsics needs cleanup in order to support JSR 292 intrinsics
jrose
parents:
726
diff
changeset
|
384 bool did_rewrite = false; |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
385 int i = _methods->length(); |
0 | 386 while (i-- > 0) { |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
387 methodOop method = (methodOop)_methods->obj_at(i); |
0 | 388 if (method->intrinsic_id() == vmIntrinsics::_Object_init) { |
389 // rewrite the return bytecodes of Object.<init> to register the | |
390 // object for finalization if needed. | |
391 methodHandle m(THREAD, method); | |
392 rewrite_Object_init(m, CHECK); | |
856
75596850f863
6862576: vmIntrinsics needs cleanup in order to support JSR 292 intrinsics
jrose
parents:
726
diff
changeset
|
393 did_rewrite = true; |
0 | 394 break; |
395 } | |
396 } | |
856
75596850f863
6862576: vmIntrinsics needs cleanup in order to support JSR 292 intrinsics
jrose
parents:
726
diff
changeset
|
397 assert(did_rewrite, "must find Object::<init> to rewrite it"); |
0 | 398 } |
399 | |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
400 // rewrite methods, in two passes |
3748 | 401 int len = _methods->length(); |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
402 |
3748 | 403 for (int i = len-1; i >= 0; i--) { |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
404 methodOop method = (methodOop)_methods->obj_at(i); |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
405 scan_method(method); |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
406 } |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
407 |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
408 // allocate constant pool cache, now that we've seen all the bytecodes |
3748 | 409 make_constant_pool_cache(THREAD); |
410 | |
411 // Restore bytecodes to their unrewritten state if there are exceptions | |
412 // rewriting bytecodes or allocating the cpCache | |
413 if (HAS_PENDING_EXCEPTION) { | |
414 restore_bytecodes(); | |
415 return; | |
416 } | |
417 } | |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
418 |
3748 | 419 // Relocate jsr/rets in a method. This can't be done with the rewriter |
420 // stage because it can throw other exceptions, leaving the bytecodes | |
421 // pointing at constant pool cache entries. | |
422 // Link and check jvmti dependencies while we're iterating over the methods. | |
423 // JSR292 code calls with a different set of methods, so two entry points. | |
424 void Rewriter::relocate_and_link(instanceKlassHandle this_oop, TRAPS) { | |
425 objArrayHandle methods(THREAD, this_oop->methods()); | |
426 relocate_and_link(this_oop, methods, THREAD); | |
427 } | |
428 | |
429 void Rewriter::relocate_and_link(instanceKlassHandle this_oop, | |
430 objArrayHandle methods, TRAPS) { | |
431 int len = methods->length(); | |
432 for (int i = len-1; i >= 0; i--) { | |
433 methodHandle m(THREAD, (methodOop)methods->obj_at(i)); | |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
434 |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
435 if (m->has_jsrs()) { |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
436 m = rewrite_jsrs(m, CHECK); |
0 | 437 // Method might have gotten rewritten. |
3748 | 438 methods->obj_at_put(i, m()); |
0 | 439 } |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
440 |
3748 | 441 // Set up method entry points for compiler and interpreter . |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
579
diff
changeset
|
442 m->link_method(m, CHECK); |
1574 | 443 |
3748 | 444 // This is for JVMTI and unrelated to relocator but the last thing we do |
1574 | 445 #ifdef ASSERT |
446 if (StressMethodComparator) { | |
447 static int nmc = 0; | |
448 for (int j = i; j >= 0 && j >= i-4; j--) { | |
449 if ((++nmc % 1000) == 0) tty->print_cr("Have run MethodComparator %d times...", nmc); | |
3748 | 450 bool z = MethodComparator::methods_EMCP(m(), |
451 (methodOop)methods->obj_at(j)); | |
1574 | 452 if (j == i && !z) { |
453 tty->print("MethodComparator FAIL: "); m->print(); m->print_codes(); | |
454 assert(z, "method must compare equal to itself"); | |
455 } | |
456 } | |
457 } | |
458 #endif //ASSERT | |
0 | 459 } |
460 } |