Mercurial > hg > truffle
annotate src/share/vm/interpreter/bytecode.cpp @ 1716:be3f9c242c9d
6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
Summary: GC workers now recognize an intermediate transient state of blocks which are allocated but have not yet completed initialization. blk_start() calls do not attempt to determine the size of a block in the transient state, rather waiting for the block to become initialized so that it is safe to query its size. Audited and ensured the order of initialization of object fields (klass, free bit and size) to respect block state transition protocol. Also included some new assertion checking code enabled in debug mode.
Reviewed-by: chrisphi, johnc, poonam
author | ysr |
---|---|
date | Mon, 16 Aug 2010 15:58:42 -0700 |
parents | 136b78722a08 |
children | f95d63e2154a |
rev | line source |
---|---|
0 | 1 /* |
1579 | 2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1135
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1135
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:
1135
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
25 #include "incls/_precompiled.incl" | |
26 #include "incls/_bytecode.cpp.incl" | |
27 | |
28 // Implementation of Bytecode | |
29 | |
1565 | 30 bool Bytecode::check_must_rewrite(Bytecodes::Code code) const { |
31 assert(Bytecodes::can_rewrite(code), "post-check only"); | |
0 | 32 |
33 // Some codes are conditionally rewriting. Look closely at them. | |
1565 | 34 switch (code) { |
0 | 35 case Bytecodes::_aload_0: |
36 // Even if RewriteFrequentPairs is turned on, | |
37 // the _aload_0 code might delay its rewrite until | |
38 // a following _getfield rewrites itself. | |
39 return false; | |
40 | |
41 case Bytecodes::_lookupswitch: | |
42 return false; // the rewrite is not done by the interpreter | |
43 | |
44 case Bytecodes::_new: | |
45 // (Could actually look at the class here, but the profit would be small.) | |
46 return false; // the rewrite is not always done | |
47 } | |
48 | |
49 // No other special cases. | |
50 return true; | |
51 } | |
52 | |
53 | |
1565 | 54 #ifdef ASSERT |
55 | |
56 void Bytecode::assert_same_format_as(Bytecodes::Code testbc, bool is_wide) const { | |
57 Bytecodes::Code thisbc = Bytecodes::cast(byte_at(0)); | |
58 if (thisbc == Bytecodes::_breakpoint) return; // let the assertion fail silently | |
59 if (is_wide) { | |
60 assert(thisbc == Bytecodes::_wide, "expected a wide instruction"); | |
61 thisbc = Bytecodes::cast(byte_at(1)); | |
62 if (thisbc == Bytecodes::_breakpoint) return; | |
63 } | |
64 int thisflags = Bytecodes::flags(testbc, is_wide) & Bytecodes::_all_fmt_bits; | |
65 int testflags = Bytecodes::flags(thisbc, is_wide) & Bytecodes::_all_fmt_bits; | |
66 if (thisflags != testflags) | |
67 tty->print_cr("assert_same_format_as(%d) failed on bc=%d%s; %d != %d", | |
68 (int)testbc, (int)thisbc, (is_wide?"/wide":""), testflags, thisflags); | |
69 assert(thisflags == testflags, "expected format"); | |
70 } | |
71 | |
72 void Bytecode::assert_index_size(int size, Bytecodes::Code bc, bool is_wide) { | |
73 int have_fmt = (Bytecodes::flags(bc, is_wide) | |
74 & (Bytecodes::_fmt_has_u2 | Bytecodes::_fmt_has_u4 | | |
75 Bytecodes::_fmt_not_simple | | |
76 // Not an offset field: | |
77 Bytecodes::_fmt_has_o)); | |
78 int need_fmt = -1; | |
79 switch (size) { | |
80 case 1: need_fmt = 0; break; | |
81 case 2: need_fmt = Bytecodes::_fmt_has_u2; break; | |
82 case 4: need_fmt = Bytecodes::_fmt_has_u4; break; | |
83 } | |
84 if (is_wide) need_fmt |= Bytecodes::_fmt_not_simple; | |
85 if (have_fmt != need_fmt) { | |
86 tty->print_cr("assert_index_size %d: bc=%d%s %d != %d", size, bc, (is_wide?"/wide":""), have_fmt, need_fmt); | |
87 assert(have_fmt == need_fmt, "assert_index_size"); | |
88 } | |
89 } | |
90 | |
91 void Bytecode::assert_offset_size(int size, Bytecodes::Code bc, bool is_wide) { | |
92 int have_fmt = Bytecodes::flags(bc, is_wide) & Bytecodes::_all_fmt_bits; | |
93 int need_fmt = -1; | |
94 switch (size) { | |
95 case 2: need_fmt = Bytecodes::_fmt_bo2; break; | |
96 case 4: need_fmt = Bytecodes::_fmt_bo4; break; | |
97 } | |
98 if (is_wide) need_fmt |= Bytecodes::_fmt_not_simple; | |
99 if (have_fmt != need_fmt) { | |
100 tty->print_cr("assert_offset_size %d: bc=%d%s %d != %d", size, bc, (is_wide?"/wide":""), have_fmt, need_fmt); | |
101 assert(have_fmt == need_fmt, "assert_offset_size"); | |
102 } | |
103 } | |
104 | |
105 void Bytecode::assert_constant_size(int size, int where, Bytecodes::Code bc, bool is_wide) { | |
106 int have_fmt = Bytecodes::flags(bc, is_wide) & (Bytecodes::_all_fmt_bits | |
107 // Ignore any 'i' field (for iinc): | |
108 & ~Bytecodes::_fmt_has_i); | |
109 int need_fmt = -1; | |
110 switch (size) { | |
111 case 1: need_fmt = Bytecodes::_fmt_bc; break; | |
112 case 2: need_fmt = Bytecodes::_fmt_bc | Bytecodes::_fmt_has_u2; break; | |
113 } | |
114 if (is_wide) need_fmt |= Bytecodes::_fmt_not_simple; | |
115 int length = is_wide ? Bytecodes::wide_length_for(bc) : Bytecodes::length_for(bc); | |
116 if (have_fmt != need_fmt || where + size != length) { | |
117 tty->print_cr("assert_constant_size %d @%d: bc=%d%s %d != %d", size, where, bc, (is_wide?"/wide":""), have_fmt, need_fmt); | |
118 } | |
119 assert(have_fmt == need_fmt, "assert_constant_size"); | |
120 assert(where + size == length, "assert_constant_size oob"); | |
121 } | |
122 | |
123 void Bytecode::assert_native_index(Bytecodes::Code bc, bool is_wide) { | |
124 assert((Bytecodes::flags(bc, is_wide) & Bytecodes::_fmt_has_nbo) != 0, "native index"); | |
125 } | |
126 | |
127 #endif //ASSERT | |
0 | 128 |
129 // Implementation of Bytecode_tableupswitch | |
130 | |
131 int Bytecode_tableswitch::dest_offset_at(int i) const { | |
1565 | 132 return get_Java_u4_at(aligned_offset(1 + (3 + i)*jintSize)); |
0 | 133 } |
134 | |
135 | |
136 // Implementation of Bytecode_invoke | |
137 | |
138 void Bytecode_invoke::verify() const { | |
139 assert(is_valid(), "check invoke"); | |
1565 | 140 assert(method()->constants()->cache() != NULL, "do not call this from verifier or rewriter"); |
0 | 141 } |
142 | |
143 | |
1602 | 144 symbolOop Bytecode_member_ref::signature() const { |
0 | 145 constantPoolOop constants = method()->constants(); |
146 return constants->signature_ref_at(index()); | |
147 } | |
148 | |
149 | |
1602 | 150 symbolOop Bytecode_member_ref::name() const { |
0 | 151 constantPoolOop constants = method()->constants(); |
152 return constants->name_ref_at(index()); | |
153 } | |
154 | |
155 | |
1602 | 156 BasicType Bytecode_member_ref::result_type(Thread *thread) const { |
0 | 157 symbolHandle sh(thread, signature()); |
158 ResultTypeFinder rts(sh); | |
159 rts.iterate(); | |
160 return rts.type(); | |
161 } | |
162 | |
163 | |
164 methodHandle Bytecode_invoke::static_target(TRAPS) { | |
165 methodHandle m; | |
166 KlassHandle resolved_klass; | |
167 constantPoolHandle constants(THREAD, _method->constants()); | |
168 | |
1602 | 169 if (java_code() == Bytecodes::_invokedynamic) { |
1135
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
844
diff
changeset
|
170 LinkResolver::resolve_dynamic_method(m, resolved_klass, constants, index(), CHECK_(methodHandle())); |
1602 | 171 } else if (java_code() != Bytecodes::_invokeinterface) { |
0 | 172 LinkResolver::resolve_method(m, resolved_klass, constants, index(), CHECK_(methodHandle())); |
173 } else { | |
174 LinkResolver::resolve_interface_method(m, resolved_klass, constants, index(), CHECK_(methodHandle())); | |
175 } | |
176 return m; | |
177 } | |
178 | |
179 | |
1602 | 180 int Bytecode_member_ref::index() const { |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
0
diff
changeset
|
181 // Note: Rewriter::rewrite changes the Java_u2 of an invokedynamic to a native_u4, |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
0
diff
changeset
|
182 // at the same time it allocates per-call-site CP cache entries. |
1602 | 183 Bytecodes::Code rawc = code(); |
184 Bytecode* invoke = bytecode(); | |
185 if (invoke->has_index_u4(rawc)) | |
186 return invoke->get_index_u4(rawc); | |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
0
diff
changeset
|
187 else |
1602 | 188 return invoke->get_index_u2_cpcache(rawc); |
0 | 189 } |
190 | |
1602 | 191 int Bytecode_member_ref::pool_index() const { |
192 int index = this->index(); | |
193 DEBUG_ONLY({ | |
194 if (!bytecode()->has_index_u4(code())) | |
195 index -= constantPoolOopDesc::CPCACHE_INDEX_TAG; | |
196 }); | |
197 return _method->constants()->cache()->entry_at(index)->constant_pool_index(); | |
198 } | |
0 | 199 |
200 // Implementation of Bytecode_field | |
201 | |
202 void Bytecode_field::verify() const { | |
1602 | 203 assert(is_valid(), "check field"); |
0 | 204 } |
205 | |
206 | |
1602 | 207 // Implementation of Bytecode_loadconstant |
208 | |
209 int Bytecode_loadconstant::raw_index() const { | |
210 Bytecode* bcp = bytecode(); | |
211 Bytecodes::Code rawc = bcp->code(); | |
212 assert(rawc != Bytecodes::_wide, "verifier prevents this"); | |
213 if (Bytecodes::java_code(rawc) == Bytecodes::_ldc) | |
214 return bcp->get_index_u1(rawc); | |
215 else | |
216 return bcp->get_index_u2(rawc, false); | |
0 | 217 } |
218 | |
1602 | 219 int Bytecode_loadconstant::pool_index() const { |
220 int index = raw_index(); | |
221 if (has_cache_index()) { | |
222 return _method->constants()->cache()->entry_at(index)->constant_pool_index(); | |
223 } | |
224 return index; | |
225 } | |
0 | 226 |
1602 | 227 BasicType Bytecode_loadconstant::result_type() const { |
228 int index = pool_index(); | |
229 constantTag tag = _method->constants()->tag_at(index); | |
230 return tag.basic_type(); | |
231 } | |
232 | |
233 oop Bytecode_loadconstant::resolve_constant(TRAPS) const { | |
234 assert(_method.not_null(), "must supply method to resolve constant"); | |
235 int index = raw_index(); | |
236 constantPoolOop constants = _method->constants(); | |
237 if (has_cache_index()) { | |
238 return constants->resolve_cached_constant_at(index, THREAD); | |
239 } else { | |
240 return constants->resolve_constant_at(index, THREAD); | |
1574 | 241 } |
0 | 242 } |
243 | |
244 //------------------------------------------------------------------------------ | |
245 // Non-product code | |
246 | |
247 #ifndef PRODUCT | |
248 | |
249 void Bytecode_lookupswitch::verify() const { | |
250 switch (Bytecodes::java_code(code())) { | |
251 case Bytecodes::_lookupswitch: | |
252 { int i = number_of_pairs() - 1; | |
253 while (i-- > 0) { | |
254 assert(pair_at(i)->match() < pair_at(i+1)->match(), "unsorted table entries"); | |
255 } | |
256 } | |
257 break; | |
258 default: | |
259 fatal("not a lookupswitch bytecode"); | |
260 } | |
261 } | |
262 | |
263 void Bytecode_tableswitch::verify() const { | |
264 switch (Bytecodes::java_code(code())) { | |
265 case Bytecodes::_tableswitch: | |
266 { int lo = low_key(); | |
267 int hi = high_key(); | |
268 assert (hi >= lo, "incorrect hi/lo values in tableswitch"); | |
269 int i = hi - lo - 1 ; | |
270 while (i-- > 0) { | |
271 // no special check needed | |
272 } | |
273 } | |
274 break; | |
275 default: | |
276 fatal("not a tableswitch bytecode"); | |
277 } | |
278 } | |
279 | |
280 #endif |