annotate src/share/vm/prims/methodComparator.cpp @ 452:00b023ae2d78

6722113: CMS: Incorrect overflow handling during precleaning of Reference lists Summary: When we encounter marking stack overflow during precleaning of Reference lists, we were using the overflow list mechanism, which can cause problems on account of mutating the mark word of the header because of conflicts with mutator accesses and updates of that field. Instead we should use the usual mechanism for overflow handling in concurrent phases, namely dirtying of the card on which the overflowed object lies. Since precleaning effectively does a form of discovered list processing, albeit with discovery enabled, we needed to adjust some code to be correct in the face of interleaved processing and discovery. Reviewed-by: apetrusenko, jcoomes
author ysr
date Thu, 20 Nov 2008 12:27:41 -0800
parents a61af66fc99e
children be93aad57795
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
2 * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved.
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 *
a61af66fc99e Initial load
duke
parents:
diff changeset
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
a61af66fc99e Initial load
duke
parents:
diff changeset
20 * CA 95054 USA or visit www.sun.com if you need additional information or
a61af66fc99e Initial load
duke
parents:
diff changeset
21 * have any questions.
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
a61af66fc99e Initial load
duke
parents:
diff changeset
25 # include "incls/_precompiled.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
26 # include "incls/_methodComparator.cpp.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
27
a61af66fc99e Initial load
duke
parents:
diff changeset
28 BytecodeStream *MethodComparator::_s_old;
a61af66fc99e Initial load
duke
parents:
diff changeset
29 BytecodeStream *MethodComparator::_s_new;
a61af66fc99e Initial load
duke
parents:
diff changeset
30 constantPoolOop MethodComparator::_old_cp;
a61af66fc99e Initial load
duke
parents:
diff changeset
31 constantPoolOop MethodComparator::_new_cp;
a61af66fc99e Initial load
duke
parents:
diff changeset
32 BciMap *MethodComparator::_bci_map;
a61af66fc99e Initial load
duke
parents:
diff changeset
33 bool MethodComparator::_switchable_test;
a61af66fc99e Initial load
duke
parents:
diff changeset
34 GrowableArray<int> *MethodComparator::_fwd_jmps;
a61af66fc99e Initial load
duke
parents:
diff changeset
35
a61af66fc99e Initial load
duke
parents:
diff changeset
36 bool MethodComparator::methods_EMCP(methodOop old_method, methodOop new_method) {
a61af66fc99e Initial load
duke
parents:
diff changeset
37 if (old_method->code_size() != new_method->code_size())
a61af66fc99e Initial load
duke
parents:
diff changeset
38 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
39 if (check_stack_and_locals_size(old_method, new_method) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
40 // RC_TRACE macro has an embedded ResourceMark
a61af66fc99e Initial load
duke
parents:
diff changeset
41 RC_TRACE(0x00800000, ("Methods %s non-comparable with diagnosis %d",
a61af66fc99e Initial load
duke
parents:
diff changeset
42 old_method->name()->as_C_string(),
a61af66fc99e Initial load
duke
parents:
diff changeset
43 check_stack_and_locals_size(old_method, new_method)));
a61af66fc99e Initial load
duke
parents:
diff changeset
44 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
45 }
a61af66fc99e Initial load
duke
parents:
diff changeset
46
a61af66fc99e Initial load
duke
parents:
diff changeset
47 _old_cp = old_method->constants();
a61af66fc99e Initial load
duke
parents:
diff changeset
48 _new_cp = new_method->constants();
a61af66fc99e Initial load
duke
parents:
diff changeset
49 BytecodeStream s_old(old_method);
a61af66fc99e Initial load
duke
parents:
diff changeset
50 BytecodeStream s_new(new_method);
a61af66fc99e Initial load
duke
parents:
diff changeset
51 _s_old = &s_old;
a61af66fc99e Initial load
duke
parents:
diff changeset
52 _s_new = &s_new;
a61af66fc99e Initial load
duke
parents:
diff changeset
53 _switchable_test = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
54 Bytecodes::Code c_old, c_new;
a61af66fc99e Initial load
duke
parents:
diff changeset
55
a61af66fc99e Initial load
duke
parents:
diff changeset
56 while ((c_old = s_old.next()) >= 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
57 if ((c_new = s_new.next()) < 0 || c_old != c_new)
a61af66fc99e Initial load
duke
parents:
diff changeset
58 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
59
a61af66fc99e Initial load
duke
parents:
diff changeset
60 if (! args_same(c_old, c_new))
a61af66fc99e Initial load
duke
parents:
diff changeset
61 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
62 }
a61af66fc99e Initial load
duke
parents:
diff changeset
63 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
64 }
a61af66fc99e Initial load
duke
parents:
diff changeset
65
a61af66fc99e Initial load
duke
parents:
diff changeset
66
a61af66fc99e Initial load
duke
parents:
diff changeset
67 bool MethodComparator::methods_switchable(methodOop old_method, methodOop new_method,
a61af66fc99e Initial load
duke
parents:
diff changeset
68 BciMap &bci_map) {
a61af66fc99e Initial load
duke
parents:
diff changeset
69 if (old_method->code_size() > new_method->code_size())
a61af66fc99e Initial load
duke
parents:
diff changeset
70 // Something has definitely been deleted in the new method, compared to the old one.
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 if (! check_stack_and_locals_size(old_method, new_method))
a61af66fc99e Initial load
duke
parents:
diff changeset
74 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
75
a61af66fc99e Initial load
duke
parents:
diff changeset
76 _old_cp = old_method->constants();
a61af66fc99e Initial load
duke
parents:
diff changeset
77 _new_cp = new_method->constants();
a61af66fc99e Initial load
duke
parents:
diff changeset
78 BytecodeStream s_old(old_method);
a61af66fc99e Initial load
duke
parents:
diff changeset
79 BytecodeStream s_new(new_method);
a61af66fc99e Initial load
duke
parents:
diff changeset
80 _s_old = &s_old;
a61af66fc99e Initial load
duke
parents:
diff changeset
81 _s_new = &s_new;
a61af66fc99e Initial load
duke
parents:
diff changeset
82 _bci_map = &bci_map;
a61af66fc99e Initial load
duke
parents:
diff changeset
83 _switchable_test = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
84 GrowableArray<int> fwd_jmps(16);
a61af66fc99e Initial load
duke
parents:
diff changeset
85 _fwd_jmps = &fwd_jmps;
a61af66fc99e Initial load
duke
parents:
diff changeset
86 Bytecodes::Code c_old, c_new;
a61af66fc99e Initial load
duke
parents:
diff changeset
87
a61af66fc99e Initial load
duke
parents:
diff changeset
88 while ((c_old = s_old.next()) >= 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
89 if ((c_new = s_new.next()) < 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
90 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
91 if (! (c_old == c_new && args_same(c_old, c_new))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
92 int old_bci = s_old.bci();
a61af66fc99e Initial load
duke
parents:
diff changeset
93 int new_st_bci = s_new.bci();
a61af66fc99e Initial load
duke
parents:
diff changeset
94 bool found_match = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
95 do {
a61af66fc99e Initial load
duke
parents:
diff changeset
96 c_new = s_new.next();
a61af66fc99e Initial load
duke
parents:
diff changeset
97 if (c_new == c_old && args_same(c_old, c_new)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
98 found_match = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
99 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
100 }
a61af66fc99e Initial load
duke
parents:
diff changeset
101 } while (c_new >= 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
102 if (! found_match)
a61af66fc99e Initial load
duke
parents:
diff changeset
103 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
104 int new_end_bci = s_new.bci();
a61af66fc99e Initial load
duke
parents:
diff changeset
105 bci_map.store_fragment_location(old_bci, new_st_bci, new_end_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
106 }
a61af66fc99e Initial load
duke
parents:
diff changeset
107 }
a61af66fc99e Initial load
duke
parents:
diff changeset
108
a61af66fc99e Initial load
duke
parents:
diff changeset
109 // Now we can test all forward jumps
a61af66fc99e Initial load
duke
parents:
diff changeset
110 for (int i = 0; i < fwd_jmps.length() / 2; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
111 if (! bci_map.old_and_new_locations_same(fwd_jmps.at(i*2), fwd_jmps.at(i*2+1))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
112 RC_TRACE(0x00800000,
a61af66fc99e Initial load
duke
parents:
diff changeset
113 ("Fwd jump miss: old dest = %d, calc new dest = %d, act new dest = %d",
a61af66fc99e Initial load
duke
parents:
diff changeset
114 fwd_jmps.at(i*2), bci_map.new_bci_for_old(fwd_jmps.at(i*2)),
a61af66fc99e Initial load
duke
parents:
diff changeset
115 fwd_jmps.at(i*2+1)));
a61af66fc99e Initial load
duke
parents:
diff changeset
116 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
117 }
a61af66fc99e Initial load
duke
parents:
diff changeset
118 }
a61af66fc99e Initial load
duke
parents:
diff changeset
119
a61af66fc99e Initial load
duke
parents:
diff changeset
120 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
121 }
a61af66fc99e Initial load
duke
parents:
diff changeset
122
a61af66fc99e Initial load
duke
parents:
diff changeset
123
a61af66fc99e Initial load
duke
parents:
diff changeset
124 bool MethodComparator::args_same(Bytecodes::Code c_old, Bytecodes::Code c_new) {
a61af66fc99e Initial load
duke
parents:
diff changeset
125 // BytecodeStream returns the correct standard Java bytecodes for various "fast"
a61af66fc99e Initial load
duke
parents:
diff changeset
126 // bytecode versions, so we don't have to bother about them here..
a61af66fc99e Initial load
duke
parents:
diff changeset
127 switch (c_old) {
a61af66fc99e Initial load
duke
parents:
diff changeset
128 case Bytecodes::_new : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
129 case Bytecodes::_anewarray : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
130 case Bytecodes::_multianewarray : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
131 case Bytecodes::_checkcast : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
132 case Bytecodes::_instanceof : {
a61af66fc99e Initial load
duke
parents:
diff changeset
133 u2 cpi_old = _s_old->get_index_big();
a61af66fc99e Initial load
duke
parents:
diff changeset
134 u2 cpi_new = _s_new->get_index_big();
a61af66fc99e Initial load
duke
parents:
diff changeset
135 if ((_old_cp->klass_at_noresolve(cpi_old) != _new_cp->klass_at_noresolve(cpi_new)))
a61af66fc99e Initial load
duke
parents:
diff changeset
136 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
137 if (c_old == Bytecodes::_multianewarray &&
a61af66fc99e Initial load
duke
parents:
diff changeset
138 *(jbyte*)(_s_old->bcp() + 3) != *(jbyte*)(_s_new->bcp() + 3))
a61af66fc99e Initial load
duke
parents:
diff changeset
139 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
140 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
141 }
a61af66fc99e Initial load
duke
parents:
diff changeset
142
a61af66fc99e Initial load
duke
parents:
diff changeset
143 case Bytecodes::_getstatic : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
144 case Bytecodes::_putstatic : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
145 case Bytecodes::_getfield : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
146 case Bytecodes::_putfield : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
147 case Bytecodes::_invokevirtual : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
148 case Bytecodes::_invokespecial : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
149 case Bytecodes::_invokestatic : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
150 case Bytecodes::_invokeinterface : {
a61af66fc99e Initial load
duke
parents:
diff changeset
151 u2 cpci_old = _s_old->get_index_big();
a61af66fc99e Initial load
duke
parents:
diff changeset
152 u2 cpci_new = _s_new->get_index_big();
a61af66fc99e Initial load
duke
parents:
diff changeset
153 // Check if the names of classes, field/method names and signatures at these indexes
a61af66fc99e Initial load
duke
parents:
diff changeset
154 // are the same. Indices which are really into constantpool cache (rather than constant
a61af66fc99e Initial load
duke
parents:
diff changeset
155 // pool itself) are accepted by the constantpool query routines below.
a61af66fc99e Initial load
duke
parents:
diff changeset
156 if ((_old_cp->klass_ref_at_noresolve(cpci_old) != _new_cp->klass_ref_at_noresolve(cpci_new)) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
157 (_old_cp->name_ref_at(cpci_old) != _new_cp->name_ref_at(cpci_new)) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
158 (_old_cp->signature_ref_at(cpci_old) != _new_cp->signature_ref_at(cpci_new)))
a61af66fc99e Initial load
duke
parents:
diff changeset
159 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
160 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
161 }
a61af66fc99e Initial load
duke
parents:
diff changeset
162
a61af66fc99e Initial load
duke
parents:
diff changeset
163 case Bytecodes::_ldc : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
164 case Bytecodes::_ldc_w : {
a61af66fc99e Initial load
duke
parents:
diff changeset
165 u2 cpi_old, cpi_new;
a61af66fc99e Initial load
duke
parents:
diff changeset
166 if (c_old == Bytecodes::_ldc) {
a61af66fc99e Initial load
duke
parents:
diff changeset
167 cpi_old = _s_old->bcp()[1];
a61af66fc99e Initial load
duke
parents:
diff changeset
168 cpi_new = _s_new->bcp()[1];
a61af66fc99e Initial load
duke
parents:
diff changeset
169 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
170 cpi_old = _s_old->get_index_big();
a61af66fc99e Initial load
duke
parents:
diff changeset
171 cpi_new = _s_new->get_index_big();
a61af66fc99e Initial load
duke
parents:
diff changeset
172 }
a61af66fc99e Initial load
duke
parents:
diff changeset
173 constantTag tag_old = _old_cp->tag_at(cpi_old);
a61af66fc99e Initial load
duke
parents:
diff changeset
174 constantTag tag_new = _new_cp->tag_at(cpi_new);
a61af66fc99e Initial load
duke
parents:
diff changeset
175 if (tag_old.is_int() || tag_old.is_float()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
176 if (tag_old.value() != tag_new.value())
a61af66fc99e Initial load
duke
parents:
diff changeset
177 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
178 if (tag_old.is_int()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
179 if (_old_cp->int_at(cpi_old) != _new_cp->int_at(cpi_new))
a61af66fc99e Initial load
duke
parents:
diff changeset
180 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
181 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
182 if (_old_cp->float_at(cpi_old) != _new_cp->float_at(cpi_new))
a61af66fc99e Initial load
duke
parents:
diff changeset
183 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
184 }
a61af66fc99e Initial load
duke
parents:
diff changeset
185 } else if (tag_old.is_string() || tag_old.is_unresolved_string()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
186 if (! (tag_new.is_unresolved_string() || tag_new.is_string()))
a61af66fc99e Initial load
duke
parents:
diff changeset
187 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
188 if (strcmp(_old_cp->string_at_noresolve(cpi_old),
a61af66fc99e Initial load
duke
parents:
diff changeset
189 _new_cp->string_at_noresolve(cpi_new)) != 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
190 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
191 } else { // tag_old should be klass - 4881222
a61af66fc99e Initial load
duke
parents:
diff changeset
192 if (! (tag_new.is_unresolved_klass() || tag_new.is_klass()))
a61af66fc99e Initial load
duke
parents:
diff changeset
193 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
194 if (_old_cp->klass_at_noresolve(cpi_old) !=
a61af66fc99e Initial load
duke
parents:
diff changeset
195 _new_cp->klass_at_noresolve(cpi_new))
a61af66fc99e Initial load
duke
parents:
diff changeset
196 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
197 }
a61af66fc99e Initial load
duke
parents:
diff changeset
198 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
199 }
a61af66fc99e Initial load
duke
parents:
diff changeset
200
a61af66fc99e Initial load
duke
parents:
diff changeset
201 case Bytecodes::_ldc2_w : {
a61af66fc99e Initial load
duke
parents:
diff changeset
202 u2 cpi_old = _s_old->get_index_big();
a61af66fc99e Initial load
duke
parents:
diff changeset
203 u2 cpi_new = _s_new->get_index_big();
a61af66fc99e Initial load
duke
parents:
diff changeset
204 constantTag tag_old = _old_cp->tag_at(cpi_old);
a61af66fc99e Initial load
duke
parents:
diff changeset
205 constantTag tag_new = _new_cp->tag_at(cpi_new);
a61af66fc99e Initial load
duke
parents:
diff changeset
206 if (tag_old.value() != tag_new.value())
a61af66fc99e Initial load
duke
parents:
diff changeset
207 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
208 if (tag_old.is_long()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
209 if (_old_cp->long_at(cpi_old) != _new_cp->long_at(cpi_new))
a61af66fc99e Initial load
duke
parents:
diff changeset
210 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
211 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
212 if (_old_cp->double_at(cpi_old) != _new_cp->double_at(cpi_new))
a61af66fc99e Initial load
duke
parents:
diff changeset
213 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
214 }
a61af66fc99e Initial load
duke
parents:
diff changeset
215 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
216 }
a61af66fc99e Initial load
duke
parents:
diff changeset
217
a61af66fc99e Initial load
duke
parents:
diff changeset
218 case Bytecodes::_bipush :
a61af66fc99e Initial load
duke
parents:
diff changeset
219 if (_s_old->bcp()[1] != _s_new->bcp()[1])
a61af66fc99e Initial load
duke
parents:
diff changeset
220 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
221 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
222
a61af66fc99e Initial load
duke
parents:
diff changeset
223 case Bytecodes::_sipush :
a61af66fc99e Initial load
duke
parents:
diff changeset
224 if (_s_old->get_index_big() != _s_new->get_index_big())
a61af66fc99e Initial load
duke
parents:
diff changeset
225 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
226 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
227
a61af66fc99e Initial load
duke
parents:
diff changeset
228 case Bytecodes::_aload : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
229 case Bytecodes::_astore : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
230 case Bytecodes::_dload : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
231 case Bytecodes::_dstore : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
232 case Bytecodes::_fload : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
233 case Bytecodes::_fstore : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
234 case Bytecodes::_iload : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
235 case Bytecodes::_istore : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
236 case Bytecodes::_lload : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
237 case Bytecodes::_lstore : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
238 case Bytecodes::_ret :
a61af66fc99e Initial load
duke
parents:
diff changeset
239 if (_s_old->is_wide() != _s_new->is_wide())
a61af66fc99e Initial load
duke
parents:
diff changeset
240 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
241 if (_s_old->get_index() != _s_new->get_index())
a61af66fc99e Initial load
duke
parents:
diff changeset
242 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
243 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
244
a61af66fc99e Initial load
duke
parents:
diff changeset
245 case Bytecodes::_goto : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
246 case Bytecodes::_if_acmpeq : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
247 case Bytecodes::_if_acmpne : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
248 case Bytecodes::_if_icmpeq : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
249 case Bytecodes::_if_icmpne : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
250 case Bytecodes::_if_icmplt : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
251 case Bytecodes::_if_icmpge : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
252 case Bytecodes::_if_icmpgt : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
253 case Bytecodes::_if_icmple : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
254 case Bytecodes::_ifeq : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
255 case Bytecodes::_ifne : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
256 case Bytecodes::_iflt : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
257 case Bytecodes::_ifge : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
258 case Bytecodes::_ifgt : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
259 case Bytecodes::_ifle : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
260 case Bytecodes::_ifnonnull : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
261 case Bytecodes::_ifnull : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
262 case Bytecodes::_jsr : {
a61af66fc99e Initial load
duke
parents:
diff changeset
263 short old_ofs = (short) _s_old->get_index_big();
a61af66fc99e Initial load
duke
parents:
diff changeset
264 short new_ofs = (short) _s_new->get_index_big();
a61af66fc99e Initial load
duke
parents:
diff changeset
265 if (_switchable_test) {
a61af66fc99e Initial load
duke
parents:
diff changeset
266 int old_dest = _s_old->bci() + old_ofs;
a61af66fc99e Initial load
duke
parents:
diff changeset
267 int new_dest = _s_new->bci() + new_ofs;
a61af66fc99e Initial load
duke
parents:
diff changeset
268 if (old_ofs < 0 && new_ofs < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
269 if (! _bci_map->old_and_new_locations_same(old_dest, new_dest))
a61af66fc99e Initial load
duke
parents:
diff changeset
270 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
271 } else if (old_ofs > 0 && new_ofs > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
272 _fwd_jmps->append(old_dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
273 _fwd_jmps->append(new_dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
274 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
275 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
276 }
a61af66fc99e Initial load
duke
parents:
diff changeset
277 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
278 if (old_ofs != new_ofs)
a61af66fc99e Initial load
duke
parents:
diff changeset
279 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
280 }
a61af66fc99e Initial load
duke
parents:
diff changeset
281 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
282 }
a61af66fc99e Initial load
duke
parents:
diff changeset
283
a61af66fc99e Initial load
duke
parents:
diff changeset
284 case Bytecodes::_iinc :
a61af66fc99e Initial load
duke
parents:
diff changeset
285 if (_s_old->is_wide() != _s_new->is_wide())
a61af66fc99e Initial load
duke
parents:
diff changeset
286 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
287 if (! _s_old->is_wide()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
288 if (_s_old->get_index_big() != _s_new->get_index_big())
a61af66fc99e Initial load
duke
parents:
diff changeset
289 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
290 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
291 if (Bytes::get_Java_u4(_s_old->bcp() + 1) != Bytes::get_Java_u4(_s_new->bcp() + 1))
a61af66fc99e Initial load
duke
parents:
diff changeset
292 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
293 }
a61af66fc99e Initial load
duke
parents:
diff changeset
294 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
295
a61af66fc99e Initial load
duke
parents:
diff changeset
296 case Bytecodes::_goto_w : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
297 case Bytecodes::_jsr_w : {
a61af66fc99e Initial load
duke
parents:
diff changeset
298 int old_ofs = (int) Bytes::get_Java_u4(_s_old->bcp() + 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
299 int new_ofs = (int) Bytes::get_Java_u4(_s_new->bcp() + 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
300 if (_switchable_test) {
a61af66fc99e Initial load
duke
parents:
diff changeset
301 int old_dest = _s_old->bci() + old_ofs;
a61af66fc99e Initial load
duke
parents:
diff changeset
302 int new_dest = _s_new->bci() + new_ofs;
a61af66fc99e Initial load
duke
parents:
diff changeset
303 if (old_ofs < 0 && new_ofs < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
304 if (! _bci_map->old_and_new_locations_same(old_dest, new_dest))
a61af66fc99e Initial load
duke
parents:
diff changeset
305 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
306 } else if (old_ofs > 0 && new_ofs > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
307 _fwd_jmps->append(old_dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
308 _fwd_jmps->append(new_dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
309 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
310 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
311 }
a61af66fc99e Initial load
duke
parents:
diff changeset
312 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
313 if (old_ofs != new_ofs)
a61af66fc99e Initial load
duke
parents:
diff changeset
314 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
315 }
a61af66fc99e Initial load
duke
parents:
diff changeset
316 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
317 }
a61af66fc99e Initial load
duke
parents:
diff changeset
318
a61af66fc99e Initial load
duke
parents:
diff changeset
319 case Bytecodes::_lookupswitch : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
320 case Bytecodes::_tableswitch : {
a61af66fc99e Initial load
duke
parents:
diff changeset
321 if (_switchable_test) {
a61af66fc99e Initial load
duke
parents:
diff changeset
322 address aligned_bcp_old = (address) round_to((intptr_t)_s_old->bcp() + 1, jintSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
323 address aligned_bcp_new = (address) round_to((intptr_t)_s_new->bcp() + 1, jintSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
324 int default_old = (int) Bytes::get_Java_u4(aligned_bcp_old);
a61af66fc99e Initial load
duke
parents:
diff changeset
325 int default_new = (int) Bytes::get_Java_u4(aligned_bcp_new);
a61af66fc99e Initial load
duke
parents:
diff changeset
326 _fwd_jmps->append(_s_old->bci() + default_old);
a61af66fc99e Initial load
duke
parents:
diff changeset
327 _fwd_jmps->append(_s_new->bci() + default_new);
a61af66fc99e Initial load
duke
parents:
diff changeset
328 if (c_old == Bytecodes::_lookupswitch) {
a61af66fc99e Initial load
duke
parents:
diff changeset
329 int npairs_old = (int) Bytes::get_Java_u4(aligned_bcp_old + jintSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
330 int npairs_new = (int) Bytes::get_Java_u4(aligned_bcp_new + jintSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
331 if (npairs_old != npairs_new)
a61af66fc99e Initial load
duke
parents:
diff changeset
332 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
333 for (int i = 0; i < npairs_old; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
334 int match_old = (int) Bytes::get_Java_u4(aligned_bcp_old + (2+2*i)*jintSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
335 int match_new = (int) Bytes::get_Java_u4(aligned_bcp_new + (2+2*i)*jintSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
336 if (match_old != match_new)
a61af66fc99e Initial load
duke
parents:
diff changeset
337 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
338 int ofs_old = (int) Bytes::get_Java_u4(aligned_bcp_old + (2+2*i+1)*jintSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
339 int ofs_new = (int) Bytes::get_Java_u4(aligned_bcp_new + (2+2*i+1)*jintSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
340 _fwd_jmps->append(_s_old->bci() + ofs_old);
a61af66fc99e Initial load
duke
parents:
diff changeset
341 _fwd_jmps->append(_s_new->bci() + ofs_new);
a61af66fc99e Initial load
duke
parents:
diff changeset
342 }
a61af66fc99e Initial load
duke
parents:
diff changeset
343 } else if (c_old == Bytecodes::_tableswitch) {
a61af66fc99e Initial load
duke
parents:
diff changeset
344 int lo_old = (int) Bytes::get_Java_u4(aligned_bcp_old + jintSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
345 int lo_new = (int) Bytes::get_Java_u4(aligned_bcp_new + jintSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
346 if (lo_old != lo_new)
a61af66fc99e Initial load
duke
parents:
diff changeset
347 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
348 int hi_old = (int) Bytes::get_Java_u4(aligned_bcp_old + 2*jintSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
349 int hi_new = (int) Bytes::get_Java_u4(aligned_bcp_new + 2*jintSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
350 if (hi_old != hi_new)
a61af66fc99e Initial load
duke
parents:
diff changeset
351 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
352 for (int i = 0; i < hi_old - lo_old + 1; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
353 int ofs_old = (int) Bytes::get_Java_u4(aligned_bcp_old + (3+i)*jintSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
354 int ofs_new = (int) Bytes::get_Java_u4(aligned_bcp_new + (3+i)*jintSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
355 _fwd_jmps->append(_s_old->bci() + ofs_old);
a61af66fc99e Initial load
duke
parents:
diff changeset
356 _fwd_jmps->append(_s_new->bci() + ofs_new);
a61af66fc99e Initial load
duke
parents:
diff changeset
357 }
a61af66fc99e Initial load
duke
parents:
diff changeset
358 }
a61af66fc99e Initial load
duke
parents:
diff changeset
359 } else { // !_switchable_test, can use fast rough compare
a61af66fc99e Initial load
duke
parents:
diff changeset
360 int len_old = _s_old->next_bcp() - _s_old->bcp();
a61af66fc99e Initial load
duke
parents:
diff changeset
361 int len_new = _s_new->next_bcp() - _s_new->bcp();
a61af66fc99e Initial load
duke
parents:
diff changeset
362 if (len_old != len_new)
a61af66fc99e Initial load
duke
parents:
diff changeset
363 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
364 if (memcmp(_s_old->bcp(), _s_new->bcp(), len_old) != 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
365 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
366 }
a61af66fc99e Initial load
duke
parents:
diff changeset
367 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
368 }
a61af66fc99e Initial load
duke
parents:
diff changeset
369 }
a61af66fc99e Initial load
duke
parents:
diff changeset
370
a61af66fc99e Initial load
duke
parents:
diff changeset
371 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
372 }
a61af66fc99e Initial load
duke
parents:
diff changeset
373
a61af66fc99e Initial load
duke
parents:
diff changeset
374
a61af66fc99e Initial load
duke
parents:
diff changeset
375 int MethodComparator::check_stack_and_locals_size(methodOop old_method, methodOop new_method) {
a61af66fc99e Initial load
duke
parents:
diff changeset
376 if (old_method->max_stack() != new_method->max_stack()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
377 return 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
378 } else if (old_method->max_locals() != new_method->max_locals()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
379 return 2;
a61af66fc99e Initial load
duke
parents:
diff changeset
380 } else if (old_method->size_of_parameters() != new_method->size_of_parameters()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
381 return 3;
a61af66fc99e Initial load
duke
parents:
diff changeset
382 } else return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
383 }