Top

relocInfo クラス関連のクラス (relocInfo, *Relocation(FORWARD_DECLARE_EACH_CLASSで生成されるクラス群), RelocationHolder, RelocIterator, Relocation, DataRelocation, CallRelocation, oop_Relocation, virtual_call_Relocation, opt_virtual_call_Relocation, static_callRelocation, static_stub_Relocation, runtime_call_Relocation, external_word_Relocation, internal_word_Relocation, section_word_Relocation, poll_Relocation, poll_return_Relocation, breakpoint_Relocation, PatchingRelocIterator)

これらは, 実行時に生成したマシン語中のアドレスを動的再配置(relocation)するためのクラス.

概要(Summary)

relocation は以下のようなケースで必要になる.

    ((cite: hotspot/src/share/vm/code/relocInfo.hpp))
    // These hold enough information to read or write a value embedded in
    // the instructions of an CodeBlob.  They're used to update:
    //
    //   1) embedded oops     (isOop()          == true)
    //   2) inline caches     (isIC()           == true)
    //   3) runtime calls     (isRuntimeCall()  == true)
    //   4) internal word ref (isInternalWord() == true)
    //   5) external word ref (isExternalWord() == true)
    //
    // when objects move (GC) or if code moves (compacting the code heap).
    // They are also used to patch the code (if a call site must change)

行われる relocation 処理の概要は以下の通り.

このファイルで定義されている各クラスはそれぞれ以下の役割を持つ.

(なお, コメントでは以下のクラスが定義されていることになっているが, BoundRelocation は見当たらない...)

    ((cite: hotspot/src/share/vm/code/relocInfo.hpp))
    // Types in this file:
    //    relocInfo
    //      One element of an array of halfwords encoding compressed relocations.
    //      Also, the source of relocation types (relocInfo::oop_type, ...).
    //    Relocation
    //      A flyweight object representing a single relocation.
    //      It is fully unpacked from the compressed relocation array.
    //    oop_Relocation, ... (subclasses of Relocation)
    //      The location of some type-specific operations (oop_addr, ...).
    //      Also, the source of relocation specs (oop_Relocation::spec, ...).
    //    RelocationHolder
    //      A ValueObj type which acts as a union holding a Relocation object.
    //      Represents a relocation spec passed into a CodeBuffer during assembly.
    //    RelocIterator
    //      A StackObj which iterates over the relocations associated with
    //      a range of code addresses.  Can be used to operate a copy of code.
    //    PatchingRelocIterator
    //      Specialized subtype of RelocIterator which removes breakpoints
    //      temporarily during iteration, then restores them.
    //    BoundRelocation
    //      An _internal_ type shared by packers and unpackers of relocations.
    //      It pastes together a RelocationHolder with some pointers into
    //      code and relocInfo streams.

Relocation のサブクラスには以下のような種別がある模様.

    ((cite: hotspot/src/share/vm/code/relocInfo.hpp))
      enum relocType {
        none                    =  0, // Used when no relocation should be generated
        oop_type                =  1, // embedded oop
        virtual_call_type       =  2, // a standard inline cache call for a virtual send
        opt_virtual_call_type   =  3, // a virtual call that has been statically bound (i.e., no IC cache)
        static_call_type        =  4, // a static send
        static_stub_type        =  5, // stub-entry for static send  (takes care of interpreter case)
        runtime_call_type       =  6, // call to fixed external routine
        external_word_type      =  7, // reference to fixed external address
        internal_word_type      =  8, // reference within the current code blob
        section_word_type       =  9, // internal, but a cross-section reference
        poll_type               = 10, // polling instruction for safepoints
        poll_return_type        = 11, // polling instruction for safepoints at return
        breakpoint_type         = 12, // an initialization barrier or safepoint
        yet_unused_type         = 13, // Still unused
        yet_unused_type_2       = 14, // Still unused
        data_prefix_tag         = 15, // tag for a prefix (carries data arguments)
        type_mask               = 15  // A mask which selects only the above values
      };

これらの継承関係は以下のようになっている.

クラス一覧(class list)


relocInfo

概要(Summary)

16 bit に圧縮された形式の relocation 情報を表すクラス

nmethod に関する relocation 情報は, relocInfo の配列として nmethod オブジェクト内に格納されている.

    ((cite: hotspot/src/share/vm/code/relocInfo.hpp))
    class relocInfo VALUE_OBJ_CLASS_SPEC {

内部構造(Internal structure)

relocInfo オブジェクトは 16bits の値で構成される. 4bit で 16 種類の relocation type(後述)を表し, 残りの 12bit で relocate 対象のアドレス("offset")を記録している.

    ((cite: hotspot/src/share/vm/code/relocInfo.hpp))
    // A relocInfo is represented in 16 bits:
    //   4 bits indicating the relocation type
    //  12 bits indicating the offset from the previous relocInfo address

offset については, 前の relocInfo からの差分とすることで, 12bit で収まるようにしている模様. (なお, 固定長命令のアーキテクチャでは最下位bitの幾つかは0なので (例えば sparc では 2bit は必ず0), その分シフトさせて詰めることで offset は稼げる (例えば sparc では実際に使っているbit数よりも実質的に2bit多い))

またアーキテクチャによっては, この 12bit のうちの何 bit かに別の情報("format")を埋め込んでいることもある (relocInfo_${arch}.hpp 参照). format が付くため, 実際のデータとしては |type|format|offset| のようになる模様 (type が 4bit, offset は (12-format分) bit)

    ((cite: hotspot/src/share/vm/code/relocInfo.hpp))
    // The offsets accumulate along the relocInfo stream to encode the
    // address within the CodeBlob, which is named RelocIterator::addr().
    // The address of a particular relocInfo always points to the first
    // byte of the relevant instruction (and not to any of its subfields
    // or embedded immediate constants).
    //
    // The offset value is scaled appropriately for the target machine.
    // (See relocInfo_<arch>.hpp for the offset scaling.)
    //
    // On some machines, there may also be a "format" field which may provide
    // additional information about the format of the instruction stream
    // at the corresponding code address.  The format value is usually zero.
    // Any machine (such as Intel) whose instructions can sometimes contain
    // more than one relocatable constant needs format codes to distinguish
    // which operand goes with a given relocation.
    //
    // If the target machine needs N format bits, the offset has 12-N bits,
    // the format is encoded between the offset and the type, and the
    // relocInfo_<arch>.hpp file has manifest constants for the format codes.
    //
    // If the type is "data_prefix_tag" then the offset bits are further encoded,
    // and in fact represent not a code-stream offset but some inline data.
    // The data takes the form of a counted sequence of halfwords, which
    // precedes the actual relocation record.  (Clients never see it directly.)
    // The interpetation of this extra data depends on the relocation type.
    //
    // On machines that have 32-bit immediate fields, there is usually
    // little need for relocation "prefix" data, because the instruction stream
    // is a perfectly reasonable place to store the value.  On machines in
    // which 32-bit values must be "split" across instructions, the relocation
    // data is the "true" specification of the value, which is then applied
    // to some field of the instruction (22 or 13 bits, on SPARC).
    //
    // Whenever the location of the CodeBlob changes, any PC-relative
    // relocations, and any internal_word_type relocations, must be reapplied.
    // After the GC runs, oop_type relocations must be reapplied.

relocation type としては, 以下のような種類が用意されている模様.

    ((cite: hotspot/src/share/vm/code/relocInfo.hpp))
    // Here are meanings of the types:
    //
    // relocInfo::none -- a filler record
    //   Value:  none
    //   Instruction: The corresponding code address is ignored
    //   Data:  Any data prefix and format code are ignored
    //   (This means that any relocInfo can be disabled by setting
    //   its type to none.  See relocInfo::remove.)
    //
    // relocInfo::oop_type -- a reference to an oop
    //   Value:  an oop, or else the address (handle) of an oop
    //   Instruction types: memory (load), set (load address)
    //   Data:  []       an oop stored in 4 bytes of instruction
    //          [n]      n is the index of an oop in the CodeBlob's oop pool
    //          [[N]n l] and l is a byte offset to be applied to the oop
    //          [Nn Ll]  both index and offset may be 32 bits if necessary
    //   Here is a special hack, used only by the old compiler:
    //          [[N]n 00] the value is the __address__ of the nth oop in the pool
    //   (Note that the offset allows optimal references to class variables.)
    //
    // relocInfo::internal_word_type -- an address within the same CodeBlob
    // relocInfo::section_word_type -- same, but can refer to another section
    //   Value:  an address in the CodeBlob's code or constants section
    //   Instruction types: memory (load), set (load address)
    //   Data:  []     stored in 4 bytes of instruction
    //          [[L]l] a relative offset (see [About Offsets] below)
    //   In the case of section_word_type, the offset is relative to a section
    //   base address, and the section number (e.g., SECT_INSTS) is encoded
    //   into the low two bits of the offset L.
    //
    // relocInfo::external_word_type -- a fixed address in the runtime system
    //   Value:  an address
    //   Instruction types: memory (load), set (load address)
    //   Data:  []   stored in 4 bytes of instruction
    //          [n]  the index of a "well-known" stub (usual case on RISC)
    //          [Ll] a 32-bit address
    //
    // relocInfo::runtime_call_type -- a fixed subroutine in the runtime system
    //   Value:  an address
    //   Instruction types: PC-relative call (or a PC-relative branch)
    //   Data:  []   stored in 4 bytes of instruction
    //
    // relocInfo::static_call_type -- a static call
    //   Value:  an CodeBlob, a stub, or a fixup routine
    //   Instruction types: a call
    //   Data:  []
    //   The identity of the callee is extracted from debugging information.
    //   //%note reloc_3
    //
    // relocInfo::virtual_call_type -- a virtual call site (which includes an inline
    //                                 cache)
    //   Value:  an CodeBlob, a stub, the interpreter, or a fixup routine
    //   Instruction types: a call, plus some associated set-oop instructions
    //   Data:  []       the associated set-oops are adjacent to the call
    //          [n]      n is a relative offset to the first set-oop
    //          [[N]n l] and l is a limit within which the set-oops occur
    //          [Nn Ll]  both n and l may be 32 bits if necessary
    //   The identity of the callee is extracted from debugging information.
    //
    // relocInfo::opt_virtual_call_type -- a virtual call site that is statically bound
    //
    //    Same info as a static_call_type. We use a special type, so the handling of
    //    virtuals and statics are separated.
    //
    //
    //   The offset n points to the first set-oop.  (See [About Offsets] below.)
    //   In turn, the set-oop instruction specifies or contains an oop cell devoted
    //   exclusively to the IC call, which can be patched along with the call.
    //
    //   The locations of any other set-oops are found by searching the relocation
    //   information starting at the first set-oop, and continuing until all
    //   relocations up through l have been inspected.  The value l is another
    //   relative offset.  (Both n and l are relative to the call's first byte.)
    //
    //   The limit l of the search is exclusive.  However, if it points within
    //   the call (e.g., offset zero), it is adjusted to point after the call and
    //   any associated machine-specific delay slot.
    //
    //   Since the offsets could be as wide as 32-bits, these conventions
    //   put no restrictions whatever upon code reorganization.
    //
    //   The compiler is responsible for ensuring that transition from a clean
    //   state to a monomorphic compiled state is MP-safe.  This implies that
    //   the system must respond well to intermediate states where a random
    //   subset of the set-oops has been correctly from the clean state
    //   upon entry to the VEP of the compiled method.  In the case of a
    //   machine (Intel) with a single set-oop instruction, the 32-bit
    //   immediate field must not straddle a unit of memory coherence.
    //   //%note reloc_3
    //
    // relocInfo::breakpoint_type -- a conditional breakpoint in the code
    //   Value:  none
    //   Instruction types: any whatsoever
    //   Data:  [b [T]t  i...]
    //   The b is a bit-packed word representing the breakpoint's attributes.
    //   The t is a target address which the breakpoint calls (when it is enabled).
    //   The i... is a place to store one or two instruction words overwritten
    //   by a trap, so that the breakpoint may be subsequently removed.
    //
    // relocInfo::static_stub_type -- an extra stub for each static_call_type
    //   Value:  none
    //   Instruction types: a virtual call:  { set_oop; jump; }
    //   Data:  [[N]n]  the offset of the associated static_call reloc
    //   This stub becomes the target of a static call which must be upgraded
    //   to a virtual call (because the callee is interpreted).
    //   See [About Offsets] below.
    //   //%note reloc_2
    //
    // For example:
    //
    //   INSTRUCTIONS                        RELOC: TYPE    PREFIX DATA
    //   ------------                               ----    -----------
    // sethi      %hi(myObject),  R               oop_type [n(myObject)]
    // ld      [R+%lo(myObject)+fldOffset], R2    oop_type [n(myObject) fldOffset]
    // add R2, 1, R2
    // st  R2, [R+%lo(myObject)+fldOffset]        oop_type [n(myObject) fldOffset]
    //%note reloc_1
    //
    // This uses 4 instruction words, 8 relocation halfwords,
    // and an entry (which is sharable) in the CodeBlob's oop pool,
    // for a total of 36 bytes.
    //
    // Note that the compiler is responsible for ensuring the "fldOffset" when
    // added to "%lo(myObject)" does not overflow the immediate fields of the
    // memory instructions.
    //
    //
    // [About Offsets] Relative offsets are supplied to this module as
    // positive byte offsets, but they may be internally stored scaled
    // and/or negated, depending on what is most compact for the target
    // system.  Since the object pointed to by the offset typically
    // precedes the relocation address, it is profitable to store
    // these negative offsets as positive numbers, but this decision
    // is internal to the relocation information abstractions.

詳細(Details)

See: here for details


Relocation

概要(Summary)

圧縮されていない relocation 情報を扱うクラスの基底クラス.

    ((cite: hotspot/src/share/vm/code/relocInfo.hpp))
    // A Relocation is a flyweight object allocated within a RelocationHolder.
    // It represents the relocation data of relocation record.
    // So, the RelocIterator unpacks relocInfos into Relocations.

    class Relocation VALUE_OBJ_CLASS_SPEC {

内部構造(Internal structure)

Relocation クラスのサブクラスでは, それぞれのサブクラスに応じた relocation 処理を行うために, Relocation::fix_relocation_after_move() メソッドをオーバーライドする模様.

    ((cite: hotspot/src/share/vm/code/relocInfo.hpp))
      // This method assumes that all virtual/static (inline) caches are cleared (since for static_call_type and
      // ic_call_type is not always posisition dependent (depending on the state of the cache)). However, this is
      // probably a reasonable assumption, since empty caches simplifies code reloacation.
      virtual void fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) { }

参考(for your information): CallRelocation::fix_relocation_after_move()

CallRelocation::fix_relocation_after_move()
-> Relocation::pd_set_call_destination()

See: here for details

参考(for your information): external_word_Relocation::fix_relocation_after_move()

external_word_Relocation::fix_relocation_after_move()
-> Relocation::set_value()
   -> Relocation::pd_set_data_value()

See: here for details

詳細(Details)

See: here for details


DataRelocation

概要(Summary)

メモリからのロード命令, あるいは即値のロード命令に対する Relocation クラス(の基底クラス).

(これらは多くのアーキテクチャで絶対アドレスであり RISC においては即値フィールドに収まるように分割されていることが多い, とのこと)

    ((cite: hotspot/src/share/vm/code/relocInfo.hpp))
    // A DataRelocation always points at a memory or load-constant instruction..
    // It is absolute on most machines, and the constant is split on RISCs.
    // The specific subtypes are oop, external_word, and internal_word.
    // By convention, the "value" does not include a separately reckoned "offset".
    class DataRelocation : public Relocation {

詳細(Details)

See: here for details


oop_Relocation

概要(Summary)

(#Under Construction)

    ((cite: hotspot/src/share/vm/code/relocInfo.hpp))
    class oop_Relocation : public DataRelocation {

詳細(Details)

See: here for details


external_word_Relocation

概要(Summary)

(#Under Construction)

    ((cite: hotspot/src/share/vm/code/relocInfo.hpp))
    class external_word_Relocation : public DataRelocation {

詳細(Details)

See: here for details


internal_word_Relocation

概要(Summary)

(#Under Construction)

    ((cite: hotspot/src/share/vm/code/relocInfo.hpp))
    class internal_word_Relocation : public DataRelocation {

詳細(Details)

See: here for details


section_word_Relocation

概要(Summary)

(#Under Construction)

    ((cite: hotspot/src/share/vm/code/relocInfo.hpp))
    class section_word_Relocation : public internal_word_Relocation {

詳細(Details)

See: here for details


CallRelocation

概要(Summary)

メソッド呼び出し命令に対する Relocation クラスの基底クラス.

(これらは多くのアーキテクチャで相対アドレス, とのこと)

    ((cite: hotspot/src/share/vm/code/relocInfo.hpp))
    // A CallRelocation always points at a call instruction.
    // It is PC-relative on most machines.
    class CallRelocation : public Relocation {

詳細(Details)

See: here for details


virtual_call_Relocation

概要(Summary)

(#Under Construction)

    ((cite: hotspot/src/share/vm/code/relocInfo.hpp))
    class virtual_call_Relocation : public CallRelocation {

詳細(Details)

See: here for details


opt_virtual_call_Relocation

概要(Summary)

(#Under Construction)

    ((cite: hotspot/src/share/vm/code/relocInfo.hpp))
    class opt_virtual_call_Relocation : public CallRelocation {

詳細(Details)

See: here for details


static_call_Relocation

概要(Summary)

(#Under Construction)

    ((cite: hotspot/src/share/vm/code/relocInfo.hpp))
    class static_call_Relocation : public CallRelocation {

詳細(Details)

See: here for details


runtime_call_Relocation

概要(Summary)

(#Under Construction)

    ((cite: hotspot/src/share/vm/code/relocInfo.hpp))
    class runtime_call_Relocation : public CallRelocation {

詳細(Details)

See: here for details


static_stub_Relocation

概要(Summary)

(#Under Construction)

    ((cite: hotspot/src/share/vm/code/relocInfo.hpp))
    class static_stub_Relocation : public Relocation {

詳細(Details)

See: here for details


poll_Relocation

概要(Summary)

(#Under Construction)

    ((cite: hotspot/src/share/vm/code/relocInfo.hpp))
    class poll_Relocation : public Relocation {

詳細(Details)

See: here for details


poll_return_Relocation

概要(Summary)

(#Under Construction)

    ((cite: hotspot/src/share/vm/code/relocInfo.hpp))
    class poll_return_Relocation : public Relocation {

詳細(Details)

See: here for details


breakpoint_Relocation

概要(Summary)

(#Under Construction)

    ((cite: hotspot/src/share/vm/code/relocInfo.hpp))
    class breakpoint_Relocation : public Relocation {

詳細(Details)

See: here for details


RelocationHolder

概要(Summary)

Relocation クラスの任意のサブクラスを格納できる ValueObj クラス.

全サブクラスの union 型のようなクラス. これらのサブクラスはそれぞれ大きさが違うが RelocationHolder にすることで統一的に扱える模様.

    ((cite: hotspot/src/share/vm/code/relocInfo.hpp))
    // Holder for flyweight relocation objects.
    // Although the flyweight subclasses are of varying sizes,
    // the holder is "one size fits all".
    class RelocationHolder VALUE_OBJ_CLASS_SPEC {

使われ方(Usage)

それぞれの *_Relocation クラスの spec() メソッドで生成される? (#TODO)

内部構造(Internal structure)

現在は void* 5つ分の大きさを用意している模様 (現時点では, この大きさで任意の *_Relocation オブジェクトが格納できる).

    ((cite: hotspot/src/share/vm/code/relocInfo.hpp))
      // this preallocated memory must accommodate all subclasses of Relocation
      // (this number is assertion-checked in Relocation::operator new)
      enum { _relocbuf_size = 5 };
      void* _relocbuf[ _relocbuf_size ];

詳細(Details)

See: here for details


RelocIterator

概要(Summary)

CodeBlob 中の relocation 情報を辿るためのイテレータクラス. relocInfo オブジェクトを Relocation オブジェクトに変換する役割も果たす.

利用する際には, 以下のコメント中の "Usage:" のように使う (RelocIterator::reloc() メソッドを呼ぶと, 現在の iterate 先の relocInfo を Relocation オブジェクト(またはそのサブクラスのオブジェクト)に変換して返してくれる. また, 特定のサブクラスに限定した RelocIterator::oop_reloc() のようなメソッドもある模様).

    ((cite: hotspot/src/share/vm/code/relocInfo.hpp))
    // A RelocIterator iterates through the relocation information of a CodeBlob.
    // It is a variable BoundRelocation which is able to take on successive
    // values as it is advanced through a code stream.
    // Usage:
    //   RelocIterator iter(nm);
    //   while (iter.next()) {
    //     iter.reloc()->some_operation();
    //   }
    // or:
    //   RelocIterator iter(nm);
    //   while (iter.next()) {
    //     switch (iter.type()) {
    //      case relocInfo::oop_type          :
    //      case relocInfo::ic_type           :
    //      case relocInfo::prim_type         :
    //      case relocInfo::uncommon_type     :
    //      case relocInfo::runtime_call_type :
    //      case relocInfo::internal_word_type:
    //      case relocInfo::external_word_type:
    //      ...
    //     }
    //   }

    class RelocIterator : public StackObj {

備考(Notes)

知りたいのが特定のアドレス範囲だけであれば, 以下のように iterate 範囲を絞ることもできる (この例では pc と pc+1 の間).

    ((cite: hotspot/src/share/vm/code/nmethod.cpp))
    bool nmethod::is_at_poll_or_poll_return(address pc) {
      RelocIterator iter(this, pc, pc+1);
      while (iter.next()) {
        relocInfo::relocType t = iter.type();
    ...

詳細(Details)

See: here for details


PatchingRelocIterator

概要(Summary)

特殊な RelocIterator クラス.

iterate 処理の間だけブレークポイントを外して処理を行う. コードに対する動的なパッチ当ての際にはこのクラスを使うとよい, とのこと.

    ((cite: hotspot/src/share/vm/code/relocInfo.hpp))
    // if you are going to patch code, you should use this subclass of
    // RelocIterator
    class PatchingRelocIterator : public RelocIterator {

詳細(Details)

See: here for details



This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.