annotate src/share/vm/prims/jvmtiRedefineClasses.cpp @ 3992:d1bdeef3e3e2

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