1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/interpreter/bytecode.hpp Sat Dec 01 00:00:00 2007 +0000 1.3 @@ -0,0 +1,376 @@ 1.4 +/* 1.5 + * Copyright 1997-2002 Sun Microsystems, Inc. All Rights Reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 1.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 1.24 + * have any questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +// Base class for different kinds of abstractions working 1.29 +// relative to an objects 'this' pointer. 1.30 + 1.31 +class ThisRelativeObj VALUE_OBJ_CLASS_SPEC { 1.32 + private: 1.33 + int sign_extend (int x, int size) const { const int s = (BytesPerInt - size)*BitsPerByte; return (x << s) >> s; } 1.34 + 1.35 + public: 1.36 + // Address computation 1.37 + address addr_at (int offset) const { return (address)this + offset; } 1.38 + address aligned_addr_at (int offset) const { return (address)round_to((intptr_t)addr_at(offset), jintSize); } 1.39 + int aligned_offset (int offset) const { return aligned_addr_at(offset) - addr_at(0); } 1.40 + 1.41 + // Java unsigned accessors (using Java spec byte ordering) 1.42 + int java_byte_at (int offset) const { return *(jubyte*)addr_at(offset); } 1.43 + int java_hwrd_at (int offset) const { return java_byte_at(offset) << (1 * BitsPerByte) | java_byte_at(offset + 1); } 1.44 + int java_word_at (int offset) const { return java_hwrd_at(offset) << (2 * BitsPerByte) | java_hwrd_at(offset + 2); } 1.45 + 1.46 + // Java signed accessors (using Java spec byte ordering) 1.47 + int java_signed_byte_at(int offset) const { return sign_extend(java_byte_at(offset), 1); } 1.48 + int java_signed_hwrd_at(int offset) const { return sign_extend(java_hwrd_at(offset), 2); } 1.49 + int java_signed_word_at(int offset) const { return java_word_at(offset) ; } 1.50 + 1.51 + // Fast accessors (using the machine's natural byte ordering) 1.52 + int fast_byte_at (int offset) const { return *(jubyte *)addr_at(offset); } 1.53 + int fast_hwrd_at (int offset) const { return *(jushort*)addr_at(offset); } 1.54 + int fast_word_at (int offset) const { return *(juint *)addr_at(offset); } 1.55 + 1.56 + // Fast signed accessors (using the machine's natural byte ordering) 1.57 + int fast_signed_byte_at(int offset) const { return *(jbyte *)addr_at(offset); } 1.58 + int fast_signed_hwrd_at(int offset) const { return *(jshort*)addr_at(offset); } 1.59 + int fast_signed_word_at(int offset) const { return *(jint *)addr_at(offset); } 1.60 + 1.61 + // Fast manipulators (using the machine's natural byte ordering) 1.62 + void set_fast_byte_at (int offset, int x) const { *(jbyte *)addr_at(offset) = (jbyte )x; } 1.63 + void set_fast_hwrd_at (int offset, int x) const { *(jshort*)addr_at(offset) = (jshort)x; } 1.64 + void set_fast_word_at (int offset, int x) const { *(jint *)addr_at(offset) = (jint )x; } 1.65 +}; 1.66 + 1.67 + 1.68 +// The base class for different kinds of bytecode abstractions. 1.69 +// Provides the primitive operations to manipulate code relative 1.70 +// to an objects 'this' pointer. 1.71 +// 1.72 +// Note: Even though it seems that the fast_index & set_fast_index 1.73 +// functions are machine specific, they're not. They only use 1.74 +// the natural way to store a 16bit index on a given machine, 1.75 +// independent of the particular byte ordering. Since all other 1.76 +// places in the system that refer to these indices use the 1.77 +// same method (the natural byte ordering on the platform) 1.78 +// this will always work and be machine-independent). 1.79 + 1.80 +class Bytecode: public ThisRelativeObj { 1.81 + protected: 1.82 + u_char byte_at(int offset) const { return *addr_at(offset); } 1.83 + bool check_must_rewrite() const; 1.84 + 1.85 + public: 1.86 + // Attributes 1.87 + address bcp() const { return addr_at(0); } 1.88 + address next_bcp() const { return addr_at(0) + Bytecodes::length_at(bcp()); } 1.89 + 1.90 + Bytecodes::Code code() const { return Bytecodes::code_at(addr_at(0)); } 1.91 + Bytecodes::Code java_code() const { return Bytecodes::java_code(code()); } 1.92 + bool must_rewrite() const { return Bytecodes::can_rewrite(code()) && check_must_rewrite(); } 1.93 + bool is_active_breakpoint() const { return Bytecodes::is_active_breakpoint_at(bcp()); } 1.94 + 1.95 + int one_byte_index() const { return byte_at(1); } 1.96 + int two_byte_index() const { return (byte_at(1) << 8) + byte_at(2); } 1.97 + int offset() const { return (two_byte_index() << 16) >> 16; } 1.98 + address destination() const { return bcp() + offset(); } 1.99 + int fast_index() const { return Bytes::get_native_u2(addr_at(1)); } 1.100 + 1.101 + // Attribute modification 1.102 + void set_code(Bytecodes::Code code); 1.103 + void set_fast_index(int i); 1.104 + 1.105 + // Creation 1.106 + inline friend Bytecode* Bytecode_at(address bcp); 1.107 +}; 1.108 + 1.109 +inline Bytecode* Bytecode_at(address bcp) { 1.110 + return (Bytecode*)bcp; 1.111 +} 1.112 + 1.113 + 1.114 +// Abstractions for lookupswitch bytecode 1.115 + 1.116 +class LookupswitchPair: ThisRelativeObj { 1.117 + private: 1.118 + int _match; 1.119 + int _offset; 1.120 + 1.121 + public: 1.122 + int match() const { return java_signed_word_at(0 * jintSize); } 1.123 + int offset() const { return java_signed_word_at(1 * jintSize); } 1.124 +}; 1.125 + 1.126 + 1.127 +class Bytecode_lookupswitch: public Bytecode { 1.128 + public: 1.129 + void verify() const PRODUCT_RETURN; 1.130 + 1.131 + // Attributes 1.132 + int default_offset() const { return java_signed_word_at(aligned_offset(1 + 0*jintSize)); } 1.133 + int number_of_pairs() const { return java_signed_word_at(aligned_offset(1 + 1*jintSize)); } 1.134 + LookupswitchPair* pair_at(int i) const { assert(0 <= i && i < number_of_pairs(), "pair index out of bounds"); 1.135 + return (LookupswitchPair*)aligned_addr_at(1 + (1 + i)*2*jintSize); } 1.136 + // Creation 1.137 + inline friend Bytecode_lookupswitch* Bytecode_lookupswitch_at(address bcp); 1.138 +}; 1.139 + 1.140 +inline Bytecode_lookupswitch* Bytecode_lookupswitch_at(address bcp) { 1.141 + Bytecode_lookupswitch* b = (Bytecode_lookupswitch*)bcp; 1.142 + debug_only(b->verify()); 1.143 + return b; 1.144 +} 1.145 + 1.146 + 1.147 +class Bytecode_tableswitch: public Bytecode { 1.148 + public: 1.149 + void verify() const PRODUCT_RETURN; 1.150 + 1.151 + // Attributes 1.152 + int default_offset() const { return java_signed_word_at(aligned_offset(1 + 0*jintSize)); } 1.153 + int low_key() const { return java_signed_word_at(aligned_offset(1 + 1*jintSize)); } 1.154 + int high_key() const { return java_signed_word_at(aligned_offset(1 + 2*jintSize)); } 1.155 + int dest_offset_at(int i) const; 1.156 + int length() { return high_key()-low_key()+1; } 1.157 + 1.158 + // Creation 1.159 + inline friend Bytecode_tableswitch* Bytecode_tableswitch_at(address bcp); 1.160 +}; 1.161 + 1.162 +inline Bytecode_tableswitch* Bytecode_tableswitch_at(address bcp) { 1.163 + Bytecode_tableswitch* b = (Bytecode_tableswitch*)bcp; 1.164 + debug_only(b->verify()); 1.165 + return b; 1.166 +} 1.167 + 1.168 + 1.169 +// Abstraction for invoke_{virtual, static, interface, special} 1.170 + 1.171 +class Bytecode_invoke: public ResourceObj { 1.172 + protected: 1.173 + methodHandle _method; // method containing the bytecode 1.174 + int _bci; // position of the bytecode 1.175 + 1.176 + Bytecode_invoke(methodHandle method, int bci) : _method(method), _bci(bci) {} 1.177 + 1.178 + public: 1.179 + void verify() const; 1.180 + 1.181 + // Attributes 1.182 + methodHandle method() const { return _method; } 1.183 + int bci() const { return _bci; } 1.184 + address bcp() const { return _method->bcp_from(bci()); } 1.185 + 1.186 + int index() const; // the constant pool index for the invoke 1.187 + symbolOop name() const; // returns the name of the invoked method 1.188 + symbolOop signature() const; // returns the signature of the invoked method 1.189 + BasicType result_type(Thread *thread) const; // returns the result type of the invoke 1.190 + 1.191 + Bytecodes::Code code() const { return Bytecodes::code_at(bcp(), _method()); } 1.192 + Bytecodes::Code adjusted_invoke_code() const { return Bytecodes::java_code(code()); } 1.193 + 1.194 + methodHandle static_target(TRAPS); // "specified" method (from constant pool) 1.195 + 1.196 + // Testers 1.197 + bool is_invokeinterface() const { return adjusted_invoke_code() == Bytecodes::_invokeinterface; } 1.198 + bool is_invokevirtual() const { return adjusted_invoke_code() == Bytecodes::_invokevirtual; } 1.199 + bool is_invokestatic() const { return adjusted_invoke_code() == Bytecodes::_invokestatic; } 1.200 + bool is_invokespecial() const { return adjusted_invoke_code() == Bytecodes::_invokespecial; } 1.201 + 1.202 + bool is_valid() const { return is_invokeinterface() || 1.203 + is_invokevirtual() || 1.204 + is_invokestatic() || 1.205 + is_invokespecial(); } 1.206 + 1.207 + // Creation 1.208 + inline friend Bytecode_invoke* Bytecode_invoke_at(methodHandle method, int bci); 1.209 + 1.210 + // Like Bytecode_invoke_at. Instead it returns NULL if the bci is not at an invoke. 1.211 + inline friend Bytecode_invoke* Bytecode_invoke_at_check(methodHandle method, int bci); 1.212 +}; 1.213 + 1.214 +inline Bytecode_invoke* Bytecode_invoke_at(methodHandle method, int bci) { 1.215 + Bytecode_invoke* b = new Bytecode_invoke(method, bci); 1.216 + debug_only(b->verify()); 1.217 + return b; 1.218 +} 1.219 + 1.220 +inline Bytecode_invoke* Bytecode_invoke_at_check(methodHandle method, int bci) { 1.221 + Bytecode_invoke* b = new Bytecode_invoke(method, bci); 1.222 + return b->is_valid() ? b : NULL; 1.223 +} 1.224 + 1.225 + 1.226 +// Abstraction for all field accesses (put/get field/static_ 1.227 +class Bytecode_field: public Bytecode { 1.228 +public: 1.229 + void verify() const; 1.230 + 1.231 + int index() const; 1.232 + bool is_static() const; 1.233 + 1.234 + // Creation 1.235 + inline friend Bytecode_field* Bytecode_field_at(const methodOop method, address bcp); 1.236 +}; 1.237 + 1.238 +inline Bytecode_field* Bytecode_field_at(const methodOop method, address bcp) { 1.239 + Bytecode_field* b = (Bytecode_field*)bcp; 1.240 + debug_only(b->verify()); 1.241 + return b; 1.242 +} 1.243 + 1.244 + 1.245 +// Abstraction for {get,put}static 1.246 + 1.247 +class Bytecode_static: public Bytecode { 1.248 + public: 1.249 + void verify() const; 1.250 + 1.251 + // Returns the result type of the send by inspecting the field ref 1.252 + BasicType result_type(methodOop method) const; 1.253 + 1.254 + // Creation 1.255 + inline friend Bytecode_static* Bytecode_static_at(const methodOop method, address bcp); 1.256 +}; 1.257 + 1.258 +inline Bytecode_static* Bytecode_static_at(const methodOop method, address bcp) { 1.259 + Bytecode_static* b = (Bytecode_static*)bcp; 1.260 + debug_only(b->verify()); 1.261 + return b; 1.262 +} 1.263 + 1.264 + 1.265 +// Abstraction for checkcast 1.266 + 1.267 +class Bytecode_checkcast: public Bytecode { 1.268 + public: 1.269 + void verify() const { assert(Bytecodes::java_code(code()) == Bytecodes::_checkcast, "check checkcast"); } 1.270 + 1.271 + // Returns index 1.272 + long index() const { return java_hwrd_at(1); }; 1.273 + 1.274 + // Creation 1.275 + inline friend Bytecode_checkcast* Bytecode_checkcast_at(address bcp); 1.276 +}; 1.277 + 1.278 +inline Bytecode_checkcast* Bytecode_checkcast_at(address bcp) { 1.279 + Bytecode_checkcast* b = (Bytecode_checkcast*)bcp; 1.280 + debug_only(b->verify()); 1.281 + return b; 1.282 +} 1.283 + 1.284 + 1.285 +// Abstraction for instanceof 1.286 + 1.287 +class Bytecode_instanceof: public Bytecode { 1.288 + public: 1.289 + void verify() const { assert(code() == Bytecodes::_instanceof, "check instanceof"); } 1.290 + 1.291 + // Returns index 1.292 + long index() const { return java_hwrd_at(1); }; 1.293 + 1.294 + // Creation 1.295 + inline friend Bytecode_instanceof* Bytecode_instanceof_at(address bcp); 1.296 +}; 1.297 + 1.298 +inline Bytecode_instanceof* Bytecode_instanceof_at(address bcp) { 1.299 + Bytecode_instanceof* b = (Bytecode_instanceof*)bcp; 1.300 + debug_only(b->verify()); 1.301 + return b; 1.302 +} 1.303 + 1.304 + 1.305 +class Bytecode_new: public Bytecode { 1.306 + public: 1.307 + void verify() const { assert(java_code() == Bytecodes::_new, "check new"); } 1.308 + 1.309 + // Returns index 1.310 + long index() const { return java_hwrd_at(1); }; 1.311 + 1.312 + // Creation 1.313 + inline friend Bytecode_new* Bytecode_new_at(address bcp); 1.314 +}; 1.315 + 1.316 +inline Bytecode_new* Bytecode_new_at(address bcp) { 1.317 + Bytecode_new* b = (Bytecode_new*)bcp; 1.318 + debug_only(b->verify()); 1.319 + return b; 1.320 +} 1.321 + 1.322 + 1.323 +class Bytecode_multianewarray: public Bytecode { 1.324 + public: 1.325 + void verify() const { assert(java_code() == Bytecodes::_multianewarray, "check new"); } 1.326 + 1.327 + // Returns index 1.328 + long index() const { return java_hwrd_at(1); }; 1.329 + 1.330 + // Creation 1.331 + inline friend Bytecode_multianewarray* Bytecode_multianewarray_at(address bcp); 1.332 +}; 1.333 + 1.334 +inline Bytecode_multianewarray* Bytecode_multianewarray_at(address bcp) { 1.335 + Bytecode_multianewarray* b = (Bytecode_multianewarray*)bcp; 1.336 + debug_only(b->verify()); 1.337 + return b; 1.338 +} 1.339 + 1.340 + 1.341 +class Bytecode_anewarray: public Bytecode { 1.342 + public: 1.343 + void verify() const { assert(java_code() == Bytecodes::_anewarray, "check anewarray"); } 1.344 + 1.345 + // Returns index 1.346 + long index() const { return java_hwrd_at(1); }; 1.347 + 1.348 + // Creation 1.349 + inline friend Bytecode_anewarray* Bytecode_anewarray_at(address bcp); 1.350 +}; 1.351 + 1.352 +inline Bytecode_anewarray* Bytecode_anewarray_at(address bcp) { 1.353 + Bytecode_anewarray* b = (Bytecode_anewarray*)bcp; 1.354 + debug_only(b->verify()); 1.355 + return b; 1.356 +} 1.357 + 1.358 + 1.359 +// Abstraction for ldc, ldc_w and ldc2_w 1.360 + 1.361 +class Bytecode_loadconstant: public Bytecode { 1.362 + public: 1.363 + void verify() const { 1.364 + Bytecodes::Code stdc = Bytecodes::java_code(code()); 1.365 + assert(stdc == Bytecodes::_ldc || 1.366 + stdc == Bytecodes::_ldc_w || 1.367 + stdc == Bytecodes::_ldc2_w, "load constant"); 1.368 + } 1.369 + 1.370 + int index() const; 1.371 + 1.372 + inline friend Bytecode_loadconstant* Bytecode_loadconstant_at(const methodOop method, address bcp); 1.373 +}; 1.374 + 1.375 +inline Bytecode_loadconstant* Bytecode_loadconstant_at(const methodOop method, address bcp) { 1.376 + Bytecode_loadconstant* b = (Bytecode_loadconstant*)bcp; 1.377 + debug_only(b->verify()); 1.378 + return b; 1.379 +}