1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/interpreter/bytecode.hpp Wed Apr 27 01:25:04 2016 +0800 1.3 @@ -0,0 +1,356 @@ 1.4 +/* 1.5 + * Copyright (c) 1997, 2012, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.23 + * or visit www.oracle.com if you need additional information or have any 1.24 + * questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +#ifndef SHARE_VM_INTERPRETER_BYTECODE_HPP 1.29 +#define SHARE_VM_INTERPRETER_BYTECODE_HPP 1.30 + 1.31 +#include "interpreter/bytecodes.hpp" 1.32 +#include "memory/allocation.hpp" 1.33 +#include "oops/method.hpp" 1.34 +#ifdef TARGET_ARCH_x86 1.35 +# include "bytes_x86.hpp" 1.36 +#endif 1.37 +#ifdef TARGET_ARCH_sparc 1.38 +# include "bytes_sparc.hpp" 1.39 +#endif 1.40 +#ifdef TARGET_ARCH_zero 1.41 +# include "bytes_zero.hpp" 1.42 +#endif 1.43 +#ifdef TARGET_ARCH_arm 1.44 +# include "bytes_arm.hpp" 1.45 +#endif 1.46 +#ifdef TARGET_ARCH_ppc 1.47 +# include "bytes_ppc.hpp" 1.48 +#endif 1.49 + 1.50 +class ciBytecodeStream; 1.51 + 1.52 +// The base class for different kinds of bytecode abstractions. 1.53 +// Provides the primitive operations to manipulate code relative 1.54 +// to the bcp. 1.55 + 1.56 +class Bytecode: public StackObj { 1.57 + protected: 1.58 + const address _bcp; 1.59 + const Bytecodes::Code _code; 1.60 + 1.61 + // Address computation 1.62 + address addr_at (int offset) const { return (address)_bcp + offset; } 1.63 + u_char byte_at(int offset) const { return *addr_at(offset); } 1.64 + address aligned_addr_at (int offset) const { return (address)round_to((intptr_t)addr_at(offset), jintSize); } 1.65 + int aligned_offset (int offset) const { return aligned_addr_at(offset) - addr_at(0); } 1.66 + 1.67 + // Word access: 1.68 + int get_Java_u2_at (int offset) const { return Bytes::get_Java_u2(addr_at(offset)); } 1.69 + int get_Java_u4_at (int offset) const { return Bytes::get_Java_u4(addr_at(offset)); } 1.70 + int get_native_u2_at (int offset) const { return Bytes::get_native_u2(addr_at(offset)); } 1.71 + int get_native_u4_at (int offset) const { return Bytes::get_native_u4(addr_at(offset)); } 1.72 + 1.73 + public: 1.74 + Bytecode(Method* method, address bcp): _bcp(bcp), _code(Bytecodes::code_at(method, addr_at(0))) { 1.75 + assert(method != NULL, "this form requires a valid Method*"); 1.76 + } 1.77 + // Defined in ciStreams.hpp 1.78 + inline Bytecode(const ciBytecodeStream* stream, address bcp = NULL); 1.79 + 1.80 + // Attributes 1.81 + address bcp() const { return _bcp; } 1.82 + int instruction_size() const { return Bytecodes::length_for_code_at(_code, bcp()); } 1.83 + 1.84 + Bytecodes::Code code() const { return _code; } 1.85 + Bytecodes::Code java_code() const { return Bytecodes::java_code(code()); } 1.86 + Bytecodes::Code invoke_code() const { return (code() == Bytecodes::_invokehandle) ? code() : java_code(); } 1.87 + 1.88 + // Static functions for parsing bytecodes in place. 1.89 + int get_index_u1(Bytecodes::Code bc) const { 1.90 + assert_same_format_as(bc); assert_index_size(1, bc); 1.91 + return *(jubyte*)addr_at(1); 1.92 + } 1.93 + int get_index_u2(Bytecodes::Code bc, bool is_wide = false) const { 1.94 + assert_same_format_as(bc, is_wide); assert_index_size(2, bc, is_wide); 1.95 + address p = addr_at(is_wide ? 2 : 1); 1.96 + if (can_use_native_byte_order(bc, is_wide)) 1.97 + return Bytes::get_native_u2(p); 1.98 + else return Bytes::get_Java_u2(p); 1.99 + } 1.100 + int get_index_u1_cpcache(Bytecodes::Code bc) const { 1.101 + assert_same_format_as(bc); assert_index_size(1, bc); 1.102 + return *(jubyte*)addr_at(1) + ConstantPool::CPCACHE_INDEX_TAG; 1.103 + } 1.104 + int get_index_u2_cpcache(Bytecodes::Code bc) const { 1.105 + assert_same_format_as(bc); assert_index_size(2, bc); assert_native_index(bc); 1.106 + return Bytes::get_native_u2(addr_at(1)) + ConstantPool::CPCACHE_INDEX_TAG; 1.107 + } 1.108 + int get_index_u4(Bytecodes::Code bc) const { 1.109 + assert_same_format_as(bc); assert_index_size(4, bc); 1.110 + assert(can_use_native_byte_order(bc), ""); 1.111 + return Bytes::get_native_u4(addr_at(1)); 1.112 + } 1.113 + bool has_index_u4(Bytecodes::Code bc) const { 1.114 + return bc == Bytecodes::_invokedynamic; 1.115 + } 1.116 + 1.117 + int get_offset_s2(Bytecodes::Code bc) const { 1.118 + assert_same_format_as(bc); assert_offset_size(2, bc); 1.119 + return (jshort) Bytes::get_Java_u2(addr_at(1)); 1.120 + } 1.121 + int get_offset_s4(Bytecodes::Code bc) const { 1.122 + assert_same_format_as(bc); assert_offset_size(4, bc); 1.123 + return (jint) Bytes::get_Java_u4(addr_at(1)); 1.124 + } 1.125 + 1.126 + int get_constant_u1(int offset, Bytecodes::Code bc) const { 1.127 + assert_same_format_as(bc); assert_constant_size(1, offset, bc); 1.128 + return *(jbyte*)addr_at(offset); 1.129 + } 1.130 + int get_constant_u2(int offset, Bytecodes::Code bc, bool is_wide = false) const { 1.131 + assert_same_format_as(bc, is_wide); assert_constant_size(2, offset, bc, is_wide); 1.132 + return (jshort) Bytes::get_Java_u2(addr_at(offset)); 1.133 + } 1.134 + 1.135 + // These are used locally and also from bytecode streams. 1.136 + void assert_same_format_as(Bytecodes::Code testbc, bool is_wide = false) const NOT_DEBUG_RETURN; 1.137 + static void assert_index_size(int required_size, Bytecodes::Code bc, bool is_wide = false) NOT_DEBUG_RETURN; 1.138 + static void assert_offset_size(int required_size, Bytecodes::Code bc, bool is_wide = false) NOT_DEBUG_RETURN; 1.139 + static void assert_constant_size(int required_size, int where, Bytecodes::Code bc, bool is_wide = false) NOT_DEBUG_RETURN; 1.140 + static void assert_native_index(Bytecodes::Code bc, bool is_wide = false) NOT_DEBUG_RETURN; 1.141 + static bool can_use_native_byte_order(Bytecodes::Code bc, bool is_wide = false) { 1.142 + return (!Bytes::is_Java_byte_ordering_different() || Bytecodes::native_byte_order(bc /*, is_wide*/)); 1.143 + } 1.144 +}; 1.145 + 1.146 + 1.147 +// Abstractions for lookupswitch bytecode 1.148 +class LookupswitchPair VALUE_OBJ_CLASS_SPEC { 1.149 + private: 1.150 + const address _bcp; 1.151 + 1.152 + address addr_at (int offset) const { return _bcp + offset; } 1.153 + int get_Java_u4_at (int offset) const { return Bytes::get_Java_u4(addr_at(offset)); } 1.154 + 1.155 + public: 1.156 + LookupswitchPair(address bcp): _bcp(bcp) {} 1.157 + int match() const { return get_Java_u4_at(0 * jintSize); } 1.158 + int offset() const { return get_Java_u4_at(1 * jintSize); } 1.159 +}; 1.160 + 1.161 + 1.162 +class Bytecode_lookupswitch: public Bytecode { 1.163 + public: 1.164 + Bytecode_lookupswitch(Method* method, address bcp): Bytecode(method, bcp) { verify(); } 1.165 + // Defined in ciStreams.hpp 1.166 + inline Bytecode_lookupswitch(const ciBytecodeStream* stream); 1.167 + void verify() const PRODUCT_RETURN; 1.168 + 1.169 + // Attributes 1.170 + int default_offset() const { return get_Java_u4_at(aligned_offset(1 + 0*jintSize)); } 1.171 + int number_of_pairs() const { return get_Java_u4_at(aligned_offset(1 + 1*jintSize)); } 1.172 + LookupswitchPair pair_at(int i) const { 1.173 + assert(0 <= i && i < number_of_pairs(), "pair index out of bounds"); 1.174 + return LookupswitchPair(aligned_addr_at(1 + (1 + i)*2*jintSize)); 1.175 + } 1.176 +}; 1.177 + 1.178 +class Bytecode_tableswitch: public Bytecode { 1.179 + public: 1.180 + Bytecode_tableswitch(Method* method, address bcp): Bytecode(method, bcp) { verify(); } 1.181 + // Defined in ciStreams.hpp 1.182 + inline Bytecode_tableswitch(const ciBytecodeStream* stream); 1.183 + void verify() const PRODUCT_RETURN; 1.184 + 1.185 + // Attributes 1.186 + int default_offset() const { return get_Java_u4_at(aligned_offset(1 + 0*jintSize)); } 1.187 + int low_key() const { return get_Java_u4_at(aligned_offset(1 + 1*jintSize)); } 1.188 + int high_key() const { return get_Java_u4_at(aligned_offset(1 + 2*jintSize)); } 1.189 + int dest_offset_at(int i) const; 1.190 + int length() { return high_key()-low_key()+1; } 1.191 +}; 1.192 + 1.193 +// Common code for decoding invokes and field references. 1.194 + 1.195 +class Bytecode_member_ref: public Bytecode { 1.196 + protected: 1.197 + const methodHandle _method; // method containing the bytecode 1.198 + 1.199 + Bytecode_member_ref(methodHandle method, int bci) : Bytecode(method(), method()->bcp_from(bci)), _method(method) {} 1.200 + 1.201 + methodHandle method() const { return _method; } 1.202 + ConstantPool* constants() const { return _method->constants(); } 1.203 + ConstantPoolCache* cpcache() const { return _method->constants()->cache(); } 1.204 + ConstantPoolCacheEntry* cpcache_entry() const; 1.205 + 1.206 + public: 1.207 + int index() const; // cache index (loaded from instruction) 1.208 + int pool_index() const; // constant pool index 1.209 + Symbol* klass() const; // returns the klass of the method or field 1.210 + Symbol* name() const; // returns the name of the method or field 1.211 + Symbol* signature() const; // returns the signature of the method or field 1.212 + 1.213 + BasicType result_type() const; // returns the result type of the getfield or invoke 1.214 +}; 1.215 + 1.216 +// Abstraction for invoke_{virtual, static, interface, special} 1.217 + 1.218 +class Bytecode_invoke: public Bytecode_member_ref { 1.219 + protected: 1.220 + // Constructor that skips verification 1.221 + Bytecode_invoke(methodHandle method, int bci, bool unused) : Bytecode_member_ref(method, bci) {} 1.222 + 1.223 + public: 1.224 + Bytecode_invoke(methodHandle method, int bci) : Bytecode_member_ref(method, bci) { verify(); } 1.225 + void verify() const; 1.226 + 1.227 + // Attributes 1.228 + methodHandle static_target(TRAPS); // "specified" method (from constant pool) 1.229 + Handle appendix(TRAPS); // if CPCE::has_appendix (from constant pool) 1.230 + 1.231 + // Testers 1.232 + bool is_invokeinterface() const { return invoke_code() == Bytecodes::_invokeinterface; } 1.233 + bool is_invokevirtual() const { return invoke_code() == Bytecodes::_invokevirtual; } 1.234 + bool is_invokestatic() const { return invoke_code() == Bytecodes::_invokestatic; } 1.235 + bool is_invokespecial() const { return invoke_code() == Bytecodes::_invokespecial; } 1.236 + bool is_invokedynamic() const { return invoke_code() == Bytecodes::_invokedynamic; } 1.237 + bool is_invokehandle() const { return invoke_code() == Bytecodes::_invokehandle; } 1.238 + 1.239 + bool has_receiver() const { return !is_invokestatic() && !is_invokedynamic(); } 1.240 + 1.241 + bool is_valid() const { return is_invokeinterface() || 1.242 + is_invokevirtual() || 1.243 + is_invokestatic() || 1.244 + is_invokespecial() || 1.245 + is_invokedynamic() || 1.246 + is_invokehandle(); } 1.247 + 1.248 + bool has_appendix() { return cpcache_entry()->has_appendix(); } 1.249 + 1.250 + private: 1.251 + // Helper to skip verification. Used is_valid() to check if the result is really an invoke 1.252 + inline friend Bytecode_invoke Bytecode_invoke_check(methodHandle method, int bci); 1.253 +}; 1.254 + 1.255 +inline Bytecode_invoke Bytecode_invoke_check(methodHandle method, int bci) { 1.256 + return Bytecode_invoke(method, bci, false); 1.257 +} 1.258 + 1.259 + 1.260 +// Abstraction for all field accesses (put/get field/static) 1.261 +class Bytecode_field: public Bytecode_member_ref { 1.262 + public: 1.263 + Bytecode_field(methodHandle method, int bci) : Bytecode_member_ref(method, bci) { verify(); } 1.264 + 1.265 + // Testers 1.266 + bool is_getfield() const { return java_code() == Bytecodes::_getfield; } 1.267 + bool is_putfield() const { return java_code() == Bytecodes::_putfield; } 1.268 + bool is_getstatic() const { return java_code() == Bytecodes::_getstatic; } 1.269 + bool is_putstatic() const { return java_code() == Bytecodes::_putstatic; } 1.270 + 1.271 + bool is_getter() const { return is_getfield() || is_getstatic(); } 1.272 + bool is_static() const { return is_getstatic() || is_putstatic(); } 1.273 + 1.274 + bool is_valid() const { return is_getfield() || 1.275 + is_putfield() || 1.276 + is_getstatic() || 1.277 + is_putstatic(); } 1.278 + void verify() const; 1.279 +}; 1.280 + 1.281 +// Abstraction for checkcast 1.282 +class Bytecode_checkcast: public Bytecode { 1.283 + public: 1.284 + Bytecode_checkcast(Method* method, address bcp): Bytecode(method, bcp) { verify(); } 1.285 + void verify() const { assert(Bytecodes::java_code(code()) == Bytecodes::_checkcast, "check checkcast"); } 1.286 + 1.287 + // Returns index 1.288 + long index() const { return get_index_u2(Bytecodes::_checkcast); }; 1.289 +}; 1.290 + 1.291 +// Abstraction for instanceof 1.292 +class Bytecode_instanceof: public Bytecode { 1.293 + public: 1.294 + Bytecode_instanceof(Method* method, address bcp): Bytecode(method, bcp) { verify(); } 1.295 + void verify() const { assert(code() == Bytecodes::_instanceof, "check instanceof"); } 1.296 + 1.297 + // Returns index 1.298 + long index() const { return get_index_u2(Bytecodes::_instanceof); }; 1.299 +}; 1.300 + 1.301 +class Bytecode_new: public Bytecode { 1.302 + public: 1.303 + Bytecode_new(Method* method, address bcp): Bytecode(method, bcp) { verify(); } 1.304 + void verify() const { assert(java_code() == Bytecodes::_new, "check new"); } 1.305 + 1.306 + // Returns index 1.307 + long index() const { return get_index_u2(Bytecodes::_new); }; 1.308 +}; 1.309 + 1.310 +class Bytecode_multianewarray: public Bytecode { 1.311 + public: 1.312 + Bytecode_multianewarray(Method* method, address bcp): Bytecode(method, bcp) { verify(); } 1.313 + void verify() const { assert(java_code() == Bytecodes::_multianewarray, "check new"); } 1.314 + 1.315 + // Returns index 1.316 + long index() const { return get_index_u2(Bytecodes::_multianewarray); }; 1.317 +}; 1.318 + 1.319 +class Bytecode_anewarray: public Bytecode { 1.320 + public: 1.321 + Bytecode_anewarray(Method* method, address bcp): Bytecode(method, bcp) { verify(); } 1.322 + void verify() const { assert(java_code() == Bytecodes::_anewarray, "check anewarray"); } 1.323 + 1.324 + // Returns index 1.325 + long index() const { return get_index_u2(Bytecodes::_anewarray); }; 1.326 +}; 1.327 + 1.328 +// Abstraction for ldc, ldc_w and ldc2_w 1.329 +class Bytecode_loadconstant: public Bytecode { 1.330 + private: 1.331 + const methodHandle _method; 1.332 + 1.333 + int raw_index() const; 1.334 + 1.335 + public: 1.336 + Bytecode_loadconstant(methodHandle method, int bci): Bytecode(method(), method->bcp_from(bci)), _method(method) { verify(); } 1.337 + 1.338 + void verify() const { 1.339 + assert(_method.not_null(), "must supply method"); 1.340 + Bytecodes::Code stdc = Bytecodes::java_code(code()); 1.341 + assert(stdc == Bytecodes::_ldc || 1.342 + stdc == Bytecodes::_ldc_w || 1.343 + stdc == Bytecodes::_ldc2_w, "load constant"); 1.344 + } 1.345 + 1.346 + // Only non-standard bytecodes (fast_aldc) have reference cache indexes. 1.347 + bool has_cache_index() const { return code() >= Bytecodes::number_of_java_codes; } 1.348 + 1.349 + int pool_index() const; // index into constant pool 1.350 + int cache_index() const { // index into reference cache (or -1 if none) 1.351 + return has_cache_index() ? raw_index() : -1; 1.352 + } 1.353 + 1.354 + BasicType result_type() const; // returns the result type of the ldc 1.355 + 1.356 + oop resolve_constant(TRAPS) const; 1.357 +}; 1.358 + 1.359 +#endif // SHARE_VM_INTERPRETER_BYTECODE_HPP