1 /*
2 * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved.
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 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "cds/aotMetaspace.hpp"
26 #include "cds/cdsConfig.hpp"
27 #include "classfile/vmClasses.hpp"
28 #include "interpreter/bytecodes.hpp"
29 #include "interpreter/bytecodeStream.hpp"
30 #include "interpreter/interpreter.hpp"
31 #include "interpreter/rewriter.hpp"
32 #include "memory/metadataFactory.hpp"
33 #include "memory/resourceArea.hpp"
34 #include "oops/generateOopMap.hpp"
35 #include "oops/resolvedFieldEntry.hpp"
36 #include "oops/resolvedIndyEntry.hpp"
37 #include "oops/resolvedMethodEntry.hpp"
38 #include "prims/methodHandles.hpp"
39 #include "runtime/fieldDescriptor.inline.hpp"
40 #include "runtime/handles.inline.hpp"
41 #include "utilities/checkedCast.hpp"
42
43 // Computes a CPC map (new_index -> original_index) for constant pool entries
44 // that are referred to by the interpreter at runtime via the constant pool cache.
45 // Also computes a CP map (original_index -> new_index).
46 // Marks entries in CP which require additional processing.
47 void Rewriter::compute_index_maps() {
48 const int length = _pool->length();
49 init_maps(length);
50 bool saw_mh_symbol = false;
51 for (int i = 0; i < length; i++) {
52 int tag = _pool->tag_at(i).value();
53 switch (tag) {
54 case JVM_CONSTANT_Fieldref :
55 _cp_map.at_put(i, _field_entry_index);
56 _field_entry_index++;
57 _initialized_field_entries.push(ResolvedFieldEntry((u2)i));
58 break;
59 case JVM_CONSTANT_InterfaceMethodref: // fall through
60 case JVM_CONSTANT_Methodref :
61 _cp_map.at_put(i, _method_entry_index);
62 _method_entry_index++;
63 _initialized_method_entries.push(ResolvedMethodEntry((u2)i));
64 break;
65 case JVM_CONSTANT_Dynamic:
66 assert(_pool->has_dynamic_constant(), "constant pool's _has_dynamic_constant flag not set");
67 add_resolved_references_entry(i);
68 break;
69 case JVM_CONSTANT_String : // fall through
70 case JVM_CONSTANT_MethodHandle : // fall through
71 case JVM_CONSTANT_MethodType : // fall through
72 add_resolved_references_entry(i);
73 break;
74 case JVM_CONSTANT_Utf8:
75 if (_pool->symbol_at(i) == vmSymbols::java_lang_invoke_MethodHandle() ||
76 _pool->symbol_at(i) == vmSymbols::java_lang_invoke_VarHandle()) {
77 saw_mh_symbol = true;
78 }
79 break;
80 }
81 }
82
83 // Record limits of resolved reference map for constant pool cache indices
84 record_map_limits();
85
86 guarantee(_initialized_field_entries.length() - 1 <= (int)((u2)-1), "All resolved field indices fit in a u2");
87 guarantee(_initialized_method_entries.length() - 1 <= (int)((u2)-1), "All resolved method indices fit in a u2");
88
89 if (saw_mh_symbol) {
90 _method_handle_invokers.at_grow(length, 0);
91 }
92 }
93
94 // Unrewrite the bytecodes if an error occurs.
95 void Rewriter::restore_bytecodes(Thread* thread) {
96 int len = _methods->length();
97 bool invokespecial_error = false;
98
99 for (int i = len-1; i >= 0; i--) {
100 Method* method = _methods->at(i);
101 scan_method(thread, method, true, &invokespecial_error);
102 assert(!invokespecial_error, "reversing should not get an invokespecial error");
103 }
104 }
105
106 // Creates a constant pool cache given a CPC map
107 void Rewriter::make_constant_pool_cache(TRAPS) {
108 ClassLoaderData* loader_data = _pool->pool_holder()->class_loader_data();
109 assert(_field_entry_index == _initialized_field_entries.length(), "Field entry size mismatch");
110 assert(_method_entry_index == _initialized_method_entries.length(), "Method entry size mismatch");
111 ConstantPoolCache* cache =
112 ConstantPoolCache::allocate(loader_data, _invokedynamic_references_map,
113 _initialized_indy_entries, _initialized_field_entries, _initialized_method_entries,
114 CHECK);
115
116 // initialize object cache in constant pool
117 _pool->set_cache(cache);
118 cache->set_constant_pool(_pool());
119
120 // _resolved_references is stored in pool->cache(), so need to be done after
121 // the above lines.
122 _pool->initialize_resolved_references(loader_data, _resolved_references_map,
123 _resolved_reference_limit,
124 THREAD);
125 #if INCLUDE_CDS
126 if (!HAS_PENDING_EXCEPTION && CDSConfig::is_dumping_archive()) {
127 if (_pool->pool_holder()->in_aot_cache()) {
128 assert(CDSConfig::is_dumping_dynamic_archive(), "must be");
129 // We are linking a shared class from the base archive. This
130 // class won't be written into the dynamic archive, so there's no
131 // need to save its CpCaches.
132 }
133 }
134 #endif
135
136 // Clean up constant pool cache if initialize_resolved_references() failed.
137 if (HAS_PENDING_EXCEPTION) {
138 MetadataFactory::free_metadata(loader_data, cache);
139 _pool->set_cache(nullptr); // so the verifier isn't confused
140 }
141 }
142
143
144
145 // The new finalization semantics says that registration of
146 // finalizable objects must be performed on successful return from the
147 // Object.<init> constructor. We could implement this trivially if
148 // <init> were never rewritten but since JVMTI allows this to occur, a
149 // more complicated solution is required. A special return bytecode
150 // is used only by Object.<init> to signal the finalization
151 // registration point. Additionally local 0 must be preserved so it's
152 // available to pass to the registration function. For simplicity we
153 // require that local 0 is never overwritten so it's available as an
154 // argument for registration.
155
156 void Rewriter::rewrite_Object_init(const methodHandle& method, TRAPS) {
157 RawBytecodeStream bcs(method);
158 while (!bcs.is_last_bytecode()) {
159 Bytecodes::Code opcode = bcs.raw_next();
160 switch (opcode) {
161 case Bytecodes::_return: *bcs.bcp() = Bytecodes::_return_register_finalizer; break;
162
163 case Bytecodes::_istore:
164 case Bytecodes::_lstore:
165 case Bytecodes::_fstore:
166 case Bytecodes::_dstore:
167 case Bytecodes::_astore:
168 if (bcs.get_index() != 0) continue;
169
170 // fall through
171 case Bytecodes::_istore_0:
172 case Bytecodes::_lstore_0:
173 case Bytecodes::_fstore_0:
174 case Bytecodes::_dstore_0:
175 case Bytecodes::_astore_0:
176 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(),
177 "can't overwrite local 0 in Object.<init>");
178 break;
179
180 default:
181 break;
182 }
183 }
184 }
185
186
187 void Rewriter::rewrite_field_reference(address bcp, int offset, bool reverse) {
188 address p = bcp + offset;
189 if (!reverse) {
190 int cp_index = Bytes::get_Java_u2(p);
191 int field_entry_index = _cp_map.at(cp_index);
192 Bytes::put_native_u2(p, checked_cast<u2>(field_entry_index));
193 } else {
194 int field_entry_index = Bytes::get_native_u2(p);
195 int pool_index = _initialized_field_entries.at(field_entry_index).constant_pool_index();
196 Bytes::put_Java_u2(p, checked_cast<u2>(pool_index));
197 }
198 }
199
200 void Rewriter::rewrite_method_reference(address bcp, int offset, bool reverse) {
201 address p = bcp + offset;
202 if (!reverse) {
203 int cp_index = Bytes::get_Java_u2(p);
204 int method_entry_index = _cp_map.at(cp_index);
205 Bytes::put_native_u2(p, (u2)method_entry_index);
206 if (!_method_handle_invokers.is_empty()) {
207 maybe_rewrite_invokehandle(p - 1, cp_index, method_entry_index, reverse);
208 }
209 } else {
210 int method_entry_index = Bytes::get_native_u2(p);
211 int pool_index = _initialized_method_entries.at(method_entry_index).constant_pool_index();
212 Bytes::put_Java_u2(p, (u2)pool_index);
213 if (!_method_handle_invokers.is_empty()) {
214 maybe_rewrite_invokehandle(p - 1, pool_index, method_entry_index, reverse);
215 }
216 }
217 }
218
219 // If the constant pool entry for invokespecial is InterfaceMethodref,
220 // we need to add a separate cpCache entry for its resolution, because it is
221 // different than the resolution for invokeinterface with InterfaceMethodref.
222 // These cannot share cpCache entries.
223 void Rewriter::rewrite_invokespecial(address bcp, int offset, bool reverse, bool* invokespecial_error) {
224 address p = bcp + offset;
225 if (!reverse) {
226 int cp_index = Bytes::get_Java_u2(p);
227 if (_pool->tag_at(cp_index).is_interface_method()) {
228 _initialized_method_entries.push(ResolvedMethodEntry((u2)cp_index));
229 Bytes::put_native_u2(p, (u2)_method_entry_index);
230 _method_entry_index++;
231 if (_method_entry_index != (int)(u2)_method_entry_index) {
232 *invokespecial_error = true;
233 }
234 } else {
235 rewrite_method_reference(bcp, offset, reverse);
236 }
237 } else {
238 rewrite_method_reference(bcp, offset, reverse);
239 }
240 }
241
242 // Adjust the invocation bytecode for a signature-polymorphic method (MethodHandle.invoke, etc.)
243 void Rewriter::maybe_rewrite_invokehandle(address opc, int cp_index, int cache_index, bool reverse) {
244 if (!reverse) {
245 if ((*opc) == (u1)Bytecodes::_invokevirtual ||
246 // allow invokespecial as an alias, although it would be very odd:
247 ((*opc) == (u1)Bytecodes::_invokespecial)) {
248 assert(_pool->tag_at(cp_index).is_method(), "wrong index");
249 // Determine whether this is a signature-polymorphic method.
250 if (cp_index >= _method_handle_invokers.length()) return;
251 int status = _method_handle_invokers.at(cp_index);
252 assert(status >= -1 && status <= 1, "oob tri-state");
253 if (status == 0) {
254 if (_pool->uncached_klass_ref_at_noresolve(cp_index) == vmSymbols::java_lang_invoke_MethodHandle() &&
255 MethodHandles::is_signature_polymorphic_name(vmClasses::MethodHandle_klass(),
256 _pool->uncached_name_ref_at(cp_index))) {
257 // we may need a resolved_refs entry for the appendix
258 int resolved_index = add_invokedynamic_resolved_references_entry(cp_index, cache_index);
259 _initialized_method_entries.at(cache_index).set_resolved_references_index((u2)resolved_index);
260 status = +1;
261 } else if (_pool->uncached_klass_ref_at_noresolve(cp_index) == vmSymbols::java_lang_invoke_VarHandle() &&
262 MethodHandles::is_signature_polymorphic_name(vmClasses::VarHandle_klass(),
263 _pool->uncached_name_ref_at(cp_index))) {
264 // we may need a resolved_refs entry for the appendix
265 int resolved_index = add_invokedynamic_resolved_references_entry(cp_index, cache_index);
266 _initialized_method_entries.at(cache_index).set_resolved_references_index((u2)resolved_index);
267 status = +1;
268 } else {
269 status = -1;
270 }
271 _method_handle_invokers.at(cp_index) = status;
272 }
273 // We use a special internal bytecode for such methods (if non-static).
274 // The basic reason for this is that such methods need an extra "appendix" argument
275 // to transmit the call site's intended call type.
276 if (status > 0) {
277 (*opc) = (u1)Bytecodes::_invokehandle;
278 }
279 }
280 } else {
281 // Do not need to look at cp_index.
282 if ((*opc) == (u1)Bytecodes::_invokehandle) {
283 (*opc) = (u1)Bytecodes::_invokevirtual;
284 // Ignore corner case of original _invokespecial instruction.
285 // This is safe because (a) the signature polymorphic method was final, and
286 // (b) the implementation of MethodHandle will not call invokespecial on it.
287 }
288 }
289 }
290
291
292 void Rewriter::rewrite_invokedynamic(address bcp, int offset, bool reverse) {
293 address p = bcp + offset;
294 assert(p[-1] == Bytecodes::_invokedynamic, "not invokedynamic bytecode");
295 if (!reverse) {
296 int cp_index = Bytes::get_Java_u2(p);
297 int resolved_index = add_invokedynamic_resolved_references_entry(cp_index, -1); // Indy no longer has a CPCE
298 // Replace the trailing four bytes with an index to the array of
299 // indy resolution information in the CPC. There is one entry for
300 // each bytecode, even if they make the same call. In other words,
301 // the CPC-to-CP relation is many-to-one for invokedynamic entries.
302 // This means we must use a larger index size than u2 to address
303 // all these entries. That is the main reason invokedynamic
304 // must have a five-byte instruction format. (Of course, other JVM
305 // implementations can use the bytes for other purposes.)
306 // Note: We use native_u4 format exclusively for 4-byte indexes.
307 Bytes::put_native_u4(p, (u2)_invokedynamic_index);
308 _invokedynamic_index++;
309
310 // Collect invokedynamic information before creating ResolvedInvokeDynamicInfo array
311 _initialized_indy_entries.push(ResolvedIndyEntry((u2)resolved_index, (u2)cp_index));
312 } else {
313 // Should do nothing since we are not patching this bytecode
314 int cache_index = Bytes::get_native_u4(p);
315 int cp_index = _initialized_indy_entries.at(cache_index).constant_pool_index();
316 assert(_pool->tag_at(cp_index).is_invoke_dynamic(), "wrong index");
317 // zero out 4 bytes
318 Bytes::put_Java_u4(p, 0);
319 Bytes::put_Java_u2(p, (u2)cp_index);
320 }
321 }
322
323 // Rewrite some ldc bytecodes to _fast_aldc
324 void Rewriter::maybe_rewrite_ldc(address bcp, int offset, bool is_wide,
325 bool reverse) {
326 if (!reverse) {
327 assert((*bcp) == (is_wide ? Bytecodes::_ldc_w : Bytecodes::_ldc), "not ldc bytecode");
328 address p = bcp + offset;
329 int cp_index = is_wide ? Bytes::get_Java_u2(p) : (u1)(*p);
330 constantTag tag = _pool->tag_at(cp_index).value();
331
332 if (tag.is_method_handle() ||
333 tag.is_method_type() ||
334 tag.is_string() ||
335 (tag.is_dynamic_constant() &&
336 // keep regular ldc interpreter logic for condy primitives
337 is_reference_type(Signature::basic_type(_pool->uncached_signature_ref_at(cp_index))))
338 ) {
339 int ref_index = cp_entry_to_resolved_references(cp_index);
340 if (is_wide) {
341 (*bcp) = Bytecodes::_fast_aldc_w;
342 assert(ref_index == (u2)ref_index, "index overflow");
343 Bytes::put_native_u2(p, (u2)ref_index);
344 } else {
345 (*bcp) = Bytecodes::_fast_aldc;
346 assert(ref_index == (u1)ref_index, "index overflow");
347 (*p) = (u1)ref_index;
348 }
349 }
350 } else {
351 Bytecodes::Code rewritten_bc =
352 (is_wide ? Bytecodes::_fast_aldc_w : Bytecodes::_fast_aldc);
353 if ((*bcp) == rewritten_bc) {
354 address p = bcp + offset;
355 int ref_index = is_wide ? Bytes::get_native_u2(p) : (u1)(*p);
356 int pool_index = resolved_references_entry_to_pool_index(ref_index);
357 if (is_wide) {
358 (*bcp) = Bytecodes::_ldc_w;
359 assert(pool_index == (u2)pool_index, "index overflow");
360 Bytes::put_Java_u2(p, (u2)pool_index);
361 } else {
362 (*bcp) = Bytecodes::_ldc;
363 assert(pool_index == (u1)pool_index, "index overflow");
364 (*p) = (u1)pool_index;
365 }
366 }
367 }
368 }
369
370
371 // Rewrites a method given the index_map information
372 void Rewriter::scan_method(Thread* thread, Method* method, bool reverse, bool* invokespecial_error) {
373
374 int nof_jsrs = 0;
375 bool has_monitor_bytecodes = false;
376 Bytecodes::Code c;
377
378 // Bytecodes and their length
379 const address code_base = method->code_base();
380 const int code_length = method->code_size();
381
382 int bc_length;
383 for (int bci = 0; bci < code_length; bci += bc_length) {
384 address bcp = code_base + bci;
385 int prefix_length = 0;
386 c = (Bytecodes::Code)(*bcp);
387
388 // Since we have the code, see if we can get the length
389 // directly. Some more complicated bytecodes will report
390 // a length of zero, meaning we need to make another method
391 // call to calculate the length.
392 bc_length = Bytecodes::length_for(c);
393 if (bc_length == 0) {
394 bc_length = Bytecodes::length_at(method, bcp);
395
396 // length_at will put us at the bytecode after the one modified
397 // by 'wide'. We don't currently examine any of the bytecodes
398 // modified by wide, but in case we do in the future...
399 if (c == Bytecodes::_wide) {
400 prefix_length = 1;
401 c = (Bytecodes::Code)bcp[1];
402 }
403 }
404
405 // Continuing with an invalid bytecode will fail in the loop below.
406 // So guarantee here.
407 guarantee(bc_length > 0, "Verifier should have caught this invalid bytecode");
408
409 switch (c) {
410 case Bytecodes::_lookupswitch : {
411 #ifndef ZERO
412 Bytecode_lookupswitch bc(method, bcp);
413 (*bcp) = (
414 bc.number_of_pairs() < BinarySwitchThreshold
415 ? Bytecodes::_fast_linearswitch
416 : Bytecodes::_fast_binaryswitch
417 );
418 #endif
419 break;
420 }
421 case Bytecodes::_fast_linearswitch:
422 case Bytecodes::_fast_binaryswitch: {
423 #ifndef ZERO
424 (*bcp) = Bytecodes::_lookupswitch;
425 #endif
426 break;
427 }
428
429 case Bytecodes::_invokespecial : {
430 rewrite_invokespecial(bcp, prefix_length+1, reverse, invokespecial_error);
431 break;
432 }
433
434 case Bytecodes::_putstatic :
435 case Bytecodes::_putfield : {
436 if (!reverse) {
437 // Check if any final field of the class given as parameter is modified
438 // outside of initializer methods of the class. Fields that are modified
439 // are marked with a flag. For marked fields, the compilers do not perform
440 // constant folding (as the field can be changed after initialization).
441 //
442 // The check is performed after verification and only if verification has
443 // succeeded. Therefore, the class is guaranteed to be well-formed.
444 InstanceKlass* klass = method->method_holder();
445 u2 bc_index = Bytes::get_Java_u2(bcp + prefix_length + 1);
446 constantPoolHandle cp(thread, method->constants());
447 Symbol* ref_class_name = cp->klass_name_at(cp->uncached_klass_ref_index_at(bc_index));
448
449 if (klass->name() == ref_class_name) {
450 Symbol* field_name = cp->uncached_name_ref_at(bc_index);
451 Symbol* field_sig = cp->uncached_signature_ref_at(bc_index);
452
453 fieldDescriptor fd;
454 if (klass->find_field(field_name, field_sig, &fd) != nullptr) {
455 if (fd.access_flags().is_final()) {
456 if (fd.access_flags().is_static()) {
457 if (!method->is_static_initializer()) {
458 fd.set_has_initialized_final_update(true);
459 }
460 } else {
461 if (!method->is_object_initializer()) {
462 fd.set_has_initialized_final_update(true);
463 }
464 }
465 }
466 }
467 }
468 }
469 }
470 // fall through
471 case Bytecodes::_getstatic : // fall through
472 case Bytecodes::_getfield : // fall through
473 rewrite_field_reference(bcp, prefix_length+1, reverse);
474 break;
475 case Bytecodes::_invokevirtual : // fall through
476 case Bytecodes::_invokestatic :
477 case Bytecodes::_invokeinterface:
478 case Bytecodes::_invokehandle : // if reverse=true
479 rewrite_method_reference(bcp, prefix_length+1, reverse);
480 break;
481 case Bytecodes::_invokedynamic:
482 rewrite_invokedynamic(bcp, prefix_length+1, reverse);
483 break;
484 case Bytecodes::_ldc:
485 case Bytecodes::_fast_aldc: // if reverse=true
486 maybe_rewrite_ldc(bcp, prefix_length+1, false, reverse);
487 break;
488 case Bytecodes::_ldc_w:
489 case Bytecodes::_fast_aldc_w: // if reverse=true
490 maybe_rewrite_ldc(bcp, prefix_length+1, true, reverse);
491 break;
492 case Bytecodes::_jsr : // fall through
493 case Bytecodes::_jsr_w : nof_jsrs++; break;
494 case Bytecodes::_monitorenter : // fall through
495 case Bytecodes::_monitorexit : has_monitor_bytecodes = true; break;
496
497 default: break;
498 }
499 }
500
501 // Update flags
502 if (has_monitor_bytecodes) {
503 method->set_has_monitor_bytecodes();
504 }
505
506 // The present of a jsr bytecode implies that the method might potentially
507 // have to be rewritten, so we run the oopMapGenerator on the method
508 if (nof_jsrs > 0) {
509 method->set_has_jsrs();
510 }
511 }
512
513 // After constant pool is created, revisit methods containing jsrs.
514 methodHandle Rewriter::rewrite_jsrs(const methodHandle& method, TRAPS) {
515 ResourceMark rm(THREAD);
516 ResolveOopMapConflicts romc(method);
517 methodHandle new_method = romc.do_potential_rewrite(CHECK_(methodHandle()));
518 // Update monitor matching info.
519 if (romc.monitor_safe()) {
520 new_method->set_guaranteed_monitor_matching();
521 }
522
523 return new_method;
524 }
525
526 void Rewriter::rewrite_bytecodes(TRAPS) {
527 assert(_pool->cache() == nullptr, "constant pool cache must not be set yet");
528
529 // determine index maps for Method* rewriting
530 compute_index_maps();
531
532 if (_klass->name() == vmSymbols::java_lang_Object()) {
533 bool did_rewrite = false;
534 int i = _methods->length();
535 while (i-- > 0) {
536 Method* method = _methods->at(i);
537 if (method->intrinsic_id() == vmIntrinsics::_Object_init) {
538 // rewrite the return bytecodes of Object.<init> to register the
539 // object for finalization if needed.
540 methodHandle m(THREAD, method);
541 rewrite_Object_init(m, CHECK);
542 did_rewrite = true;
543 break;
544 }
545 }
546 assert(did_rewrite, "must find Object::<init> to rewrite it");
547 }
548
549 // rewrite methods, in two passes
550 int len = _methods->length();
551 bool invokespecial_error = false;
552
553 for (int i = len-1; i >= 0; i--) {
554 Method* method = _methods->at(i);
555 scan_method(THREAD, method, false, &invokespecial_error);
556 if (invokespecial_error) {
557 // If you get an error here, there is no reversing bytecodes
558 // This exception is stored for this class and no further attempt is
559 // made at verifying or rewriting.
560 THROW_MSG(vmSymbols::java_lang_InternalError(),
561 "This classfile overflows invokespecial for interfaces "
562 "and cannot be loaded");
563 return;
564 }
565 }
566 }
567
568 void Rewriter::rewrite(InstanceKlass* klass, TRAPS) {
569 #if INCLUDE_CDS
570 if (klass->in_aot_cache()) {
571 assert(!klass->is_rewritten(), "rewritten classes in the AOT cache cannot be rewritten again");
572 }
573 #endif // INCLUDE_CDS
574 ResourceMark rm(THREAD);
575 constantPoolHandle cpool(THREAD, klass->constants());
576 Rewriter rw(klass, cpool, klass->methods(), CHECK);
577 // (That's all, folks.)
578 }
579
580 Rewriter::Rewriter(InstanceKlass* klass, const constantPoolHandle& cpool, Array<Method*>* methods, TRAPS)
581 : _klass(klass),
582 _pool(cpool),
583 _methods(methods),
584 _cp_map(cpool->length()),
585 _reference_map(cpool->length()),
586 _resolved_references_map(cpool->length() / 2),
587 _invokedynamic_references_map(cpool->length() / 2),
588 _method_handle_invokers(cpool->length()),
589 _invokedynamic_index(0),
590 _field_entry_index(0),
591 _method_entry_index(0)
592 {
593
594 // Rewrite bytecodes - exception here exits.
595 rewrite_bytecodes(CHECK);
596
597 // Stress restoring bytecodes
598 if (StressRewriter) {
599 restore_bytecodes(THREAD);
600 rewrite_bytecodes(CHECK);
601 }
602
603 // allocate constant pool cache, now that we've seen all the bytecodes
604 make_constant_pool_cache(THREAD);
605
606 // Restore bytecodes to their unrewritten state if there are exceptions
607 // rewriting bytecodes or allocating the cpCache
608 if (HAS_PENDING_EXCEPTION) {
609 restore_bytecodes(THREAD);
610 return;
611 }
612
613 // Relocate after everything, but still do this under the is_rewritten flag,
614 // so methods with jsrs in custom class lists in aren't attempted to be
615 // rewritten in the RO section of the shared archive.
616 // Relocated bytecodes don't have to be restored, only the cp cache entries
617 int len = _methods->length();
618 for (int i = len-1; i >= 0; i--) {
619 methodHandle m(THREAD, _methods->at(i));
620
621 if (m->has_jsrs()) {
622 m = rewrite_jsrs(m, THREAD);
623 // Restore bytecodes to their unrewritten state if there are exceptions
624 // relocating bytecodes. If some are relocated, that is ok because that
625 // doesn't affect constant pool to cpCache rewriting.
626 if (HAS_PENDING_EXCEPTION) {
627 restore_bytecodes(THREAD);
628 return;
629 }
630 // Method might have gotten rewritten.
631 methods->at_put(i, m());
632 }
633 }
634 }
--- EOF ---