src/share/vm/interpreter/bytecode.hpp

changeset 0
f90c822e73f8
child 1
2d8a650513c2
     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

mercurial