Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  jvmciCodeInstaller.hpp   Sprache: C

 
/*
 * Copyright (c) 2011, 2022, 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_JVMCI_JVMCICODEINSTALLER_HPP
#define SHARE_JVMCI_JVMCICODEINSTALLER_HPP

#include "classfile/classFileStream.hpp"
#include "code/debugInfoRec.hpp"
#include "code/exceptionHandlerTable.hpp"
#include "code/nativeInst.hpp"
#include "jvmci/jvmci.hpp"
#include "jvmci/jvmciEnv.hpp"

// Object for decoding a serialized HotSpotCompiledCode object.
// Encoding is done by jdk.vm.ci.hotspot.HotSpotCompiledCodeStream.
class HotSpotCompiledCodeStream : public ResourceObj {
 private:
  class Chunk {
   private:
    Chunk* _next;
    u4 _size;

   public:
    u4 size() const            { return _size; }
    const u1* data()     const { return ((const u1*)this) + HEADER; }
    const u1* data_end() const { return data() + _size; }
    Chunk* next() const        { return _next; }
  };

  // Mirrors jdk.vm.ci.hotspot.HotSpotCompiledCodeStream.HEADER
  static const int HEADER = sizeof(Chunk*) + sizeof(u4);

  Chunk* _head;                 // First chunk in buffer
  Chunk* _chunk;                // Chunk currently being read
  mutable const u1* _pos;       // Read position in _chunk
  const bool _with_type_info;
  objArrayHandle _object_pool;  // Pool for objects in Java heap (ignored if libjvmci)
  JavaThread* _thread;          // Current thread

  // Virtual objects in DebugInfo currently being decoded
  GrowableArray<ScopeValue*>* _virtual_objects;

  // HotSpotCompiledCode.name or HotSpotCompiledNmethod.method
  const char* _code_desc;

#define checked_read(value, name, type) do { \
  if (_with_type_info) { check_data(sizeof(type), name); } \
  return (type) value; \
while (0)

  void before_read(u1 size);

  u1 get_u1() { before_read(1); u1 res = *_pos;         _pos += 1; return res; }
  u2 get_u2() { before_read(2); u2 res = *((u2*) _pos); _pos += 2; return res; }
  u4 get_u4() { before_read(4); u4 res = *((u4*) _pos); _pos += 4; return res; }
  u8 get_u8() { before_read(8); u8 res = *((u8*) _pos); _pos += 8; return res; }

  void check_data(u2 expect_size, const char *expect_name);

 public:
  HotSpotCompiledCodeStream(JavaThread* thread, const u1* buffer, bool with_type_info, objArrayHandle& object_pool) :
    _head((Chunk*) buffer),
    _chunk((Chunk*) buffer),
    _pos(_chunk->data()),
    _with_type_info(with_type_info),
    _object_pool(object_pool),
    _thread(thread),
    _virtual_objects(nullptr),
    _code_desc("")
  {}

  // Dump complete buffer to `st`.
  void dump_buffer(outputStream* st=tty) const;

  // Dump last `len` bytes of current buffer chunk to `st`
  void dump_buffer_tail(int len, outputStream* st=tty) const;

  // Gets a string containing code_desc() followed by a hexdump
  // of about 100 bytes in the stream up to the current read position.
  const char* context() const;

  // Gets HotSpotCompiledCode.name or HotSpotCompiledNmethod.method.name_and_sig_as_C_string().
  const char* code_desc() const { return _code_desc; }

  void set_code_desc(const char* name, methodHandle& method) {
    if (name != nullptr) {
      _code_desc = name;
    } else if (!method.is_null()) {
      _code_desc = method->name_and_sig_as_C_string();
    }
  }

  // Current read address.
  address pos() const { return (address) _pos; }

  // Offset of current read position from start of buffer.
  u4 offset() const;

  // Gets the number of remaining bytes in the stream.
  bool available() const;

  oop get_oop(int id, JVMCI_TRAPS) const;
  JavaThread* thread() const { return _thread; }

  void set_virtual_objects(GrowableArray<ScopeValue*>* objs) { _virtual_objects = objs; }
  ScopeValue* virtual_object_at(int id, JVMCI_TRAPS) const;

  u1 read_u1(const char* name) { checked_read(get_u1(), name, u1); }
  u2 read_u2(const char* name) { checked_read(get_u2(), name, u2); }
  u4 read_u4(const char* name) { checked_read(get_u4(), name, u4); }
  u8 read_u8(const char* name) { checked_read(get_u8(), name, u8); }
  s2 read_s2(const char* name) { checked_read(get_u2(), name, s2); }
  s4 read_s4(const char* name) { checked_read(get_u4(), name, s4); }
  s8 read_s8(const char* name) { checked_read(get_u8(), name, s8); }

  bool        read_bool(const char* name) { checked_read((get_u1() != 0), name, bool); }
  Method*     read_method(const char* name);
  Klass*      read_klass(const char* name);
  const char* read_utf8(const char* name, JVMCI_TRAPS);
#undef checked_read
};

// Converts a HotSpotCompiledCode to a CodeBlob or an nmethod.
class CodeInstaller : public StackObj {
  friend class JVMCIVMStructs;
private:
  enum MarkId {
    INVALID_MARK,
    VERIFIED_ENTRY,
    UNVERIFIED_ENTRY,
    OSR_ENTRY,
    EXCEPTION_HANDLER_ENTRY,
    DEOPT_HANDLER_ENTRY,
    FRAME_COMPLETE,
    INVOKEINTERFACE,
    INVOKEVIRTUAL,
    INVOKESTATIC,
    INVOKESPECIAL,
    INLINE_INVOKE,
    POLL_NEAR,
    POLL_RETURN_NEAR,
    POLL_FAR,
    POLL_RETURN_FAR,
    CARD_TABLE_ADDRESS,
    CARD_TABLE_SHIFT,
    HEAP_TOP_ADDRESS,
    HEAP_END_ADDRESS,
    NARROW_KLASS_BASE_ADDRESS,
    NARROW_OOP_BASE_ADDRESS,
    CRC_TABLE_ADDRESS,
    LOG_OF_HEAP_REGION_GRAIN_BYTES,
    INLINE_CONTIGUOUS_ALLOCATION_SUPPORTED,
    DEOPT_MH_HANDLER_ENTRY,
    VERIFY_OOPS,
    VERIFY_OOP_BITS,
    VERIFY_OOP_MASK,
    VERIFY_OOP_COUNT_ADDRESS,
    INVOKE_INVALID = -1
  };

  // Mirrors jdk.vm.ci.hotspot.HotSpotCompiledCodeStream.Tag
  enum Tag {
    ILLEGAL,
    REGISTER_PRIMITIVE,
    REGISTER_OOP,
    REGISTER_NARROW_OOP,
    STACK_SLOT_PRIMITIVE,
    STACK_SLOT_OOP,
    STACK_SLOT_NARROW_OOP,
    VIRTUAL_OBJECT_ID,
    VIRTUAL_OBJECT_ID2,
    NULL_CONSTANT,
    RAW_CONSTANT,
    PRIMITIVE_0,
    PRIMITIVE4,
    PRIMITIVE8,
    JOBJECT,
    OBJECT_ID,
    OBJECT_ID2,

    NO_FINALIZABLE_SUBCLASS,
    CONCRETE_SUBTYPE,
    LEAF_TYPE,
    CONCRETE_METHOD,
    CALLSITE_TARGET_VALUE,

    PATCH_OBJECT_ID,
    PATCH_OBJECT_ID2,
    PATCH_NARROW_OBJECT_ID,
    PATCH_NARROW_OBJECT_ID2,
    PATCH_JOBJECT,
    PATCH_NARROW_JOBJECT,
    PATCH_KLASS,
    PATCH_NARROW_KLASS,
    PATCH_METHOD,
    PATCH_DATA_SECTION_REFERENCE,

    SITE_CALL,
    SITE_FOREIGN_CALL,
    SITE_FOREIGN_CALL_NO_DEBUG_INFO,
    SITE_SAFEPOINT,
    SITE_INFOPOINT,
    SITE_IMPLICIT_EXCEPTION,
    SITE_IMPLICIT_EXCEPTION_DISPATCH,
    SITE_MARK,
    SITE_DATA_PATCH,
    SITE_EXCEPTION_HANDLER,
  };

  // Mirrors constants from jdk.vm.ci.code.BytecodeFrame.
  enum BytecodeFrameBCI {
    UNWIND_BCI = -1,
    BEFORE_BCI = -2,
    AFTER_BCI = -3,
    AFTER_EXCEPTION_BCI = -4,
    UNKNOWN_BCI = -5,
    INVALID_FRAMESTATE_BCI = -6
  };

  // Mirrors HotSpotCompiledCode flags from jdk.vm.ci.hotspot.HotSpotCompiledCodeStream.
  enum HotSpotCompiledCodeFlags {
    HCC_IS_NMETHOD            = 0x01,
    HCC_HAS_ASSUMPTIONS       = 0x02,
    HCC_HAS_METHODS           = 0x04,
    HCC_HAS_DEOPT_RESCUE_SLOT = 0x08,
    HCC_HAS_COMMENTS          = 0x10
  };

  // Mirrors DebugInfo flags from jdk.vm.ci.hotspot.HotSpotCompiledCodeStream.
  enum DebugInfoFlags {
    DI_HAS_REFERENCE_MAP    = 0x01,
    DI_HAS_CALLEE_SAVE_INFO = 0x02,
    DI_HAS_FRAMES           = 0x04
  };

  // Mirrors BytecodeFrame flags from jdk.vm.ci.hotspot.HotSpotCompiledCodeStream.
  enum DebugInfoFrameFlags {
    DIF_HAS_LOCALS        = 0x01,
    DIF_HAS_STACK         = 0x02,
    DIF_HAS_LOCKS         = 0x04,
    DIF_DURING_CALL       = 0x08,
    DIF_RETHROW_EXCEPTION = 0x10
  };

  // Sentinel value in a DebugInfo stream denoting no register.
  static const int NO_REGISTER = 0xFFFF;

  Arena         _arena;
  JVMCIEnv*     _jvmci_env;

  jint          _sites_count;

  CodeOffsets   _offsets;

  jint          _code_size;
  jint          _total_frame_size;
  jint          _orig_pc_offset;
  jint          _parameter_count;
  jint          _constants_size;

  bool          _has_monitors;
  bool          _has_wide_vector;

  MarkId        _next_call_type;
  address       _invoke_mark_pc;

  CodeSection*  _instructions;
  CodeSection*  _constants;

  OopRecorder*              _oop_recorder;
  DebugInformationRecorder* _debug_recorder;
  Dependencies*             _dependencies;
  ExceptionHandlerTable     _exception_handler_table;
  ImplicitExceptionTable    _implicit_exception_table;
  bool                      _has_auto_box;

  static ConstantOopWriteValue* _oop_null_scope_value;
  static ConstantIntValue*    _int_m1_scope_value;
  static ConstantIntValue*    _int_0_scope_value;
  static ConstantIntValue*    _int_1_scope_value;
  static ConstantIntValue*    _int_2_scope_value;
  static LocationValue*       _illegal_value;
  static MarkerValue*         _virtual_byte_array_marker;

  jint pd_next_offset(NativeInstruction* inst, jint pc_offset, JVMCI_TRAPS);
  void pd_patch_OopConstant(int pc_offset, Handle& obj, bool compressed, JVMCI_TRAPS);
  void pd_patch_MetaspaceConstant(int pc_offset, HotSpotCompiledCodeStream* stream, u1 tag, JVMCI_TRAPS);
  void pd_patch_DataSectionReference(int pc_offset, int data_offset, JVMCI_TRAPS);
  void pd_relocate_ForeignCall(NativeInstruction* inst, jlong foreign_call_destination, JVMCI_TRAPS);
  void pd_relocate_JavaMethod(CodeBuffer &cbuf, methodHandle& method, jint pc_offset, JVMCI_TRAPS);
  void pd_relocate_poll(address pc, jint mark, JVMCI_TRAPS);

public:

#ifndef PRODUCT
  // Verifies the enum mirroring BCI constants in BytecodeFrame is in sync.
  static void verify_bci_constants(JVMCIEnv* env);
#endif

  CodeInstaller(JVMCIEnv* jvmci_env) :
    _arena(mtJVMCI),
    _jvmci_env(jvmci_env),
    _has_auto_box(false) {}

  JVMCI::CodeInstallResult install(JVMCICompiler* compiler,
                                   jlong compiled_code_buffer,
                                   bool with_type_info,
                                   JVMCIObject compiled_code,
                                   objArrayHandle object_pool,
                                   CodeBlob*& cb,
                                   JVMCIObject installed_code,
                                   FailedSpeculation** failed_speculations,
                                   char* speculations,
                                   int speculations_len,
                                   JVMCI_TRAPS);

  JVMCIEnv* jvmci_env() { return _jvmci_env; }
  JVMCIRuntime* runtime() { return _jvmci_env->runtime(); }

  static address runtime_call_target_address(oop runtime_call);
  static VMReg get_hotspot_reg(jint jvmciRegisterNumber, JVMCI_TRAPS);
  static bool is_general_purpose_reg(VMReg hotspotRegister);
  static ScopeValue* to_primitive_value(HotSpotCompiledCodeStream* stream, jlong raw, BasicType type, ScopeValue* &second, JVMCI_TRAPS);

  const OopMapSet* oopMapSet() const { return _debug_recorder->_oopmaps; }

  // Gets the tag to be used with `read_oop()` corresponding to `patch_object_tag`.
  static u1 as_read_oop_tag(HotSpotCompiledCodeStream* stream, u1 patch_object_tag, JVMCI_TRAPS);

protected:
  Handle read_oop(HotSpotCompiledCodeStream* stream, u1 tag, JVMCI_TRAPS);

  ScopeValue* get_scope_value(HotSpotCompiledCodeStream* stream, u1 tag, BasicType type, ScopeValue* &second, JVMCI_TRAPS);

  GrowableArray<ScopeValue*>* read_local_or_stack_values(HotSpotCompiledCodeStream* stream, u1 frame_flags, bool is_locals, JVMCI_TRAPS);

  void* record_metadata_reference(CodeSection* section, address dest, HotSpotCompiledCodeStream* stream, u1 tag, JVMCI_TRAPS);
#ifdef _LP64
  narrowKlass record_narrow_metadata_reference(CodeSection* section, address dest, HotSpotCompiledCodeStream* stream, u1 tag, JVMCI_TRAPS);
#endif
  GrowableArray<MonitorValue*>* read_monitor_values(HotSpotCompiledCodeStream* stream, u1 frame_flags, JVMCI_TRAPS);

  // extract the fields of the HotSpotCompiledCode
  void initialize_fields(HotSpotCompiledCodeStream* stream, u1 code_flags, methodHandle&&nbsp;method, CodeBuffer& buffer, JVMCI_TRAPS);
  void initialize_dependencies(HotSpotCompiledCodeStream* stream, u1 code_flags, OopRecorder* oop_recorder, JVMCI_TRAPS);

  int estimate_stubs_size(HotSpotCompiledCodeStream* stream, JVMCI_TRAPS);

  // perform data and call relocation on the CodeBuffer
  JVMCI::CodeInstallResult initialize_buffer(JVMCIObject compiled_code, CodeBuffer&&nbsp;buffer, HotSpotCompiledCodeStream* stream, u1 code_flags, JVMCI_TRAPS);

  void site_Safepoint(CodeBuffer& buffer, jint pc_offset, HotSpotCompiledCodeStream* stream, u1 tag, JVMCI_TRAPS);
  void site_Infopoint(CodeBuffer& buffer, jint pc_offset, HotSpotCompiledCodeStream* stream, JVMCI_TRAPS);
  void site_Call(CodeBuffer& buffer, u1 tag, jint pc_offset, HotSpotCompiledCodeStream* stream, JVMCI_TRAPS);
  void site_DataPatch(CodeBuffer& buffer, jint pc_offset, HotSpotCompiledCodeStream* stream, JVMCI_TRAPS);
  void site_Mark(CodeBuffer& buffer, jint pc_offset, HotSpotCompiledCodeStream* stream, JVMCI_TRAPS);
  void site_ExceptionHandler(jint pc_offset, HotSpotCompiledCodeStream* stream);

  OopMap* create_oop_map(HotSpotCompiledCodeStream* stream, u1 debug_info_flags, JVMCI_TRAPS);

  VMReg getVMRegFromLocation(HotSpotCompiledCodeStream* stream, int total_frame_size, JVMCI_TRAPS);

  int map_jvmci_bci(int bci);

  void record_oop_patch(HotSpotCompiledCodeStream* stream, address dest, u1 read_tag, bool narrow, JVMCI_TRAPS);

  // full_info: if false, only BytecodePosition is in stream otherwise all DebugInfo is in stream
  void record_scope(jint pc_offset, HotSpotCompiledCodeStream* stream, u1 debug_info_flags, bool full_info, bool is_mh_invoke, bool return_oop, JVMCI_TRAPS);

  void record_scope(jint pc_offset, HotSpotCompiledCodeStream* stream, u1 debug_info_flags, bool full_info, JVMCI_TRAPS) {
    record_scope(pc_offset, stream, debug_info_flags, full_info, false /* is_mh_invoke */, false /* return_oop */, JVMCIENV);
  }
  void record_object_value(ObjectValue* sv, HotSpotCompiledCodeStream* stream, JVMCI_TRAPS);

  void read_virtual_objects(HotSpotCompiledCodeStream* stream, JVMCI_TRAPS);

  int estimateStubSpace(int static_call_stubs);
};

#endif // SHARE_JVMCI_JVMCICODEINSTALLER_HPP

98%


¤ Dauer der Verarbeitung: 0.25 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung ist noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge