alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (bytecode.hpp)

This example Java source code file (bytecode.hpp) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

bytecode, bytecode_invoke, bytecode_loadconstant, bytecode_lookupswitch, bytecode_member_ref, bytecode_tableswitch, bytecodes::code, bytes\:\:get_java_u2, bytes\:\:get_java_u4, bytes\:\:get_native_u2, lookupswitchpair, not_debug_return, share_vm_interpreter_bytecode_hpp, symbol

The bytecode.hpp Java example source code

/*
 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

#ifndef SHARE_VM_INTERPRETER_BYTECODE_HPP
#define SHARE_VM_INTERPRETER_BYTECODE_HPP

#include "interpreter/bytecodes.hpp"
#include "memory/allocation.hpp"
#include "oops/method.hpp"
#ifdef TARGET_ARCH_x86
# include "bytes_x86.hpp"
#endif
#ifdef TARGET_ARCH_sparc
# include "bytes_sparc.hpp"
#endif
#ifdef TARGET_ARCH_zero
# include "bytes_zero.hpp"
#endif
#ifdef TARGET_ARCH_arm
# include "bytes_arm.hpp"
#endif
#ifdef TARGET_ARCH_ppc
# include "bytes_ppc.hpp"
#endif

class ciBytecodeStream;

// The base class for different kinds of bytecode abstractions.
// Provides the primitive operations to manipulate code relative
// to the bcp.

class Bytecode: public StackObj {
 protected:
  const address   _bcp;
  const Bytecodes::Code _code;

  // Address computation
  address addr_at            (int offset)        const     { return (address)_bcp + offset; }
  u_char byte_at(int offset) const               { return *addr_at(offset); }
  address aligned_addr_at    (int offset)        const     { return (address)round_to((intptr_t)addr_at(offset), jintSize); }
  int     aligned_offset     (int offset)        const     { return aligned_addr_at(offset) - addr_at(0); }

  // Word access:
  int     get_Java_u2_at     (int offset)        const     { return Bytes::get_Java_u2(addr_at(offset)); }
  int     get_Java_u4_at     (int offset)        const     { return Bytes::get_Java_u4(addr_at(offset)); }
  int     get_native_u2_at   (int offset)        const     { return Bytes::get_native_u2(addr_at(offset)); }
  int     get_native_u4_at   (int offset)        const     { return Bytes::get_native_u4(addr_at(offset)); }

 public:
  Bytecode(Method* method, address bcp): _bcp(bcp), _code(Bytecodes::code_at(method, addr_at(0))) {
    assert(method != NULL, "this form requires a valid Method*");
  }
  // Defined in ciStreams.hpp
  inline Bytecode(const ciBytecodeStream* stream, address bcp = NULL);

  // Attributes
  address bcp() const                            { return _bcp; }
  int instruction_size() const                   { return Bytecodes::length_for_code_at(_code, bcp()); }

  Bytecodes::Code code() const                   { return _code; }
  Bytecodes::Code java_code() const              { return Bytecodes::java_code(code()); }
  Bytecodes::Code invoke_code() const            { return (code() == Bytecodes::_invokehandle) ? code() : java_code(); }

  // Static functions for parsing bytecodes in place.
  int get_index_u1(Bytecodes::Code bc) const {
    assert_same_format_as(bc); assert_index_size(1, bc);
    return *(jubyte*)addr_at(1);
  }
  int get_index_u2(Bytecodes::Code bc, bool is_wide = false) const {
    assert_same_format_as(bc, is_wide); assert_index_size(2, bc, is_wide);
    address p = addr_at(is_wide ? 2 : 1);
    if (can_use_native_byte_order(bc, is_wide))
      return Bytes::get_native_u2(p);
    else  return Bytes::get_Java_u2(p);
  }
  int get_index_u1_cpcache(Bytecodes::Code bc) const {
    assert_same_format_as(bc); assert_index_size(1, bc);
    return *(jubyte*)addr_at(1) + ConstantPool::CPCACHE_INDEX_TAG;
  }
  int get_index_u2_cpcache(Bytecodes::Code bc) const {
    assert_same_format_as(bc); assert_index_size(2, bc); assert_native_index(bc);
    return Bytes::get_native_u2(addr_at(1)) + ConstantPool::CPCACHE_INDEX_TAG;
  }
  int get_index_u4(Bytecodes::Code bc) const {
    assert_same_format_as(bc); assert_index_size(4, bc);
    assert(can_use_native_byte_order(bc), "");
    return Bytes::get_native_u4(addr_at(1));
  }
  bool has_index_u4(Bytecodes::Code bc) const {
    return bc == Bytecodes::_invokedynamic;
  }

  int get_offset_s2(Bytecodes::Code bc) const {
    assert_same_format_as(bc); assert_offset_size(2, bc);
    return (jshort) Bytes::get_Java_u2(addr_at(1));
  }
  int get_offset_s4(Bytecodes::Code bc) const {
    assert_same_format_as(bc); assert_offset_size(4, bc);
    return (jint) Bytes::get_Java_u4(addr_at(1));
  }

  int get_constant_u1(int offset, Bytecodes::Code bc) const {
    assert_same_format_as(bc); assert_constant_size(1, offset, bc);
    return *(jbyte*)addr_at(offset);
  }
  int get_constant_u2(int offset, Bytecodes::Code bc, bool is_wide = false) const {
    assert_same_format_as(bc, is_wide); assert_constant_size(2, offset, bc, is_wide);
    return (jshort) Bytes::get_Java_u2(addr_at(offset));
  }

  // These are used locally and also from bytecode streams.
  void assert_same_format_as(Bytecodes::Code testbc, bool is_wide = false) const NOT_DEBUG_RETURN;
  static void assert_index_size(int required_size, Bytecodes::Code bc, bool is_wide = false) NOT_DEBUG_RETURN;
  static void assert_offset_size(int required_size, Bytecodes::Code bc, bool is_wide = false) NOT_DEBUG_RETURN;
  static void assert_constant_size(int required_size, int where, Bytecodes::Code bc, bool is_wide = false) NOT_DEBUG_RETURN;
  static void assert_native_index(Bytecodes::Code bc, bool is_wide = false) NOT_DEBUG_RETURN;
  static bool can_use_native_byte_order(Bytecodes::Code bc, bool is_wide = false) {
    return (!Bytes::is_Java_byte_ordering_different() || Bytecodes::native_byte_order(bc /*, is_wide*/));
  }
};


// Abstractions for lookupswitch bytecode
class LookupswitchPair VALUE_OBJ_CLASS_SPEC {
 private:
  const address _bcp;

  address addr_at            (int offset)        const     { return _bcp + offset; }
  int     get_Java_u4_at     (int offset)        const     { return Bytes::get_Java_u4(addr_at(offset)); }

 public:
  LookupswitchPair(address bcp): _bcp(bcp) {}
  int  match() const                             { return get_Java_u4_at(0 * jintSize); }
  int  offset() const                            { return get_Java_u4_at(1 * jintSize); }
};


class Bytecode_lookupswitch: public Bytecode {
 public:
  Bytecode_lookupswitch(Method* method, address bcp): Bytecode(method, bcp) { verify(); }
  // Defined in ciStreams.hpp
  inline Bytecode_lookupswitch(const ciBytecodeStream* stream);
  void verify() const PRODUCT_RETURN;

  // Attributes
  int  default_offset() const                    { return get_Java_u4_at(aligned_offset(1 + 0*jintSize)); }
  int  number_of_pairs() const                   { return get_Java_u4_at(aligned_offset(1 + 1*jintSize)); }
  LookupswitchPair pair_at(int i) const          {
    assert(0 <= i && i < number_of_pairs(), "pair index out of bounds");
    return LookupswitchPair(aligned_addr_at(1 + (1 + i)*2*jintSize));
  }
};

class Bytecode_tableswitch: public Bytecode {
 public:
  Bytecode_tableswitch(Method* method, address bcp): Bytecode(method, bcp) { verify(); }
  // Defined in ciStreams.hpp
  inline Bytecode_tableswitch(const ciBytecodeStream* stream);
  void verify() const PRODUCT_RETURN;

  // Attributes
  int  default_offset() const                    { return get_Java_u4_at(aligned_offset(1 + 0*jintSize)); }
  int  low_key() const                           { return get_Java_u4_at(aligned_offset(1 + 1*jintSize)); }
  int  high_key() const                          { return get_Java_u4_at(aligned_offset(1 + 2*jintSize)); }
  int  dest_offset_at(int i) const;
  int  length()                                  { return high_key()-low_key()+1; }
};

// Common code for decoding invokes and field references.

class Bytecode_member_ref: public Bytecode {
 protected:
  const methodHandle _method;                          // method containing the bytecode

  Bytecode_member_ref(methodHandle method, int bci)  : Bytecode(method(), method()->bcp_from(bci)), _method(method) {}

  methodHandle method() const                    { return _method; }
  ConstantPool* constants() const              { return _method->constants(); }
  ConstantPoolCache* cpcache() const           { return _method->constants()->cache(); }
  ConstantPoolCacheEntry* cpcache_entry() const;

 public:
  int          index() const;                    // cache index (loaded from instruction)
  int          pool_index() const;               // constant pool index
  Symbol*      klass() const;                    // returns the klass of the method or field
  Symbol*      name() const;                     // returns the name of the method or field
  Symbol*      signature() const;                // returns the signature of the method or field

  BasicType    result_type() const;              // returns the result type of the getfield or invoke
};

// Abstraction for invoke_{virtual, static, interface, special}

class Bytecode_invoke: public Bytecode_member_ref {
 protected:
  // Constructor that skips verification
  Bytecode_invoke(methodHandle method, int bci, bool unused)  : Bytecode_member_ref(method, bci) {}

 public:
  Bytecode_invoke(methodHandle method, int bci)  : Bytecode_member_ref(method, bci) { verify(); }
  void verify() const;

  // Attributes
  methodHandle static_target(TRAPS);             // "specified" method   (from constant pool)
  Handle       appendix(TRAPS);                  // if CPCE::has_appendix (from constant pool)

  // Testers
  bool is_invokeinterface() const                { return invoke_code() == Bytecodes::_invokeinterface; }
  bool is_invokevirtual() const                  { return invoke_code() == Bytecodes::_invokevirtual; }
  bool is_invokestatic() const                   { return invoke_code() == Bytecodes::_invokestatic; }
  bool is_invokespecial() const                  { return invoke_code() == Bytecodes::_invokespecial; }
  bool is_invokedynamic() const                  { return invoke_code() == Bytecodes::_invokedynamic; }
  bool is_invokehandle() const                   { return invoke_code() == Bytecodes::_invokehandle; }

  bool has_receiver() const                      { return !is_invokestatic() && !is_invokedynamic(); }

  bool is_valid() const                          { return is_invokeinterface() ||
                                                          is_invokevirtual()   ||
                                                          is_invokestatic()    ||
                                                          is_invokespecial()   ||
                                                          is_invokedynamic()   ||
                                                          is_invokehandle(); }

  bool has_appendix()                            { return cpcache_entry()->has_appendix(); }

 private:
  // Helper to skip verification.   Used is_valid() to check if the result is really an invoke
  inline friend Bytecode_invoke Bytecode_invoke_check(methodHandle method, int bci);
};

inline Bytecode_invoke Bytecode_invoke_check(methodHandle method, int bci) {
  return Bytecode_invoke(method, bci, false);
}


// Abstraction for all field accesses (put/get field/static)
class Bytecode_field: public Bytecode_member_ref {
 public:
  Bytecode_field(methodHandle method, int bci)  : Bytecode_member_ref(method, bci) { verify(); }

  // Testers
  bool is_getfield() const                       { return java_code() == Bytecodes::_getfield; }
  bool is_putfield() const                       { return java_code() == Bytecodes::_putfield; }
  bool is_getstatic() const                      { return java_code() == Bytecodes::_getstatic; }
  bool is_putstatic() const                      { return java_code() == Bytecodes::_putstatic; }

  bool is_getter() const                         { return is_getfield()  || is_getstatic(); }
  bool is_static() const                         { return is_getstatic() || is_putstatic(); }

  bool is_valid() const                          { return is_getfield()   ||
                                                          is_putfield()   ||
                                                          is_getstatic()  ||
                                                          is_putstatic(); }
  void verify() const;
};

// Abstraction for checkcast
class Bytecode_checkcast: public Bytecode {
 public:
  Bytecode_checkcast(Method* method, address bcp): Bytecode(method, bcp) { verify(); }
  void verify() const { assert(Bytecodes::java_code(code()) == Bytecodes::_checkcast, "check checkcast"); }

  // Returns index
  long index() const   { return get_index_u2(Bytecodes::_checkcast); };
};

// Abstraction for instanceof
class Bytecode_instanceof: public Bytecode {
 public:
  Bytecode_instanceof(Method* method, address bcp): Bytecode(method, bcp) { verify(); }
  void verify() const { assert(code() == Bytecodes::_instanceof, "check instanceof"); }

  // Returns index
  long index() const   { return get_index_u2(Bytecodes::_instanceof); };
};

class Bytecode_new: public Bytecode {
 public:
  Bytecode_new(Method* method, address bcp): Bytecode(method, bcp) { verify(); }
  void verify() const { assert(java_code() == Bytecodes::_new, "check new"); }

  // Returns index
  long index() const   { return get_index_u2(Bytecodes::_new); };
};

class Bytecode_multianewarray: public Bytecode {
 public:
  Bytecode_multianewarray(Method* method, address bcp): Bytecode(method, bcp) { verify(); }
  void verify() const { assert(java_code() == Bytecodes::_multianewarray, "check new"); }

  // Returns index
  long index() const   { return get_index_u2(Bytecodes::_multianewarray); };
};

class Bytecode_anewarray: public Bytecode {
 public:
  Bytecode_anewarray(Method* method, address bcp): Bytecode(method, bcp) { verify(); }
  void verify() const { assert(java_code() == Bytecodes::_anewarray, "check anewarray"); }

  // Returns index
  long index() const   { return get_index_u2(Bytecodes::_anewarray); };
};

// Abstraction for ldc, ldc_w and ldc2_w
class Bytecode_loadconstant: public Bytecode {
 private:
  const methodHandle _method;

  int raw_index() const;

 public:
  Bytecode_loadconstant(methodHandle method, int bci): Bytecode(method(), method->bcp_from(bci)), _method(method) { verify(); }

  void verify() const {
    assert(_method.not_null(), "must supply method");
    Bytecodes::Code stdc = Bytecodes::java_code(code());
    assert(stdc == Bytecodes::_ldc ||
           stdc == Bytecodes::_ldc_w ||
           stdc == Bytecodes::_ldc2_w, "load constant");
  }

  // Only non-standard bytecodes (fast_aldc) have reference cache indexes.
  bool has_cache_index() const { return code() >= Bytecodes::number_of_java_codes; }

  int pool_index() const;               // index into constant pool
  int cache_index() const {             // index into reference cache (or -1 if none)
    return has_cache_index() ? raw_index() : -1;
  }

  BasicType result_type() const;        // returns the result type of the ldc

  oop resolve_constant(TRAPS) const;
};

#endif // SHARE_VM_INTERPRETER_BYTECODE_HPP

Other Java examples (source code examples)

Here is a short list of links related to this Java bytecode.hpp source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.