annotate src/share/vm/prims/jvmtiRedefineClasses.cpp @ 3762:5c0a3c1858b1

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