Mercurial > hg > truffle
annotate src/share/vm/prims/jvmtiRedefineClasses.cpp @ 12233:40136aa2cdb1
8010722: assert: failed: heap size is too big for compressed oops
Summary: Use conservative assumptions of required alignment for the various garbage collector components into account when determining the maximum heap size that supports compressed oops. Using this conservative value avoids several circular dependencies in the calculation.
Reviewed-by: stefank, dholmes
author | tschatzl |
---|---|
date | Wed, 11 Sep 2013 16:25:02 +0200 |
parents | ff2520b97b00 |
children | ff8a09595db3 b2e698d2276c |
rev | line source |
---|---|
0 | 1 /* |
7624
b14da2e6f2dc
7174978: NPG: Fix bactrace builder for class redefinition
coleenp
parents:
7459
diff
changeset
|
2 * Copyright (c) 2003, 2013, 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:
1142
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1142
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:
1142
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
7949
5daaddd917a1
8006040: NPG: on_stack processing wastes space in ConstantPool
coleenp
parents:
7624
diff
changeset
|
26 #include "classfile/metadataOnStackMark.hpp" |
1972 | 27 #include "classfile/systemDictionary.hpp" |
28 #include "classfile/verifier.hpp" | |
29 #include "code/codeCache.hpp" | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
30 #include "compiler/compileBroker.hpp" |
1972 | 31 #include "interpreter/oopMapCache.hpp" |
32 #include "interpreter/rewriter.hpp" | |
33 #include "memory/gcLocker.hpp" | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
34 #include "memory/metadataFactory.hpp" |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
35 #include "memory/metaspaceShared.hpp" |
1972 | 36 #include "memory/universe.inline.hpp" |
3938 | 37 #include "oops/fieldStreams.hpp" |
1972 | 38 #include "oops/klassVtable.hpp" |
39 #include "prims/jvmtiImpl.hpp" | |
40 #include "prims/jvmtiRedefineClasses.hpp" | |
41 #include "prims/methodComparator.hpp" | |
42 #include "runtime/deoptimization.hpp" | |
43 #include "runtime/relocator.hpp" | |
44 #include "utilities/bitMap.inline.hpp" | |
0 | 45 |
46 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
47 Array<Method*>* VM_RedefineClasses::_old_methods = NULL; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
48 Array<Method*>* VM_RedefineClasses::_new_methods = NULL; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
49 Method** VM_RedefineClasses::_matching_old_methods = NULL; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
50 Method** VM_RedefineClasses::_matching_new_methods = NULL; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
51 Method** VM_RedefineClasses::_deleted_methods = NULL; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
52 Method** VM_RedefineClasses::_added_methods = NULL; |
0 | 53 int VM_RedefineClasses::_matching_methods_length = 0; |
54 int VM_RedefineClasses::_deleted_methods_length = 0; | |
55 int VM_RedefineClasses::_added_methods_length = 0; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
56 Klass* VM_RedefineClasses::_the_class_oop = NULL; |
0 | 57 |
58 | |
59 VM_RedefineClasses::VM_RedefineClasses(jint class_count, | |
60 const jvmtiClassDefinition *class_defs, | |
61 JvmtiClassLoadKind class_load_kind) { | |
62 _class_count = class_count; | |
63 _class_defs = class_defs; | |
64 _class_load_kind = class_load_kind; | |
65 _res = JVMTI_ERROR_NONE; | |
66 } | |
67 | |
68 bool VM_RedefineClasses::doit_prologue() { | |
69 if (_class_count == 0) { | |
70 _res = JVMTI_ERROR_NONE; | |
71 return false; | |
72 } | |
73 if (_class_defs == NULL) { | |
74 _res = JVMTI_ERROR_NULL_POINTER; | |
75 return false; | |
76 } | |
77 for (int i = 0; i < _class_count; i++) { | |
78 if (_class_defs[i].klass == NULL) { | |
79 _res = JVMTI_ERROR_INVALID_CLASS; | |
80 return false; | |
81 } | |
82 if (_class_defs[i].class_byte_count == 0) { | |
83 _res = JVMTI_ERROR_INVALID_CLASS_FORMAT; | |
84 return false; | |
85 } | |
86 if (_class_defs[i].class_bytes == NULL) { | |
87 _res = JVMTI_ERROR_NULL_POINTER; | |
88 return false; | |
89 } | |
90 } | |
91 | |
92 // Start timer after all the sanity checks; not quite accurate, but | |
93 // better than adding a bunch of stop() calls. | |
94 RC_TIMER_START(_timer_vm_op_prologue); | |
95 | |
96 // We first load new class versions in the prologue, because somewhere down the | |
97 // call chain it is required that the current thread is a Java thread. | |
98 _res = load_new_class_versions(Thread::current()); | |
99 if (_res != JVMTI_ERROR_NONE) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
100 // free any successfully created classes, since none are redefined |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
101 for (int i = 0; i < _class_count; i++) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
102 if (_scratch_classes[i] != NULL) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
103 ClassLoaderData* cld = _scratch_classes[i]->class_loader_data(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
104 // Free the memory for this class at class unloading time. Not before |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
105 // because CMS might think this is still live. |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
106 cld->add_to_deallocate_list((InstanceKlass*)_scratch_classes[i]); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
107 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
108 } |
0 | 109 // Free os::malloc allocated memory in load_new_class_version. |
110 os::free(_scratch_classes); | |
111 RC_TIMER_STOP(_timer_vm_op_prologue); | |
112 return false; | |
113 } | |
114 | |
115 RC_TIMER_STOP(_timer_vm_op_prologue); | |
116 return true; | |
117 } | |
118 | |
119 void VM_RedefineClasses::doit() { | |
120 Thread *thread = Thread::current(); | |
121 | |
122 if (UseSharedSpaces) { | |
123 // Sharing is enabled so we remap the shared readonly space to | |
124 // shared readwrite, private just in case we need to redefine | |
125 // a shared class. We do the remap during the doit() phase of | |
126 // the safepoint to be safer. | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
127 if (!MetaspaceShared::remap_shared_readonly_as_readwrite()) { |
0 | 128 RC_TRACE_WITH_THREAD(0x00000001, thread, |
129 ("failed to remap shared readonly space to readwrite, private")); | |
130 _res = JVMTI_ERROR_INTERNAL; | |
131 return; | |
132 } | |
133 } | |
134 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
135 // Mark methods seen on stack and everywhere else so old methods are not |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
136 // cleaned up if they're on the stack. |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
137 MetadataOnStackMark md_on_stack; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
138 HandleMark hm(thread); // make sure any handles created are deleted |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
139 // before the stack walk again. |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
140 |
0 | 141 for (int i = 0; i < _class_count; i++) { |
142 redefine_single_class(_class_defs[i].klass, _scratch_classes[i], thread); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
143 ClassLoaderData* cld = _scratch_classes[i]->class_loader_data(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
144 // Free the memory for this class at class unloading time. Not before |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
145 // because CMS might think this is still live. |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
146 cld->add_to_deallocate_list((InstanceKlass*)_scratch_classes[i]); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
147 _scratch_classes[i] = NULL; |
0 | 148 } |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
149 |
0 | 150 // Disable any dependent concurrent compilations |
151 SystemDictionary::notice_modification(); | |
152 | |
153 // Set flag indicating that some invariants are no longer true. | |
154 // See jvmtiExport.hpp for detailed explanation. | |
155 JvmtiExport::set_has_redefined_a_class(); | |
156 | |
8021
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
157 // check_class() is optionally called for product bits, but is |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
158 // always called for non-product bits. |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
159 #ifdef PRODUCT |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
160 if (RC_TRACE_ENABLED(0x00004000)) { |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
161 #endif |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
162 RC_TRACE_WITH_THREAD(0x00004000, thread, ("calling check_class")); |
10268
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
163 CheckClass check_class(thread); |
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
164 ClassLoaderDataGraph::classes_do(&check_class); |
8021
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
165 #ifdef PRODUCT |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
166 } |
0 | 167 #endif |
168 } | |
169 | |
170 void VM_RedefineClasses::doit_epilogue() { | |
171 // Free os::malloc allocated memory. | |
172 os::free(_scratch_classes); | |
173 | |
174 if (RC_TRACE_ENABLED(0x00000004)) { | |
175 // Used to have separate timers for "doit" and "all", but the timer | |
176 // overhead skewed the measurements. | |
177 jlong doit_time = _timer_rsc_phase1.milliseconds() + | |
178 _timer_rsc_phase2.milliseconds(); | |
179 jlong all_time = _timer_vm_op_prologue.milliseconds() + doit_time; | |
180 | |
181 RC_TRACE(0x00000004, ("vm_op: all=" UINT64_FORMAT | |
182 " prologue=" UINT64_FORMAT " doit=" UINT64_FORMAT, all_time, | |
183 _timer_vm_op_prologue.milliseconds(), doit_time)); | |
184 RC_TRACE(0x00000004, | |
185 ("redefine_single_class: phase1=" UINT64_FORMAT " phase2=" UINT64_FORMAT, | |
186 _timer_rsc_phase1.milliseconds(), _timer_rsc_phase2.milliseconds())); | |
187 } | |
188 } | |
189 | |
190 bool VM_RedefineClasses::is_modifiable_class(oop klass_mirror) { | |
191 // classes for primitives cannot be redefined | |
192 if (java_lang_Class::is_primitive(klass_mirror)) { | |
193 return false; | |
194 } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
195 Klass* the_class_oop = java_lang_Class::as_Klass(klass_mirror); |
0 | 196 // classes for arrays cannot be redefined |
6983 | 197 if (the_class_oop == NULL || !the_class_oop->oop_is_instance()) { |
0 | 198 return false; |
199 } | |
200 return true; | |
201 } | |
202 | |
203 // Append the current entry at scratch_i in scratch_cp to *merge_cp_p | |
204 // where the end of *merge_cp_p is specified by *merge_cp_length_p. For | |
205 // direct CP entries, there is just the current entry to append. For | |
206 // indirect and double-indirect CP entries, there are zero or more | |
207 // referenced CP entries along with the current entry to append. | |
208 // Indirect and double-indirect CP entries are handled by recursive | |
209 // calls to append_entry() as needed. The referenced CP entries are | |
210 // always appended to *merge_cp_p before the referee CP entry. These | |
211 // referenced CP entries may already exist in *merge_cp_p in which case | |
212 // there is nothing extra to append and only the current entry is | |
213 // appended. | |
214 void VM_RedefineClasses::append_entry(constantPoolHandle scratch_cp, | |
215 int scratch_i, constantPoolHandle *merge_cp_p, int *merge_cp_length_p, | |
216 TRAPS) { | |
217 | |
218 // append is different depending on entry tag type | |
219 switch (scratch_cp->tag_at(scratch_i).value()) { | |
220 | |
221 // The old verifier is implemented outside the VM. It loads classes, | |
222 // but does not resolve constant pool entries directly so we never | |
223 // see Class entries here with the old verifier. Similarly the old | |
224 // verifier does not like Class entries in the input constant pool. | |
225 // The split-verifier is implemented in the VM so it can optionally | |
226 // and directly resolve constant pool entries to load classes. The | |
227 // split-verifier can accept either Class entries or UnresolvedClass | |
228 // entries in the input constant pool. We revert the appended copy | |
229 // back to UnresolvedClass so that either verifier will be happy | |
230 // with the constant pool entry. | |
231 case JVM_CONSTANT_Class: | |
232 { | |
233 // revert the copy to JVM_CONSTANT_UnresolvedClass | |
234 (*merge_cp_p)->unresolved_klass_at_put(*merge_cp_length_p, | |
235 scratch_cp->klass_name_at(scratch_i)); | |
236 | |
237 if (scratch_i != *merge_cp_length_p) { | |
238 // The new entry in *merge_cp_p is at a different index than | |
239 // the new entry in scratch_cp so we need to map the index values. | |
240 map_index(scratch_cp, scratch_i, *merge_cp_length_p); | |
241 } | |
242 (*merge_cp_length_p)++; | |
243 } break; | |
244 | |
245 // these are direct CP entries so they can be directly appended, | |
246 // but double and long take two constant pool entries | |
247 case JVM_CONSTANT_Double: // fall through | |
248 case JVM_CONSTANT_Long: | |
249 { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
250 ConstantPool::copy_entry_to(scratch_cp, scratch_i, *merge_cp_p, *merge_cp_length_p, |
0 | 251 THREAD); |
252 | |
253 if (scratch_i != *merge_cp_length_p) { | |
254 // The new entry in *merge_cp_p is at a different index than | |
255 // the new entry in scratch_cp so we need to map the index values. | |
256 map_index(scratch_cp, scratch_i, *merge_cp_length_p); | |
257 } | |
258 (*merge_cp_length_p) += 2; | |
259 } break; | |
260 | |
261 // these are direct CP entries so they can be directly appended | |
262 case JVM_CONSTANT_Float: // fall through | |
263 case JVM_CONSTANT_Integer: // fall through | |
264 case JVM_CONSTANT_Utf8: // fall through | |
265 | |
266 // This was an indirect CP entry, but it has been changed into | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
267 // Symbol*s so this entry can be directly appended. |
0 | 268 case JVM_CONSTANT_String: // fall through |
269 | |
270 // These were indirect CP entries, but they have been changed into | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
271 // Symbol*s so these entries can be directly appended. |
0 | 272 case JVM_CONSTANT_UnresolvedClass: // fall through |
273 { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
274 ConstantPool::copy_entry_to(scratch_cp, scratch_i, *merge_cp_p, *merge_cp_length_p, |
0 | 275 THREAD); |
276 | |
277 if (scratch_i != *merge_cp_length_p) { | |
278 // The new entry in *merge_cp_p is at a different index than | |
279 // the new entry in scratch_cp so we need to map the index values. | |
280 map_index(scratch_cp, scratch_i, *merge_cp_length_p); | |
281 } | |
282 (*merge_cp_length_p)++; | |
283 } break; | |
284 | |
285 // this is an indirect CP entry so it needs special handling | |
286 case JVM_CONSTANT_NameAndType: | |
287 { | |
288 int name_ref_i = scratch_cp->name_ref_index_at(scratch_i); | |
7963
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
289 int new_name_ref_i = find_or_append_indirect_entry(scratch_cp, name_ref_i, merge_cp_p, |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
290 merge_cp_length_p, THREAD); |
0 | 291 |
292 int signature_ref_i = scratch_cp->signature_ref_index_at(scratch_i); | |
7963
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
293 int new_signature_ref_i = find_or_append_indirect_entry(scratch_cp, signature_ref_i, |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
294 merge_cp_p, merge_cp_length_p, |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
295 THREAD); |
0 | 296 |
297 // If the referenced entries already exist in *merge_cp_p, then | |
298 // both new_name_ref_i and new_signature_ref_i will both be 0. | |
299 // In that case, all we are appending is the current entry. | |
7963
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
300 if (new_name_ref_i != name_ref_i) { |
0 | 301 RC_TRACE(0x00080000, |
302 ("NameAndType entry@%d name_ref_index change: %d to %d", | |
303 *merge_cp_length_p, name_ref_i, new_name_ref_i)); | |
304 } | |
7963
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
305 if (new_signature_ref_i != signature_ref_i) { |
0 | 306 RC_TRACE(0x00080000, |
307 ("NameAndType entry@%d signature_ref_index change: %d to %d", | |
308 *merge_cp_length_p, signature_ref_i, new_signature_ref_i)); | |
309 } | |
310 | |
311 (*merge_cp_p)->name_and_type_at_put(*merge_cp_length_p, | |
312 new_name_ref_i, new_signature_ref_i); | |
313 if (scratch_i != *merge_cp_length_p) { | |
314 // The new entry in *merge_cp_p is at a different index than | |
315 // the new entry in scratch_cp so we need to map the index values. | |
316 map_index(scratch_cp, scratch_i, *merge_cp_length_p); | |
317 } | |
318 (*merge_cp_length_p)++; | |
319 } break; | |
320 | |
321 // this is a double-indirect CP entry so it needs special handling | |
322 case JVM_CONSTANT_Fieldref: // fall through | |
323 case JVM_CONSTANT_InterfaceMethodref: // fall through | |
324 case JVM_CONSTANT_Methodref: | |
325 { | |
326 int klass_ref_i = scratch_cp->uncached_klass_ref_index_at(scratch_i); | |
7963
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
327 int new_klass_ref_i = find_or_append_indirect_entry(scratch_cp, klass_ref_i, |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
328 merge_cp_p, merge_cp_length_p, THREAD); |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
329 |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
330 int name_and_type_ref_i = scratch_cp->uncached_name_and_type_ref_index_at(scratch_i); |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
331 int new_name_and_type_ref_i = find_or_append_indirect_entry(scratch_cp, name_and_type_ref_i, |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
332 merge_cp_p, merge_cp_length_p, THREAD); |
0 | 333 |
334 const char *entry_name; | |
335 switch (scratch_cp->tag_at(scratch_i).value()) { | |
336 case JVM_CONSTANT_Fieldref: | |
337 entry_name = "Fieldref"; | |
338 (*merge_cp_p)->field_at_put(*merge_cp_length_p, new_klass_ref_i, | |
339 new_name_and_type_ref_i); | |
340 break; | |
341 case JVM_CONSTANT_InterfaceMethodref: | |
342 entry_name = "IFMethodref"; | |
343 (*merge_cp_p)->interface_method_at_put(*merge_cp_length_p, | |
344 new_klass_ref_i, new_name_and_type_ref_i); | |
345 break; | |
346 case JVM_CONSTANT_Methodref: | |
347 entry_name = "Methodref"; | |
348 (*merge_cp_p)->method_at_put(*merge_cp_length_p, new_klass_ref_i, | |
349 new_name_and_type_ref_i); | |
350 break; | |
351 default: | |
352 guarantee(false, "bad switch"); | |
353 break; | |
354 } | |
355 | |
356 if (klass_ref_i != new_klass_ref_i) { | |
357 RC_TRACE(0x00080000, ("%s entry@%d class_index changed: %d to %d", | |
358 entry_name, *merge_cp_length_p, klass_ref_i, new_klass_ref_i)); | |
359 } | |
360 if (name_and_type_ref_i != new_name_and_type_ref_i) { | |
361 RC_TRACE(0x00080000, | |
362 ("%s entry@%d name_and_type_index changed: %d to %d", | |
363 entry_name, *merge_cp_length_p, name_and_type_ref_i, | |
364 new_name_and_type_ref_i)); | |
365 } | |
366 | |
367 if (scratch_i != *merge_cp_length_p) { | |
368 // The new entry in *merge_cp_p is at a different index than | |
369 // the new entry in scratch_cp so we need to map the index values. | |
370 map_index(scratch_cp, scratch_i, *merge_cp_length_p); | |
371 } | |
372 (*merge_cp_length_p)++; | |
373 } break; | |
374 | |
7963
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
375 // this is an indirect CP entry so it needs special handling |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
376 case JVM_CONSTANT_MethodType: |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
377 { |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
378 int ref_i = scratch_cp->method_type_index_at(scratch_i); |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
379 int new_ref_i = find_or_append_indirect_entry(scratch_cp, ref_i, merge_cp_p, |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
380 merge_cp_length_p, THREAD); |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
381 if (new_ref_i != ref_i) { |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
382 RC_TRACE(0x00080000, |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
383 ("MethodType entry@%d ref_index change: %d to %d", |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
384 *merge_cp_length_p, ref_i, new_ref_i)); |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
385 } |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
386 (*merge_cp_p)->method_type_index_at_put(*merge_cp_length_p, new_ref_i); |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
387 if (scratch_i != *merge_cp_length_p) { |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
388 // The new entry in *merge_cp_p is at a different index than |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
389 // the new entry in scratch_cp so we need to map the index values. |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
390 map_index(scratch_cp, scratch_i, *merge_cp_length_p); |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
391 } |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
392 (*merge_cp_length_p)++; |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
393 } break; |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
394 |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
395 // this is an indirect CP entry so it needs special handling |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
396 case JVM_CONSTANT_MethodHandle: |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
397 { |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
398 int ref_kind = scratch_cp->method_handle_ref_kind_at(scratch_i); |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
399 int ref_i = scratch_cp->method_handle_index_at(scratch_i); |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
400 int new_ref_i = find_or_append_indirect_entry(scratch_cp, ref_i, merge_cp_p, |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
401 merge_cp_length_p, THREAD); |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
402 if (new_ref_i != ref_i) { |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
403 RC_TRACE(0x00080000, |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
404 ("MethodHandle entry@%d ref_index change: %d to %d", |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
405 *merge_cp_length_p, ref_i, new_ref_i)); |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
406 } |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
407 (*merge_cp_p)->method_handle_index_at_put(*merge_cp_length_p, ref_kind, new_ref_i); |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
408 if (scratch_i != *merge_cp_length_p) { |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
409 // The new entry in *merge_cp_p is at a different index than |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
410 // the new entry in scratch_cp so we need to map the index values. |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
411 map_index(scratch_cp, scratch_i, *merge_cp_length_p); |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
412 } |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
413 (*merge_cp_length_p)++; |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
414 } break; |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
415 |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
416 // this is an indirect CP entry so it needs special handling |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
417 case JVM_CONSTANT_InvokeDynamic: |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
418 { |
10151
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
419 // Index of the bootstrap specifier in the operands array |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
420 int old_bs_i = scratch_cp->invoke_dynamic_bootstrap_specifier_index(scratch_i); |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
421 int new_bs_i = find_or_append_operand(scratch_cp, old_bs_i, merge_cp_p, |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
422 merge_cp_length_p, THREAD); |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
423 // The bootstrap method NameAndType_info index |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
424 int old_ref_i = scratch_cp->invoke_dynamic_name_and_type_ref_index_at(scratch_i); |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
425 int new_ref_i = find_or_append_indirect_entry(scratch_cp, old_ref_i, merge_cp_p, |
7963
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
426 merge_cp_length_p, THREAD); |
10151
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
427 if (new_bs_i != old_bs_i) { |
7963
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
428 RC_TRACE(0x00080000, |
10151
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
429 ("InvokeDynamic entry@%d bootstrap_method_attr_index change: %d to %d", |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
430 *merge_cp_length_p, old_bs_i, new_bs_i)); |
7963
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
431 } |
10151
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
432 if (new_ref_i != old_ref_i) { |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
433 RC_TRACE(0x00080000, |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
434 ("InvokeDynamic entry@%d name_and_type_index change: %d to %d", |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
435 *merge_cp_length_p, old_ref_i, new_ref_i)); |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
436 } |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
437 |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
438 (*merge_cp_p)->invoke_dynamic_at_put(*merge_cp_length_p, new_bs_i, new_ref_i); |
7963
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
439 if (scratch_i != *merge_cp_length_p) { |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
440 // The new entry in *merge_cp_p is at a different index than |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
441 // the new entry in scratch_cp so we need to map the index values. |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
442 map_index(scratch_cp, scratch_i, *merge_cp_length_p); |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
443 } |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
444 (*merge_cp_length_p)++; |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
445 } break; |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
446 |
0 | 447 // At this stage, Class or UnresolvedClass could be here, but not |
448 // ClassIndex | |
449 case JVM_CONSTANT_ClassIndex: // fall through | |
450 | |
451 // Invalid is used as the tag for the second constant pool entry | |
452 // occupied by JVM_CONSTANT_Double or JVM_CONSTANT_Long. It should | |
453 // not be seen by itself. | |
454 case JVM_CONSTANT_Invalid: // fall through | |
455 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
456 // At this stage, String could be here, but not StringIndex |
0 | 457 case JVM_CONSTANT_StringIndex: // fall through |
458 | |
459 // At this stage JVM_CONSTANT_UnresolvedClassInError should not be | |
460 // here | |
461 case JVM_CONSTANT_UnresolvedClassInError: // fall through | |
462 | |
463 default: | |
464 { | |
465 // leave a breadcrumb | |
466 jbyte bad_value = scratch_cp->tag_at(scratch_i).value(); | |
467 ShouldNotReachHere(); | |
468 } break; | |
469 } // end switch tag value | |
470 } // end append_entry() | |
471 | |
472 | |
7963
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
473 int VM_RedefineClasses::find_or_append_indirect_entry(constantPoolHandle scratch_cp, |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
474 int ref_i, constantPoolHandle *merge_cp_p, int *merge_cp_length_p, TRAPS) { |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
475 |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
476 int new_ref_i = ref_i; |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
477 bool match = (ref_i < *merge_cp_length_p) && |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
478 scratch_cp->compare_entry_to(ref_i, *merge_cp_p, ref_i, THREAD); |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
479 |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
480 if (!match) { |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
481 // forward reference in *merge_cp_p or not a direct match |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
482 int found_i = scratch_cp->find_matching_entry(ref_i, *merge_cp_p, THREAD); |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
483 if (found_i != 0) { |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
484 guarantee(found_i != ref_i, "compare_entry_to() and find_matching_entry() do not agree"); |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
485 // Found a matching entry somewhere else in *merge_cp_p so just need a mapping entry. |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
486 new_ref_i = found_i; |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
487 map_index(scratch_cp, ref_i, found_i); |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
488 } else { |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
489 // no match found so we have to append this entry to *merge_cp_p |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
490 append_entry(scratch_cp, ref_i, merge_cp_p, merge_cp_length_p, THREAD); |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
491 // The above call to append_entry() can only append one entry |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
492 // so the post call query of *merge_cp_length_p is only for |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
493 // the sake of consistency. |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
494 new_ref_i = *merge_cp_length_p - 1; |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
495 } |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
496 } |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
497 |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
498 return new_ref_i; |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
499 } // end find_or_append_indirect_entry() |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
500 |
9bf5f643d1cf
8006542: JSR 292: the VM_RedefineClasses::append_entry() must support invokedynamic entry kinds
sspitsyn
parents:
7954
diff
changeset
|
501 |
10151
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
502 // Append a bootstrap specifier into the merge_cp operands that is semantically equal |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
503 // to the scratch_cp operands bootstrap specifier passed by the old_bs_i index. |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
504 // Recursively append new merge_cp entries referenced by the new bootstrap specifier. |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
505 void VM_RedefineClasses::append_operand(constantPoolHandle scratch_cp, int old_bs_i, |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
506 constantPoolHandle *merge_cp_p, int *merge_cp_length_p, TRAPS) { |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
507 |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
508 int old_ref_i = scratch_cp->operand_bootstrap_method_ref_index_at(old_bs_i); |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
509 int new_ref_i = find_or_append_indirect_entry(scratch_cp, old_ref_i, merge_cp_p, |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
510 merge_cp_length_p, THREAD); |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
511 if (new_ref_i != old_ref_i) { |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
512 RC_TRACE(0x00080000, |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
513 ("operands entry@%d bootstrap method ref_index change: %d to %d", |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
514 _operands_cur_length, old_ref_i, new_ref_i)); |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
515 } |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
516 |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
517 Array<u2>* merge_ops = (*merge_cp_p)->operands(); |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
518 int new_bs_i = _operands_cur_length; |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
519 // We have _operands_cur_length == 0 when the merge_cp operands is empty yet. |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
520 // However, the operand_offset_at(0) was set in the extend_operands() call. |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
521 int new_base = (new_bs_i == 0) ? (*merge_cp_p)->operand_offset_at(0) |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
522 : (*merge_cp_p)->operand_next_offset_at(new_bs_i - 1); |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
523 int argc = scratch_cp->operand_argument_count_at(old_bs_i); |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
524 |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
525 ConstantPool::operand_offset_at_put(merge_ops, _operands_cur_length, new_base); |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
526 merge_ops->at_put(new_base++, new_ref_i); |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
527 merge_ops->at_put(new_base++, argc); |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
528 |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
529 for (int i = 0; i < argc; i++) { |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
530 int old_arg_ref_i = scratch_cp->operand_argument_index_at(old_bs_i, i); |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
531 int new_arg_ref_i = find_or_append_indirect_entry(scratch_cp, old_arg_ref_i, merge_cp_p, |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
532 merge_cp_length_p, THREAD); |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
533 merge_ops->at_put(new_base++, new_arg_ref_i); |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
534 if (new_arg_ref_i != old_arg_ref_i) { |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
535 RC_TRACE(0x00080000, |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
536 ("operands entry@%d bootstrap method argument ref_index change: %d to %d", |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
537 _operands_cur_length, old_arg_ref_i, new_arg_ref_i)); |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
538 } |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
539 } |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
540 if (old_bs_i != _operands_cur_length) { |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
541 // The bootstrap specifier in *merge_cp_p is at a different index than |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
542 // that in scratch_cp so we need to map the index values. |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
543 map_operand_index(old_bs_i, new_bs_i); |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
544 } |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
545 _operands_cur_length++; |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
546 } // end append_operand() |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
547 |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
548 |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
549 int VM_RedefineClasses::find_or_append_operand(constantPoolHandle scratch_cp, |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
550 int old_bs_i, constantPoolHandle *merge_cp_p, int *merge_cp_length_p, TRAPS) { |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
551 |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
552 int new_bs_i = old_bs_i; // bootstrap specifier index |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
553 bool match = (old_bs_i < _operands_cur_length) && |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
554 scratch_cp->compare_operand_to(old_bs_i, *merge_cp_p, old_bs_i, THREAD); |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
555 |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
556 if (!match) { |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
557 // forward reference in *merge_cp_p or not a direct match |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
558 int found_i = scratch_cp->find_matching_operand(old_bs_i, *merge_cp_p, |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
559 _operands_cur_length, THREAD); |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
560 if (found_i != -1) { |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
561 guarantee(found_i != old_bs_i, "compare_operand_to() and find_matching_operand() disagree"); |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
562 // found a matching operand somewhere else in *merge_cp_p so just need a mapping |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
563 new_bs_i = found_i; |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
564 map_operand_index(old_bs_i, found_i); |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
565 } else { |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
566 // no match found so we have to append this bootstrap specifier to *merge_cp_p |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
567 append_operand(scratch_cp, old_bs_i, merge_cp_p, merge_cp_length_p, THREAD); |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
568 new_bs_i = _operands_cur_length - 1; |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
569 } |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
570 } |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
571 return new_bs_i; |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
572 } // end find_or_append_operand() |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
573 |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
574 |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
575 void VM_RedefineClasses::finalize_operands_merge(constantPoolHandle merge_cp, TRAPS) { |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
576 if (merge_cp->operands() == NULL) { |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
577 return; |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
578 } |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
579 // Shrink the merge_cp operands |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
580 merge_cp->shrink_operands(_operands_cur_length, CHECK); |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
581 |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
582 if (RC_TRACE_ENABLED(0x00040000)) { |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
583 // don't want to loop unless we are tracing |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
584 int count = 0; |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
585 for (int i = 1; i < _operands_index_map_p->length(); i++) { |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
586 int value = _operands_index_map_p->at(i); |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
587 if (value != -1) { |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
588 RC_TRACE_WITH_THREAD(0x00040000, THREAD, |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
589 ("operands_index_map[%d]: old=%d new=%d", count, i, value)); |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
590 count++; |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
591 } |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
592 } |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
593 } |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
594 // Clean-up |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
595 _operands_index_map_p = NULL; |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
596 _operands_cur_length = 0; |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
597 _operands_index_map_count = 0; |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
598 } // end finalize_operands_merge() |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
599 |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
600 |
0 | 601 jvmtiError VM_RedefineClasses::compare_and_normalize_class_versions( |
602 instanceKlassHandle the_class, | |
603 instanceKlassHandle scratch_class) { | |
604 int i; | |
605 | |
606 // Check superclasses, or rather their names, since superclasses themselves can be | |
607 // requested to replace. | |
608 // Check for NULL superclass first since this might be java.lang.Object | |
609 if (the_class->super() != scratch_class->super() && | |
610 (the_class->super() == NULL || scratch_class->super() == NULL || | |
6983 | 611 the_class->super()->name() != |
612 scratch_class->super()->name())) { | |
0 | 613 return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED; |
614 } | |
615 | |
616 // Check if the number, names and order of directly implemented interfaces are the same. | |
617 // I think in principle we should just check if the sets of names of directly implemented | |
618 // interfaces are the same, i.e. the order of declaration (which, however, if changed in the | |
619 // .java file, also changes in .class file) should not matter. However, comparing sets is | |
620 // technically a bit more difficult, and, more importantly, I am not sure at present that the | |
621 // order of interfaces does not matter on the implementation level, i.e. that the VM does not | |
622 // rely on it somewhere. | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
623 Array<Klass*>* k_interfaces = the_class->local_interfaces(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
624 Array<Klass*>* k_new_interfaces = scratch_class->local_interfaces(); |
0 | 625 int n_intfs = k_interfaces->length(); |
626 if (n_intfs != k_new_interfaces->length()) { | |
627 return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED; | |
628 } | |
629 for (i = 0; i < n_intfs; i++) { | |
6983 | 630 if (k_interfaces->at(i)->name() != |
631 k_new_interfaces->at(i)->name()) { | |
0 | 632 return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED; |
633 } | |
634 } | |
635 | |
636 // Check whether class is in the error init state. | |
637 if (the_class->is_in_error_state()) { | |
638 // TBD #5057930: special error code is needed in 1.6 | |
639 return JVMTI_ERROR_INVALID_CLASS; | |
640 } | |
641 | |
642 // Check whether class modifiers are the same. | |
643 jushort old_flags = (jushort) the_class->access_flags().get_flags(); | |
644 jushort new_flags = (jushort) scratch_class->access_flags().get_flags(); | |
645 if (old_flags != new_flags) { | |
646 return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED; | |
647 } | |
648 | |
649 // Check if the number, names, types and order of fields declared in these classes | |
650 // are the same. | |
3938 | 651 JavaFieldStream old_fs(the_class); |
652 JavaFieldStream new_fs(scratch_class); | |
653 for (; !old_fs.done() && !new_fs.done(); old_fs.next(), new_fs.next()) { | |
0 | 654 // access |
3938 | 655 old_flags = old_fs.access_flags().as_short(); |
656 new_flags = new_fs.access_flags().as_short(); | |
0 | 657 if ((old_flags ^ new_flags) & JVM_RECOGNIZED_FIELD_MODIFIERS) { |
658 return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED; | |
659 } | |
660 // offset | |
3938 | 661 if (old_fs.offset() != new_fs.offset()) { |
0 | 662 return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED; |
663 } | |
664 // name and signature | |
3938 | 665 Symbol* name_sym1 = the_class->constants()->symbol_at(old_fs.name_index()); |
666 Symbol* sig_sym1 = the_class->constants()->symbol_at(old_fs.signature_index()); | |
667 Symbol* name_sym2 = scratch_class->constants()->symbol_at(new_fs.name_index()); | |
668 Symbol* sig_sym2 = scratch_class->constants()->symbol_at(new_fs.signature_index()); | |
0 | 669 if (name_sym1 != name_sym2 || sig_sym1 != sig_sym2) { |
670 return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED; | |
671 } | |
672 } | |
673 | |
3938 | 674 // If both streams aren't done then we have a differing number of |
675 // fields. | |
676 if (!old_fs.done() || !new_fs.done()) { | |
677 return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED; | |
678 } | |
679 | |
0 | 680 // Do a parallel walk through the old and new methods. Detect |
681 // cases where they match (exist in both), have been added in | |
682 // the new methods, or have been deleted (exist only in the | |
683 // old methods). The class file parser places methods in order | |
684 // by method name, but does not order overloaded methods by | |
685 // signature. In order to determine what fate befell the methods, | |
686 // this code places the overloaded new methods that have matching | |
687 // old methods in the same order as the old methods and places | |
688 // new overloaded methods at the end of overloaded methods of | |
689 // that name. The code for this order normalization is adapted | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
690 // from the algorithm used in InstanceKlass::find_method(). |
0 | 691 // Since we are swapping out of order entries as we find them, |
692 // we only have to search forward through the overloaded methods. | |
693 // Methods which are added and have the same name as an existing | |
694 // method (but different signature) will be put at the end of | |
695 // the methods with that name, and the name mismatch code will | |
696 // handle them. | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
697 Array<Method*>* k_old_methods(the_class->methods()); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
698 Array<Method*>* k_new_methods(scratch_class->methods()); |
0 | 699 int n_old_methods = k_old_methods->length(); |
700 int n_new_methods = k_new_methods->length(); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
701 Thread* thread = Thread::current(); |
0 | 702 |
703 int ni = 0; | |
704 int oi = 0; | |
705 while (true) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
706 Method* k_old_method; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
707 Method* k_new_method; |
0 | 708 enum { matched, added, deleted, undetermined } method_was = undetermined; |
709 | |
710 if (oi >= n_old_methods) { | |
711 if (ni >= n_new_methods) { | |
712 break; // we've looked at everything, done | |
713 } | |
714 // New method at the end | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
715 k_new_method = k_new_methods->at(ni); |
0 | 716 method_was = added; |
717 } else if (ni >= n_new_methods) { | |
718 // Old method, at the end, is deleted | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
719 k_old_method = k_old_methods->at(oi); |
0 | 720 method_was = deleted; |
721 } else { | |
722 // There are more methods in both the old and new lists | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
723 k_old_method = k_old_methods->at(oi); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
724 k_new_method = k_new_methods->at(ni); |
0 | 725 if (k_old_method->name() != k_new_method->name()) { |
726 // Methods are sorted by method name, so a mismatch means added | |
727 // or deleted | |
728 if (k_old_method->name()->fast_compare(k_new_method->name()) > 0) { | |
729 method_was = added; | |
730 } else { | |
731 method_was = deleted; | |
732 } | |
733 } else if (k_old_method->signature() == k_new_method->signature()) { | |
734 // Both the name and signature match | |
735 method_was = matched; | |
736 } else { | |
737 // The name matches, but the signature doesn't, which means we have to | |
738 // search forward through the new overloaded methods. | |
739 int nj; // outside the loop for post-loop check | |
740 for (nj = ni + 1; nj < n_new_methods; nj++) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
741 Method* m = k_new_methods->at(nj); |
0 | 742 if (k_old_method->name() != m->name()) { |
743 // reached another method name so no more overloaded methods | |
744 method_was = deleted; | |
745 break; | |
746 } | |
747 if (k_old_method->signature() == m->signature()) { | |
748 // found a match so swap the methods | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
749 k_new_methods->at_put(ni, m); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
750 k_new_methods->at_put(nj, k_new_method); |
0 | 751 k_new_method = m; |
752 method_was = matched; | |
753 break; | |
754 } | |
755 } | |
756 | |
757 if (nj >= n_new_methods) { | |
758 // reached the end without a match; so method was deleted | |
759 method_was = deleted; | |
760 } | |
761 } | |
762 } | |
763 | |
764 switch (method_was) { | |
765 case matched: | |
766 // methods match, be sure modifiers do too | |
767 old_flags = (jushort) k_old_method->access_flags().get_flags(); | |
768 new_flags = (jushort) k_new_method->access_flags().get_flags(); | |
769 if ((old_flags ^ new_flags) & ~(JVM_ACC_NATIVE)) { | |
770 return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED; | |
771 } | |
772 { | |
773 u2 new_num = k_new_method->method_idnum(); | |
774 u2 old_num = k_old_method->method_idnum(); | |
775 if (new_num != old_num) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
776 Method* idnum_owner = scratch_class->method_with_idnum(old_num); |
0 | 777 if (idnum_owner != NULL) { |
778 // There is already a method assigned this idnum -- switch them | |
779 idnum_owner->set_method_idnum(new_num); | |
780 } | |
781 k_new_method->set_method_idnum(old_num); | |
8031 | 782 if (thread->has_pending_exception()) { |
783 return JVMTI_ERROR_OUT_OF_MEMORY; | |
784 } | |
0 | 785 } |
786 } | |
787 RC_TRACE(0x00008000, ("Method matched: new: %s [%d] == old: %s [%d]", | |
788 k_new_method->name_and_sig_as_C_string(), ni, | |
789 k_old_method->name_and_sig_as_C_string(), oi)); | |
790 // advance to next pair of methods | |
791 ++oi; | |
792 ++ni; | |
793 break; | |
794 case added: | |
795 // method added, see if it is OK | |
796 new_flags = (jushort) k_new_method->access_flags().get_flags(); | |
797 if ((new_flags & JVM_ACC_PRIVATE) == 0 | |
798 // hack: private should be treated as final, but alas | |
799 || (new_flags & (JVM_ACC_FINAL|JVM_ACC_STATIC)) == 0 | |
800 ) { | |
801 // new methods must be private | |
802 return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED; | |
803 } | |
804 { | |
805 u2 num = the_class->next_method_idnum(); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
806 if (num == ConstMethod::UNSET_IDNUM) { |
0 | 807 // cannot add any more methods |
808 return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED; | |
809 } | |
810 u2 new_num = k_new_method->method_idnum(); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
811 Method* idnum_owner = scratch_class->method_with_idnum(num); |
0 | 812 if (idnum_owner != NULL) { |
813 // There is already a method assigned this idnum -- switch them | |
814 idnum_owner->set_method_idnum(new_num); | |
815 } | |
816 k_new_method->set_method_idnum(num); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
817 if (thread->has_pending_exception()) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
818 return JVMTI_ERROR_OUT_OF_MEMORY; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
819 } |
0 | 820 } |
821 RC_TRACE(0x00008000, ("Method added: new: %s [%d]", | |
822 k_new_method->name_and_sig_as_C_string(), ni)); | |
823 ++ni; // advance to next new method | |
824 break; | |
825 case deleted: | |
826 // method deleted, see if it is OK | |
827 old_flags = (jushort) k_old_method->access_flags().get_flags(); | |
828 if ((old_flags & JVM_ACC_PRIVATE) == 0 | |
829 // hack: private should be treated as final, but alas | |
830 || (old_flags & (JVM_ACC_FINAL|JVM_ACC_STATIC)) == 0 | |
831 ) { | |
832 // deleted methods must be private | |
833 return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED; | |
834 } | |
835 RC_TRACE(0x00008000, ("Method deleted: old: %s [%d]", | |
836 k_old_method->name_and_sig_as_C_string(), oi)); | |
837 ++oi; // advance to next old method | |
838 break; | |
839 default: | |
840 ShouldNotReachHere(); | |
841 } | |
842 } | |
843 | |
844 return JVMTI_ERROR_NONE; | |
845 } | |
846 | |
847 | |
848 // Find new constant pool index value for old constant pool index value | |
849 // by seaching the index map. Returns zero (0) if there is no mapped | |
850 // value for the old constant pool index. | |
851 int VM_RedefineClasses::find_new_index(int old_index) { | |
852 if (_index_map_count == 0) { | |
853 // map is empty so nothing can be found | |
854 return 0; | |
855 } | |
856 | |
857 if (old_index < 1 || old_index >= _index_map_p->length()) { | |
858 // The old_index is out of range so it is not mapped. This should | |
859 // not happen in regular constant pool merging use, but it can | |
860 // happen if a corrupt annotation is processed. | |
861 return 0; | |
862 } | |
863 | |
864 int value = _index_map_p->at(old_index); | |
865 if (value == -1) { | |
866 // the old_index is not mapped | |
867 return 0; | |
868 } | |
869 | |
870 return value; | |
871 } // end find_new_index() | |
872 | |
873 | |
10151
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
874 // Find new bootstrap specifier index value for old bootstrap specifier index |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
875 // value by seaching the index map. Returns unused index (-1) if there is |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
876 // no mapped value for the old bootstrap specifier index. |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
877 int VM_RedefineClasses::find_new_operand_index(int old_index) { |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
878 if (_operands_index_map_count == 0) { |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
879 // map is empty so nothing can be found |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
880 return -1; |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
881 } |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
882 |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
883 if (old_index == -1 || old_index >= _operands_index_map_p->length()) { |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
884 // The old_index is out of range so it is not mapped. |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
885 // This should not happen in regular constant pool merging use. |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
886 return -1; |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
887 } |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
888 |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
889 int value = _operands_index_map_p->at(old_index); |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
890 if (value == -1) { |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
891 // the old_index is not mapped |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
892 return -1; |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
893 } |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
894 |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
895 return value; |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
896 } // end find_new_operand_index() |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
897 |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
898 |
0 | 899 // Returns true if the current mismatch is due to a resolved/unresolved |
900 // class pair. Otherwise, returns false. | |
901 bool VM_RedefineClasses::is_unresolved_class_mismatch(constantPoolHandle cp1, | |
902 int index1, constantPoolHandle cp2, int index2) { | |
903 | |
904 jbyte t1 = cp1->tag_at(index1).value(); | |
905 if (t1 != JVM_CONSTANT_Class && t1 != JVM_CONSTANT_UnresolvedClass) { | |
906 return false; // wrong entry type; not our special case | |
907 } | |
908 | |
909 jbyte t2 = cp2->tag_at(index2).value(); | |
910 if (t2 != JVM_CONSTANT_Class && t2 != JVM_CONSTANT_UnresolvedClass) { | |
911 return false; // wrong entry type; not our special case | |
912 } | |
913 | |
914 if (t1 == t2) { | |
915 return false; // not a mismatch; not our special case | |
916 } | |
917 | |
918 char *s1 = cp1->klass_name_at(index1)->as_C_string(); | |
919 char *s2 = cp2->klass_name_at(index2)->as_C_string(); | |
920 if (strcmp(s1, s2) != 0) { | |
921 return false; // strings don't match; not our special case | |
922 } | |
923 | |
924 return true; // made it through the gauntlet; this is our special case | |
925 } // end is_unresolved_class_mismatch() | |
926 | |
927 | |
928 jvmtiError VM_RedefineClasses::load_new_class_versions(TRAPS) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
929 |
0 | 930 // For consistency allocate memory using os::malloc wrapper. |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
931 _scratch_classes = (Klass**) |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
932 os::malloc(sizeof(Klass*) * _class_count, mtClass); |
0 | 933 if (_scratch_classes == NULL) { |
934 return JVMTI_ERROR_OUT_OF_MEMORY; | |
935 } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
936 // Zero initialize the _scratch_classes array. |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
937 for (int i = 0; i < _class_count; i++) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
938 _scratch_classes[i] = NULL; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
939 } |
0 | 940 |
941 ResourceMark rm(THREAD); | |
942 | |
943 JvmtiThreadState *state = JvmtiThreadState::state_for(JavaThread::current()); | |
609
ea20d7ce26b0
6800721: 3/4 JavaThread::jvmti_thread_state() and JvmtiThreadState::state_for() robustness
dcubed
parents:
0
diff
changeset
|
944 // state can only be NULL if the current thread is exiting which |
ea20d7ce26b0
6800721: 3/4 JavaThread::jvmti_thread_state() and JvmtiThreadState::state_for() robustness
dcubed
parents:
0
diff
changeset
|
945 // should not happen since we're trying to do a RedefineClasses |
ea20d7ce26b0
6800721: 3/4 JavaThread::jvmti_thread_state() and JvmtiThreadState::state_for() robustness
dcubed
parents:
0
diff
changeset
|
946 guarantee(state != NULL, "exiting thread calling load_new_class_versions"); |
0 | 947 for (int i = 0; i < _class_count; i++) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
948 // Create HandleMark so that any handles created while loading new class |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
949 // versions are deleted. Constant pools are deallocated while merging |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
950 // constant pools |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
951 HandleMark hm(THREAD); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
952 |
0 | 953 oop mirror = JNIHandles::resolve_non_null(_class_defs[i].klass); |
954 // classes for primitives cannot be redefined | |
955 if (!is_modifiable_class(mirror)) { | |
956 return JVMTI_ERROR_UNMODIFIABLE_CLASS; | |
957 } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
958 Klass* the_class_oop = java_lang_Class::as_Klass(mirror); |
0 | 959 instanceKlassHandle the_class = instanceKlassHandle(THREAD, the_class_oop); |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
960 Symbol* the_class_sym = the_class->name(); |
0 | 961 |
962 // RC_TRACE_WITH_THREAD macro has an embedded ResourceMark | |
963 RC_TRACE_WITH_THREAD(0x00000001, THREAD, | |
4731
4ceaf61479fc
7122253: Instrumentation.retransformClasses() leaks class bytes
dcubed
parents:
3938
diff
changeset
|
964 ("loading name=%s kind=%d (avail_mem=" UINT64_FORMAT "K)", |
4ceaf61479fc
7122253: Instrumentation.retransformClasses() leaks class bytes
dcubed
parents:
3938
diff
changeset
|
965 the_class->external_name(), _class_load_kind, |
4ceaf61479fc
7122253: Instrumentation.retransformClasses() leaks class bytes
dcubed
parents:
3938
diff
changeset
|
966 os::available_memory() >> 10)); |
0 | 967 |
968 ClassFileStream st((u1*) _class_defs[i].class_bytes, | |
969 _class_defs[i].class_byte_count, (char *)"__VM_RedefineClasses__"); | |
970 | |
971 // Parse the stream. | |
972 Handle the_class_loader(THREAD, the_class->class_loader()); | |
973 Handle protection_domain(THREAD, the_class->protection_domain()); | |
974 // Set redefined class handle in JvmtiThreadState class. | |
975 // This redefined class is sent to agent event handler for class file | |
976 // load hook event. | |
977 state->set_class_being_redefined(&the_class, _class_load_kind); | |
978 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
979 Klass* k = SystemDictionary::parse_stream(the_class_sym, |
0 | 980 the_class_loader, |
981 protection_domain, | |
982 &st, | |
983 THREAD); | |
984 // Clear class_being_redefined just to be sure. | |
985 state->clear_class_being_redefined(); | |
986 | |
987 // TODO: if this is retransform, and nothing changed we can skip it | |
988 | |
989 instanceKlassHandle scratch_class (THREAD, k); | |
990 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
991 // Need to clean up allocated InstanceKlass if there's an error so assign |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
992 // the result here. Caller deallocates all the scratch classes in case of |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
993 // an error. |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
994 _scratch_classes[i] = k; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
995 |
0 | 996 if (HAS_PENDING_EXCEPTION) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
997 Symbol* ex_name = PENDING_EXCEPTION->klass()->name(); |
0 | 998 // RC_TRACE_WITH_THREAD macro has an embedded ResourceMark |
999 RC_TRACE_WITH_THREAD(0x00000002, THREAD, ("parse_stream exception: '%s'", | |
1000 ex_name->as_C_string())); | |
1001 CLEAR_PENDING_EXCEPTION; | |
1002 | |
1003 if (ex_name == vmSymbols::java_lang_UnsupportedClassVersionError()) { | |
1004 return JVMTI_ERROR_UNSUPPORTED_VERSION; | |
1005 } else if (ex_name == vmSymbols::java_lang_ClassFormatError()) { | |
1006 return JVMTI_ERROR_INVALID_CLASS_FORMAT; | |
1007 } else if (ex_name == vmSymbols::java_lang_ClassCircularityError()) { | |
1008 return JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION; | |
1009 } else if (ex_name == vmSymbols::java_lang_NoClassDefFoundError()) { | |
1010 // The message will be "XXX (wrong name: YYY)" | |
1011 return JVMTI_ERROR_NAMES_DONT_MATCH; | |
1012 } else if (ex_name == vmSymbols::java_lang_OutOfMemoryError()) { | |
1013 return JVMTI_ERROR_OUT_OF_MEMORY; | |
1014 } else { // Just in case more exceptions can be thrown.. | |
1015 return JVMTI_ERROR_FAILS_VERIFICATION; | |
1016 } | |
1017 } | |
1018 | |
1019 // Ensure class is linked before redefine | |
1020 if (!the_class->is_linked()) { | |
1021 the_class->link_class(THREAD); | |
1022 if (HAS_PENDING_EXCEPTION) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1023 Symbol* ex_name = PENDING_EXCEPTION->klass()->name(); |
0 | 1024 // RC_TRACE_WITH_THREAD macro has an embedded ResourceMark |
1025 RC_TRACE_WITH_THREAD(0x00000002, THREAD, ("link_class exception: '%s'", | |
1026 ex_name->as_C_string())); | |
1027 CLEAR_PENDING_EXCEPTION; | |
1028 if (ex_name == vmSymbols::java_lang_OutOfMemoryError()) { | |
1029 return JVMTI_ERROR_OUT_OF_MEMORY; | |
1030 } else { | |
1031 return JVMTI_ERROR_INTERNAL; | |
1032 } | |
1033 } | |
1034 } | |
1035 | |
1036 // Do the validity checks in compare_and_normalize_class_versions() | |
1037 // before verifying the byte codes. By doing these checks first, we | |
1038 // limit the number of functions that require redirection from | |
1039 // the_class to scratch_class. In particular, we don't have to | |
1040 // modify JNI GetSuperclass() and thus won't change its performance. | |
1041 jvmtiError res = compare_and_normalize_class_versions(the_class, | |
1042 scratch_class); | |
1043 if (res != JVMTI_ERROR_NONE) { | |
1044 return res; | |
1045 } | |
1046 | |
1047 // verify what the caller passed us | |
1048 { | |
1049 // The bug 6214132 caused the verification to fail. | |
1050 // Information about the_class and scratch_class is temporarily | |
1051 // recorded into jvmtiThreadState. This data is used to redirect | |
1052 // the_class to scratch_class in the JVM_* functions called by the | |
1053 // verifier. Please, refer to jvmtiThreadState.hpp for the detailed | |
1054 // description. | |
1055 RedefineVerifyMark rvm(&the_class, &scratch_class, state); | |
1056 Verifier::verify( | |
973
ad6585fd4087
6830542: Performance: JVM_DefineClass already verified.
acorn
parents:
628
diff
changeset
|
1057 scratch_class, Verifier::ThrowException, true, THREAD); |
0 | 1058 } |
1059 | |
1060 if (HAS_PENDING_EXCEPTION) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1061 Symbol* ex_name = PENDING_EXCEPTION->klass()->name(); |
0 | 1062 // RC_TRACE_WITH_THREAD macro has an embedded ResourceMark |
1063 RC_TRACE_WITH_THREAD(0x00000002, THREAD, | |
1064 ("verify_byte_codes exception: '%s'", ex_name->as_C_string())); | |
1065 CLEAR_PENDING_EXCEPTION; | |
1066 if (ex_name == vmSymbols::java_lang_OutOfMemoryError()) { | |
1067 return JVMTI_ERROR_OUT_OF_MEMORY; | |
1068 } else { | |
1069 // tell the caller the bytecodes are bad | |
1070 return JVMTI_ERROR_FAILS_VERIFICATION; | |
1071 } | |
1072 } | |
1073 | |
1074 res = merge_cp_and_rewrite(the_class, scratch_class, THREAD); | |
1075 if (res != JVMTI_ERROR_NONE) { | |
1076 return res; | |
1077 } | |
1078 | |
1079 if (VerifyMergedCPBytecodes) { | |
1080 // verify what we have done during constant pool merging | |
1081 { | |
1082 RedefineVerifyMark rvm(&the_class, &scratch_class, state); | |
973
ad6585fd4087
6830542: Performance: JVM_DefineClass already verified.
acorn
parents:
628
diff
changeset
|
1083 Verifier::verify(scratch_class, Verifier::ThrowException, true, THREAD); |
0 | 1084 } |
1085 | |
1086 if (HAS_PENDING_EXCEPTION) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1087 Symbol* ex_name = PENDING_EXCEPTION->klass()->name(); |
0 | 1088 // RC_TRACE_WITH_THREAD macro has an embedded ResourceMark |
1089 RC_TRACE_WITH_THREAD(0x00000002, THREAD, | |
1090 ("verify_byte_codes post merge-CP exception: '%s'", | |
1091 ex_name->as_C_string())); | |
1092 CLEAR_PENDING_EXCEPTION; | |
1093 if (ex_name == vmSymbols::java_lang_OutOfMemoryError()) { | |
1094 return JVMTI_ERROR_OUT_OF_MEMORY; | |
1095 } else { | |
1096 // tell the caller that constant pool merging screwed up | |
1097 return JVMTI_ERROR_INTERNAL; | |
1098 } | |
1099 } | |
1100 } | |
1101 | |
1102 Rewriter::rewrite(scratch_class, THREAD); | |
3748 | 1103 if (!HAS_PENDING_EXCEPTION) { |
7459
cc6a617fffd2
8005494: SIGSEGV in Rewriter::relocate_and_link() when testing Weblogic with CompressedOops and KlassPtrs
coleenp
parents:
7457
diff
changeset
|
1104 scratch_class->link_methods(THREAD); |
3748 | 1105 } |
0 | 1106 if (HAS_PENDING_EXCEPTION) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1107 Symbol* ex_name = PENDING_EXCEPTION->klass()->name(); |
0 | 1108 CLEAR_PENDING_EXCEPTION; |
1109 if (ex_name == vmSymbols::java_lang_OutOfMemoryError()) { | |
1110 return JVMTI_ERROR_OUT_OF_MEMORY; | |
1111 } else { | |
1112 return JVMTI_ERROR_INTERNAL; | |
1113 } | |
1114 } | |
1115 | |
1116 // RC_TRACE_WITH_THREAD macro has an embedded ResourceMark | |
1117 RC_TRACE_WITH_THREAD(0x00000001, THREAD, | |
1118 ("loaded name=%s (avail_mem=" UINT64_FORMAT "K)", | |
1119 the_class->external_name(), os::available_memory() >> 10)); | |
1120 } | |
1121 | |
1122 return JVMTI_ERROR_NONE; | |
1123 } | |
1124 | |
1125 | |
1126 // Map old_index to new_index as needed. scratch_cp is only needed | |
1127 // for RC_TRACE() calls. | |
1128 void VM_RedefineClasses::map_index(constantPoolHandle scratch_cp, | |
1129 int old_index, int new_index) { | |
1130 if (find_new_index(old_index) != 0) { | |
1131 // old_index is already mapped | |
1132 return; | |
1133 } | |
1134 | |
1135 if (old_index == new_index) { | |
1136 // no mapping is needed | |
1137 return; | |
1138 } | |
1139 | |
1140 _index_map_p->at_put(old_index, new_index); | |
1141 _index_map_count++; | |
1142 | |
1143 RC_TRACE(0x00040000, ("mapped tag %d at index %d to %d", | |
1144 scratch_cp->tag_at(old_index).value(), old_index, new_index)); | |
1145 } // end map_index() | |
1146 | |
1147 | |
10151
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
1148 // Map old_index to new_index as needed. |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
1149 void VM_RedefineClasses::map_operand_index(int old_index, int new_index) { |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
1150 if (find_new_operand_index(old_index) != -1) { |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
1151 // old_index is already mapped |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
1152 return; |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
1153 } |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
1154 |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
1155 if (old_index == new_index) { |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
1156 // no mapping is needed |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
1157 return; |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
1158 } |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
1159 |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
1160 _operands_index_map_p->at_put(old_index, new_index); |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
1161 _operands_index_map_count++; |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
1162 |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
1163 RC_TRACE(0x00040000, ("mapped bootstrap specifier at index %d to %d", old_index, new_index)); |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
1164 } // end map_index() |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
1165 |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
1166 |
0 | 1167 // Merge old_cp and scratch_cp and return the results of the merge via |
1168 // merge_cp_p. The number of entries in *merge_cp_p is returned via | |
1169 // merge_cp_length_p. The entries in old_cp occupy the same locations | |
1170 // in *merge_cp_p. Also creates a map of indices from entries in | |
1171 // scratch_cp to the corresponding entry in *merge_cp_p. Index map | |
1172 // entries are only created for entries in scratch_cp that occupy a | |
1173 // different location in *merged_cp_p. | |
1174 bool VM_RedefineClasses::merge_constant_pools(constantPoolHandle old_cp, | |
1175 constantPoolHandle scratch_cp, constantPoolHandle *merge_cp_p, | |
1176 int *merge_cp_length_p, TRAPS) { | |
1177 | |
1178 if (merge_cp_p == NULL) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1179 assert(false, "caller must provide scratch constantPool"); |
0 | 1180 return false; // robustness |
1181 } | |
1182 if (merge_cp_length_p == NULL) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1183 assert(false, "caller must provide scratch CP length"); |
0 | 1184 return false; // robustness |
1185 } | |
1186 // Worst case we need old_cp->length() + scratch_cp()->length(), | |
1187 // but the caller might be smart so make sure we have at least | |
1188 // the minimum. | |
1189 if ((*merge_cp_p)->length() < old_cp->length()) { | |
1190 assert(false, "merge area too small"); | |
1191 return false; // robustness | |
1192 } | |
1193 | |
1194 RC_TRACE_WITH_THREAD(0x00010000, THREAD, | |
1195 ("old_cp_len=%d, scratch_cp_len=%d", old_cp->length(), | |
1196 scratch_cp->length())); | |
1197 | |
1198 { | |
1199 // Pass 0: | |
1200 // The old_cp is copied to *merge_cp_p; this means that any code | |
1201 // using old_cp does not have to change. This work looks like a | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1202 // perfect fit for ConstantPool*::copy_cp_to(), but we need to |
0 | 1203 // handle one special case: |
1204 // - revert JVM_CONSTANT_Class to JVM_CONSTANT_UnresolvedClass | |
1205 // This will make verification happy. | |
1206 | |
1207 int old_i; // index into old_cp | |
1208 | |
1209 // index zero (0) is not used in constantPools | |
1210 for (old_i = 1; old_i < old_cp->length(); old_i++) { | |
1211 // leave debugging crumb | |
1212 jbyte old_tag = old_cp->tag_at(old_i).value(); | |
1213 switch (old_tag) { | |
1214 case JVM_CONSTANT_Class: | |
2332
fbbeec6dad2d
6512830: Error: assert(tag_at(which).is_unresolved_klass(), "Corrupted constant pool")
coleenp
parents:
2226
diff
changeset
|
1215 case JVM_CONSTANT_UnresolvedClass: |
0 | 1216 // revert the copy to JVM_CONSTANT_UnresolvedClass |
2332
fbbeec6dad2d
6512830: Error: assert(tag_at(which).is_unresolved_klass(), "Corrupted constant pool")
coleenp
parents:
2226
diff
changeset
|
1217 // May be resolving while calling this so do the same for |
fbbeec6dad2d
6512830: Error: assert(tag_at(which).is_unresolved_klass(), "Corrupted constant pool")
coleenp
parents:
2226
diff
changeset
|
1218 // JVM_CONSTANT_UnresolvedClass (klass_name_at() deals with transition) |
0 | 1219 (*merge_cp_p)->unresolved_klass_at_put(old_i, |
1220 old_cp->klass_name_at(old_i)); | |
1221 break; | |
1222 | |
1223 case JVM_CONSTANT_Double: | |
1224 case JVM_CONSTANT_Long: | |
1225 // just copy the entry to *merge_cp_p, but double and long take | |
1226 // two constant pool entries | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1227 ConstantPool::copy_entry_to(old_cp, old_i, *merge_cp_p, old_i, CHECK_0); |
0 | 1228 old_i++; |
1229 break; | |
1230 | |
1231 default: | |
1232 // just copy the entry to *merge_cp_p | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1233 ConstantPool::copy_entry_to(old_cp, old_i, *merge_cp_p, old_i, CHECK_0); |
0 | 1234 break; |
1235 } | |
1236 } // end for each old_cp entry | |
1237 | |
7952
edd76a5856f7
8005128: JSR 292: the mlvm redefineClassInBootstrap test crashes in ConstantPool::compare_entry_to
sspitsyn
parents:
7949
diff
changeset
|
1238 ConstantPool::copy_operands(old_cp, *merge_cp_p, CHECK_0); |
10151
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
1239 (*merge_cp_p)->extend_operands(scratch_cp, CHECK_0); |
7952
edd76a5856f7
8005128: JSR 292: the mlvm redefineClassInBootstrap test crashes in ConstantPool::compare_entry_to
sspitsyn
parents:
7949
diff
changeset
|
1240 |
0 | 1241 // We don't need to sanity check that *merge_cp_length_p is within |
1242 // *merge_cp_p bounds since we have the minimum on-entry check above. | |
1243 (*merge_cp_length_p) = old_i; | |
1244 } | |
1245 | |
1246 // merge_cp_len should be the same as old_cp->length() at this point | |
1247 // so this trace message is really a "warm-and-breathing" message. | |
1248 RC_TRACE_WITH_THREAD(0x00020000, THREAD, | |
1249 ("after pass 0: merge_cp_len=%d", *merge_cp_length_p)); | |
1250 | |
1251 int scratch_i; // index into scratch_cp | |
1252 { | |
1253 // Pass 1a: | |
1254 // Compare scratch_cp entries to the old_cp entries that we have | |
1255 // already copied to *merge_cp_p. In this pass, we are eliminating | |
1256 // exact duplicates (matching entry at same index) so we only | |
1257 // compare entries in the common indice range. | |
1258 int increment = 1; | |
1259 int pass1a_length = MIN2(old_cp->length(), scratch_cp->length()); | |
1260 for (scratch_i = 1; scratch_i < pass1a_length; scratch_i += increment) { | |
1261 switch (scratch_cp->tag_at(scratch_i).value()) { | |
1262 case JVM_CONSTANT_Double: | |
1263 case JVM_CONSTANT_Long: | |
1264 // double and long take two constant pool entries | |
1265 increment = 2; | |
1266 break; | |
1267 | |
1268 default: | |
1269 increment = 1; | |
1270 break; | |
1271 } | |
1272 | |
1273 bool match = scratch_cp->compare_entry_to(scratch_i, *merge_cp_p, | |
1274 scratch_i, CHECK_0); | |
1275 if (match) { | |
1276 // found a match at the same index so nothing more to do | |
1277 continue; | |
1278 } else if (is_unresolved_class_mismatch(scratch_cp, scratch_i, | |
1279 *merge_cp_p, scratch_i)) { | |
1280 // The mismatch in compare_entry_to() above is because of a | |
1281 // resolved versus unresolved class entry at the same index | |
1282 // with the same string value. Since Pass 0 reverted any | |
1283 // class entries to unresolved class entries in *merge_cp_p, | |
1284 // we go with the unresolved class entry. | |
1285 continue; | |
1286 } | |
1287 | |
1288 int found_i = scratch_cp->find_matching_entry(scratch_i, *merge_cp_p, | |
1289 CHECK_0); | |
1290 if (found_i != 0) { | |
1291 guarantee(found_i != scratch_i, | |
1292 "compare_entry_to() and find_matching_entry() do not agree"); | |
1293 | |
1294 // Found a matching entry somewhere else in *merge_cp_p so | |
1295 // just need a mapping entry. | |
1296 map_index(scratch_cp, scratch_i, found_i); | |
1297 continue; | |
1298 } | |
1299 | |
1300 // The find_matching_entry() call above could fail to find a match | |
1301 // due to a resolved versus unresolved class or string entry situation | |
1302 // like we solved above with the is_unresolved_*_mismatch() calls. | |
1303 // However, we would have to call is_unresolved_*_mismatch() over | |
1304 // all of *merge_cp_p (potentially) and that doesn't seem to be | |
1305 // worth the time. | |
1306 | |
1307 // No match found so we have to append this entry and any unique | |
1308 // referenced entries to *merge_cp_p. | |
1309 append_entry(scratch_cp, scratch_i, merge_cp_p, merge_cp_length_p, | |
1310 CHECK_0); | |
1311 } | |
1312 } | |
1313 | |
1314 RC_TRACE_WITH_THREAD(0x00020000, THREAD, | |
1315 ("after pass 1a: merge_cp_len=%d, scratch_i=%d, index_map_len=%d", | |
1316 *merge_cp_length_p, scratch_i, _index_map_count)); | |
1317 | |
1318 if (scratch_i < scratch_cp->length()) { | |
1319 // Pass 1b: | |
1320 // old_cp is smaller than scratch_cp so there are entries in | |
1321 // scratch_cp that we have not yet processed. We take care of | |
1322 // those now. | |
1323 int increment = 1; | |
1324 for (; scratch_i < scratch_cp->length(); scratch_i += increment) { | |
1325 switch (scratch_cp->tag_at(scratch_i).value()) { | |
1326 case JVM_CONSTANT_Double: | |
1327 case JVM_CONSTANT_Long: | |
1328 // double and long take two constant pool entries | |
1329 increment = 2; | |
1330 break; | |
1331 | |
1332 default: | |
1333 increment = 1; | |
1334 break; | |
1335 } | |
1336 | |
1337 int found_i = | |
1338 scratch_cp->find_matching_entry(scratch_i, *merge_cp_p, CHECK_0); | |
1339 if (found_i != 0) { | |
1340 // Found a matching entry somewhere else in *merge_cp_p so | |
1341 // just need a mapping entry. | |
1342 map_index(scratch_cp, scratch_i, found_i); | |
1343 continue; | |
1344 } | |
1345 | |
1346 // No match found so we have to append this entry and any unique | |
1347 // referenced entries to *merge_cp_p. | |
1348 append_entry(scratch_cp, scratch_i, merge_cp_p, merge_cp_length_p, | |
1349 CHECK_0); | |
1350 } | |
1351 | |
1352 RC_TRACE_WITH_THREAD(0x00020000, THREAD, | |
1353 ("after pass 1b: merge_cp_len=%d, scratch_i=%d, index_map_len=%d", | |
1354 *merge_cp_length_p, scratch_i, _index_map_count)); | |
1355 } | |
10382
e7d29a019a3c
8014052: JSR292: assert(end_offset == next_offset) failed: matched ending
sspitsyn
parents:
10268
diff
changeset
|
1356 finalize_operands_merge(*merge_cp_p, THREAD); |
0 | 1357 |
1358 return true; | |
1359 } // end merge_constant_pools() | |
1360 | |
1361 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1362 // Scoped object to clean up the constant pool(s) created for merging |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1363 class MergeCPCleaner { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1364 ClassLoaderData* _loader_data; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1365 ConstantPool* _cp; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1366 ConstantPool* _scratch_cp; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1367 public: |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1368 MergeCPCleaner(ClassLoaderData* loader_data, ConstantPool* merge_cp) : |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1369 _loader_data(loader_data), _cp(merge_cp), _scratch_cp(NULL) {} |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1370 ~MergeCPCleaner() { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1371 _loader_data->add_to_deallocate_list(_cp); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1372 if (_scratch_cp != NULL) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1373 _loader_data->add_to_deallocate_list(_scratch_cp); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1374 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1375 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1376 void add_scratch_cp(ConstantPool* scratch_cp) { _scratch_cp = scratch_cp; } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1377 }; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1378 |
0 | 1379 // Merge constant pools between the_class and scratch_class and |
1380 // potentially rewrite bytecodes in scratch_class to use the merged | |
1381 // constant pool. | |
1382 jvmtiError VM_RedefineClasses::merge_cp_and_rewrite( | |
1383 instanceKlassHandle the_class, instanceKlassHandle scratch_class, | |
1384 TRAPS) { | |
1385 // worst case merged constant pool length is old and new combined | |
1386 int merge_cp_length = the_class->constants()->length() | |
1387 + scratch_class->constants()->length(); | |
1388 | |
1389 // Constant pools are not easily reused so we allocate a new one | |
1390 // each time. | |
518
0af8b0718fc9
6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents:
0
diff
changeset
|
1391 // merge_cp is created unsafe for concurrent GC processing. It |
2226
c5a923563727
6912621: iCMS: Error: assert(_markBitMap.isMarked(addr + 1),"Missing Printezis bit?")
ysr
parents:
2177
diff
changeset
|
1392 // should be marked safe before discarding it. Even though |
c5a923563727
6912621: iCMS: Error: assert(_markBitMap.isMarked(addr + 1),"Missing Printezis bit?")
ysr
parents:
2177
diff
changeset
|
1393 // garbage, if it crosses a card boundary, it may be scanned |
518
0af8b0718fc9
6692899: CMS: many vm.parallel_class_loading tests fail with assert "missing Printezis mark"
jmasa
parents:
0
diff
changeset
|
1394 // in order to find the start of the first complete object on the card. |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1395 ClassLoaderData* loader_data = the_class->class_loader_data(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1396 ConstantPool* merge_cp_oop = |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1397 ConstantPool::allocate(loader_data, |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1398 merge_cp_length, |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1399 THREAD); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1400 MergeCPCleaner cp_cleaner(loader_data, merge_cp_oop); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1401 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1402 HandleMark hm(THREAD); // make sure handles are cleared before |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1403 // MergeCPCleaner clears out merge_cp_oop |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1404 constantPoolHandle merge_cp(THREAD, merge_cp_oop); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1405 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1406 // Get constants() from the old class because it could have been rewritten |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1407 // while we were at a safepoint allocating a new constant pool. |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1408 constantPoolHandle old_cp(THREAD, the_class->constants()); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1409 constantPoolHandle scratch_cp(THREAD, scratch_class->constants()); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1410 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1411 // If the length changed, the class was redefined out from under us. Return |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1412 // an error. |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1413 if (merge_cp_length != the_class->constants()->length() |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1414 + scratch_class->constants()->length()) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1415 return JVMTI_ERROR_INTERNAL; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1416 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1417 |
7624
b14da2e6f2dc
7174978: NPG: Fix bactrace builder for class redefinition
coleenp
parents:
7459
diff
changeset
|
1418 // Update the version number of the constant pool |
b14da2e6f2dc
7174978: NPG: Fix bactrace builder for class redefinition
coleenp
parents:
7459
diff
changeset
|
1419 merge_cp->increment_and_save_version(old_cp->version()); |
0 | 1420 |
1421 ResourceMark rm(THREAD); | |
1422 _index_map_count = 0; | |
1423 _index_map_p = new intArray(scratch_cp->length(), -1); | |
1424 | |
10151
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
1425 _operands_cur_length = ConstantPool::operand_array_length(old_cp->operands()); |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
1426 _operands_index_map_count = 0; |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
1427 _operands_index_map_p = new intArray( |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
1428 ConstantPool::operand_array_length(scratch_cp->operands()), -1); |
15a99ca4ee34
8007037: JSR 292: the VM_RedefineClasses::append_entry() should do cross-checks with indy operands
sspitsyn
parents:
10133
diff
changeset
|
1429 |
7952
edd76a5856f7
8005128: JSR 292: the mlvm redefineClassInBootstrap test crashes in ConstantPool::compare_entry_to
sspitsyn
parents:
7949
diff
changeset
|
1430 // reference to the cp holder is needed for copy_operands() |
edd76a5856f7
8005128: JSR 292: the mlvm redefineClassInBootstrap test crashes in ConstantPool::compare_entry_to
sspitsyn
parents:
7949
diff
changeset
|
1431 merge_cp->set_pool_holder(scratch_class()); |
0 | 1432 bool result = merge_constant_pools(old_cp, scratch_cp, &merge_cp, |
1433 &merge_cp_length, THREAD); | |
7952
edd76a5856f7
8005128: JSR 292: the mlvm redefineClassInBootstrap test crashes in ConstantPool::compare_entry_to
sspitsyn
parents:
7949
diff
changeset
|
1434 merge_cp->set_pool_holder(NULL); |
edd76a5856f7
8005128: JSR 292: the mlvm redefineClassInBootstrap test crashes in ConstantPool::compare_entry_to
sspitsyn
parents:
7949
diff
changeset
|
1435 |
0 | 1436 if (!result) { |
1437 // The merge can fail due to memory allocation failure or due | |
1438 // to robustness checks. | |
1439 return JVMTI_ERROR_INTERNAL; | |
1440 } | |
1441 | |
1442 RC_TRACE_WITH_THREAD(0x00010000, THREAD, | |
1443 ("merge_cp_len=%d, index_map_len=%d", merge_cp_length, _index_map_count)); | |
1444 | |
1445 if (_index_map_count == 0) { | |
1446 // there is nothing to map between the new and merged constant pools | |
1447 | |
1448 if (old_cp->length() == scratch_cp->length()) { | |
1449 // The old and new constant pools are the same length and the | |
1450 // index map is empty. This means that the three constant pools | |
1451 // are equivalent (but not the same). Unfortunately, the new | |
1452 // constant pool has not gone through link resolution nor have | |
1453 // the new class bytecodes gone through constant pool cache | |
1454 // rewriting so we can't use the old constant pool with the new | |
1455 // class. | |
1456 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1457 // toss the merged constant pool at return |
0 | 1458 } else if (old_cp->length() < scratch_cp->length()) { |
1459 // The old constant pool has fewer entries than the new constant | |
1460 // pool and the index map is empty. This means the new constant | |
1461 // pool is a superset of the old constant pool. However, the old | |
1462 // class bytecodes have already gone through constant pool cache | |
1463 // rewriting so we can't use the new constant pool with the old | |
1464 // class. | |
1465 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1466 // toss the merged constant pool at return |
0 | 1467 } else { |
1468 // The old constant pool has more entries than the new constant | |
1469 // pool and the index map is empty. This means that both the old | |
1470 // and merged constant pools are supersets of the new constant | |
1471 // pool. | |
1472 | |
1473 // Replace the new constant pool with a shrunken copy of the | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1474 // merged constant pool |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1475 set_new_constant_pool(loader_data, scratch_class, merge_cp, merge_cp_length, THREAD); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1476 // The new constant pool replaces scratch_cp so have cleaner clean it up. |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1477 // It can't be cleaned up while there are handles to it. |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1478 cp_cleaner.add_scratch_cp(scratch_cp()); |
0 | 1479 } |
1480 } else { | |
1481 if (RC_TRACE_ENABLED(0x00040000)) { | |
1482 // don't want to loop unless we are tracing | |
1483 int count = 0; | |
1484 for (int i = 1; i < _index_map_p->length(); i++) { | |
1485 int value = _index_map_p->at(i); | |
1486 | |
1487 if (value != -1) { | |
1488 RC_TRACE_WITH_THREAD(0x00040000, THREAD, | |
1489 ("index_map[%d]: old=%d new=%d", count, i, value)); | |
1490 count++; | |
1491 } | |
1492 } | |
1493 } | |
1494 | |
1495 // We have entries mapped between the new and merged constant pools | |
1496 // so we have to rewrite some constant pool references. | |
1497 if (!rewrite_cp_refs(scratch_class, THREAD)) { | |
1498 return JVMTI_ERROR_INTERNAL; | |
1499 } | |
1500 | |
1501 // Replace the new constant pool with a shrunken copy of the | |
1502 // merged constant pool so now the rewritten bytecodes have | |
1503 // valid references; the previous new constant pool will get | |
1504 // GCed. | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1505 set_new_constant_pool(loader_data, scratch_class, merge_cp, merge_cp_length, THREAD); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1506 // The new constant pool replaces scratch_cp so have cleaner clean it up. |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1507 // It can't be cleaned up while there are handles to it. |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1508 cp_cleaner.add_scratch_cp(scratch_cp()); |
0 | 1509 } |
1510 | |
1511 return JVMTI_ERROR_NONE; | |
1512 } // end merge_cp_and_rewrite() | |
1513 | |
1514 | |
1515 // Rewrite constant pool references in klass scratch_class. | |
1516 bool VM_RedefineClasses::rewrite_cp_refs(instanceKlassHandle scratch_class, | |
1517 TRAPS) { | |
1518 | |
1519 // rewrite constant pool references in the methods: | |
1520 if (!rewrite_cp_refs_in_methods(scratch_class, THREAD)) { | |
605 | 1521 // propagate failure back to caller |
0 | 1522 return false; |
1523 } | |
1524 | |
1525 // rewrite constant pool references in the class_annotations: | |
1526 if (!rewrite_cp_refs_in_class_annotations(scratch_class, THREAD)) { | |
605 | 1527 // propagate failure back to caller |
0 | 1528 return false; |
1529 } | |
1530 | |
1531 // rewrite constant pool references in the fields_annotations: | |
1532 if (!rewrite_cp_refs_in_fields_annotations(scratch_class, THREAD)) { | |
605 | 1533 // propagate failure back to caller |
0 | 1534 return false; |
1535 } | |
1536 | |
1537 // rewrite constant pool references in the methods_annotations: | |
1538 if (!rewrite_cp_refs_in_methods_annotations(scratch_class, THREAD)) { | |
605 | 1539 // propagate failure back to caller |
0 | 1540 return false; |
1541 } | |
1542 | |
1543 // rewrite constant pool references in the methods_parameter_annotations: | |
1544 if (!rewrite_cp_refs_in_methods_parameter_annotations(scratch_class, | |
1545 THREAD)) { | |
605 | 1546 // propagate failure back to caller |
0 | 1547 return false; |
1548 } | |
1549 | |
1550 // rewrite constant pool references in the methods_default_annotations: | |
1551 if (!rewrite_cp_refs_in_methods_default_annotations(scratch_class, | |
1552 THREAD)) { | |
605 | 1553 // propagate failure back to caller |
0 | 1554 return false; |
1555 } | |
1556 | |
12101
ff2520b97b00
8023547: com/sun/jdi/RedefineMulti.sh fails with IllegalArgumentException after JDK-8021948 .
jiangli
parents:
12067
diff
changeset
|
1557 // rewrite source file name index: |
12067
e22ee8e7ae62
8021948: Change InstanceKlass::_source_file_name and _generic_signature from Symbol* to constant pool indexes.
jiangli
parents:
12022
diff
changeset
|
1558 u2 source_file_name_idx = scratch_class->source_file_name_index(); |
e22ee8e7ae62
8021948: Change InstanceKlass::_source_file_name and _generic_signature from Symbol* to constant pool indexes.
jiangli
parents:
12022
diff
changeset
|
1559 if (source_file_name_idx != 0) { |
e22ee8e7ae62
8021948: Change InstanceKlass::_source_file_name and _generic_signature from Symbol* to constant pool indexes.
jiangli
parents:
12022
diff
changeset
|
1560 u2 new_source_file_name_idx = find_new_index(source_file_name_idx); |
12101
ff2520b97b00
8023547: com/sun/jdi/RedefineMulti.sh fails with IllegalArgumentException after JDK-8021948 .
jiangli
parents:
12067
diff
changeset
|
1561 if (new_source_file_name_idx != 0) { |
ff2520b97b00
8023547: com/sun/jdi/RedefineMulti.sh fails with IllegalArgumentException after JDK-8021948 .
jiangli
parents:
12067
diff
changeset
|
1562 scratch_class->set_source_file_name_index(new_source_file_name_idx); |
ff2520b97b00
8023547: com/sun/jdi/RedefineMulti.sh fails with IllegalArgumentException after JDK-8021948 .
jiangli
parents:
12067
diff
changeset
|
1563 } |
12067
e22ee8e7ae62
8021948: Change InstanceKlass::_source_file_name and _generic_signature from Symbol* to constant pool indexes.
jiangli
parents:
12022
diff
changeset
|
1564 } |
e22ee8e7ae62
8021948: Change InstanceKlass::_source_file_name and _generic_signature from Symbol* to constant pool indexes.
jiangli
parents:
12022
diff
changeset
|
1565 |
e22ee8e7ae62
8021948: Change InstanceKlass::_source_file_name and _generic_signature from Symbol* to constant pool indexes.
jiangli
parents:
12022
diff
changeset
|
1566 // rewrite class generic signature index: |
e22ee8e7ae62
8021948: Change InstanceKlass::_source_file_name and _generic_signature from Symbol* to constant pool indexes.
jiangli
parents:
12022
diff
changeset
|
1567 u2 generic_signature_index = scratch_class->generic_signature_index(); |
e22ee8e7ae62
8021948: Change InstanceKlass::_source_file_name and _generic_signature from Symbol* to constant pool indexes.
jiangli
parents:
12022
diff
changeset
|
1568 if (generic_signature_index != 0) { |
e22ee8e7ae62
8021948: Change InstanceKlass::_source_file_name and _generic_signature from Symbol* to constant pool indexes.
jiangli
parents:
12022
diff
changeset
|
1569 u2 new_generic_signature_index = find_new_index(generic_signature_index); |
12101
ff2520b97b00
8023547: com/sun/jdi/RedefineMulti.sh fails with IllegalArgumentException after JDK-8021948 .
jiangli
parents:
12067
diff
changeset
|
1570 if (new_generic_signature_index != 0) { |
ff2520b97b00
8023547: com/sun/jdi/RedefineMulti.sh fails with IllegalArgumentException after JDK-8021948 .
jiangli
parents:
12067
diff
changeset
|
1571 scratch_class->set_generic_signature_index(new_generic_signature_index); |
ff2520b97b00
8023547: com/sun/jdi/RedefineMulti.sh fails with IllegalArgumentException after JDK-8021948 .
jiangli
parents:
12067
diff
changeset
|
1572 } |
12067
e22ee8e7ae62
8021948: Change InstanceKlass::_source_file_name and _generic_signature from Symbol* to constant pool indexes.
jiangli
parents:
12022
diff
changeset
|
1573 } |
e22ee8e7ae62
8021948: Change InstanceKlass::_source_file_name and _generic_signature from Symbol* to constant pool indexes.
jiangli
parents:
12022
diff
changeset
|
1574 |
0 | 1575 return true; |
1576 } // end rewrite_cp_refs() | |
1577 | |
1578 // Rewrite constant pool references in the methods. | |
1579 bool VM_RedefineClasses::rewrite_cp_refs_in_methods( | |
1580 instanceKlassHandle scratch_class, TRAPS) { | |
1581 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1582 Array<Method*>* methods = scratch_class->methods(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1583 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1584 if (methods == NULL || methods->length() == 0) { |
0 | 1585 // no methods so nothing to do |
1586 return true; | |
1587 } | |
1588 | |
1589 // rewrite constant pool references in the methods: | |
1590 for (int i = methods->length() - 1; i >= 0; i--) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1591 methodHandle method(THREAD, methods->at(i)); |
0 | 1592 methodHandle new_method; |
1593 rewrite_cp_refs_in_method(method, &new_method, CHECK_false); | |
1594 if (!new_method.is_null()) { | |
1595 // the method has been replaced so save the new method version | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1596 methods->at_put(i, new_method()); |
0 | 1597 } |
1598 } | |
1599 | |
1600 return true; | |
1601 } | |
1602 | |
1603 | |
1604 // Rewrite constant pool references in the specific method. This code | |
1605 // was adapted from Rewriter::rewrite_method(). | |
1606 void VM_RedefineClasses::rewrite_cp_refs_in_method(methodHandle method, | |
1607 methodHandle *new_method_p, TRAPS) { | |
1608 | |
1609 *new_method_p = methodHandle(); // default is no new method | |
1610 | |
1611 // We cache a pointer to the bytecodes here in code_base. If GC | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1612 // moves the Method*, then the bytecodes will also move which |
0 | 1613 // will likely cause a crash. We create a No_Safepoint_Verifier |
1614 // object to detect whether we pass a possible safepoint in this | |
1615 // code block. | |
1616 No_Safepoint_Verifier nsv; | |
1617 | |
1618 // Bytecodes and their length | |
1619 address code_base = method->code_base(); | |
1620 int code_length = method->code_size(); | |
1621 | |
1622 int bc_length; | |
1623 for (int bci = 0; bci < code_length; bci += bc_length) { | |
1624 address bcp = code_base + bci; | |
1625 Bytecodes::Code c = (Bytecodes::Code)(*bcp); | |
1626 | |
1627 bc_length = Bytecodes::length_for(c); | |
1628 if (bc_length == 0) { | |
1629 // More complicated bytecodes report a length of zero so | |
1630 // we have to try again a slightly different way. | |
2142 | 1631 bc_length = Bytecodes::length_at(method(), bcp); |
0 | 1632 } |
1633 | |
1634 assert(bc_length != 0, "impossible bytecode length"); | |
1635 | |
1636 switch (c) { | |
1637 case Bytecodes::_ldc: | |
1638 { | |
1639 int cp_index = *(bcp + 1); | |
1640 int new_index = find_new_index(cp_index); | |
1641 | |
1642 if (StressLdcRewrite && new_index == 0) { | |
1643 // If we are stressing ldc -> ldc_w rewriting, then we | |
1644 // always need a new_index value. | |
1645 new_index = cp_index; | |
1646 } | |
1647 if (new_index != 0) { | |
1648 // the original index is mapped so we have more work to do | |
1649 if (!StressLdcRewrite && new_index <= max_jubyte) { | |
1650 // The new value can still use ldc instead of ldc_w | |
1651 // unless we are trying to stress ldc -> ldc_w rewriting | |
1652 RC_TRACE_WITH_THREAD(0x00080000, THREAD, | |
1653 ("%s@" INTPTR_FORMAT " old=%d, new=%d", Bytecodes::name(c), | |
1654 bcp, cp_index, new_index)); | |
1655 *(bcp + 1) = new_index; | |
1656 } else { | |
1657 RC_TRACE_WITH_THREAD(0x00080000, THREAD, | |
1658 ("%s->ldc_w@" INTPTR_FORMAT " old=%d, new=%d", | |
1659 Bytecodes::name(c), bcp, cp_index, new_index)); | |
1660 // the new value needs ldc_w instead of ldc | |
1661 u_char inst_buffer[4]; // max instruction size is 4 bytes | |
1662 bcp = (address)inst_buffer; | |
1663 // construct new instruction sequence | |
1664 *bcp = Bytecodes::_ldc_w; | |
1665 bcp++; | |
1666 // Rewriter::rewrite_method() does not rewrite ldc -> ldc_w. | |
1667 // See comment below for difference between put_Java_u2() | |
1668 // and put_native_u2(). | |
1669 Bytes::put_Java_u2(bcp, new_index); | |
1670 | |
1671 Relocator rc(method, NULL /* no RelocatorListener needed */); | |
1672 methodHandle m; | |
1673 { | |
1674 Pause_No_Safepoint_Verifier pnsv(&nsv); | |
1675 | |
1676 // ldc is 2 bytes and ldc_w is 3 bytes | |
1677 m = rc.insert_space_at(bci, 3, inst_buffer, THREAD); | |
1678 if (m.is_null() || HAS_PENDING_EXCEPTION) { | |
1679 guarantee(false, "insert_space_at() failed"); | |
1680 } | |
1681 } | |
1682 | |
1683 // return the new method so that the caller can update | |
1684 // the containing class | |
1685 *new_method_p = method = m; | |
1686 // switch our bytecode processing loop from the old method | |
1687 // to the new method | |
1688 code_base = method->code_base(); | |
1689 code_length = method->code_size(); | |
1690 bcp = code_base + bci; | |
1691 c = (Bytecodes::Code)(*bcp); | |
1692 bc_length = Bytecodes::length_for(c); | |
1693 assert(bc_length != 0, "sanity check"); | |
1694 } // end we need ldc_w instead of ldc | |
1695 } // end if there is a mapped index | |
1696 } break; | |
1697 | |
1698 // these bytecodes have a two-byte constant pool index | |
1699 case Bytecodes::_anewarray : // fall through | |
1700 case Bytecodes::_checkcast : // fall through | |
1701 case Bytecodes::_getfield : // fall through | |
1702 case Bytecodes::_getstatic : // fall through | |
1703 case Bytecodes::_instanceof : // fall through | |
7965
79c1bb8fce5d
8006731: JSR 292: the VM_RedefineClasses::rewrite_cp_refs_in_method() must support invokedynamic
sspitsyn
parents:
7963
diff
changeset
|
1704 case Bytecodes::_invokedynamic : // fall through |
0 | 1705 case Bytecodes::_invokeinterface: // fall through |
1706 case Bytecodes::_invokespecial : // fall through | |
1707 case Bytecodes::_invokestatic : // fall through | |
1708 case Bytecodes::_invokevirtual : // fall through | |
1709 case Bytecodes::_ldc_w : // fall through | |
1710 case Bytecodes::_ldc2_w : // fall through | |
1711 case Bytecodes::_multianewarray : // fall through | |
1712 case Bytecodes::_new : // fall through | |
1713 case Bytecodes::_putfield : // fall through | |
1714 case Bytecodes::_putstatic : | |
1715 { | |
1716 address p = bcp + 1; | |
1717 int cp_index = Bytes::get_Java_u2(p); | |
1718 int new_index = find_new_index(cp_index); | |
1719 if (new_index != 0) { | |
1720 // the original index is mapped so update w/ new value | |
1721 RC_TRACE_WITH_THREAD(0x00080000, THREAD, | |
1722 ("%s@" INTPTR_FORMAT " old=%d, new=%d", Bytecodes::name(c), | |
1723 bcp, cp_index, new_index)); | |
1724 // Rewriter::rewrite_method() uses put_native_u2() in this | |
1725 // situation because it is reusing the constant pool index | |
8021
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
1726 // location for a native index into the ConstantPoolCache. |
0 | 1727 // Since we are updating the constant pool index prior to |
8021
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
1728 // verification and ConstantPoolCache initialization, we |
0 | 1729 // need to keep the new index in Java byte order. |
1730 Bytes::put_Java_u2(p, new_index); | |
1731 } | |
1732 } break; | |
1733 } | |
1734 } // end for each bytecode | |
8068
56c364daccc3
8007153: Ensure that MethodParameters API works properly with RedefineClasses
emc
parents:
8031
diff
changeset
|
1735 |
56c364daccc3
8007153: Ensure that MethodParameters API works properly with RedefineClasses
emc
parents:
8031
diff
changeset
|
1736 // We also need to rewrite the parameter name indexes, if there is |
56c364daccc3
8007153: Ensure that MethodParameters API works properly with RedefineClasses
emc
parents:
8031
diff
changeset
|
1737 // method parameter data present |
56c364daccc3
8007153: Ensure that MethodParameters API works properly with RedefineClasses
emc
parents:
8031
diff
changeset
|
1738 if(method->has_method_parameters()) { |
56c364daccc3
8007153: Ensure that MethodParameters API works properly with RedefineClasses
emc
parents:
8031
diff
changeset
|
1739 const int len = method->method_parameters_length(); |
56c364daccc3
8007153: Ensure that MethodParameters API works properly with RedefineClasses
emc
parents:
8031
diff
changeset
|
1740 MethodParametersElement* elem = method->method_parameters_start(); |
56c364daccc3
8007153: Ensure that MethodParameters API works properly with RedefineClasses
emc
parents:
8031
diff
changeset
|
1741 |
56c364daccc3
8007153: Ensure that MethodParameters API works properly with RedefineClasses
emc
parents:
8031
diff
changeset
|
1742 for (int i = 0; i < len; i++) { |
56c364daccc3
8007153: Ensure that MethodParameters API works properly with RedefineClasses
emc
parents:
8031
diff
changeset
|
1743 const u2 cp_index = elem[i].name_cp_index; |
12101
ff2520b97b00
8023547: com/sun/jdi/RedefineMulti.sh fails with IllegalArgumentException after JDK-8021948 .
jiangli
parents:
12067
diff
changeset
|
1744 const u2 new_cp_index = find_new_index(cp_index); |
ff2520b97b00
8023547: com/sun/jdi/RedefineMulti.sh fails with IllegalArgumentException after JDK-8021948 .
jiangli
parents:
12067
diff
changeset
|
1745 if (new_cp_index != 0) { |
ff2520b97b00
8023547: com/sun/jdi/RedefineMulti.sh fails with IllegalArgumentException after JDK-8021948 .
jiangli
parents:
12067
diff
changeset
|
1746 elem[i].name_cp_index = new_cp_index; |
ff2520b97b00
8023547: com/sun/jdi/RedefineMulti.sh fails with IllegalArgumentException after JDK-8021948 .
jiangli
parents:
12067
diff
changeset
|
1747 } |
8068
56c364daccc3
8007153: Ensure that MethodParameters API works properly with RedefineClasses
emc
parents:
8031
diff
changeset
|
1748 } |
56c364daccc3
8007153: Ensure that MethodParameters API works properly with RedefineClasses
emc
parents:
8031
diff
changeset
|
1749 } |
0 | 1750 } // end rewrite_cp_refs_in_method() |
1751 | |
1752 | |
1753 // Rewrite constant pool references in the class_annotations field. | |
1754 bool VM_RedefineClasses::rewrite_cp_refs_in_class_annotations( | |
1755 instanceKlassHandle scratch_class, TRAPS) { | |
1756 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1757 AnnotationArray* class_annotations = scratch_class->class_annotations(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1758 if (class_annotations == NULL || class_annotations->length() == 0) { |
0 | 1759 // no class_annotations so nothing to do |
1760 return true; | |
1761 } | |
1762 | |
1763 RC_TRACE_WITH_THREAD(0x02000000, THREAD, | |
1764 ("class_annotations length=%d", class_annotations->length())); | |
1765 | |
1766 int byte_i = 0; // byte index into class_annotations | |
1767 return rewrite_cp_refs_in_annotations_typeArray(class_annotations, byte_i, | |
1768 THREAD); | |
1769 } | |
1770 | |
1771 | |
1772 // Rewrite constant pool references in an annotations typeArray. This | |
1773 // "structure" is adapted from the RuntimeVisibleAnnotations_attribute | |
1774 // that is described in section 4.8.15 of the 2nd-edition of the VM spec: | |
1775 // | |
1776 // annotations_typeArray { | |
1777 // u2 num_annotations; | |
1778 // annotation annotations[num_annotations]; | |
1779 // } | |
1780 // | |
1781 bool VM_RedefineClasses::rewrite_cp_refs_in_annotations_typeArray( | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1782 AnnotationArray* annotations_typeArray, int &byte_i_ref, TRAPS) { |
0 | 1783 |
1784 if ((byte_i_ref + 2) > annotations_typeArray->length()) { | |
1785 // not enough room for num_annotations field | |
1786 RC_TRACE_WITH_THREAD(0x02000000, THREAD, | |
1787 ("length() is too small for num_annotations field")); | |
1788 return false; | |
1789 } | |
1790 | |
1791 u2 num_annotations = Bytes::get_Java_u2((address) | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1792 annotations_typeArray->adr_at(byte_i_ref)); |
0 | 1793 byte_i_ref += 2; |
1794 | |
1795 RC_TRACE_WITH_THREAD(0x02000000, THREAD, | |
1796 ("num_annotations=%d", num_annotations)); | |
1797 | |
1798 int calc_num_annotations = 0; | |
1799 for (; calc_num_annotations < num_annotations; calc_num_annotations++) { | |
1800 if (!rewrite_cp_refs_in_annotation_struct(annotations_typeArray, | |
1801 byte_i_ref, THREAD)) { | |
1802 RC_TRACE_WITH_THREAD(0x02000000, THREAD, | |
1803 ("bad annotation_struct at %d", calc_num_annotations)); | |
605 | 1804 // propagate failure back to caller |
0 | 1805 return false; |
1806 } | |
1807 } | |
1808 assert(num_annotations == calc_num_annotations, "sanity check"); | |
1809 | |
1810 return true; | |
1811 } // end rewrite_cp_refs_in_annotations_typeArray() | |
1812 | |
1813 | |
1814 // Rewrite constant pool references in the annotation struct portion of | |
1815 // an annotations_typeArray. This "structure" is from section 4.8.15 of | |
1816 // the 2nd-edition of the VM spec: | |
1817 // | |
1818 // struct annotation { | |
1819 // u2 type_index; | |
1820 // u2 num_element_value_pairs; | |
1821 // { | |
1822 // u2 element_name_index; | |
1823 // element_value value; | |
1824 // } element_value_pairs[num_element_value_pairs]; | |
1825 // } | |
1826 // | |
1827 bool VM_RedefineClasses::rewrite_cp_refs_in_annotation_struct( | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1828 AnnotationArray* annotations_typeArray, int &byte_i_ref, TRAPS) { |
0 | 1829 if ((byte_i_ref + 2 + 2) > annotations_typeArray->length()) { |
1830 // not enough room for smallest annotation_struct | |
1831 RC_TRACE_WITH_THREAD(0x02000000, THREAD, | |
1832 ("length() is too small for annotation_struct")); | |
1833 return false; | |
1834 } | |
1835 | |
1836 u2 type_index = rewrite_cp_ref_in_annotation_data(annotations_typeArray, | |
1837 byte_i_ref, "mapped old type_index=%d", THREAD); | |
1838 | |
1839 u2 num_element_value_pairs = Bytes::get_Java_u2((address) | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1840 annotations_typeArray->adr_at(byte_i_ref)); |
0 | 1841 byte_i_ref += 2; |
1842 | |
1843 RC_TRACE_WITH_THREAD(0x02000000, THREAD, | |
1844 ("type_index=%d num_element_value_pairs=%d", type_index, | |
1845 num_element_value_pairs)); | |
1846 | |
1847 int calc_num_element_value_pairs = 0; | |
1848 for (; calc_num_element_value_pairs < num_element_value_pairs; | |
1849 calc_num_element_value_pairs++) { | |
1850 if ((byte_i_ref + 2) > annotations_typeArray->length()) { | |
1851 // not enough room for another element_name_index, let alone | |
1852 // the rest of another component | |
1853 RC_TRACE_WITH_THREAD(0x02000000, THREAD, | |
1854 ("length() is too small for element_name_index")); | |
1855 return false; | |
1856 } | |
1857 | |
1858 u2 element_name_index = rewrite_cp_ref_in_annotation_data( | |
1859 annotations_typeArray, byte_i_ref, | |
1860 "mapped old element_name_index=%d", THREAD); | |
1861 | |
1862 RC_TRACE_WITH_THREAD(0x02000000, THREAD, | |
1863 ("element_name_index=%d", element_name_index)); | |
1864 | |
1865 if (!rewrite_cp_refs_in_element_value(annotations_typeArray, | |
1866 byte_i_ref, THREAD)) { | |
1867 RC_TRACE_WITH_THREAD(0x02000000, THREAD, | |
1868 ("bad element_value at %d", calc_num_element_value_pairs)); | |
605 | 1869 // propagate failure back to caller |
0 | 1870 return false; |
1871 } | |
1872 } // end for each component | |
1873 assert(num_element_value_pairs == calc_num_element_value_pairs, | |
1874 "sanity check"); | |
1875 | |
1876 return true; | |
1877 } // end rewrite_cp_refs_in_annotation_struct() | |
1878 | |
1879 | |
1880 // Rewrite a constant pool reference at the current position in | |
1881 // annotations_typeArray if needed. Returns the original constant | |
1882 // pool reference if a rewrite was not needed or the new constant | |
1883 // pool reference if a rewrite was needed. | |
1884 u2 VM_RedefineClasses::rewrite_cp_ref_in_annotation_data( | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1885 AnnotationArray* annotations_typeArray, int &byte_i_ref, |
0 | 1886 const char * trace_mesg, TRAPS) { |
1887 | |
1888 address cp_index_addr = (address) | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1889 annotations_typeArray->adr_at(byte_i_ref); |
0 | 1890 u2 old_cp_index = Bytes::get_Java_u2(cp_index_addr); |
1891 u2 new_cp_index = find_new_index(old_cp_index); | |
1892 if (new_cp_index != 0) { | |
1893 RC_TRACE_WITH_THREAD(0x02000000, THREAD, (trace_mesg, old_cp_index)); | |
1894 Bytes::put_Java_u2(cp_index_addr, new_cp_index); | |
1895 old_cp_index = new_cp_index; | |
1896 } | |
1897 byte_i_ref += 2; | |
1898 return old_cp_index; | |
1899 } | |
1900 | |
1901 | |
1902 // Rewrite constant pool references in the element_value portion of an | |
1903 // annotations_typeArray. This "structure" is from section 4.8.15.1 of | |
1904 // the 2nd-edition of the VM spec: | |
1905 // | |
1906 // struct element_value { | |
1907 // u1 tag; | |
1908 // union { | |
1909 // u2 const_value_index; | |
1910 // { | |
1911 // u2 type_name_index; | |
1912 // u2 const_name_index; | |
1913 // } enum_const_value; | |
1914 // u2 class_info_index; | |
1915 // annotation annotation_value; | |
1916 // struct { | |
1917 // u2 num_values; | |
1918 // element_value values[num_values]; | |
1919 // } array_value; | |
1920 // } value; | |
1921 // } | |
1922 // | |
1923 bool VM_RedefineClasses::rewrite_cp_refs_in_element_value( | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1924 AnnotationArray* annotations_typeArray, int &byte_i_ref, TRAPS) { |
0 | 1925 |
1926 if ((byte_i_ref + 1) > annotations_typeArray->length()) { | |
1927 // not enough room for a tag let alone the rest of an element_value | |
1928 RC_TRACE_WITH_THREAD(0x02000000, THREAD, | |
1929 ("length() is too small for a tag")); | |
1930 return false; | |
1931 } | |
1932 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
1933 u1 tag = annotations_typeArray->at(byte_i_ref); |
0 | 1934 byte_i_ref++; |
1935 RC_TRACE_WITH_THREAD(0x02000000, THREAD, ("tag='%c'", tag)); | |
1936 | |
1937 switch (tag) { | |
1938 // These BaseType tag values are from Table 4.2 in VM spec: | |
1939 case 'B': // byte | |
1940 case 'C': // char | |
1941 case 'D': // double | |
1942 case 'F': // float | |
1943 case 'I': // int | |
1944 case 'J': // long | |
1945 case 'S': // short | |
1946 case 'Z': // boolean | |
1947 | |
1948 // The remaining tag values are from Table 4.8 in the 2nd-edition of | |
1949 // the VM spec: | |
1950 case 's': | |
1951 { | |
1952 // For the above tag values (including the BaseType values), | |
1953 // value.const_value_index is right union field. | |
1954 | |
1955 if ((byte_i_ref + 2) > annotations_typeArray->length()) { | |
1956 // not enough room for a const_value_index | |
1957 RC_TRACE_WITH_THREAD(0x02000000, THREAD, | |
1958 ("length() is too small for a const_value_index")); | |
1959 return false; | |
1960 } | |
1961 | |
1962 u2 const_value_index = rewrite_cp_ref_in_annotation_data( | |
1963 annotations_typeArray, byte_i_ref, | |
1964 "mapped old const_value_index=%d", THREAD); | |
1965 | |
1966 RC_TRACE_WITH_THREAD(0x02000000, THREAD, | |
1967 ("const_value_index=%d", const_value_index)); | |
1968 } break; | |
1969 | |
1970 case 'e': | |
1971 { | |
1972 // for the above tag value, value.enum_const_value is right union field | |
1973 | |
1974 if ((byte_i_ref + 4) > annotations_typeArray->length()) { | |
1975 // not enough room for a enum_const_value | |
1976 RC_TRACE_WITH_THREAD(0x02000000, THREAD, | |
1977 ("length() is too small for a enum_const_value")); | |
1978 return false; | |
1979 } | |
1980 | |
1981 u2 type_name_index = rewrite_cp_ref_in_annotation_data( | |
1982 annotations_typeArray, byte_i_ref, | |
1983 "mapped old type_name_index=%d", THREAD); | |
1984 | |
1985 u2 const_name_index = rewrite_cp_ref_in_annotation_data( | |
1986 annotations_typeArray, byte_i_ref, | |
1987 "mapped old const_name_index=%d", THREAD); | |
1988 | |
1989 RC_TRACE_WITH_THREAD(0x02000000, THREAD, | |
1990 ("type_name_index=%d const_name_index=%d", type_name_index, | |
1991 const_name_index)); | |
1992 } break; | |
1993 | |
1994 case 'c': | |
1995 { | |
1996 // for the above tag value, value.class_info_index is right union field | |
1997 | |
1998 if ((byte_i_ref + 2) > annotations_typeArray->length()) { | |
1999 // not enough room for a class_info_index | |
2000 RC_TRACE_WITH_THREAD(0x02000000, THREAD, | |
2001 ("length() is too small for a class_info_index")); | |
2002 return false; | |
2003 } | |
2004 | |
2005 u2 class_info_index = rewrite_cp_ref_in_annotation_data( | |
2006 annotations_typeArray, byte_i_ref, | |
2007 "mapped old class_info_index=%d", THREAD); | |
2008 | |
2009 RC_TRACE_WITH_THREAD(0x02000000, THREAD, | |
2010 ("class_info_index=%d", class_info_index)); | |
2011 } break; | |
2012 | |
2013 case '@': | |
2014 // For the above tag value, value.attr_value is the right union | |
2015 // field. This is a nested annotation. | |
2016 if (!rewrite_cp_refs_in_annotation_struct(annotations_typeArray, | |
2017 byte_i_ref, THREAD)) { | |
605 | 2018 // propagate failure back to caller |
0 | 2019 return false; |
2020 } | |
2021 break; | |
2022 | |
2023 case '[': | |
2024 { | |
2025 if ((byte_i_ref + 2) > annotations_typeArray->length()) { | |
2026 // not enough room for a num_values field | |
2027 RC_TRACE_WITH_THREAD(0x02000000, THREAD, | |
2028 ("length() is too small for a num_values field")); | |
2029 return false; | |
2030 } | |
2031 | |
2032 // For the above tag value, value.array_value is the right union | |
2033 // field. This is an array of nested element_value. | |
2034 u2 num_values = Bytes::get_Java_u2((address) | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
2035 annotations_typeArray->adr_at(byte_i_ref)); |
0 | 2036 byte_i_ref += 2; |
2037 RC_TRACE_WITH_THREAD(0x02000000, THREAD, ("num_values=%d", num_values)); | |
2038 | |
2039 int calc_num_values = 0; | |
2040 for (; calc_num_values < num_values; calc_num_values++) { | |
2041 if (!rewrite_cp_refs_in_element_value( | |
2042 annotations_typeArray, byte_i_ref, THREAD)) { | |
2043 RC_TRACE_WITH_THREAD(0x02000000, THREAD, | |
2044 ("bad nested element_value at %d", calc_num_values)); | |
605 | 2045 // propagate failure back to caller |
0 | 2046 return false; |
2047 } | |
2048 } | |
2049 assert(num_values == calc_num_values, "sanity check"); | |
2050 } break; | |
2051 | |
2052 default: | |
2053 RC_TRACE_WITH_THREAD(0x02000000, THREAD, ("bad tag=0x%x", tag)); | |
2054 return false; | |
2055 } // end decode tag field | |
2056 | |
2057 return true; | |
2058 } // end rewrite_cp_refs_in_element_value() | |
2059 | |
2060 | |
2061 // Rewrite constant pool references in a fields_annotations field. | |
2062 bool VM_RedefineClasses::rewrite_cp_refs_in_fields_annotations( | |
2063 instanceKlassHandle scratch_class, TRAPS) { | |
2064 | |
8031 | 2065 Array<AnnotationArray*>* fields_annotations = scratch_class->fields_annotations(); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
2066 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
2067 if (fields_annotations == NULL || fields_annotations->length() == 0) { |
0 | 2068 // no fields_annotations so nothing to do |
2069 return true; | |
2070 } | |
2071 | |
2072 RC_TRACE_WITH_THREAD(0x02000000, THREAD, | |
2073 ("fields_annotations length=%d", fields_annotations->length())); | |
2074 | |
2075 for (int i = 0; i < fields_annotations->length(); i++) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
2076 AnnotationArray* field_annotations = fields_annotations->at(i); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
2077 if (field_annotations == NULL || field_annotations->length() == 0) { |
0 | 2078 // this field does not have any annotations so skip it |
2079 continue; | |
2080 } | |
2081 | |
2082 int byte_i = 0; // byte index into field_annotations | |
2083 if (!rewrite_cp_refs_in_annotations_typeArray(field_annotations, byte_i, | |
2084 THREAD)) { | |
2085 RC_TRACE_WITH_THREAD(0x02000000, THREAD, | |
2086 ("bad field_annotations at %d", i)); | |
605 | 2087 // propagate failure back to caller |
0 | 2088 return false; |
2089 } | |
2090 } | |
2091 | |
2092 return true; | |
2093 } // end rewrite_cp_refs_in_fields_annotations() | |
2094 | |
2095 | |
2096 // Rewrite constant pool references in a methods_annotations field. | |
2097 bool VM_RedefineClasses::rewrite_cp_refs_in_methods_annotations( | |
2098 instanceKlassHandle scratch_class, TRAPS) { | |
2099 | |
8031 | 2100 for (int i = 0; i < scratch_class->methods()->length(); i++) { |
2101 Method* m = scratch_class->methods()->at(i); | |
2102 AnnotationArray* method_annotations = m->constMethod()->method_annotations(); | |
2103 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
2104 if (method_annotations == NULL || method_annotations->length() == 0) { |
0 | 2105 // this method does not have any annotations so skip it |
2106 continue; | |
2107 } | |
2108 | |
2109 int byte_i = 0; // byte index into method_annotations | |
2110 if (!rewrite_cp_refs_in_annotations_typeArray(method_annotations, byte_i, | |
2111 THREAD)) { | |
2112 RC_TRACE_WITH_THREAD(0x02000000, THREAD, | |
2113 ("bad method_annotations at %d", i)); | |
605 | 2114 // propagate failure back to caller |
0 | 2115 return false; |
2116 } | |
2117 } | |
2118 | |
2119 return true; | |
2120 } // end rewrite_cp_refs_in_methods_annotations() | |
2121 | |
2122 | |
2123 // Rewrite constant pool references in a methods_parameter_annotations | |
2124 // field. This "structure" is adapted from the | |
2125 // RuntimeVisibleParameterAnnotations_attribute described in section | |
2126 // 4.8.17 of the 2nd-edition of the VM spec: | |
2127 // | |
2128 // methods_parameter_annotations_typeArray { | |
2129 // u1 num_parameters; | |
2130 // { | |
2131 // u2 num_annotations; | |
2132 // annotation annotations[num_annotations]; | |
2133 // } parameter_annotations[num_parameters]; | |
2134 // } | |
2135 // | |
2136 bool VM_RedefineClasses::rewrite_cp_refs_in_methods_parameter_annotations( | |
2137 instanceKlassHandle scratch_class, TRAPS) { | |
2138 | |
8031 | 2139 for (int i = 0; i < scratch_class->methods()->length(); i++) { |
2140 Method* m = scratch_class->methods()->at(i); | |
2141 AnnotationArray* method_parameter_annotations = m->constMethod()->parameter_annotations(); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
2142 if (method_parameter_annotations == NULL |
0 | 2143 || method_parameter_annotations->length() == 0) { |
2144 // this method does not have any parameter annotations so skip it | |
2145 continue; | |
2146 } | |
2147 | |
2148 if (method_parameter_annotations->length() < 1) { | |
2149 // not enough room for a num_parameters field | |
2150 RC_TRACE_WITH_THREAD(0x02000000, THREAD, | |
2151 ("length() is too small for a num_parameters field at %d", i)); | |
2152 return false; | |
2153 } | |
2154 | |
2155 int byte_i = 0; // byte index into method_parameter_annotations | |
2156 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
2157 u1 num_parameters = method_parameter_annotations->at(byte_i); |
0 | 2158 byte_i++; |
2159 | |
2160 RC_TRACE_WITH_THREAD(0x02000000, THREAD, | |
2161 ("num_parameters=%d", num_parameters)); | |
2162 | |
2163 int calc_num_parameters = 0; | |
2164 for (; calc_num_parameters < num_parameters; calc_num_parameters++) { | |
2165 if (!rewrite_cp_refs_in_annotations_typeArray( | |
2166 method_parameter_annotations, byte_i, THREAD)) { | |
2167 RC_TRACE_WITH_THREAD(0x02000000, THREAD, | |
2168 ("bad method_parameter_annotations at %d", calc_num_parameters)); | |
605 | 2169 // propagate failure back to caller |
0 | 2170 return false; |
2171 } | |
2172 } | |
2173 assert(num_parameters == calc_num_parameters, "sanity check"); | |
2174 } | |
2175 | |
2176 return true; | |
2177 } // end rewrite_cp_refs_in_methods_parameter_annotations() | |
2178 | |
2179 | |
2180 // Rewrite constant pool references in a methods_default_annotations | |
2181 // field. This "structure" is adapted from the AnnotationDefault_attribute | |
2182 // that is described in section 4.8.19 of the 2nd-edition of the VM spec: | |
2183 // | |
2184 // methods_default_annotations_typeArray { | |
2185 // element_value default_value; | |
2186 // } | |
2187 // | |
2188 bool VM_RedefineClasses::rewrite_cp_refs_in_methods_default_annotations( | |
2189 instanceKlassHandle scratch_class, TRAPS) { | |
2190 | |
8031 | 2191 for (int i = 0; i < scratch_class->methods()->length(); i++) { |
2192 Method* m = scratch_class->methods()->at(i); | |
2193 AnnotationArray* method_default_annotations = m->constMethod()->default_annotations(); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
2194 if (method_default_annotations == NULL |
0 | 2195 || method_default_annotations->length() == 0) { |
2196 // this method does not have any default annotations so skip it | |
2197 continue; | |
2198 } | |
2199 | |
2200 int byte_i = 0; // byte index into method_default_annotations | |
2201 | |
2202 if (!rewrite_cp_refs_in_element_value( | |
2203 method_default_annotations, byte_i, THREAD)) { | |
2204 RC_TRACE_WITH_THREAD(0x02000000, THREAD, | |
2205 ("bad default element_value at %d", i)); | |
605 | 2206 // propagate failure back to caller |
0 | 2207 return false; |
2208 } | |
2209 } | |
2210 | |
2211 return true; | |
2212 } // end rewrite_cp_refs_in_methods_default_annotations() | |
2213 | |
2214 | |
2215 // Rewrite constant pool references in the method's stackmap table. | |
2216 // These "structures" are adapted from the StackMapTable_attribute that | |
2217 // is described in section 4.8.4 of the 6.0 version of the VM spec | |
2218 // (dated 2005.10.26): | |
2219 // file:///net/quincunx.sfbay/export/gbracha/ClassFile-Java6.pdf | |
2220 // | |
2221 // stack_map { | |
2222 // u2 number_of_entries; | |
2223 // stack_map_frame entries[number_of_entries]; | |
2224 // } | |
2225 // | |
2226 void VM_RedefineClasses::rewrite_cp_refs_in_stack_map_table( | |
2227 methodHandle method, TRAPS) { | |
2228 | |
2229 if (!method->has_stackmap_table()) { | |
2230 return; | |
2231 } | |
2232 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
2233 AnnotationArray* stackmap_data = method->stackmap_data(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
2234 address stackmap_p = (address)stackmap_data->adr_at(0); |
0 | 2235 address stackmap_end = stackmap_p + stackmap_data->length(); |
2236 | |
2237 assert(stackmap_p + 2 <= stackmap_end, "no room for number_of_entries"); | |
2238 u2 number_of_entries = Bytes::get_Java_u2(stackmap_p); | |
2239 stackmap_p += 2; | |
2240 | |
2241 RC_TRACE_WITH_THREAD(0x04000000, THREAD, | |
2242 ("number_of_entries=%u", number_of_entries)); | |
2243 | |
2244 // walk through each stack_map_frame | |
2245 u2 calc_number_of_entries = 0; | |
2246 for (; calc_number_of_entries < number_of_entries; calc_number_of_entries++) { | |
2247 // The stack_map_frame structure is a u1 frame_type followed by | |
2248 // 0 or more bytes of data: | |
2249 // | |
2250 // union stack_map_frame { | |
2251 // same_frame; | |
2252 // same_locals_1_stack_item_frame; | |
2253 // same_locals_1_stack_item_frame_extended; | |
2254 // chop_frame; | |
2255 // same_frame_extended; | |
2256 // append_frame; | |
2257 // full_frame; | |
2258 // } | |
2259 | |
2260 assert(stackmap_p + 1 <= stackmap_end, "no room for frame_type"); | |
2261 // The Linux compiler does not like frame_type to be u1 or u2. It | |
2262 // issues the following warning for the first if-statement below: | |
2263 // | |
2264 // "warning: comparison is always true due to limited range of data type" | |
2265 // | |
2266 u4 frame_type = *stackmap_p; | |
2267 stackmap_p++; | |
2268 | |
2269 // same_frame { | |
2270 // u1 frame_type = SAME; /* 0-63 */ | |
2271 // } | |
2272 if (frame_type >= 0 && frame_type <= 63) { | |
2273 // nothing more to do for same_frame | |
2274 } | |
2275 | |
2276 // same_locals_1_stack_item_frame { | |
2277 // u1 frame_type = SAME_LOCALS_1_STACK_ITEM; /* 64-127 */ | |
2278 // verification_type_info stack[1]; | |
2279 // } | |
2280 else if (frame_type >= 64 && frame_type <= 127) { | |
2281 rewrite_cp_refs_in_verification_type_info(stackmap_p, stackmap_end, | |
2282 calc_number_of_entries, frame_type, THREAD); | |
2283 } | |
2284 | |
2285 // reserved for future use | |
2286 else if (frame_type >= 128 && frame_type <= 246) { | |
2287 // nothing more to do for reserved frame_types | |
2288 } | |
2289 | |
2290 // same_locals_1_stack_item_frame_extended { | |
2291 // u1 frame_type = SAME_LOCALS_1_STACK_ITEM_EXTENDED; /* 247 */ | |
2292 // u2 offset_delta; | |
2293 // verification_type_info stack[1]; | |
2294 // } | |
2295 else if (frame_type == 247) { | |
2296 stackmap_p += 2; | |
2297 rewrite_cp_refs_in_verification_type_info(stackmap_p, stackmap_end, | |
2298 calc_number_of_entries, frame_type, THREAD); | |
2299 } | |
2300 | |
2301 // chop_frame { | |
2302 // u1 frame_type = CHOP; /* 248-250 */ | |
2303 // u2 offset_delta; | |
2304 // } | |
2305 else if (frame_type >= 248 && frame_type <= 250) { | |
2306 stackmap_p += 2; | |
2307 } | |
2308 | |
2309 // same_frame_extended { | |
2310 // u1 frame_type = SAME_FRAME_EXTENDED; /* 251*/ | |
2311 // u2 offset_delta; | |
2312 // } | |
2313 else if (frame_type == 251) { | |
2314 stackmap_p += 2; | |
2315 } | |
2316 | |
2317 // append_frame { | |
2318 // u1 frame_type = APPEND; /* 252-254 */ | |
2319 // u2 offset_delta; | |
2320 // verification_type_info locals[frame_type - 251]; | |
2321 // } | |
2322 else if (frame_type >= 252 && frame_type <= 254) { | |
2323 assert(stackmap_p + 2 <= stackmap_end, | |
2324 "no room for offset_delta"); | |
2325 stackmap_p += 2; | |
2326 u1 len = frame_type - 251; | |
2327 for (u1 i = 0; i < len; i++) { | |
2328 rewrite_cp_refs_in_verification_type_info(stackmap_p, stackmap_end, | |
2329 calc_number_of_entries, frame_type, THREAD); | |
2330 } | |
2331 } | |
2332 | |
2333 // full_frame { | |
2334 // u1 frame_type = FULL_FRAME; /* 255 */ | |
2335 // u2 offset_delta; | |
2336 // u2 number_of_locals; | |
2337 // verification_type_info locals[number_of_locals]; | |
2338 // u2 number_of_stack_items; | |
2339 // verification_type_info stack[number_of_stack_items]; | |
2340 // } | |
2341 else if (frame_type == 255) { | |
2342 assert(stackmap_p + 2 + 2 <= stackmap_end, | |
2343 "no room for smallest full_frame"); | |
2344 stackmap_p += 2; | |
2345 | |
2346 u2 number_of_locals = Bytes::get_Java_u2(stackmap_p); | |
2347 stackmap_p += 2; | |
2348 | |
2349 for (u2 locals_i = 0; locals_i < number_of_locals; locals_i++) { | |
2350 rewrite_cp_refs_in_verification_type_info(stackmap_p, stackmap_end, | |
2351 calc_number_of_entries, frame_type, THREAD); | |
2352 } | |
2353 | |
2354 // Use the largest size for the number_of_stack_items, but only get | |
2355 // the right number of bytes. | |
2356 u2 number_of_stack_items = Bytes::get_Java_u2(stackmap_p); | |
2357 stackmap_p += 2; | |
2358 | |
2359 for (u2 stack_i = 0; stack_i < number_of_stack_items; stack_i++) { | |
2360 rewrite_cp_refs_in_verification_type_info(stackmap_p, stackmap_end, | |
2361 calc_number_of_entries, frame_type, THREAD); | |
2362 } | |
2363 } | |
2364 } // end while there is a stack_map_frame | |
2365 assert(number_of_entries == calc_number_of_entries, "sanity check"); | |
2366 } // end rewrite_cp_refs_in_stack_map_table() | |
2367 | |
2368 | |
2369 // Rewrite constant pool references in the verification type info | |
2370 // portion of the method's stackmap table. These "structures" are | |
2371 // adapted from the StackMapTable_attribute that is described in | |
2372 // section 4.8.4 of the 6.0 version of the VM spec (dated 2005.10.26): | |
2373 // file:///net/quincunx.sfbay/export/gbracha/ClassFile-Java6.pdf | |
2374 // | |
2375 // The verification_type_info structure is a u1 tag followed by 0 or | |
2376 // more bytes of data: | |
2377 // | |
2378 // union verification_type_info { | |
2379 // Top_variable_info; | |
2380 // Integer_variable_info; | |
2381 // Float_variable_info; | |
2382 // Long_variable_info; | |
2383 // Double_variable_info; | |
2384 // Null_variable_info; | |
2385 // UninitializedThis_variable_info; | |
2386 // Object_variable_info; | |
2387 // Uninitialized_variable_info; | |
2388 // } | |
2389 // | |
2390 void VM_RedefineClasses::rewrite_cp_refs_in_verification_type_info( | |
2391 address& stackmap_p_ref, address stackmap_end, u2 frame_i, | |
2392 u1 frame_type, TRAPS) { | |
2393 | |
2394 assert(stackmap_p_ref + 1 <= stackmap_end, "no room for tag"); | |
2395 u1 tag = *stackmap_p_ref; | |
2396 stackmap_p_ref++; | |
2397 | |
2398 switch (tag) { | |
2399 // Top_variable_info { | |
2400 // u1 tag = ITEM_Top; /* 0 */ | |
2401 // } | |
2402 // verificationType.hpp has zero as ITEM_Bogus instead of ITEM_Top | |
2403 case 0: // fall through | |
2404 | |
2405 // Integer_variable_info { | |
2406 // u1 tag = ITEM_Integer; /* 1 */ | |
2407 // } | |
2408 case ITEM_Integer: // fall through | |
2409 | |
2410 // Float_variable_info { | |
2411 // u1 tag = ITEM_Float; /* 2 */ | |
2412 // } | |
2413 case ITEM_Float: // fall through | |
2414 | |
2415 // Double_variable_info { | |
2416 // u1 tag = ITEM_Double; /* 3 */ | |
2417 // } | |
2418 case ITEM_Double: // fall through | |
2419 | |
2420 // Long_variable_info { | |
2421 // u1 tag = ITEM_Long; /* 4 */ | |
2422 // } | |
2423 case ITEM_Long: // fall through | |
2424 | |
2425 // Null_variable_info { | |
2426 // u1 tag = ITEM_Null; /* 5 */ | |
2427 // } | |
2428 case ITEM_Null: // fall through | |
2429 | |
2430 // UninitializedThis_variable_info { | |
2431 // u1 tag = ITEM_UninitializedThis; /* 6 */ | |
2432 // } | |
2433 case ITEM_UninitializedThis: | |
2434 // nothing more to do for the above tag types | |
2435 break; | |
2436 | |
2437 // Object_variable_info { | |
2438 // u1 tag = ITEM_Object; /* 7 */ | |
2439 // u2 cpool_index; | |
2440 // } | |
2441 case ITEM_Object: | |
2442 { | |
2443 assert(stackmap_p_ref + 2 <= stackmap_end, "no room for cpool_index"); | |
2444 u2 cpool_index = Bytes::get_Java_u2(stackmap_p_ref); | |
2445 u2 new_cp_index = find_new_index(cpool_index); | |
2446 if (new_cp_index != 0) { | |
2447 RC_TRACE_WITH_THREAD(0x04000000, THREAD, | |
2448 ("mapped old cpool_index=%d", cpool_index)); | |
2449 Bytes::put_Java_u2(stackmap_p_ref, new_cp_index); | |
2450 cpool_index = new_cp_index; | |
2451 } | |
2452 stackmap_p_ref += 2; | |
2453 | |
2454 RC_TRACE_WITH_THREAD(0x04000000, THREAD, | |
2455 ("frame_i=%u, frame_type=%u, cpool_index=%d", frame_i, | |
2456 frame_type, cpool_index)); | |
2457 } break; | |
2458 | |
2459 // Uninitialized_variable_info { | |
2460 // u1 tag = ITEM_Uninitialized; /* 8 */ | |
2461 // u2 offset; | |
2462 // } | |
2463 case ITEM_Uninitialized: | |
2464 assert(stackmap_p_ref + 2 <= stackmap_end, "no room for offset"); | |
2465 stackmap_p_ref += 2; | |
2466 break; | |
2467 | |
2468 default: | |
2469 RC_TRACE_WITH_THREAD(0x04000000, THREAD, | |
2470 ("frame_i=%u, frame_type=%u, bad tag=0x%x", frame_i, frame_type, tag)); | |
2471 ShouldNotReachHere(); | |
2472 break; | |
2473 } // end switch (tag) | |
2474 } // end rewrite_cp_refs_in_verification_type_info() | |
2475 | |
2476 | |
2477 // Change the constant pool associated with klass scratch_class to | |
2478 // scratch_cp. If shrink is true, then scratch_cp_length elements | |
2479 // are copied from scratch_cp to a smaller constant pool and the | |
2480 // smaller constant pool is associated with scratch_class. | |
2481 void VM_RedefineClasses::set_new_constant_pool( | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
2482 ClassLoaderData* loader_data, |
0 | 2483 instanceKlassHandle scratch_class, constantPoolHandle scratch_cp, |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
2484 int scratch_cp_length, TRAPS) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
2485 assert(scratch_cp->length() >= scratch_cp_length, "sanity check"); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
2486 |
7624
b14da2e6f2dc
7174978: NPG: Fix bactrace builder for class redefinition
coleenp
parents:
7459
diff
changeset
|
2487 // scratch_cp is a merged constant pool and has enough space for a |
b14da2e6f2dc
7174978: NPG: Fix bactrace builder for class redefinition
coleenp
parents:
7459
diff
changeset
|
2488 // worst case merge situation. We want to associate the minimum |
b14da2e6f2dc
7174978: NPG: Fix bactrace builder for class redefinition
coleenp
parents:
7459
diff
changeset
|
2489 // sized constant pool with the klass to save space. |
b14da2e6f2dc
7174978: NPG: Fix bactrace builder for class redefinition
coleenp
parents:
7459
diff
changeset
|
2490 constantPoolHandle smaller_cp(THREAD, |
b14da2e6f2dc
7174978: NPG: Fix bactrace builder for class redefinition
coleenp
parents:
7459
diff
changeset
|
2491 ConstantPool::allocate(loader_data, scratch_cp_length, THREAD)); |
b14da2e6f2dc
7174978: NPG: Fix bactrace builder for class redefinition
coleenp
parents:
7459
diff
changeset
|
2492 |
b14da2e6f2dc
7174978: NPG: Fix bactrace builder for class redefinition
coleenp
parents:
7459
diff
changeset
|
2493 // preserve version() value in the smaller copy |
b14da2e6f2dc
7174978: NPG: Fix bactrace builder for class redefinition
coleenp
parents:
7459
diff
changeset
|
2494 int version = scratch_cp->version(); |
b14da2e6f2dc
7174978: NPG: Fix bactrace builder for class redefinition
coleenp
parents:
7459
diff
changeset
|
2495 assert(version != 0, "sanity check"); |
b14da2e6f2dc
7174978: NPG: Fix bactrace builder for class redefinition
coleenp
parents:
7459
diff
changeset
|
2496 smaller_cp->set_version(version); |
b14da2e6f2dc
7174978: NPG: Fix bactrace builder for class redefinition
coleenp
parents:
7459
diff
changeset
|
2497 |
7952
edd76a5856f7
8005128: JSR 292: the mlvm redefineClassInBootstrap test crashes in ConstantPool::compare_entry_to
sspitsyn
parents:
7949
diff
changeset
|
2498 // attach klass to new constant pool |
edd76a5856f7
8005128: JSR 292: the mlvm redefineClassInBootstrap test crashes in ConstantPool::compare_entry_to
sspitsyn
parents:
7949
diff
changeset
|
2499 // reference to the cp holder is needed for copy_operands() |
edd76a5856f7
8005128: JSR 292: the mlvm redefineClassInBootstrap test crashes in ConstantPool::compare_entry_to
sspitsyn
parents:
7949
diff
changeset
|
2500 smaller_cp->set_pool_holder(scratch_class()); |
edd76a5856f7
8005128: JSR 292: the mlvm redefineClassInBootstrap test crashes in ConstantPool::compare_entry_to
sspitsyn
parents:
7949
diff
changeset
|
2501 |
7624
b14da2e6f2dc
7174978: NPG: Fix bactrace builder for class redefinition
coleenp
parents:
7459
diff
changeset
|
2502 scratch_cp->copy_cp_to(1, scratch_cp_length - 1, smaller_cp, 1, THREAD); |
b14da2e6f2dc
7174978: NPG: Fix bactrace builder for class redefinition
coleenp
parents:
7459
diff
changeset
|
2503 scratch_cp = smaller_cp; |
0 | 2504 |
2505 // attach new constant pool to klass | |
2506 scratch_class->set_constants(scratch_cp()); | |
2507 | |
2508 int i; // for portability | |
2509 | |
2510 // update each field in klass to use new constant pool indices as needed | |
3938 | 2511 for (JavaFieldStream fs(scratch_class); !fs.done(); fs.next()) { |
2512 jshort cur_index = fs.name_index(); | |
0 | 2513 jshort new_index = find_new_index(cur_index); |
2514 if (new_index != 0) { | |
2515 RC_TRACE_WITH_THREAD(0x00080000, THREAD, | |
2516 ("field-name_index change: %d to %d", cur_index, new_index)); | |
3938 | 2517 fs.set_name_index(new_index); |
0 | 2518 } |
3938 | 2519 cur_index = fs.signature_index(); |
0 | 2520 new_index = find_new_index(cur_index); |
2521 if (new_index != 0) { | |
2522 RC_TRACE_WITH_THREAD(0x00080000, THREAD, | |
2523 ("field-signature_index change: %d to %d", cur_index, new_index)); | |
3938 | 2524 fs.set_signature_index(new_index); |
0 | 2525 } |
3938 | 2526 cur_index = fs.initval_index(); |
0 | 2527 new_index = find_new_index(cur_index); |
2528 if (new_index != 0) { | |
2529 RC_TRACE_WITH_THREAD(0x00080000, THREAD, | |
2530 ("field-initval_index change: %d to %d", cur_index, new_index)); | |
3938 | 2531 fs.set_initval_index(new_index); |
0 | 2532 } |
3938 | 2533 cur_index = fs.generic_signature_index(); |
0 | 2534 new_index = find_new_index(cur_index); |
2535 if (new_index != 0) { | |
2536 RC_TRACE_WITH_THREAD(0x00080000, THREAD, | |
2537 ("field-generic_signature change: %d to %d", cur_index, new_index)); | |
3938 | 2538 fs.set_generic_signature_index(new_index); |
0 | 2539 } |
2540 } // end for each field | |
2541 | |
2542 // Update constant pool indices in the inner classes info to use | |
2543 // new constant indices as needed. The inner classes info is a | |
2544 // quadruple: | |
2545 // (inner_class_info, outer_class_info, inner_name, inner_access_flags) | |
5967
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4731
diff
changeset
|
2546 InnerClassesIterator iter(scratch_class); |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4731
diff
changeset
|
2547 for (; !iter.done(); iter.next()) { |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4731
diff
changeset
|
2548 int cur_index = iter.inner_class_info_index(); |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4731
diff
changeset
|
2549 if (cur_index == 0) { |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4731
diff
changeset
|
2550 continue; // JVM spec. allows null inner class refs so skip it |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4731
diff
changeset
|
2551 } |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4731
diff
changeset
|
2552 int new_index = find_new_index(cur_index); |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4731
diff
changeset
|
2553 if (new_index != 0) { |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4731
diff
changeset
|
2554 RC_TRACE_WITH_THREAD(0x00080000, THREAD, |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4731
diff
changeset
|
2555 ("inner_class_info change: %d to %d", cur_index, new_index)); |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4731
diff
changeset
|
2556 iter.set_inner_class_info_index(new_index); |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4731
diff
changeset
|
2557 } |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4731
diff
changeset
|
2558 cur_index = iter.outer_class_info_index(); |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4731
diff
changeset
|
2559 new_index = find_new_index(cur_index); |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4731
diff
changeset
|
2560 if (new_index != 0) { |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4731
diff
changeset
|
2561 RC_TRACE_WITH_THREAD(0x00080000, THREAD, |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4731
diff
changeset
|
2562 ("outer_class_info change: %d to %d", cur_index, new_index)); |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4731
diff
changeset
|
2563 iter.set_outer_class_info_index(new_index); |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4731
diff
changeset
|
2564 } |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4731
diff
changeset
|
2565 cur_index = iter.inner_name_index(); |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4731
diff
changeset
|
2566 new_index = find_new_index(cur_index); |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4731
diff
changeset
|
2567 if (new_index != 0) { |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4731
diff
changeset
|
2568 RC_TRACE_WITH_THREAD(0x00080000, THREAD, |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4731
diff
changeset
|
2569 ("inner_name change: %d to %d", cur_index, new_index)); |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4731
diff
changeset
|
2570 iter.set_inner_name_index(new_index); |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4731
diff
changeset
|
2571 } |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
4731
diff
changeset
|
2572 } // end for each inner class |
0 | 2573 |
2574 // Attach each method in klass to the new constant pool and update | |
2575 // to use new constant pool indices as needed: | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
2576 Array<Method*>* methods = scratch_class->methods(); |
0 | 2577 for (i = methods->length() - 1; i >= 0; i--) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
2578 methodHandle method(THREAD, methods->at(i)); |
0 | 2579 method->set_constants(scratch_cp()); |
2580 | |
2581 int new_index = find_new_index(method->name_index()); | |
2582 if (new_index != 0) { | |
2583 RC_TRACE_WITH_THREAD(0x00080000, THREAD, | |
2584 ("method-name_index change: %d to %d", method->name_index(), | |
2585 new_index)); | |
2586 method->set_name_index(new_index); | |
2587 } | |
2588 new_index = find_new_index(method->signature_index()); | |
2589 if (new_index != 0) { | |
2590 RC_TRACE_WITH_THREAD(0x00080000, THREAD, | |
2591 ("method-signature_index change: %d to %d", | |
2592 method->signature_index(), new_index)); | |
2593 method->set_signature_index(new_index); | |
2594 } | |
2595 new_index = find_new_index(method->generic_signature_index()); | |
2596 if (new_index != 0) { | |
2597 RC_TRACE_WITH_THREAD(0x00080000, THREAD, | |
2598 ("method-generic_signature_index change: %d to %d", | |
2599 method->generic_signature_index(), new_index)); | |
2600 method->set_generic_signature_index(new_index); | |
2601 } | |
2602 | |
2603 // Update constant pool indices in the method's checked exception | |
2604 // table to use new constant indices as needed. | |
2605 int cext_length = method->checked_exceptions_length(); | |
2606 if (cext_length > 0) { | |
2607 CheckedExceptionElement * cext_table = | |
2608 method->checked_exceptions_start(); | |
2609 for (int j = 0; j < cext_length; j++) { | |
2610 int cur_index = cext_table[j].class_cp_index; | |
2611 int new_index = find_new_index(cur_index); | |
2612 if (new_index != 0) { | |
2613 RC_TRACE_WITH_THREAD(0x00080000, THREAD, | |
2614 ("cext-class_cp_index change: %d to %d", cur_index, new_index)); | |
2615 cext_table[j].class_cp_index = (u2)new_index; | |
2616 } | |
2617 } // end for each checked exception table entry | |
2618 } // end if there are checked exception table entries | |
2619 | |
2620 // Update each catch type index in the method's exception table | |
2621 // to use new constant pool indices as needed. The exception table | |
2622 // holds quadruple entries of the form: | |
2623 // (beg_bci, end_bci, handler_bci, klass_index) | |
6213
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
5967
diff
changeset
|
2624 |
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
5967
diff
changeset
|
2625 ExceptionTable ex_table(method()); |
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
5967
diff
changeset
|
2626 int ext_length = ex_table.length(); |
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
5967
diff
changeset
|
2627 |
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
5967
diff
changeset
|
2628 for (int j = 0; j < ext_length; j ++) { |
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
5967
diff
changeset
|
2629 int cur_index = ex_table.catch_type_index(j); |
0 | 2630 int new_index = find_new_index(cur_index); |
2631 if (new_index != 0) { | |
2632 RC_TRACE_WITH_THREAD(0x00080000, THREAD, | |
2633 ("ext-klass_index change: %d to %d", cur_index, new_index)); | |
6213
8150fa46d2ed
7178145: Change constMethodOop::_exception_table to optionally inlined u2 table.
jiangli
parents:
5967
diff
changeset
|
2634 ex_table.set_catch_type_index(j, new_index); |
0 | 2635 } |
2636 } // end for each exception table entry | |
2637 | |
2638 // Update constant pool indices in the method's local variable | |
2639 // table to use new constant indices as needed. The local variable | |
2640 // table hold sextuple entries of the form: | |
2641 // (start_pc, length, name_index, descriptor_index, signature_index, slot) | |
2642 int lvt_length = method->localvariable_table_length(); | |
2643 if (lvt_length > 0) { | |
2644 LocalVariableTableElement * lv_table = | |
2645 method->localvariable_table_start(); | |
2646 for (int j = 0; j < lvt_length; j++) { | |
2647 int cur_index = lv_table[j].name_cp_index; | |
2648 int new_index = find_new_index(cur_index); | |
2649 if (new_index != 0) { | |
2650 RC_TRACE_WITH_THREAD(0x00080000, THREAD, | |
2651 ("lvt-name_cp_index change: %d to %d", cur_index, new_index)); | |
2652 lv_table[j].name_cp_index = (u2)new_index; | |
2653 } | |
2654 cur_index = lv_table[j].descriptor_cp_index; | |
2655 new_index = find_new_index(cur_index); | |
2656 if (new_index != 0) { | |
2657 RC_TRACE_WITH_THREAD(0x00080000, THREAD, | |
2658 ("lvt-descriptor_cp_index change: %d to %d", cur_index, | |
2659 new_index)); | |
2660 lv_table[j].descriptor_cp_index = (u2)new_index; | |
2661 } | |
2662 cur_index = lv_table[j].signature_cp_index; | |
2663 new_index = find_new_index(cur_index); | |
2664 if (new_index != 0) { | |
2665 RC_TRACE_WITH_THREAD(0x00080000, THREAD, | |
2666 ("lvt-signature_cp_index change: %d to %d", cur_index, new_index)); | |
2667 lv_table[j].signature_cp_index = (u2)new_index; | |
2668 } | |
2669 } // end for each local variable table entry | |
2670 } // end if there are local variable table entries | |
2671 | |
2672 rewrite_cp_refs_in_stack_map_table(method, THREAD); | |
2673 } // end for each method | |
2674 } // end set_new_constant_pool() | |
2675 | |
2676 | |
2677 // Unevolving classes may point to methods of the_class directly | |
2678 // from their constant pool caches, itables, and/or vtables. We | |
10268
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
2679 // use the ClassLoaderDataGraph::classes_do() facility and this helper |
0 | 2680 // to fix up these pointers. |
10268
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
2681 |
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
2682 // Adjust cpools and vtables closure |
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
2683 void VM_RedefineClasses::AdjustCpoolCacheAndVtable::do_klass(Klass* k) { |
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
2684 |
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
2685 // This is a very busy routine. We don't want too much tracing |
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
2686 // printed out. |
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
2687 bool trace_name_printed = false; |
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
2688 |
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
2689 // Very noisy: only enable this call if you are trying to determine |
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
2690 // that a specific class gets found by this routine. |
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
2691 // RC_TRACE macro has an embedded ResourceMark |
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
2692 // RC_TRACE_WITH_THREAD(0x00100000, THREAD, |
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
2693 // ("adjust check: name=%s", k->external_name())); |
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
2694 // trace_name_printed = true; |
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
2695 |
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
2696 // If the class being redefined is java.lang.Object, we need to fix all |
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
2697 // array class vtables also |
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
2698 if (k->oop_is_array() && _the_class_oop == SystemDictionary::Object_klass()) { |
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
2699 k->vtable()->adjust_method_entries(_matching_old_methods, |
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
2700 _matching_new_methods, |
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
2701 _matching_methods_length, |
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
2702 &trace_name_printed); |
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
2703 } else if (k->oop_is_instance()) { |
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
2704 HandleMark hm(_thread); |
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
2705 InstanceKlass *ik = InstanceKlass::cast(k); |
0 | 2706 |
2707 // HotSpot specific optimization! HotSpot does not currently | |
2708 // support delegation from the bootstrap class loader to a | |
2709 // user-defined class loader. This means that if the bootstrap | |
2710 // class loader is the initiating class loader, then it will also | |
2711 // be the defining class loader. This also means that classes | |
2712 // loaded by the bootstrap class loader cannot refer to classes | |
2713 // loaded by a user-defined class loader. Note: a user-defined | |
2714 // class loader can delegate to the bootstrap class loader. | |
2715 // | |
2716 // If the current class being redefined has a user-defined class | |
2717 // loader as its defining class loader, then we can skip all | |
2718 // classes loaded by the bootstrap class loader. | |
2719 bool is_user_defined = | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
2720 InstanceKlass::cast(_the_class_oop)->class_loader() != NULL; |
0 | 2721 if (is_user_defined && ik->class_loader() == NULL) { |
2722 return; | |
2723 } | |
2724 | |
2725 // Fix the vtable embedded in the_class and subclasses of the_class, | |
2726 // if one exists. We discard scratch_class and we don't keep an | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
2727 // InstanceKlass around to hold obsolete methods so we don't have |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
2728 // any other InstanceKlass embedded vtables to update. The vtable |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
2729 // holds the Method*s for virtual (but not final) methods. |
0 | 2730 if (ik->vtable_length() > 0 && ik->is_subtype_of(_the_class_oop)) { |
2731 // ik->vtable() creates a wrapper object; rm cleans it up | |
10268
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
2732 ResourceMark rm(_thread); |
0 | 2733 ik->vtable()->adjust_method_entries(_matching_old_methods, |
2734 _matching_new_methods, | |
2735 _matching_methods_length, | |
2736 &trace_name_printed); | |
2737 } | |
2738 | |
2739 // If the current class has an itable and we are either redefining an | |
2740 // interface or if the current class is a subclass of the_class, then | |
2741 // we potentially have to fix the itable. If we are redefining an | |
2742 // interface, then we have to call adjust_method_entries() for | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
2743 // every InstanceKlass that has an itable since there isn't a |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
2744 // subclass relationship between an interface and an InstanceKlass. |
6983 | 2745 if (ik->itable_length() > 0 && (_the_class_oop->is_interface() |
0 | 2746 || ik->is_subclass_of(_the_class_oop))) { |
2747 // ik->itable() creates a wrapper object; rm cleans it up | |
10268
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
2748 ResourceMark rm(_thread); |
0 | 2749 ik->itable()->adjust_method_entries(_matching_old_methods, |
2750 _matching_new_methods, | |
2751 _matching_methods_length, | |
2752 &trace_name_printed); | |
2753 } | |
2754 | |
2755 // The constant pools in other classes (other_cp) can refer to | |
2756 // methods in the_class. We have to update method information in | |
2757 // other_cp's cache. If other_cp has a previous version, then we | |
2758 // have to repeat the process for each previous version. The | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
2759 // constant pool cache holds the Method*s for non-virtual |
0 | 2760 // methods and for virtual, final methods. |
2761 // | |
2762 // Special case: if the current class is the_class, then new_cp | |
2763 // has already been attached to the_class and old_cp has already | |
2764 // been added as a previous version. The new_cp doesn't have any | |
2765 // cached references to old methods so it doesn't need to be | |
2766 // updated. We can simply start with the previous version(s) in | |
2767 // that case. | |
2768 constantPoolHandle other_cp; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
2769 ConstantPoolCache* cp_cache; |
0 | 2770 |
10268
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
2771 if (ik != _the_class_oop) { |
0 | 2772 // this klass' constant pool cache may need adjustment |
2773 other_cp = constantPoolHandle(ik->constants()); | |
2774 cp_cache = other_cp->cache(); | |
2775 if (cp_cache != NULL) { | |
2776 cp_cache->adjust_method_entries(_matching_old_methods, | |
2777 _matching_new_methods, | |
2778 _matching_methods_length, | |
2779 &trace_name_printed); | |
2780 } | |
2781 } | |
2782 { | |
10268
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
2783 ResourceMark rm(_thread); |
0 | 2784 // PreviousVersionInfo objects returned via PreviousVersionWalker |
2785 // contain a GrowableArray of handles. We have to clean up the | |
2786 // GrowableArray _after_ the PreviousVersionWalker destructor | |
2787 // has destroyed the handles. | |
2788 { | |
2789 // the previous versions' constant pool caches may need adjustment | |
2790 PreviousVersionWalker pvw(ik); | |
2791 for (PreviousVersionInfo * pv_info = pvw.next_previous_version(); | |
2792 pv_info != NULL; pv_info = pvw.next_previous_version()) { | |
2793 other_cp = pv_info->prev_constant_pool_handle(); | |
2794 cp_cache = other_cp->cache(); | |
2795 if (cp_cache != NULL) { | |
2796 cp_cache->adjust_method_entries(_matching_old_methods, | |
2797 _matching_new_methods, | |
2798 _matching_methods_length, | |
2799 &trace_name_printed); | |
2800 } | |
2801 } | |
2802 } // pvw is cleaned up | |
2803 } // rm is cleaned up | |
2804 } | |
2805 } | |
2806 | |
2807 void VM_RedefineClasses::update_jmethod_ids() { | |
2808 for (int j = 0; j < _matching_methods_length; ++j) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
2809 Method* old_method = _matching_old_methods[j]; |
0 | 2810 jmethodID jmid = old_method->find_jmethod_id_or_null(); |
2811 if (jmid != NULL) { | |
2812 // There is a jmethodID, change it to point to the new method | |
2813 methodHandle new_method_h(_matching_new_methods[j]); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
2814 Method::change_method_associated_with_jmethod_id(jmid, new_method_h()); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
2815 assert(Method::resolve_jmethod_id(jmid) == _matching_new_methods[j], |
0 | 2816 "should be replaced"); |
2817 } | |
2818 } | |
2819 } | |
2820 | |
2821 void VM_RedefineClasses::check_methods_and_mark_as_obsolete( | |
2822 BitMap *emcp_methods, int * emcp_method_count_p) { | |
2823 *emcp_method_count_p = 0; | |
2824 int obsolete_count = 0; | |
2825 int old_index = 0; | |
2826 for (int j = 0; j < _matching_methods_length; ++j, ++old_index) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
2827 Method* old_method = _matching_old_methods[j]; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
2828 Method* new_method = _matching_new_methods[j]; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
2829 Method* old_array_method; |
0 | 2830 |
2831 // Maintain an old_index into the _old_methods array by skipping | |
2832 // deleted methods | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
2833 while ((old_array_method = _old_methods->at(old_index)) != old_method) { |
0 | 2834 ++old_index; |
2835 } | |
2836 | |
2837 if (MethodComparator::methods_EMCP(old_method, new_method)) { | |
2838 // The EMCP definition from JSR-163 requires the bytecodes to be | |
2839 // the same with the exception of constant pool indices which may | |
2840 // differ. However, the constants referred to by those indices | |
2841 // must be the same. | |
2842 // | |
2843 // We use methods_EMCP() for comparison since constant pool | |
2844 // merging can remove duplicate constant pool entries that were | |
2845 // present in the old method and removed from the rewritten new | |
2846 // method. A faster binary comparison function would consider the | |
2847 // old and new methods to be different when they are actually | |
2848 // EMCP. | |
2849 // | |
2850 // The old and new methods are EMCP and you would think that we | |
2851 // could get rid of one of them here and now and save some space. | |
2852 // However, the concept of EMCP only considers the bytecodes and | |
2853 // the constant pool entries in the comparison. Other things, | |
2854 // e.g., the line number table (LNT) or the local variable table | |
2855 // (LVT) don't count in the comparison. So the new (and EMCP) | |
2856 // method can have a new LNT that we need so we can't just | |
2857 // overwrite the new method with the old method. | |
2858 // | |
2859 // When this routine is called, we have already attached the new | |
2860 // methods to the_class so the old methods are effectively | |
2861 // overwritten. However, if an old method is still executing, | |
2862 // then the old method cannot be collected until sometime after | |
2863 // the old method call has returned. So the overwriting of old | |
2864 // methods by new methods will save us space except for those | |
2865 // (hopefully few) old methods that are still executing. | |
2866 // | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
2867 // A method refers to a ConstMethod* and this presents another |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
2868 // possible avenue to space savings. The ConstMethod* in the |
0 | 2869 // new method contains possibly new attributes (LNT, LVT, etc). |
2870 // At first glance, it seems possible to save space by replacing | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
2871 // the ConstMethod* in the old method with the ConstMethod* |
0 | 2872 // from the new method. The old and new methods would share the |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
2873 // same ConstMethod* and we would save the space occupied by |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
2874 // the old ConstMethod*. However, the ConstMethod* contains |
0 | 2875 // a back reference to the containing method. Sharing the |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
2876 // ConstMethod* between two methods could lead to confusion in |
0 | 2877 // the code that uses the back reference. This would lead to |
2878 // brittle code that could be broken in non-obvious ways now or | |
2879 // in the future. | |
2880 // | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
2881 // Another possibility is to copy the ConstMethod* from the new |
0 | 2882 // method to the old method and then overwrite the new method with |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
2883 // the old method. Since the ConstMethod* contains the bytecodes |
0 | 2884 // for the method embedded in the oop, this option would change |
2885 // the bytecodes out from under any threads executing the old | |
2886 // method and make the thread's bcp invalid. Since EMCP requires | |
2887 // that the bytecodes be the same modulo constant pool indices, it | |
2888 // is straight forward to compute the correct new bcp in the new | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
2889 // ConstMethod* from the old bcp in the old ConstMethod*. The |
0 | 2890 // time consuming part would be searching all the frames in all |
2891 // of the threads to find all of the calls to the old method. | |
2892 // | |
2893 // It looks like we will have to live with the limited savings | |
2894 // that we get from effectively overwriting the old methods | |
2895 // when the new methods are attached to the_class. | |
2896 | |
2897 // track which methods are EMCP for add_previous_version() call | |
2898 emcp_methods->set_bit(old_index); | |
2899 (*emcp_method_count_p)++; | |
2900 | |
2901 // An EMCP method is _not_ obsolete. An obsolete method has a | |
2902 // different jmethodID than the current method. An EMCP method | |
2903 // has the same jmethodID as the current method. Having the | |
2904 // same jmethodID for all EMCP versions of a method allows for | |
2905 // a consistent view of the EMCP methods regardless of which | |
2906 // EMCP method you happen to have in hand. For example, a | |
2907 // breakpoint set in one EMCP method will work for all EMCP | |
2908 // versions of the method including the current one. | |
2909 } else { | |
2910 // mark obsolete methods as such | |
2911 old_method->set_is_obsolete(); | |
2912 obsolete_count++; | |
2913 | |
2914 // obsolete methods need a unique idnum | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
2915 u2 num = InstanceKlass::cast(_the_class_oop)->next_method_idnum(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
2916 if (num != ConstMethod::UNSET_IDNUM) { |
0 | 2917 // u2 old_num = old_method->method_idnum(); |
2918 old_method->set_method_idnum(num); | |
2919 // TO DO: attach obsolete annotations to obsolete method's new idnum | |
2920 } | |
2921 // With tracing we try not to "yack" too much. The position of | |
2922 // this trace assumes there are fewer obsolete methods than | |
2923 // EMCP methods. | |
2924 RC_TRACE(0x00000100, ("mark %s(%s) as obsolete", | |
2925 old_method->name()->as_C_string(), | |
2926 old_method->signature()->as_C_string())); | |
2927 } | |
2928 old_method->set_is_old(); | |
2929 } | |
2930 for (int i = 0; i < _deleted_methods_length; ++i) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
2931 Method* old_method = _deleted_methods[i]; |
0 | 2932 |
2933 assert(old_method->vtable_index() < 0, | |
2934 "cannot delete methods with vtable entries");; | |
2935 | |
2936 // Mark all deleted methods as old and obsolete | |
2937 old_method->set_is_old(); | |
2938 old_method->set_is_obsolete(); | |
2939 ++obsolete_count; | |
2940 // With tracing we try not to "yack" too much. The position of | |
2941 // this trace assumes there are fewer obsolete methods than | |
2942 // EMCP methods. | |
2943 RC_TRACE(0x00000100, ("mark deleted %s(%s) as obsolete", | |
2944 old_method->name()->as_C_string(), | |
2945 old_method->signature()->as_C_string())); | |
2946 } | |
2947 assert((*emcp_method_count_p + obsolete_count) == _old_methods->length(), | |
2948 "sanity check"); | |
2949 RC_TRACE(0x00000100, ("EMCP_cnt=%d, obsolete_cnt=%d", *emcp_method_count_p, | |
2950 obsolete_count)); | |
2951 } | |
2952 | |
2953 // This internal class transfers the native function registration from old methods | |
2954 // to new methods. It is designed to handle both the simple case of unchanged | |
2955 // native methods and the complex cases of native method prefixes being added and/or | |
2956 // removed. | |
2957 // It expects only to be used during the VM_RedefineClasses op (a safepoint). | |
2958 // | |
2959 // This class is used after the new methods have been installed in "the_class". | |
2960 // | |
2961 // So, for example, the following must be handled. Where 'm' is a method and | |
2962 // a number followed by an underscore is a prefix. | |
2963 // | |
2964 // Old Name New Name | |
2965 // Simple transfer to new method m -> m | |
2966 // Add prefix m -> 1_m | |
2967 // Remove prefix 1_m -> m | |
2968 // Simultaneous add of prefixes m -> 3_2_1_m | |
2969 // Simultaneous removal of prefixes 3_2_1_m -> m | |
2970 // Simultaneous add and remove 1_m -> 2_m | |
2971 // Same, caused by prefix removal only 3_2_1_m -> 3_2_m | |
2972 // | |
2973 class TransferNativeFunctionRegistration { | |
2974 private: | |
2975 instanceKlassHandle the_class; | |
2976 int prefix_count; | |
2977 char** prefixes; | |
2978 | |
2979 // Recursively search the binary tree of possibly prefixed method names. | |
2980 // Iteration could be used if all agents were well behaved. Full tree walk is | |
2981 // more resilent to agents not cleaning up intermediate methods. | |
2982 // Branch at each depth in the binary tree is: | |
2983 // (1) without the prefix. | |
2984 // (2) with the prefix. | |
2985 // where 'prefix' is the prefix at that 'depth' (first prefix, second prefix,...) | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
2986 Method* search_prefix_name_space(int depth, char* name_str, size_t name_len, |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
2987 Symbol* signature) { |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
2988 TempNewSymbol name_symbol = SymbolTable::probe(name_str, (int)name_len); |
0 | 2989 if (name_symbol != NULL) { |
6983 | 2990 Method* method = the_class()->lookup_method(name_symbol, signature); |
0 | 2991 if (method != NULL) { |
2992 // Even if prefixed, intermediate methods must exist. | |
2993 if (method->is_native()) { | |
2994 // Wahoo, we found a (possibly prefixed) version of the method, return it. | |
2995 return method; | |
2996 } | |
2997 if (depth < prefix_count) { | |
2998 // Try applying further prefixes (other than this one). | |
2999 method = search_prefix_name_space(depth+1, name_str, name_len, signature); | |
3000 if (method != NULL) { | |
3001 return method; // found | |
3002 } | |
3003 | |
3004 // Try adding this prefix to the method name and see if it matches | |
3005 // another method name. | |
3006 char* prefix = prefixes[depth]; | |
3007 size_t prefix_len = strlen(prefix); | |
3008 size_t trial_len = name_len + prefix_len; | |
3009 char* trial_name_str = NEW_RESOURCE_ARRAY(char, trial_len + 1); | |
3010 strcpy(trial_name_str, prefix); | |
3011 strcat(trial_name_str, name_str); | |
3012 method = search_prefix_name_space(depth+1, trial_name_str, trial_len, | |
3013 signature); | |
3014 if (method != NULL) { | |
3015 // If found along this branch, it was prefixed, mark as such | |
3016 method->set_is_prefixed_native(); | |
3017 return method; // found | |
3018 } | |
3019 } | |
3020 } | |
3021 } | |
3022 return NULL; // This whole branch bore nothing | |
3023 } | |
3024 | |
3025 // Return the method name with old prefixes stripped away. | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
3026 char* method_name_without_prefixes(Method* method) { |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
3027 Symbol* name = method->name(); |
0 | 3028 char* name_str = name->as_utf8(); |
3029 | |
3030 // Old prefixing may be defunct, strip prefixes, if any. | |
3031 for (int i = prefix_count-1; i >= 0; i--) { | |
3032 char* prefix = prefixes[i]; | |
3033 size_t prefix_len = strlen(prefix); | |
3034 if (strncmp(prefix, name_str, prefix_len) == 0) { | |
3035 name_str += prefix_len; | |
3036 } | |
3037 } | |
3038 return name_str; | |
3039 } | |
3040 | |
3041 // Strip any prefixes off the old native method, then try to find a | |
3042 // (possibly prefixed) new native that matches it. | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
3043 Method* strip_and_search_for_new_native(Method* method) { |
0 | 3044 ResourceMark rm; |
3045 char* name_str = method_name_without_prefixes(method); | |
3046 return search_prefix_name_space(0, name_str, strlen(name_str), | |
3047 method->signature()); | |
3048 } | |
3049 | |
3050 public: | |
3051 | |
3052 // Construct a native method transfer processor for this class. | |
3053 TransferNativeFunctionRegistration(instanceKlassHandle _the_class) { | |
3054 assert(SafepointSynchronize::is_at_safepoint(), "sanity check"); | |
3055 | |
3056 the_class = _the_class; | |
3057 prefixes = JvmtiExport::get_all_native_method_prefixes(&prefix_count); | |
3058 } | |
3059 | |
3060 // Attempt to transfer any of the old or deleted methods that are native | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
3061 void transfer_registrations(Method** old_methods, int methods_length) { |
0 | 3062 for (int j = 0; j < methods_length; j++) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
3063 Method* old_method = old_methods[j]; |
0 | 3064 |
3065 if (old_method->is_native() && old_method->has_native_function()) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
3066 Method* new_method = strip_and_search_for_new_native(old_method); |
0 | 3067 if (new_method != NULL) { |
3068 // Actually set the native function in the new method. | |
3069 // Redefine does not send events (except CFLH), certainly not this | |
3070 // behind the scenes re-registration. | |
3071 new_method->set_native_function(old_method->native_function(), | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
3072 !Method::native_bind_event_is_interesting); |
0 | 3073 } |
3074 } | |
3075 } | |
3076 } | |
3077 }; | |
3078 | |
3079 // Don't lose the association between a native method and its JNI function. | |
3080 void VM_RedefineClasses::transfer_old_native_function_registrations(instanceKlassHandle the_class) { | |
3081 TransferNativeFunctionRegistration transfer(the_class); | |
3082 transfer.transfer_registrations(_deleted_methods, _deleted_methods_length); | |
3083 transfer.transfer_registrations(_matching_old_methods, _matching_methods_length); | |
3084 } | |
3085 | |
3086 // Deoptimize all compiled code that depends on this class. | |
3087 // | |
3088 // If the can_redefine_classes capability is obtained in the onload | |
3089 // phase then the compiler has recorded all dependencies from startup. | |
3090 // In that case we need only deoptimize and throw away all compiled code | |
3091 // that depends on the class. | |
3092 // | |
3093 // If can_redefine_classes is obtained sometime after the onload | |
3094 // phase then the dependency information may be incomplete. In that case | |
3095 // the first call to RedefineClasses causes all compiled code to be | |
3096 // thrown away. As can_redefine_classes has been obtained then | |
3097 // all future compilations will record dependencies so second and | |
3098 // subsequent calls to RedefineClasses need only throw away code | |
3099 // that depends on the class. | |
3100 // | |
3101 void VM_RedefineClasses::flush_dependent_code(instanceKlassHandle k_h, TRAPS) { | |
3102 assert_locked_or_safepoint(Compile_lock); | |
3103 | |
3104 // All dependencies have been recorded from startup or this is a second or | |
3105 // subsequent use of RedefineClasses | |
3106 if (JvmtiExport::all_dependencies_are_recorded()) { | |
3107 Universe::flush_evol_dependents_on(k_h); | |
3108 } else { | |
3109 CodeCache::mark_all_nmethods_for_deoptimization(); | |
3110 | |
3111 ResourceMark rm(THREAD); | |
3112 DeoptimizationMarker dm; | |
3113 | |
3114 // Deoptimize all activations depending on marked nmethods | |
3115 Deoptimization::deoptimize_dependents(); | |
3116 | |
3117 // Make the dependent methods not entrant (in VM_Deoptimize they are made zombies) | |
3118 CodeCache::make_marked_nmethods_not_entrant(); | |
3119 | |
3120 // From now on we know that the dependency information is complete | |
3121 JvmtiExport::set_all_dependencies_are_recorded(true); | |
3122 } | |
3123 } | |
3124 | |
3125 void VM_RedefineClasses::compute_added_deleted_matching_methods() { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
3126 Method* old_method; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
3127 Method* new_method; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
3128 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
3129 _matching_old_methods = NEW_RESOURCE_ARRAY(Method*, _old_methods->length()); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
3130 _matching_new_methods = NEW_RESOURCE_ARRAY(Method*, _old_methods->length()); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
3131 _added_methods = NEW_RESOURCE_ARRAY(Method*, _new_methods->length()); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
3132 _deleted_methods = NEW_RESOURCE_ARRAY(Method*, _old_methods->length()); |
0 | 3133 |
3134 _matching_methods_length = 0; | |
3135 _deleted_methods_length = 0; | |
3136 _added_methods_length = 0; | |
3137 | |
3138 int nj = 0; | |
3139 int oj = 0; | |
3140 while (true) { | |
3141 if (oj >= _old_methods->length()) { | |
3142 if (nj >= _new_methods->length()) { | |
3143 break; // we've looked at everything, done | |
3144 } | |
3145 // New method at the end | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
3146 new_method = _new_methods->at(nj); |
0 | 3147 _added_methods[_added_methods_length++] = new_method; |
3148 ++nj; | |
3149 } else if (nj >= _new_methods->length()) { | |
3150 // Old method, at the end, is deleted | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
3151 old_method = _old_methods->at(oj); |
0 | 3152 _deleted_methods[_deleted_methods_length++] = old_method; |
3153 ++oj; | |
3154 } else { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
3155 old_method = _old_methods->at(oj); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
3156 new_method = _new_methods->at(nj); |
0 | 3157 if (old_method->name() == new_method->name()) { |
3158 if (old_method->signature() == new_method->signature()) { | |
3159 _matching_old_methods[_matching_methods_length ] = old_method; | |
3160 _matching_new_methods[_matching_methods_length++] = new_method; | |
3161 ++nj; | |
3162 ++oj; | |
3163 } else { | |
3164 // added overloaded have already been moved to the end, | |
3165 // so this is a deleted overloaded method | |
3166 _deleted_methods[_deleted_methods_length++] = old_method; | |
3167 ++oj; | |
3168 } | |
3169 } else { // names don't match | |
3170 if (old_method->name()->fast_compare(new_method->name()) > 0) { | |
3171 // new method | |
3172 _added_methods[_added_methods_length++] = new_method; | |
3173 ++nj; | |
3174 } else { | |
3175 // deleted method | |
3176 _deleted_methods[_deleted_methods_length++] = old_method; | |
3177 ++oj; | |
3178 } | |
3179 } | |
3180 } | |
3181 } | |
3182 assert(_matching_methods_length + _deleted_methods_length == _old_methods->length(), "sanity"); | |
3183 assert(_matching_methods_length + _added_methods_length == _new_methods->length(), "sanity"); | |
3184 } | |
3185 | |
3186 | |
8031 | 3187 void VM_RedefineClasses::swap_annotations(instanceKlassHandle the_class, |
3188 instanceKlassHandle scratch_class) { | |
3189 // Since there is currently no rewriting of type annotations indexes | |
3190 // into the CP, we null out type annotations on scratch_class before | |
3191 // we swap annotations with the_class rather than facing the | |
3192 // possibility of shipping annotations with broken indexes to | |
3193 // Java-land. | |
3194 ClassLoaderData* loader_data = scratch_class->class_loader_data(); | |
3195 AnnotationArray* new_class_type_annotations = scratch_class->class_type_annotations(); | |
3196 if (new_class_type_annotations != NULL) { | |
3197 MetadataFactory::free_array<u1>(loader_data, new_class_type_annotations); | |
3198 scratch_class->annotations()->set_class_type_annotations(NULL); | |
3199 } | |
3200 Array<AnnotationArray*>* new_field_type_annotations = scratch_class->fields_type_annotations(); | |
3201 if (new_field_type_annotations != NULL) { | |
3202 Annotations::free_contents(loader_data, new_field_type_annotations); | |
3203 scratch_class->annotations()->set_fields_type_annotations(NULL); | |
3204 } | |
3205 | |
3206 // Swap annotation fields values | |
3207 Annotations* old_annotations = the_class->annotations(); | |
3208 the_class->set_annotations(scratch_class->annotations()); | |
3209 scratch_class->set_annotations(old_annotations); | |
3210 } | |
3211 | |
0 | 3212 |
3213 // Install the redefinition of a class: | |
3214 // - house keeping (flushing breakpoints and caches, deoptimizing | |
3215 // dependent compiled code) | |
3216 // - replacing parts in the_class with parts from scratch_class | |
3217 // - adding a weak reference to track the obsolete but interesting | |
3218 // parts of the_class | |
3219 // - adjusting constant pool caches and vtables in other classes | |
3220 // that refer to methods in the_class. These adjustments use the | |
10268
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
3221 // ClassLoaderDataGraph::classes_do() facility which only allows |
0 | 3222 // a helper method to be specified. The interesting parameters |
3223 // that we would like to pass to the helper method are saved in | |
3224 // static global fields in the VM operation. | |
3225 void VM_RedefineClasses::redefine_single_class(jclass the_jclass, | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
3226 Klass* scratch_class_oop, TRAPS) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
3227 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
3228 HandleMark hm(THREAD); // make sure handles from this call are freed |
0 | 3229 RC_TIMER_START(_timer_rsc_phase1); |
3230 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
3231 instanceKlassHandle scratch_class(scratch_class_oop); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
3232 |
0 | 3233 oop the_class_mirror = JNIHandles::resolve_non_null(the_jclass); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
3234 Klass* the_class_oop = java_lang_Class::as_Klass(the_class_mirror); |
0 | 3235 instanceKlassHandle the_class = instanceKlassHandle(THREAD, the_class_oop); |
3236 | |
3237 // Remove all breakpoints in methods of this class | |
3238 JvmtiBreakpoints& jvmti_breakpoints = JvmtiCurrentBreakpoints::get_jvmti_breakpoints(); | |
3239 jvmti_breakpoints.clearall_in_class_at_safepoint(the_class_oop); | |
3240 | |
3241 // Deoptimize all compiled code that depends on this class | |
3242 flush_dependent_code(the_class, THREAD); | |
3243 | |
3244 _old_methods = the_class->methods(); | |
3245 _new_methods = scratch_class->methods(); | |
3246 _the_class_oop = the_class_oop; | |
3247 compute_added_deleted_matching_methods(); | |
3248 update_jmethod_ids(); | |
3249 | |
3250 // Attach new constant pool to the original klass. The original | |
3251 // klass still refers to the old constant pool (for now). | |
3252 scratch_class->constants()->set_pool_holder(the_class()); | |
3253 | |
3254 #if 0 | |
3255 // In theory, with constant pool merging in place we should be able | |
3256 // to save space by using the new, merged constant pool in place of | |
3257 // the old constant pool(s). By "pool(s)" I mean the constant pool in | |
3258 // the klass version we are replacing now and any constant pool(s) in | |
3259 // previous versions of klass. Nice theory, doesn't work in practice. | |
3260 // When this code is enabled, even simple programs throw NullPointer | |
3261 // exceptions. I'm guessing that this is caused by some constant pool | |
3262 // cache difference between the new, merged constant pool and the | |
3263 // constant pool that was just being used by the klass. I'm keeping | |
3264 // this code around to archive the idea, but the code has to remain | |
3265 // disabled for now. | |
3266 | |
3267 // Attach each old method to the new constant pool. This can be | |
3268 // done here since we are past the bytecode verification and | |
3269 // constant pool optimization phases. | |
3270 for (int i = _old_methods->length() - 1; i >= 0; i--) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
3271 Method* method = _old_methods->at(i); |
0 | 3272 method->set_constants(scratch_class->constants()); |
3273 } | |
3274 | |
3275 { | |
3276 // walk all previous versions of the klass | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
3277 InstanceKlass *ik = (InstanceKlass *)the_class(); |
0 | 3278 PreviousVersionWalker pvw(ik); |
3279 instanceKlassHandle ikh; | |
3280 do { | |
3281 ikh = pvw.next_previous_version(); | |
3282 if (!ikh.is_null()) { | |
3283 ik = ikh(); | |
3284 | |
3285 // attach previous version of klass to the new constant pool | |
3286 ik->set_constants(scratch_class->constants()); | |
3287 | |
3288 // Attach each method in the previous version of klass to the | |
3289 // new constant pool | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
3290 Array<Method*>* prev_methods = ik->methods(); |
0 | 3291 for (int i = prev_methods->length() - 1; i >= 0; i--) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
3292 Method* method = prev_methods->at(i); |
0 | 3293 method->set_constants(scratch_class->constants()); |
3294 } | |
3295 } | |
3296 } while (!ikh.is_null()); | |
3297 } | |
3298 #endif | |
3299 | |
3300 // Replace methods and constantpool | |
3301 the_class->set_methods(_new_methods); | |
3302 scratch_class->set_methods(_old_methods); // To prevent potential GCing of the old methods, | |
3303 // and to be able to undo operation easily. | |
3304 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
3305 ConstantPool* old_constants = the_class->constants(); |
0 | 3306 the_class->set_constants(scratch_class->constants()); |
3307 scratch_class->set_constants(old_constants); // See the previous comment. | |
3308 #if 0 | |
3309 // We are swapping the guts of "the new class" with the guts of "the | |
3310 // class". Since the old constant pool has just been attached to "the | |
3311 // new class", it seems logical to set the pool holder in the old | |
3312 // constant pool also. However, doing this will change the observable | |
3313 // class hierarchy for any old methods that are still executing. A | |
3314 // method can query the identity of its "holder" and this query uses | |
3315 // the method's constant pool link to find the holder. The change in | |
3316 // holding class from "the class" to "the new class" can confuse | |
3317 // things. | |
3318 // | |
3319 // Setting the old constant pool's holder will also cause | |
3320 // verification done during vtable initialization below to fail. | |
3321 // During vtable initialization, the vtable's class is verified to be | |
3322 // a subtype of the method's holder. The vtable's class is "the | |
3323 // class" and the method's holder is gotten from the constant pool | |
3324 // link in the method itself. For "the class"'s directly implemented | |
3325 // methods, the method holder is "the class" itself (as gotten from | |
3326 // the new constant pool). The check works fine in this case. The | |
3327 // check also works fine for methods inherited from super classes. | |
3328 // | |
3329 // Miranda methods are a little more complicated. A miranda method is | |
3330 // provided by an interface when the class implementing the interface | |
3331 // does not provide its own method. These interfaces are implemented | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
3332 // internally as an InstanceKlass. These special instanceKlasses |
0 | 3333 // share the constant pool of the class that "implements" the |
3334 // interface. By sharing the constant pool, the method holder of a | |
3335 // miranda method is the class that "implements" the interface. In a | |
3336 // non-redefine situation, the subtype check works fine. However, if | |
3337 // the old constant pool's pool holder is modified, then the check | |
3338 // fails because there is no class hierarchy relationship between the | |
3339 // vtable's class and "the new class". | |
3340 | |
3341 old_constants->set_pool_holder(scratch_class()); | |
3342 #endif | |
3343 | |
3344 // track which methods are EMCP for add_previous_version() call below | |
3345 BitMap emcp_methods(_old_methods->length()); | |
3346 int emcp_method_count = 0; | |
3347 emcp_methods.clear(); // clears 0..(length() - 1) | |
3348 check_methods_and_mark_as_obsolete(&emcp_methods, &emcp_method_count); | |
3349 transfer_old_native_function_registrations(the_class); | |
3350 | |
3351 // The class file bytes from before any retransformable agents mucked | |
3352 // with them was cached on the scratch class, move to the_class. | |
3353 // Note: we still want to do this if nothing needed caching since it | |
3354 // should get cleared in the_class too. | |
4731
4ceaf61479fc
7122253: Instrumentation.retransformClasses() leaks class bytes
dcubed
parents:
3938
diff
changeset
|
3355 if (the_class->get_cached_class_file_bytes() == 0) { |
4ceaf61479fc
7122253: Instrumentation.retransformClasses() leaks class bytes
dcubed
parents:
3938
diff
changeset
|
3356 // the_class doesn't have a cache yet so copy it |
11148
825e6cb66923
8020309: Eliminate InstanceKlass::_cached_class_file_len.
jiangli
parents:
10382
diff
changeset
|
3357 the_class->set_cached_class_file(scratch_class->get_cached_class_file()); |
4731
4ceaf61479fc
7122253: Instrumentation.retransformClasses() leaks class bytes
dcubed
parents:
3938
diff
changeset
|
3358 } |
4ceaf61479fc
7122253: Instrumentation.retransformClasses() leaks class bytes
dcubed
parents:
3938
diff
changeset
|
3359 #ifndef PRODUCT |
4ceaf61479fc
7122253: Instrumentation.retransformClasses() leaks class bytes
dcubed
parents:
3938
diff
changeset
|
3360 else { |
4ceaf61479fc
7122253: Instrumentation.retransformClasses() leaks class bytes
dcubed
parents:
3938
diff
changeset
|
3361 assert(the_class->get_cached_class_file_bytes() == |
4ceaf61479fc
7122253: Instrumentation.retransformClasses() leaks class bytes
dcubed
parents:
3938
diff
changeset
|
3362 scratch_class->get_cached_class_file_bytes(), "cache ptrs must match"); |
4ceaf61479fc
7122253: Instrumentation.retransformClasses() leaks class bytes
dcubed
parents:
3938
diff
changeset
|
3363 assert(the_class->get_cached_class_file_len() == |
4ceaf61479fc
7122253: Instrumentation.retransformClasses() leaks class bytes
dcubed
parents:
3938
diff
changeset
|
3364 scratch_class->get_cached_class_file_len(), "cache lens must match"); |
4ceaf61479fc
7122253: Instrumentation.retransformClasses() leaks class bytes
dcubed
parents:
3938
diff
changeset
|
3365 } |
4ceaf61479fc
7122253: Instrumentation.retransformClasses() leaks class bytes
dcubed
parents:
3938
diff
changeset
|
3366 #endif |
0 | 3367 |
10252
712a1e9c91f3
8013063: nsk/jvmti/RetransformClasses/retransform001 failed debug version on os::free
coleenp
parents:
10151
diff
changeset
|
3368 // NULL out in scratch class to not delete twice. The class to be redefined |
712a1e9c91f3
8013063: nsk/jvmti/RetransformClasses/retransform001 failed debug version on os::free
coleenp
parents:
10151
diff
changeset
|
3369 // always owns these bytes. |
11148
825e6cb66923
8020309: Eliminate InstanceKlass::_cached_class_file_len.
jiangli
parents:
10382
diff
changeset
|
3370 scratch_class->set_cached_class_file(NULL); |
10252
712a1e9c91f3
8013063: nsk/jvmti/RetransformClasses/retransform001 failed debug version on os::free
coleenp
parents:
10151
diff
changeset
|
3371 |
0 | 3372 // Replace inner_classes |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
3373 Array<u2>* old_inner_classes = the_class->inner_classes(); |
0 | 3374 the_class->set_inner_classes(scratch_class->inner_classes()); |
3375 scratch_class->set_inner_classes(old_inner_classes); | |
3376 | |
3377 // Initialize the vtable and interface table after | |
3378 // methods have been rewritten | |
3379 { | |
3380 ResourceMark rm(THREAD); | |
3381 // no exception should happen here since we explicitly | |
3382 // do not check loader constraints. | |
3383 // compare_and_normalize_class_versions has already checked: | |
3384 // - classloaders unchanged, signatures unchanged | |
3385 // - all instanceKlasses for redefined classes reused & contents updated | |
3386 the_class->vtable()->initialize_vtable(false, THREAD); | |
3387 the_class->itable()->initialize_itable(false, THREAD); | |
1142 | 3388 assert(!HAS_PENDING_EXCEPTION || (THREAD->pending_exception()->is_a(SystemDictionary::ThreadDeath_klass())), "redefine exception"); |
0 | 3389 } |
3390 | |
3391 // Leave arrays of jmethodIDs and itable index cache unchanged | |
3392 | |
3393 // Copy the "source file name" attribute from new class version | |
12067
e22ee8e7ae62
8021948: Change InstanceKlass::_source_file_name and _generic_signature from Symbol* to constant pool indexes.
jiangli
parents:
12022
diff
changeset
|
3394 the_class->set_source_file_name_index( |
e22ee8e7ae62
8021948: Change InstanceKlass::_source_file_name and _generic_signature from Symbol* to constant pool indexes.
jiangli
parents:
12022
diff
changeset
|
3395 scratch_class->source_file_name_index()); |
0 | 3396 |
3397 // Copy the "source debug extension" attribute from new class version | |
3398 the_class->set_source_debug_extension( | |
6203
04ade88d9712
6294277: java -Xdebug crashes on SourceDebugExtension attribute larger than 64K
fparain
parents:
6197
diff
changeset
|
3399 scratch_class->source_debug_extension(), |
04ade88d9712
6294277: java -Xdebug crashes on SourceDebugExtension attribute larger than 64K
fparain
parents:
6197
diff
changeset
|
3400 scratch_class->source_debug_extension() == NULL ? 0 : |
04ade88d9712
6294277: java -Xdebug crashes on SourceDebugExtension attribute larger than 64K
fparain
parents:
6197
diff
changeset
|
3401 (int)strlen(scratch_class->source_debug_extension())); |
0 | 3402 |
3403 // Use of javac -g could be different in the old and the new | |
3404 if (scratch_class->access_flags().has_localvariable_table() != | |
3405 the_class->access_flags().has_localvariable_table()) { | |
3406 | |
3407 AccessFlags flags = the_class->access_flags(); | |
3408 if (scratch_class->access_flags().has_localvariable_table()) { | |
3409 flags.set_has_localvariable_table(); | |
3410 } else { | |
3411 flags.clear_has_localvariable_table(); | |
3412 } | |
3413 the_class->set_access_flags(flags); | |
3414 } | |
3415 | |
8031 | 3416 swap_annotations(the_class, scratch_class); |
0 | 3417 |
3418 // Replace minor version number of class file | |
3419 u2 old_minor_version = the_class->minor_version(); | |
3420 the_class->set_minor_version(scratch_class->minor_version()); | |
3421 scratch_class->set_minor_version(old_minor_version); | |
3422 | |
3423 // Replace major version number of class file | |
3424 u2 old_major_version = the_class->major_version(); | |
3425 the_class->set_major_version(scratch_class->major_version()); | |
3426 scratch_class->set_major_version(old_major_version); | |
3427 | |
3428 // Replace CP indexes for class and name+type of enclosing method | |
3429 u2 old_class_idx = the_class->enclosing_method_class_index(); | |
3430 u2 old_method_idx = the_class->enclosing_method_method_index(); | |
3431 the_class->set_enclosing_method_indices( | |
3432 scratch_class->enclosing_method_class_index(), | |
3433 scratch_class->enclosing_method_method_index()); | |
3434 scratch_class->set_enclosing_method_indices(old_class_idx, old_method_idx); | |
3435 | |
3436 // keep track of previous versions of this class | |
3437 the_class->add_previous_version(scratch_class, &emcp_methods, | |
3438 emcp_method_count); | |
3439 | |
3440 RC_TIMER_STOP(_timer_rsc_phase1); | |
3441 RC_TIMER_START(_timer_rsc_phase2); | |
3442 | |
3443 // Adjust constantpool caches and vtables for all classes | |
3444 // that reference methods of the evolved class. | |
10268
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
3445 AdjustCpoolCacheAndVtable adjust_cpool_cache_and_vtable(THREAD); |
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
3446 ClassLoaderDataGraph::classes_do(&adjust_cpool_cache_and_vtable); |
0 | 3447 |
10133
6337ca4dcad8
8008511: JSR 292: MemberName vmtarget refs to methods must be updated at class redefinition
sspitsyn
parents:
8068
diff
changeset
|
3448 // JSR-292 support |
6337ca4dcad8
8008511: JSR 292: MemberName vmtarget refs to methods must be updated at class redefinition
sspitsyn
parents:
8068
diff
changeset
|
3449 MemberNameTable* mnt = the_class->member_names(); |
6337ca4dcad8
8008511: JSR 292: MemberName vmtarget refs to methods must be updated at class redefinition
sspitsyn
parents:
8068
diff
changeset
|
3450 if (mnt != NULL) { |
6337ca4dcad8
8008511: JSR 292: MemberName vmtarget refs to methods must be updated at class redefinition
sspitsyn
parents:
8068
diff
changeset
|
3451 bool trace_name_printed = false; |
6337ca4dcad8
8008511: JSR 292: MemberName vmtarget refs to methods must be updated at class redefinition
sspitsyn
parents:
8068
diff
changeset
|
3452 mnt->adjust_method_entries(_matching_old_methods, |
6337ca4dcad8
8008511: JSR 292: MemberName vmtarget refs to methods must be updated at class redefinition
sspitsyn
parents:
8068
diff
changeset
|
3453 _matching_new_methods, |
6337ca4dcad8
8008511: JSR 292: MemberName vmtarget refs to methods must be updated at class redefinition
sspitsyn
parents:
8068
diff
changeset
|
3454 _matching_methods_length, |
6337ca4dcad8
8008511: JSR 292: MemberName vmtarget refs to methods must be updated at class redefinition
sspitsyn
parents:
8068
diff
changeset
|
3455 &trace_name_printed); |
6337ca4dcad8
8008511: JSR 292: MemberName vmtarget refs to methods must be updated at class redefinition
sspitsyn
parents:
8068
diff
changeset
|
3456 } |
6337ca4dcad8
8008511: JSR 292: MemberName vmtarget refs to methods must be updated at class redefinition
sspitsyn
parents:
8068
diff
changeset
|
3457 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
3458 // Fix Resolution Error table also to remove old constant pools |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
3459 SystemDictionary::delete_resolution_error(old_constants); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
3460 |
0 | 3461 if (the_class->oop_map_cache() != NULL) { |
3462 // Flush references to any obsolete methods from the oop map cache | |
3463 // so that obsolete methods are not pinned. | |
3464 the_class->oop_map_cache()->flush_obsolete_entries(); | |
3465 } | |
3466 | |
3467 // increment the classRedefinedCount field in the_class and in any | |
3468 // direct and indirect subclasses of the_class | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
3469 increment_class_counter((InstanceKlass *)the_class(), THREAD); |
0 | 3470 |
3471 // RC_TRACE macro has an embedded ResourceMark | |
3472 RC_TRACE_WITH_THREAD(0x00000001, THREAD, | |
3473 ("redefined name=%s, count=%d (avail_mem=" UINT64_FORMAT "K)", | |
3474 the_class->external_name(), | |
3475 java_lang_Class::classRedefinedCount(the_class_mirror), | |
3476 os::available_memory() >> 10)); | |
3477 | |
3478 RC_TIMER_STOP(_timer_rsc_phase2); | |
3479 } // end redefine_single_class() | |
3480 | |
3481 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
3482 // Increment the classRedefinedCount field in the specific InstanceKlass |
0 | 3483 // and in all direct and indirect subclasses. |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
3484 void VM_RedefineClasses::increment_class_counter(InstanceKlass *ik, TRAPS) { |
0 | 3485 oop class_mirror = ik->java_mirror(); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
3486 Klass* class_oop = java_lang_Class::as_Klass(class_mirror); |
0 | 3487 int new_count = java_lang_Class::classRedefinedCount(class_mirror) + 1; |
3488 java_lang_Class::set_classRedefinedCount(class_mirror, new_count); | |
3489 | |
3490 if (class_oop != _the_class_oop) { | |
3491 // _the_class_oop count is printed at end of redefine_single_class() | |
3492 RC_TRACE_WITH_THREAD(0x00000008, THREAD, | |
3493 ("updated count in subclass=%s to %d", ik->external_name(), new_count)); | |
3494 } | |
3495 | |
3496 for (Klass *subk = ik->subklass(); subk != NULL; | |
3497 subk = subk->next_sibling()) { | |
2377
57552dca1708
7029509: nightly failures after static fields in Class
never
parents:
2332
diff
changeset
|
3498 if (subk->oop_is_instance()) { |
57552dca1708
7029509: nightly failures after static fields in Class
never
parents:
2332
diff
changeset
|
3499 // Only update instanceKlasses |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
3500 InstanceKlass *subik = (InstanceKlass*)subk; |
2377
57552dca1708
7029509: nightly failures after static fields in Class
never
parents:
2332
diff
changeset
|
3501 // recursively do subclasses of the current subclass |
57552dca1708
7029509: nightly failures after static fields in Class
never
parents:
2332
diff
changeset
|
3502 increment_class_counter(subik, THREAD); |
57552dca1708
7029509: nightly failures after static fields in Class
never
parents:
2332
diff
changeset
|
3503 } |
0 | 3504 } |
3505 } | |
3506 | |
10268
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
3507 void VM_RedefineClasses::CheckClass::do_klass(Klass* k) { |
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
3508 bool no_old_methods = true; // be optimistic |
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
3509 |
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
3510 // Both array and instance classes have vtables. |
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
3511 // a vtable should never contain old or obsolete methods |
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
3512 ResourceMark rm(_thread); |
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
3513 if (k->vtable_length() > 0 && |
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
3514 !k->vtable()->check_no_old_or_obsolete_entries()) { |
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
3515 if (RC_TRACE_ENABLED(0x00004000)) { |
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
3516 RC_TRACE_WITH_THREAD(0x00004000, _thread, |
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
3517 ("klassVtable::check_no_old_or_obsolete_entries failure" |
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
3518 " -- OLD or OBSOLETE method found -- class: %s", |
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
3519 k->signature_name())); |
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
3520 k->vtable()->dump_vtable(); |
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
3521 } |
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
3522 no_old_methods = false; |
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
3523 } |
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
3524 |
0 | 3525 if (k->oop_is_instance()) { |
10268
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
3526 HandleMark hm(_thread); |
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
3527 InstanceKlass *ik = InstanceKlass::cast(k); |
8021
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3528 |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3529 // an itable should never contain old or obsolete methods |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3530 if (ik->itable_length() > 0 && |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3531 !ik->itable()->check_no_old_or_obsolete_entries()) { |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3532 if (RC_TRACE_ENABLED(0x00004000)) { |
10268
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
3533 RC_TRACE_WITH_THREAD(0x00004000, _thread, |
8021
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3534 ("klassItable::check_no_old_or_obsolete_entries failure" |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3535 " -- OLD or OBSOLETE method found -- class: %s", |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3536 ik->signature_name())); |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3537 ik->itable()->dump_itable(); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
3538 } |
8021
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3539 no_old_methods = false; |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
3540 } |
8021
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3541 |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3542 // the constant pool cache should never contain old or obsolete methods |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
3543 if (ik->constants() != NULL && |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
3544 ik->constants()->cache() != NULL && |
8021
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3545 !ik->constants()->cache()->check_no_old_or_obsolete_entries()) { |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3546 if (RC_TRACE_ENABLED(0x00004000)) { |
10268
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
3547 RC_TRACE_WITH_THREAD(0x00004000, _thread, |
8021
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3548 ("cp-cache::check_no_old_or_obsolete_entries failure" |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3549 " -- OLD or OBSOLETE method found -- class: %s", |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3550 ik->signature_name())); |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3551 ik->constants()->cache()->dump_cache(); |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3552 } |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3553 no_old_methods = false; |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3554 } |
10268
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
3555 } |
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
3556 |
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
3557 // print and fail guarantee if old methods are found. |
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
3558 if (!no_old_methods) { |
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
3559 if (RC_TRACE_ENABLED(0x00004000)) { |
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
3560 dump_methods(); |
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
3561 } else { |
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
3562 tty->print_cr("INFO: use the '-XX:TraceRedefineClasses=16384' option " |
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
3563 "to see more info about the following guarantee() failure."); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6217
diff
changeset
|
3564 } |
10268
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
3565 guarantee(false, "OLD and/or OBSOLETE method(s) found"); |
0 | 3566 } |
3567 } | |
3568 | |
10268
43083e670adf
8005056: NPG: Crash after redefining java.lang.Object
coleenp
parents:
10252
diff
changeset
|
3569 |
0 | 3570 void VM_RedefineClasses::dump_methods() { |
8021
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3571 int j; |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3572 RC_TRACE(0x00004000, ("_old_methods --")); |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3573 for (j = 0; j < _old_methods->length(); ++j) { |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3574 Method* m = _old_methods->at(j); |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3575 RC_TRACE_NO_CR(0x00004000, ("%4d (%5d) ", j, m->vtable_index())); |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3576 m->access_flags().print_on(tty); |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3577 tty->print(" -- "); |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3578 m->print_name(tty); |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3579 tty->cr(); |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3580 } |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3581 RC_TRACE(0x00004000, ("_new_methods --")); |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3582 for (j = 0; j < _new_methods->length(); ++j) { |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3583 Method* m = _new_methods->at(j); |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3584 RC_TRACE_NO_CR(0x00004000, ("%4d (%5d) ", j, m->vtable_index())); |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3585 m->access_flags().print_on(tty); |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3586 tty->print(" -- "); |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3587 m->print_name(tty); |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3588 tty->cr(); |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3589 } |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3590 RC_TRACE(0x00004000, ("_matching_(old/new)_methods --")); |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3591 for (j = 0; j < _matching_methods_length; ++j) { |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3592 Method* m = _matching_old_methods[j]; |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3593 RC_TRACE_NO_CR(0x00004000, ("%4d (%5d) ", j, m->vtable_index())); |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3594 m->access_flags().print_on(tty); |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3595 tty->print(" -- "); |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3596 m->print_name(tty); |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3597 tty->cr(); |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3598 m = _matching_new_methods[j]; |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3599 RC_TRACE_NO_CR(0x00004000, (" (%5d) ", m->vtable_index())); |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3600 m->access_flags().print_on(tty); |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3601 tty->cr(); |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3602 } |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3603 RC_TRACE(0x00004000, ("_deleted_methods --")); |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3604 for (j = 0; j < _deleted_methods_length; ++j) { |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3605 Method* m = _deleted_methods[j]; |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3606 RC_TRACE_NO_CR(0x00004000, ("%4d (%5d) ", j, m->vtable_index())); |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3607 m->access_flags().print_on(tty); |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3608 tty->print(" -- "); |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3609 m->print_name(tty); |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3610 tty->cr(); |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3611 } |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3612 RC_TRACE(0x00004000, ("_added_methods --")); |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3613 for (j = 0; j < _added_methods_length; ++j) { |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3614 Method* m = _added_methods[j]; |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3615 RC_TRACE_NO_CR(0x00004000, ("%4d (%5d) ", j, m->vtable_index())); |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3616 m->access_flags().print_on(tty); |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3617 tty->print(" -- "); |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3618 m->print_name(tty); |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3619 tty->cr(); |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
7965
diff
changeset
|
3620 } |
0 | 3621 } |