Mercurial > hg > truffle
comparison src/share/vm/interpreter/bytecode.hpp @ 2181:d25d4ca69222
Merge.
author | Thomas Wuerthinger <wuerthinger@ssw.jku.at> |
---|---|
date | Wed, 16 Feb 2011 13:47:20 +0100 |
parents | 3582bf76420e |
children | b92c45f2bc75 |
comparison
equal
deleted
inserted
replaced
2108:50b45e2d9725 | 2181:d25d4ca69222 |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. | 2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | 4 * |
5 * This code is free software; you can redistribute it and/or modify it | 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 | 6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
36 #endif | 36 #endif |
37 #ifdef TARGET_ARCH_zero | 37 #ifdef TARGET_ARCH_zero |
38 # include "bytes_zero.hpp" | 38 # include "bytes_zero.hpp" |
39 #endif | 39 #endif |
40 | 40 |
41 // Base class for different kinds of abstractions working | 41 class ciBytecodeStream; |
42 // relative to an objects 'this' pointer. | 42 |
43 | 43 // The base class for different kinds of bytecode abstractions. |
44 class ThisRelativeObj VALUE_OBJ_CLASS_SPEC { | 44 // Provides the primitive operations to manipulate code relative |
45 public: | 45 // to the bcp. |
46 | |
47 class Bytecode: public StackObj { | |
48 protected: | |
49 const address _bcp; | |
50 const Bytecodes::Code _code; | |
51 | |
46 // Address computation | 52 // Address computation |
47 address addr_at (int offset) const { return (address)this + offset; } | 53 address addr_at (int offset) const { return (address)_bcp + offset; } |
48 int byte_at (int offset) const { return *(addr_at(offset)); } | 54 u_char byte_at(int offset) const { return *addr_at(offset); } |
49 address aligned_addr_at (int offset) const { return (address)round_to((intptr_t)addr_at(offset), jintSize); } | 55 address aligned_addr_at (int offset) const { return (address)round_to((intptr_t)addr_at(offset), jintSize); } |
50 int aligned_offset (int offset) const { return aligned_addr_at(offset) - addr_at(0); } | 56 int aligned_offset (int offset) const { return aligned_addr_at(offset) - addr_at(0); } |
51 | 57 |
52 // Word access: | 58 // Word access: |
53 int get_Java_u2_at (int offset) const { return Bytes::get_Java_u2(addr_at(offset)); } | 59 int get_Java_u2_at (int offset) const { return Bytes::get_Java_u2(addr_at(offset)); } |
54 int get_Java_u4_at (int offset) const { return Bytes::get_Java_u4(addr_at(offset)); } | 60 int get_Java_u4_at (int offset) const { return Bytes::get_Java_u4(addr_at(offset)); } |
55 int get_native_u2_at (int offset) const { return Bytes::get_native_u2(addr_at(offset)); } | 61 int get_native_u2_at (int offset) const { return Bytes::get_native_u2(addr_at(offset)); } |
56 int get_native_u4_at (int offset) const { return Bytes::get_native_u4(addr_at(offset)); } | 62 int get_native_u4_at (int offset) const { return Bytes::get_native_u4(addr_at(offset)); } |
57 }; | 63 |
58 | 64 public: |
59 | 65 Bytecode(methodOop method, address bcp): _bcp(bcp), _code(Bytecodes::code_at(method, addr_at(0))) { |
60 // The base class for different kinds of bytecode abstractions. | 66 assert(method != NULL, "this form requires a valid methodOop"); |
61 // Provides the primitive operations to manipulate code relative | 67 } |
62 // to an objects 'this' pointer. | 68 // Defined in ciStreams.hpp |
63 // FIXME: Make this a ResourceObj, include the enclosing methodOop, and cache the opcode. | 69 inline Bytecode(const ciBytecodeStream* stream, address bcp = NULL); |
64 | 70 |
65 class Bytecode: public ThisRelativeObj { | |
66 protected: | |
67 u_char byte_at(int offset) const { return *addr_at(offset); } | |
68 bool check_must_rewrite(Bytecodes::Code bc) const; | |
69 | |
70 public: | |
71 // Attributes | 71 // Attributes |
72 address bcp() const { return addr_at(0); } | 72 address bcp() const { return _bcp; } |
73 int instruction_size() const { return Bytecodes::length_at(bcp()); } | 73 int instruction_size() const { return Bytecodes::length_for_code_at(_code, bcp()); } |
74 | 74 |
75 // Warning: Use code() with caution on live bytecode streams. 4926272 | 75 Bytecodes::Code code() const { return _code; } |
76 Bytecodes::Code code() const { return Bytecodes::code_at(addr_at(0)); } | |
77 Bytecodes::Code java_code() const { return Bytecodes::java_code(code()); } | 76 Bytecodes::Code java_code() const { return Bytecodes::java_code(code()); } |
78 bool must_rewrite(Bytecodes::Code code) const { return Bytecodes::can_rewrite(code) && check_must_rewrite(code); } | |
79 | |
80 // Creation | |
81 inline friend Bytecode* Bytecode_at(address bcp); | |
82 | 77 |
83 // Static functions for parsing bytecodes in place. | 78 // Static functions for parsing bytecodes in place. |
84 int get_index_u1(Bytecodes::Code bc) const { | 79 int get_index_u1(Bytecodes::Code bc) const { |
85 assert_same_format_as(bc); assert_index_size(1, bc); | 80 assert_same_format_as(bc); assert_index_size(1, bc); |
86 return *(jubyte*)addr_at(1); | 81 return *(jubyte*)addr_at(1); |
87 } | 82 } |
88 int get_index_u2(Bytecodes::Code bc, bool is_wide = false) const { | 83 int get_index_u2(Bytecodes::Code bc, bool is_wide = false) const { |
89 assert_same_format_as(bc, is_wide); assert_index_size(2, bc, is_wide); | 84 assert_same_format_as(bc, is_wide); assert_index_size(2, bc, is_wide); |
90 address p = addr_at(is_wide ? 2 : 1); | 85 address p = addr_at(is_wide ? 2 : 1); |
91 if (can_use_native_byte_order(bc, is_wide)) | 86 if (can_use_native_byte_order(bc, is_wide)) |
92 return Bytes::get_native_u2(p); | 87 return Bytes::get_native_u2(p); |
93 else return Bytes::get_Java_u2(p); | 88 else return Bytes::get_Java_u2(p); |
94 } | 89 } |
95 int get_index_u1_cpcache(Bytecodes::Code bc) const { | 90 int get_index_u1_cpcache(Bytecodes::Code bc) const { |
96 assert_same_format_as(bc); assert_index_size(1, bc); | 91 assert_same_format_as(bc); assert_index_size(1, bc); |
97 return *(jubyte*)addr_at(1) + constantPoolOopDesc::CPCACHE_INDEX_TAG; | 92 return *(jubyte*)addr_at(1) + constantPoolOopDesc::CPCACHE_INDEX_TAG; |
136 static bool can_use_native_byte_order(Bytecodes::Code bc, bool is_wide = false) { | 131 static bool can_use_native_byte_order(Bytecodes::Code bc, bool is_wide = false) { |
137 return (!Bytes::is_Java_byte_ordering_different() || Bytecodes::native_byte_order(bc /*, is_wide*/)); | 132 return (!Bytes::is_Java_byte_ordering_different() || Bytecodes::native_byte_order(bc /*, is_wide*/)); |
138 } | 133 } |
139 }; | 134 }; |
140 | 135 |
141 inline Bytecode* Bytecode_at(address bcp) { | |
142 // Warning: Use with caution on live bytecode streams. 4926272 | |
143 return (Bytecode*)bcp; | |
144 } | |
145 | |
146 | 136 |
147 // Abstractions for lookupswitch bytecode | 137 // Abstractions for lookupswitch bytecode |
148 | 138 class LookupswitchPair VALUE_OBJ_CLASS_SPEC { |
149 class LookupswitchPair: ThisRelativeObj { | |
150 private: | 139 private: |
151 int _match; | 140 const address _bcp; |
152 int _offset; | 141 |
153 | 142 address addr_at (int offset) const { return _bcp + offset; } |
154 public: | 143 int get_Java_u4_at (int offset) const { return Bytes::get_Java_u4(addr_at(offset)); } |
144 | |
145 public: | |
146 LookupswitchPair(address bcp): _bcp(bcp) {} | |
155 int match() const { return get_Java_u4_at(0 * jintSize); } | 147 int match() const { return get_Java_u4_at(0 * jintSize); } |
156 int offset() const { return get_Java_u4_at(1 * jintSize); } | 148 int offset() const { return get_Java_u4_at(1 * jintSize); } |
157 }; | 149 }; |
158 | 150 |
159 | 151 |
160 class Bytecode_lookupswitch: public Bytecode { | 152 class Bytecode_lookupswitch: public Bytecode { |
161 public: | 153 public: |
154 Bytecode_lookupswitch(methodOop method, address bcp): Bytecode(method, bcp) { verify(); } | |
155 // Defined in ciStreams.hpp | |
156 inline Bytecode_lookupswitch(const ciBytecodeStream* stream); | |
162 void verify() const PRODUCT_RETURN; | 157 void verify() const PRODUCT_RETURN; |
163 | 158 |
164 // Attributes | 159 // Attributes |
165 int default_offset() const { return get_Java_u4_at(aligned_offset(1 + 0*jintSize)); } | 160 int default_offset() const { return get_Java_u4_at(aligned_offset(1 + 0*jintSize)); } |
166 int number_of_pairs() const { return get_Java_u4_at(aligned_offset(1 + 1*jintSize)); } | 161 int number_of_pairs() const { return get_Java_u4_at(aligned_offset(1 + 1*jintSize)); } |
167 LookupswitchPair* pair_at(int i) const { assert(0 <= i && i < number_of_pairs(), "pair index out of bounds"); | 162 LookupswitchPair pair_at(int i) const { |
168 return (LookupswitchPair*)aligned_addr_at(1 + (1 + i)*2*jintSize); } | 163 assert(0 <= i && i < number_of_pairs(), "pair index out of bounds"); |
169 // Creation | 164 return LookupswitchPair(aligned_addr_at(1 + (1 + i)*2*jintSize)); |
170 inline friend Bytecode_lookupswitch* Bytecode_lookupswitch_at(address bcp); | 165 } |
171 }; | 166 }; |
172 | |
173 inline Bytecode_lookupswitch* Bytecode_lookupswitch_at(address bcp) { | |
174 Bytecode_lookupswitch* b = (Bytecode_lookupswitch*)bcp; | |
175 DEBUG_ONLY(b->verify()); | |
176 return b; | |
177 } | |
178 | |
179 | 167 |
180 class Bytecode_tableswitch: public Bytecode { | 168 class Bytecode_tableswitch: public Bytecode { |
181 public: | 169 public: |
170 Bytecode_tableswitch(methodOop method, address bcp): Bytecode(method, bcp) { verify(); } | |
171 // Defined in ciStreams.hpp | |
172 inline Bytecode_tableswitch(const ciBytecodeStream* stream); | |
182 void verify() const PRODUCT_RETURN; | 173 void verify() const PRODUCT_RETURN; |
183 | 174 |
184 // Attributes | 175 // Attributes |
185 int default_offset() const { return get_Java_u4_at(aligned_offset(1 + 0*jintSize)); } | 176 int default_offset() const { return get_Java_u4_at(aligned_offset(1 + 0*jintSize)); } |
186 int low_key() const { return get_Java_u4_at(aligned_offset(1 + 1*jintSize)); } | 177 int low_key() const { return get_Java_u4_at(aligned_offset(1 + 1*jintSize)); } |
187 int high_key() const { return get_Java_u4_at(aligned_offset(1 + 2*jintSize)); } | 178 int high_key() const { return get_Java_u4_at(aligned_offset(1 + 2*jintSize)); } |
188 int dest_offset_at(int i) const; | 179 int dest_offset_at(int i) const; |
189 int length() { return high_key()-low_key()+1; } | 180 int length() { return high_key()-low_key()+1; } |
190 | 181 }; |
191 // Creation | |
192 inline friend Bytecode_tableswitch* Bytecode_tableswitch_at(address bcp); | |
193 }; | |
194 | |
195 inline Bytecode_tableswitch* Bytecode_tableswitch_at(address bcp) { | |
196 Bytecode_tableswitch* b = (Bytecode_tableswitch*)bcp; | |
197 DEBUG_ONLY(b->verify()); | |
198 return b; | |
199 } | |
200 | |
201 | 182 |
202 // Common code for decoding invokes and field references. | 183 // Common code for decoding invokes and field references. |
203 | 184 |
204 class Bytecode_member_ref: public ResourceObj { | 185 class Bytecode_member_ref: public Bytecode { |
205 protected: | 186 protected: |
206 methodHandle _method; // method containing the bytecode | 187 const methodHandle _method; // method containing the bytecode |
207 int _bci; // position of the bytecode | 188 |
208 | 189 Bytecode_member_ref(methodHandle method, int bci) : Bytecode(method(), method()->bcp_from(bci)), _method(method) {} |
209 Bytecode_member_ref(methodHandle method, int bci) : _method(method), _bci(bci) {} | 190 |
210 | |
211 public: | |
212 // Attributes | |
213 methodHandle method() const { return _method; } | 191 methodHandle method() const { return _method; } |
214 int bci() const { return _bci; } | 192 |
215 address bcp() const { return _method->bcp_from(bci()); } | 193 public: |
216 Bytecode* bytecode() const { return Bytecode_at(bcp()); } | |
217 | |
218 int index() const; // cache index (loaded from instruction) | 194 int index() const; // cache index (loaded from instruction) |
219 int pool_index() const; // constant pool index | 195 int pool_index() const; // constant pool index |
220 symbolOop name() const; // returns the name of the method or field | 196 Symbol* name() const; // returns the name of the method or field |
221 symbolOop signature() const; // returns the signature of the method or field | 197 Symbol* signature() const; // returns the signature of the method or field |
222 | 198 |
223 BasicType result_type(Thread* thread) const; // returns the result type of the getfield or invoke | 199 BasicType result_type() const; // returns the result type of the getfield or invoke |
224 | |
225 Bytecodes::Code code() const { return Bytecodes::code_at(bcp(), _method()); } | |
226 Bytecodes::Code java_code() const { return Bytecodes::java_code(code()); } | |
227 }; | 200 }; |
228 | 201 |
229 // Abstraction for invoke_{virtual, static, interface, special} | 202 // Abstraction for invoke_{virtual, static, interface, special} |
230 | 203 |
231 class Bytecode_invoke: public Bytecode_member_ref { | 204 class Bytecode_invoke: public Bytecode_member_ref { |
232 protected: | 205 protected: |
233 Bytecode_invoke(methodHandle method, int bci) : Bytecode_member_ref(method, bci) {} | 206 // Constructor that skips verification |
234 | 207 Bytecode_invoke(methodHandle method, int bci, bool unused) : Bytecode_member_ref(method, bci) {} |
235 public: | 208 |
209 public: | |
210 Bytecode_invoke(methodHandle method, int bci) : Bytecode_member_ref(method, bci) { verify(); } | |
236 void verify() const; | 211 void verify() const; |
237 | 212 |
238 // Attributes | 213 // Attributes |
239 methodHandle static_target(TRAPS); // "specified" method (from constant pool) | 214 methodHandle static_target(TRAPS); // "specified" method (from constant pool) |
240 | 215 |
251 is_invokevirtual() || | 226 is_invokevirtual() || |
252 is_invokestatic() || | 227 is_invokestatic() || |
253 is_invokespecial() || | 228 is_invokespecial() || |
254 is_invokedynamic(); } | 229 is_invokedynamic(); } |
255 | 230 |
256 // Creation | 231 // Helper to skip verification. Used is_valid() to check if the result is really an invoke |
257 inline friend Bytecode_invoke* Bytecode_invoke_at(methodHandle method, int bci); | 232 inline friend Bytecode_invoke Bytecode_invoke_check(methodHandle method, int bci); |
258 | 233 }; |
259 // Like Bytecode_invoke_at. Instead it returns NULL if the bci is not at an invoke. | 234 |
260 inline friend Bytecode_invoke* Bytecode_invoke_at_check(methodHandle method, int bci); | 235 inline Bytecode_invoke Bytecode_invoke_check(methodHandle method, int bci) { |
261 }; | 236 return Bytecode_invoke(method, bci, false); |
262 | |
263 inline Bytecode_invoke* Bytecode_invoke_at(methodHandle method, int bci) { | |
264 Bytecode_invoke* b = new Bytecode_invoke(method, bci); | |
265 DEBUG_ONLY(b->verify()); | |
266 return b; | |
267 } | |
268 | |
269 inline Bytecode_invoke* Bytecode_invoke_at_check(methodHandle method, int bci) { | |
270 Bytecode_invoke* b = new Bytecode_invoke(method, bci); | |
271 return b->is_valid() ? b : NULL; | |
272 } | 237 } |
273 | 238 |
274 | 239 |
275 // Abstraction for all field accesses (put/get field/static) | 240 // Abstraction for all field accesses (put/get field/static) |
276 class Bytecode_field: public Bytecode_member_ref { | 241 class Bytecode_field: public Bytecode_member_ref { |
277 protected: | 242 public: |
278 Bytecode_field(methodHandle method, int bci) : Bytecode_member_ref(method, bci) {} | 243 Bytecode_field(methodHandle method, int bci) : Bytecode_member_ref(method, bci) { verify(); } |
279 | 244 |
280 public: | |
281 // Testers | 245 // Testers |
282 bool is_getfield() const { return java_code() == Bytecodes::_getfield; } | 246 bool is_getfield() const { return java_code() == Bytecodes::_getfield; } |
283 bool is_putfield() const { return java_code() == Bytecodes::_putfield; } | 247 bool is_putfield() const { return java_code() == Bytecodes::_putfield; } |
284 bool is_getstatic() const { return java_code() == Bytecodes::_getstatic; } | 248 bool is_getstatic() const { return java_code() == Bytecodes::_getstatic; } |
285 bool is_putstatic() const { return java_code() == Bytecodes::_putstatic; } | 249 bool is_putstatic() const { return java_code() == Bytecodes::_putstatic; } |
290 bool is_valid() const { return is_getfield() || | 254 bool is_valid() const { return is_getfield() || |
291 is_putfield() || | 255 is_putfield() || |
292 is_getstatic() || | 256 is_getstatic() || |
293 is_putstatic(); } | 257 is_putstatic(); } |
294 void verify() const; | 258 void verify() const; |
295 | 259 }; |
296 // Creation | |
297 inline friend Bytecode_field* Bytecode_field_at(methodHandle method, int bci); | |
298 }; | |
299 | |
300 inline Bytecode_field* Bytecode_field_at(methodHandle method, int bci) { | |
301 Bytecode_field* b = new Bytecode_field(method, bci); | |
302 DEBUG_ONLY(b->verify()); | |
303 return b; | |
304 } | |
305 | |
306 | 260 |
307 // Abstraction for checkcast | 261 // Abstraction for checkcast |
308 | |
309 class Bytecode_checkcast: public Bytecode { | 262 class Bytecode_checkcast: public Bytecode { |
310 public: | 263 public: |
264 Bytecode_checkcast(methodOop method, address bcp): Bytecode(method, bcp) { verify(); } | |
311 void verify() const { assert(Bytecodes::java_code(code()) == Bytecodes::_checkcast, "check checkcast"); } | 265 void verify() const { assert(Bytecodes::java_code(code()) == Bytecodes::_checkcast, "check checkcast"); } |
312 | 266 |
313 // Returns index | 267 // Returns index |
314 long index() const { return get_index_u2(Bytecodes::_checkcast); }; | 268 long index() const { return get_index_u2(Bytecodes::_checkcast); }; |
315 | 269 }; |
316 // Creation | |
317 inline friend Bytecode_checkcast* Bytecode_checkcast_at(address bcp); | |
318 }; | |
319 | |
320 inline Bytecode_checkcast* Bytecode_checkcast_at(address bcp) { | |
321 Bytecode_checkcast* b = (Bytecode_checkcast*)bcp; | |
322 DEBUG_ONLY(b->verify()); | |
323 return b; | |
324 } | |
325 | |
326 | 270 |
327 // Abstraction for instanceof | 271 // Abstraction for instanceof |
328 | |
329 class Bytecode_instanceof: public Bytecode { | 272 class Bytecode_instanceof: public Bytecode { |
330 public: | 273 public: |
274 Bytecode_instanceof(methodOop method, address bcp): Bytecode(method, bcp) { verify(); } | |
331 void verify() const { assert(code() == Bytecodes::_instanceof, "check instanceof"); } | 275 void verify() const { assert(code() == Bytecodes::_instanceof, "check instanceof"); } |
332 | 276 |
333 // Returns index | 277 // Returns index |
334 long index() const { return get_index_u2(Bytecodes::_instanceof); }; | 278 long index() const { return get_index_u2(Bytecodes::_instanceof); }; |
335 | 279 }; |
336 // Creation | |
337 inline friend Bytecode_instanceof* Bytecode_instanceof_at(address bcp); | |
338 }; | |
339 | |
340 inline Bytecode_instanceof* Bytecode_instanceof_at(address bcp) { | |
341 Bytecode_instanceof* b = (Bytecode_instanceof*)bcp; | |
342 DEBUG_ONLY(b->verify()); | |
343 return b; | |
344 } | |
345 | |
346 | 280 |
347 class Bytecode_new: public Bytecode { | 281 class Bytecode_new: public Bytecode { |
348 public: | 282 public: |
283 Bytecode_new(methodOop method, address bcp): Bytecode(method, bcp) { verify(); } | |
349 void verify() const { assert(java_code() == Bytecodes::_new, "check new"); } | 284 void verify() const { assert(java_code() == Bytecodes::_new, "check new"); } |
350 | 285 |
351 // Returns index | 286 // Returns index |
352 long index() const { return get_index_u2(Bytecodes::_new); }; | 287 long index() const { return get_index_u2(Bytecodes::_new); }; |
353 | 288 }; |
354 // Creation | |
355 inline friend Bytecode_new* Bytecode_new_at(address bcp); | |
356 }; | |
357 | |
358 inline Bytecode_new* Bytecode_new_at(address bcp) { | |
359 Bytecode_new* b = (Bytecode_new*)bcp; | |
360 DEBUG_ONLY(b->verify()); | |
361 return b; | |
362 } | |
363 | |
364 | 289 |
365 class Bytecode_multianewarray: public Bytecode { | 290 class Bytecode_multianewarray: public Bytecode { |
366 public: | 291 public: |
292 Bytecode_multianewarray(methodOop method, address bcp): Bytecode(method, bcp) { verify(); } | |
367 void verify() const { assert(java_code() == Bytecodes::_multianewarray, "check new"); } | 293 void verify() const { assert(java_code() == Bytecodes::_multianewarray, "check new"); } |
368 | 294 |
369 // Returns index | 295 // Returns index |
370 long index() const { return get_index_u2(Bytecodes::_multianewarray); }; | 296 long index() const { return get_index_u2(Bytecodes::_multianewarray); }; |
371 | 297 }; |
372 // Creation | |
373 inline friend Bytecode_multianewarray* Bytecode_multianewarray_at(address bcp); | |
374 }; | |
375 | |
376 inline Bytecode_multianewarray* Bytecode_multianewarray_at(address bcp) { | |
377 Bytecode_multianewarray* b = (Bytecode_multianewarray*)bcp; | |
378 DEBUG_ONLY(b->verify()); | |
379 return b; | |
380 } | |
381 | |
382 | 298 |
383 class Bytecode_anewarray: public Bytecode { | 299 class Bytecode_anewarray: public Bytecode { |
384 public: | 300 public: |
301 Bytecode_anewarray(methodOop method, address bcp): Bytecode(method, bcp) { verify(); } | |
385 void verify() const { assert(java_code() == Bytecodes::_anewarray, "check anewarray"); } | 302 void verify() const { assert(java_code() == Bytecodes::_anewarray, "check anewarray"); } |
386 | 303 |
387 // Returns index | 304 // Returns index |
388 long index() const { return get_index_u2(Bytecodes::_anewarray); }; | 305 long index() const { return get_index_u2(Bytecodes::_anewarray); }; |
389 | 306 }; |
390 // Creation | |
391 inline friend Bytecode_anewarray* Bytecode_anewarray_at(address bcp); | |
392 }; | |
393 | |
394 inline Bytecode_anewarray* Bytecode_anewarray_at(address bcp) { | |
395 Bytecode_anewarray* b = (Bytecode_anewarray*)bcp; | |
396 DEBUG_ONLY(b->verify()); | |
397 return b; | |
398 } | |
399 | |
400 | 307 |
401 // Abstraction for ldc, ldc_w and ldc2_w | 308 // Abstraction for ldc, ldc_w and ldc2_w |
402 | 309 class Bytecode_loadconstant: public Bytecode { |
403 class Bytecode_loadconstant: public ResourceObj { | |
404 private: | 310 private: |
405 int _bci; | 311 const methodHandle _method; |
406 methodHandle _method; | |
407 | |
408 Bytecodes::Code code() const { return bytecode()->code(); } | |
409 | 312 |
410 int raw_index() const; | 313 int raw_index() const; |
411 | 314 |
412 Bytecode_loadconstant(methodHandle method, int bci) : _method(method), _bci(bci) {} | 315 public: |
413 | 316 Bytecode_loadconstant(methodHandle method, int bci): Bytecode(method(), method->bcp_from(bci)), _method(method) { verify(); } |
414 public: | |
415 // Attributes | |
416 methodHandle method() const { return _method; } | |
417 int bci() const { return _bci; } | |
418 address bcp() const { return _method->bcp_from(bci()); } | |
419 Bytecode* bytecode() const { return Bytecode_at(bcp()); } | |
420 | 317 |
421 void verify() const { | 318 void verify() const { |
422 assert(_method.not_null(), "must supply method"); | 319 assert(_method.not_null(), "must supply method"); |
423 Bytecodes::Code stdc = Bytecodes::java_code(code()); | 320 Bytecodes::Code stdc = Bytecodes::java_code(code()); |
424 assert(stdc == Bytecodes::_ldc || | 321 assert(stdc == Bytecodes::_ldc || |
435 } | 332 } |
436 | 333 |
437 BasicType result_type() const; // returns the result type of the ldc | 334 BasicType result_type() const; // returns the result type of the ldc |
438 | 335 |
439 oop resolve_constant(TRAPS) const; | 336 oop resolve_constant(TRAPS) const; |
440 | 337 }; |
441 // Creation | |
442 inline friend Bytecode_loadconstant* Bytecode_loadconstant_at(methodHandle method, int bci); | |
443 }; | |
444 | |
445 inline Bytecode_loadconstant* Bytecode_loadconstant_at(methodHandle method, int bci) { | |
446 Bytecode_loadconstant* b = new Bytecode_loadconstant(method, bci); | |
447 DEBUG_ONLY(b->verify()); | |
448 return b; | |
449 } | |
450 | 338 |
451 #endif // SHARE_VM_INTERPRETER_BYTECODE_HPP | 339 #endif // SHARE_VM_INTERPRETER_BYTECODE_HPP |