Mercurial > hg > graal-compiler
annotate src/share/vm/interpreter/bytecode.hpp @ 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 | b92c45f2bc75 |
children | e342a5110bed |
rev | line source |
---|---|
0 | 1 /* |
2142 | 2 * Copyright (c) 1997, 2011, 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:
1138
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1138
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:
1138
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #ifndef SHARE_VM_INTERPRETER_BYTECODE_HPP |
26 #define SHARE_VM_INTERPRETER_BYTECODE_HPP | |
27 | |
28 #include "interpreter/bytecodes.hpp" | |
29 #include "memory/allocation.hpp" | |
30 #include "oops/methodOop.hpp" | |
31 #ifdef TARGET_ARCH_x86 | |
32 # include "bytes_x86.hpp" | |
33 #endif | |
34 #ifdef TARGET_ARCH_sparc | |
35 # include "bytes_sparc.hpp" | |
36 #endif | |
37 #ifdef TARGET_ARCH_zero | |
38 # include "bytes_zero.hpp" | |
39 #endif | |
2192
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2177
diff
changeset
|
40 #ifdef TARGET_ARCH_arm |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2177
diff
changeset
|
41 # include "bytes_arm.hpp" |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2177
diff
changeset
|
42 #endif |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2177
diff
changeset
|
43 #ifdef TARGET_ARCH_ppc |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2177
diff
changeset
|
44 # include "bytes_ppc.hpp" |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2177
diff
changeset
|
45 #endif |
1972 | 46 |
2142 | 47 class ciBytecodeStream; |
48 | |
49 // The base class for different kinds of bytecode abstractions. | |
50 // Provides the primitive operations to manipulate code relative | |
51 // to the bcp. | |
0 | 52 |
2142 | 53 class Bytecode: public StackObj { |
54 protected: | |
55 const address _bcp; | |
56 const Bytecodes::Code _code; | |
57 | |
0 | 58 // Address computation |
2142 | 59 address addr_at (int offset) const { return (address)_bcp + offset; } |
60 u_char byte_at(int offset) const { return *addr_at(offset); } | |
0 | 61 address aligned_addr_at (int offset) const { return (address)round_to((intptr_t)addr_at(offset), jintSize); } |
62 int aligned_offset (int offset) const { return aligned_addr_at(offset) - addr_at(0); } | |
63 | |
1565 | 64 // Word access: |
65 int get_Java_u2_at (int offset) const { return Bytes::get_Java_u2(addr_at(offset)); } | |
66 int get_Java_u4_at (int offset) const { return Bytes::get_Java_u4(addr_at(offset)); } | |
67 int get_native_u2_at (int offset) const { return Bytes::get_native_u2(addr_at(offset)); } | |
68 int get_native_u4_at (int offset) const { return Bytes::get_native_u4(addr_at(offset)); } | |
0 | 69 |
70 public: | |
2142 | 71 Bytecode(methodOop method, address bcp): _bcp(bcp), _code(Bytecodes::code_at(method, addr_at(0))) { |
72 assert(method != NULL, "this form requires a valid methodOop"); | |
73 } | |
74 // Defined in ciStreams.hpp | |
75 inline Bytecode(const ciBytecodeStream* stream, address bcp = NULL); | |
0 | 76 |
2142 | 77 // Attributes |
78 address bcp() const { return _bcp; } | |
79 int instruction_size() const { return Bytecodes::length_for_code_at(_code, bcp()); } | |
80 | |
81 Bytecodes::Code code() const { return _code; } | |
0 | 82 Bytecodes::Code java_code() const { return Bytecodes::java_code(code()); } |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
0
diff
changeset
|
83 |
1565 | 84 // Static functions for parsing bytecodes in place. |
85 int get_index_u1(Bytecodes::Code bc) const { | |
86 assert_same_format_as(bc); assert_index_size(1, bc); | |
87 return *(jubyte*)addr_at(1); | |
88 } | |
89 int get_index_u2(Bytecodes::Code bc, bool is_wide = false) const { | |
90 assert_same_format_as(bc, is_wide); assert_index_size(2, bc, is_wide); | |
91 address p = addr_at(is_wide ? 2 : 1); | |
92 if (can_use_native_byte_order(bc, is_wide)) | |
2142 | 93 return Bytes::get_native_u2(p); |
1565 | 94 else return Bytes::get_Java_u2(p); |
95 } | |
1602 | 96 int get_index_u1_cpcache(Bytecodes::Code bc) const { |
97 assert_same_format_as(bc); assert_index_size(1, bc); | |
98 return *(jubyte*)addr_at(1) + constantPoolOopDesc::CPCACHE_INDEX_TAG; | |
99 } | |
1565 | 100 int get_index_u2_cpcache(Bytecodes::Code bc) const { |
101 assert_same_format_as(bc); assert_index_size(2, bc); assert_native_index(bc); | |
1602 | 102 return Bytes::get_native_u2(addr_at(1)) + constantPoolOopDesc::CPCACHE_INDEX_TAG; |
1565 | 103 } |
104 int get_index_u4(Bytecodes::Code bc) const { | |
105 assert_same_format_as(bc); assert_index_size(4, bc); | |
106 assert(can_use_native_byte_order(bc), ""); | |
107 return Bytes::get_native_u4(addr_at(1)); | |
108 } | |
109 bool has_index_u4(Bytecodes::Code bc) const { | |
110 return bc == Bytecodes::_invokedynamic; | |
111 } | |
112 | |
113 int get_offset_s2(Bytecodes::Code bc) const { | |
114 assert_same_format_as(bc); assert_offset_size(2, bc); | |
115 return (jshort) Bytes::get_Java_u2(addr_at(1)); | |
116 } | |
117 int get_offset_s4(Bytecodes::Code bc) const { | |
118 assert_same_format_as(bc); assert_offset_size(4, bc); | |
119 return (jint) Bytes::get_Java_u4(addr_at(1)); | |
120 } | |
121 | |
122 int get_constant_u1(int offset, Bytecodes::Code bc) const { | |
123 assert_same_format_as(bc); assert_constant_size(1, offset, bc); | |
124 return *(jbyte*)addr_at(offset); | |
125 } | |
126 int get_constant_u2(int offset, Bytecodes::Code bc, bool is_wide = false) const { | |
127 assert_same_format_as(bc, is_wide); assert_constant_size(2, offset, bc, is_wide); | |
128 return (jshort) Bytes::get_Java_u2(addr_at(offset)); | |
129 } | |
130 | |
131 // These are used locally and also from bytecode streams. | |
132 void assert_same_format_as(Bytecodes::Code testbc, bool is_wide = false) const NOT_DEBUG_RETURN; | |
133 static void assert_index_size(int required_size, Bytecodes::Code bc, bool is_wide = false) NOT_DEBUG_RETURN; | |
134 static void assert_offset_size(int required_size, Bytecodes::Code bc, bool is_wide = false) NOT_DEBUG_RETURN; | |
135 static void assert_constant_size(int required_size, int where, Bytecodes::Code bc, bool is_wide = false) NOT_DEBUG_RETURN; | |
136 static void assert_native_index(Bytecodes::Code bc, bool is_wide = false) NOT_DEBUG_RETURN; | |
137 static bool can_use_native_byte_order(Bytecodes::Code bc, bool is_wide = false) { | |
138 return (!Bytes::is_Java_byte_ordering_different() || Bytecodes::native_byte_order(bc /*, is_wide*/)); | |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
0
diff
changeset
|
139 } |
0 | 140 }; |
141 | |
142 | |
143 // Abstractions for lookupswitch bytecode | |
2142 | 144 class LookupswitchPair VALUE_OBJ_CLASS_SPEC { |
0 | 145 private: |
2142 | 146 const address _bcp; |
147 | |
148 address addr_at (int offset) const { return _bcp + offset; } | |
149 int get_Java_u4_at (int offset) const { return Bytes::get_Java_u4(addr_at(offset)); } | |
0 | 150 |
151 public: | |
2142 | 152 LookupswitchPair(address bcp): _bcp(bcp) {} |
1565 | 153 int match() const { return get_Java_u4_at(0 * jintSize); } |
154 int offset() const { return get_Java_u4_at(1 * jintSize); } | |
0 | 155 }; |
156 | |
157 | |
158 class Bytecode_lookupswitch: public Bytecode { | |
159 public: | |
2142 | 160 Bytecode_lookupswitch(methodOop method, address bcp): Bytecode(method, bcp) { verify(); } |
161 // Defined in ciStreams.hpp | |
162 inline Bytecode_lookupswitch(const ciBytecodeStream* stream); | |
0 | 163 void verify() const PRODUCT_RETURN; |
164 | |
165 // Attributes | |
1565 | 166 int default_offset() const { return get_Java_u4_at(aligned_offset(1 + 0*jintSize)); } |
167 int number_of_pairs() const { return get_Java_u4_at(aligned_offset(1 + 1*jintSize)); } | |
2142 | 168 LookupswitchPair pair_at(int i) const { |
169 assert(0 <= i && i < number_of_pairs(), "pair index out of bounds"); | |
170 return LookupswitchPair(aligned_addr_at(1 + (1 + i)*2*jintSize)); | |
171 } | |
0 | 172 }; |
173 | |
174 class Bytecode_tableswitch: public Bytecode { | |
175 public: | |
2142 | 176 Bytecode_tableswitch(methodOop method, address bcp): Bytecode(method, bcp) { verify(); } |
177 // Defined in ciStreams.hpp | |
178 inline Bytecode_tableswitch(const ciBytecodeStream* stream); | |
0 | 179 void verify() const PRODUCT_RETURN; |
180 | |
181 // Attributes | |
1565 | 182 int default_offset() const { return get_Java_u4_at(aligned_offset(1 + 0*jintSize)); } |
183 int low_key() const { return get_Java_u4_at(aligned_offset(1 + 1*jintSize)); } | |
184 int high_key() const { return get_Java_u4_at(aligned_offset(1 + 2*jintSize)); } | |
0 | 185 int dest_offset_at(int i) const; |
186 int length() { return high_key()-low_key()+1; } | |
187 }; | |
188 | |
1602 | 189 // Common code for decoding invokes and field references. |
0 | 190 |
2142 | 191 class Bytecode_member_ref: public Bytecode { |
0 | 192 protected: |
2142 | 193 const methodHandle _method; // method containing the bytecode |
0 | 194 |
2142 | 195 Bytecode_member_ref(methodHandle method, int bci) : Bytecode(method(), method()->bcp_from(bci)), _method(method) {} |
196 | |
197 methodHandle method() const { return _method; } | |
1602 | 198 |
199 public: | |
200 int index() const; // cache index (loaded from instruction) | |
201 int pool_index() const; // constant pool index | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
202 Symbol* name() const; // returns the name of the method or field |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
203 Symbol* signature() const; // returns the signature of the method or field |
1602 | 204 |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
205 BasicType result_type() const; // returns the result type of the getfield or invoke |
1602 | 206 }; |
207 | |
208 // Abstraction for invoke_{virtual, static, interface, special} | |
209 | |
210 class Bytecode_invoke: public Bytecode_member_ref { | |
211 protected: | |
2142 | 212 // Constructor that skips verification |
213 Bytecode_invoke(methodHandle method, int bci, bool unused) : Bytecode_member_ref(method, bci) {} | |
0 | 214 |
215 public: | |
2142 | 216 Bytecode_invoke(methodHandle method, int bci) : Bytecode_member_ref(method, bci) { verify(); } |
0 | 217 void verify() const; |
218 | |
219 // Attributes | |
220 methodHandle static_target(TRAPS); // "specified" method (from constant pool) | |
221 | |
222 // Testers | |
1602 | 223 bool is_invokeinterface() const { return java_code() == Bytecodes::_invokeinterface; } |
224 bool is_invokevirtual() const { return java_code() == Bytecodes::_invokevirtual; } | |
225 bool is_invokestatic() const { return java_code() == Bytecodes::_invokestatic; } | |
226 bool is_invokespecial() const { return java_code() == Bytecodes::_invokespecial; } | |
227 bool is_invokedynamic() const { return java_code() == Bytecodes::_invokedynamic; } | |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
0
diff
changeset
|
228 |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1135
diff
changeset
|
229 bool has_receiver() const { return !is_invokestatic() && !is_invokedynamic(); } |
0 | 230 |
231 bool is_valid() const { return is_invokeinterface() || | |
232 is_invokevirtual() || | |
233 is_invokestatic() || | |
1135
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
844
diff
changeset
|
234 is_invokespecial() || |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
844
diff
changeset
|
235 is_invokedynamic(); } |
0 | 236 |
2142 | 237 // Helper to skip verification. Used is_valid() to check if the result is really an invoke |
238 inline friend Bytecode_invoke Bytecode_invoke_check(methodHandle method, int bci); | |
0 | 239 }; |
240 | |
2142 | 241 inline Bytecode_invoke Bytecode_invoke_check(methodHandle method, int bci) { |
242 return Bytecode_invoke(method, bci, false); | |
0 | 243 } |
244 | |
245 | |
1602 | 246 // Abstraction for all field accesses (put/get field/static) |
247 class Bytecode_field: public Bytecode_member_ref { | |
2142 | 248 public: |
249 Bytecode_field(methodHandle method, int bci) : Bytecode_member_ref(method, bci) { verify(); } | |
1602 | 250 |
251 // Testers | |
252 bool is_getfield() const { return java_code() == Bytecodes::_getfield; } | |
253 bool is_putfield() const { return java_code() == Bytecodes::_putfield; } | |
254 bool is_getstatic() const { return java_code() == Bytecodes::_getstatic; } | |
255 bool is_putstatic() const { return java_code() == Bytecodes::_putstatic; } | |
256 | |
257 bool is_getter() const { return is_getfield() || is_getstatic(); } | |
258 bool is_static() const { return is_getstatic() || is_putstatic(); } | |
259 | |
260 bool is_valid() const { return is_getfield() || | |
261 is_putfield() || | |
262 is_getstatic() || | |
263 is_putstatic(); } | |
0 | 264 void verify() const; |
265 }; | |
266 | |
267 // Abstraction for checkcast | |
268 class Bytecode_checkcast: public Bytecode { | |
269 public: | |
2142 | 270 Bytecode_checkcast(methodOop method, address bcp): Bytecode(method, bcp) { verify(); } |
0 | 271 void verify() const { assert(Bytecodes::java_code(code()) == Bytecodes::_checkcast, "check checkcast"); } |
272 | |
273 // Returns index | |
1565 | 274 long index() const { return get_index_u2(Bytecodes::_checkcast); }; |
0 | 275 }; |
276 | |
277 // Abstraction for instanceof | |
278 class Bytecode_instanceof: public Bytecode { | |
279 public: | |
2142 | 280 Bytecode_instanceof(methodOop method, address bcp): Bytecode(method, bcp) { verify(); } |
0 | 281 void verify() const { assert(code() == Bytecodes::_instanceof, "check instanceof"); } |
282 | |
283 // Returns index | |
1565 | 284 long index() const { return get_index_u2(Bytecodes::_instanceof); }; |
0 | 285 }; |
286 | |
287 class Bytecode_new: public Bytecode { | |
288 public: | |
2142 | 289 Bytecode_new(methodOop method, address bcp): Bytecode(method, bcp) { verify(); } |
0 | 290 void verify() const { assert(java_code() == Bytecodes::_new, "check new"); } |
291 | |
292 // Returns index | |
1565 | 293 long index() const { return get_index_u2(Bytecodes::_new); }; |
0 | 294 }; |
295 | |
296 class Bytecode_multianewarray: public Bytecode { | |
297 public: | |
2142 | 298 Bytecode_multianewarray(methodOop method, address bcp): Bytecode(method, bcp) { verify(); } |
0 | 299 void verify() const { assert(java_code() == Bytecodes::_multianewarray, "check new"); } |
300 | |
301 // Returns index | |
1565 | 302 long index() const { return get_index_u2(Bytecodes::_multianewarray); }; |
0 | 303 }; |
304 | |
305 class Bytecode_anewarray: public Bytecode { | |
306 public: | |
2142 | 307 Bytecode_anewarray(methodOop method, address bcp): Bytecode(method, bcp) { verify(); } |
0 | 308 void verify() const { assert(java_code() == Bytecodes::_anewarray, "check anewarray"); } |
309 | |
310 // Returns index | |
1565 | 311 long index() const { return get_index_u2(Bytecodes::_anewarray); }; |
0 | 312 }; |
313 | |
314 // Abstraction for ldc, ldc_w and ldc2_w | |
2142 | 315 class Bytecode_loadconstant: public Bytecode { |
1602 | 316 private: |
2142 | 317 const methodHandle _method; |
1602 | 318 |
319 int raw_index() const; | |
320 | |
0 | 321 public: |
2142 | 322 Bytecode_loadconstant(methodHandle method, int bci): Bytecode(method(), method->bcp_from(bci)), _method(method) { verify(); } |
1602 | 323 |
0 | 324 void verify() const { |
1602 | 325 assert(_method.not_null(), "must supply method"); |
0 | 326 Bytecodes::Code stdc = Bytecodes::java_code(code()); |
327 assert(stdc == Bytecodes::_ldc || | |
328 stdc == Bytecodes::_ldc_w || | |
329 stdc == Bytecodes::_ldc2_w, "load constant"); | |
330 } | |
331 | |
1602 | 332 // Only non-standard bytecodes (fast_aldc) have CP cache indexes. |
333 bool has_cache_index() const { return code() >= Bytecodes::number_of_java_codes; } | |
0 | 334 |
1602 | 335 int pool_index() const; // index into constant pool |
336 int cache_index() const { // index into CP cache (or -1 if none) | |
337 return has_cache_index() ? raw_index() : -1; | |
338 } | |
339 | |
340 BasicType result_type() const; // returns the result type of the ldc | |
341 | |
342 oop resolve_constant(TRAPS) const; | |
0 | 343 }; |
344 | |
1972 | 345 #endif // SHARE_VM_INTERPRETER_BYTECODE_HPP |