< prev index next > src/hotspot/share/runtime/sharedRuntime.hpp
Print this page
*/
#ifndef SHARE_RUNTIME_SHAREDRUNTIME_HPP
#define SHARE_RUNTIME_SHAREDRUNTIME_HPP
+ #include "classfile/compactHashtable.hpp"
#include "code/codeBlob.hpp"
#include "code/vmreg.hpp"
#include "interpreter/linkResolver.hpp"
#include "memory/allStatic.hpp"
+ #include "memory/metaspaceClosure.hpp"
#include "memory/resourceArea.hpp"
#include "runtime/stubDeclarations.hpp"
#include "utilities/macros.hpp"
class AdapterHandlerEntry;
// The handle is dereferenced and the return value is the event writer oop.
static RuntimeStub* generate_jfr_write_checkpoint();
// For c2: call to runtime to return a buffer lease.
static RuntimeStub* generate_jfr_return_lease();
#endif
+ static void init_adapter_library();
static const char *stub_name(SharedStubId id) {
assert(id > SharedStubId::NO_STUBID && id < SharedStubId::NUM_STUBIDS, "stub id out of range");
return _stub_names[(int)id];
}
// that the interpreter before it does any call dispatch will record the current
// stack pointer in the interpreter frame. On return it will restore the stack
// pointer as needed. This means the i2c adapter code doesn't need any special
// handshaking path with compiled code to keep the stack walking correct.
- static AdapterHandlerEntry* generate_i2c2i_adapters(MacroAssembler *_masm,
- int total_args_passed,
- int max_arg,
- const BasicType *sig_bt,
- const VMRegPair *regs,
- AdapterFingerPrint* fingerprint);
+ static void generate_i2c2i_adapters(MacroAssembler *_masm,
+ int total_args_passed,
+ int max_arg,
+ const BasicType *sig_bt,
+ const VMRegPair *regs,
+ AdapterHandlerEntry* handler);
static void gen_i2c_adapter(MacroAssembler *_masm,
int total_args_passed,
int comp_args_on_stack,
const BasicType *sig_bt,
static address handle_wrong_method_abstract(JavaThread* current);
static address handle_wrong_method_ic_miss(JavaThread* current);
static address handle_unsafe_access(JavaThread* thread, address next_pc);
+ private:
+ static PerfTickCounters* _perf_resolve_opt_virtual_total_time;
+ static PerfTickCounters* _perf_resolve_virtual_total_time;
+ static PerfTickCounters* _perf_resolve_static_total_time;
+ static PerfTickCounters* _perf_handle_wrong_method_total_time;
+ static PerfTickCounters* _perf_ic_miss_total_time;
+ public:
+ static uint _ic_miss_ctr; // total # of IC misses
+ static uint _wrong_method_ctr;
+ static uint _resolve_static_ctr;
+ static uint _resolve_virtual_ctr;
+ static uint _resolve_opt_virtual_ctr;
+
+ static void print_counters_on(outputStream* st);
+
#ifndef PRODUCT
// Collect and print inline cache miss statistics
private:
enum { maxICmiss_count = 100 };
static int _ICmiss_count[maxICmiss_count]; // miss counts
static address _ICmiss_at[maxICmiss_count]; // miss addresses
static void trace_ic_miss(address at);
public:
- static uint _ic_miss_ctr; // total # of IC misses
- static uint _wrong_method_ctr;
- static uint _resolve_static_ctr;
- static uint _resolve_virtual_ctr;
- static uint _resolve_opt_virtual_ctr;
static uint _implicit_null_throws;
static uint _implicit_div0_throws;
static uint _jbyte_array_copy_ctr; // Slow-path byte array copy
static uint _jshort_array_copy_ctr; // Slow-path short array copy
static address nof_inlined_calls_addr() { return (address)&_nof_inlined_calls; }
static address nof_static_calls_addr() { return (address)&_nof_static_calls; }
static address nof_inlined_static_calls_addr() { return (address)&_nof_inlined_static_calls; }
static address nof_interface_calls_addr() { return (address)&_nof_interface_calls; }
static address nof_inlined_interface_calls_addr() { return (address)&_nof_inlined_interface_calls; }
- static void print_call_statistics(uint64_t comp_total);
- static void print_ic_miss_histogram();
+ static void print_call_statistics_on(outputStream* st);
+ static void print_ic_miss_histogram_on(outputStream* st);
#endif // PRODUCT
static void print_statistics() PRODUCT_RETURN;
};
// routine in their middles and end in a return (instead of ending in a jump).
// The native wrappers are stored in real nmethods instead of the BufferBlobs
// used by the adapters. The code generation happens here because it's very
// similar to what the adapters have to do.
- class AdapterHandlerEntry : public CHeapObj<mtCode> {
+ class AdapterHandlerEntry : public MetaspaceObj {
friend class AdapterHandlerLibrary;
private:
AdapterFingerPrint* _fingerprint;
address _i2c_entry;
address _c2i_entry;
address _c2i_unverified_entry;
address _c2i_no_clinit_check_entry;
+ bool _linked;
#ifdef ASSERT
// Captures code and signature used to generate this adapter when
// verifying adapter equivalence.
unsigned char* _saved_code;
address c2i_no_clinit_check_entry) :
_fingerprint(fingerprint),
_i2c_entry(i2c_entry),
_c2i_entry(c2i_entry),
_c2i_unverified_entry(c2i_unverified_entry),
- _c2i_no_clinit_check_entry(c2i_no_clinit_check_entry)
+ _c2i_no_clinit_check_entry(c2i_no_clinit_check_entry),
+ _linked(false)
#ifdef ASSERT
, _saved_code_length(0)
#endif
{ }
~AdapterHandlerEntry();
public:
+ static AdapterHandlerEntry* allocate(AdapterFingerPrint* fingerprint,
+ address i2c_entry,
+ address c2i_entry,
+ address c2i_unverified_entry,
+ address c2i_no_clinit_check_entry)
+ {
+ return new (mtCode) AdapterHandlerEntry(fingerprint, i2c_entry, c2i_entry, c2i_unverified_entry, c2i_no_clinit_check_entry);
+ }
+
+ static void deallocate(AdapterHandlerEntry *handler) {
+ handler->~AdapterHandlerEntry();
+ }
+
+ void set_entry_points(address i2c_entry, address c2i_entry, address c2i_unverified_entry, address c2i_no_clinit_check_entry, bool linked = true) {
+ _i2c_entry = i2c_entry;
+ _c2i_entry = c2i_entry;
+ _c2i_unverified_entry = c2i_unverified_entry;
+ _c2i_no_clinit_check_entry = c2i_no_clinit_check_entry;
+ _linked = linked;
+ }
+
address get_i2c_entry() const { return _i2c_entry; }
address get_c2i_entry() const { return _c2i_entry; }
address get_c2i_unverified_entry() const { return _c2i_unverified_entry; }
address get_c2i_no_clinit_check_entry() const { return _c2i_no_clinit_check_entry; }
+ bool is_linked() const { return _linked; }
address base_address();
void relocate(address new_base);
AdapterFingerPrint* fingerprint() const { return _fingerprint; }
bool compare_code(AdapterHandlerEntry* other);
#endif
//virtual void print_on(outputStream* st) const; DO NOT USE
void print_adapter_on(outputStream* st) const;
+
+ void metaspace_pointers_do(MetaspaceClosure* it);
+ int size() const {return (int)heap_word_size(sizeof(AdapterHandlerEntry)); }
+ MetaspaceObj::Type type() const { return AdapterHandlerEntryType; }
+
+ void remove_unshareable_info() NOT_CDS_RETURN;
+ void restore_unshareable_info(TRAPS) NOT_CDS_RETURN;
};
+ #if INCLUDE_CDS
+ class ArchivedAdapterTable;
+ #endif // INCLUDE_CDS
+
class AdapterHandlerLibrary: public AllStatic {
friend class SharedRuntime;
private:
static BufferBlob* _buffer; // the temporary code buffer in CodeCache
static AdapterHandlerEntry* _abstract_method_handler;
static AdapterHandlerEntry* _no_arg_handler;
static AdapterHandlerEntry* _int_arg_handler;
static AdapterHandlerEntry* _obj_arg_handler;
static AdapterHandlerEntry* _obj_int_arg_handler;
static AdapterHandlerEntry* _obj_obj_arg_handler;
-
+ #if INCLUDE_CDS
+ static ArchivedAdapterTable _archived_adapter_handler_table;
+ #endif // INCLUDE_CDS
static BufferBlob* buffer_blob();
static void initialize();
+ static AdapterHandlerEntry* create_simple_adapter(AdapterBlob*& new_adapter,
+ int total_args_passed,
+ BasicType* sig_bt);
+ static AdapterHandlerEntry* get_simple_adapter(const methodHandle& method);
+ static bool lookup_aot_cache(AdapterHandlerEntry* handler, CodeBuffer* buffer);
static AdapterHandlerEntry* create_adapter(AdapterBlob*& new_adapter,
+ AdapterFingerPrint* fingerprint,
int total_args_passed,
BasicType* sig_bt,
- bool allocate_code_blob);
- static AdapterHandlerEntry* get_simple_adapter(const methodHandle& method);
+ bool is_transient);
+ #ifndef PRODUCT
+ static void print_adapter_handler_info(AdapterHandlerEntry* handler, AdapterBlob* adapter_blob);
+ #endif // PRODUCT
public:
static AdapterHandlerEntry* new_entry(AdapterFingerPrint* fingerprint,
- address i2c_entry,
- address c2i_entry,
- address c2i_unverified_entry,
+ address i2c_entry = nullptr,
+ address c2i_entry = nullptr,
+ address c2i_unverified_entry = nullptr,
address c2i_no_clinit_check_entry = nullptr);
static void create_native_wrapper(const methodHandle& method);
static AdapterHandlerEntry* get_adapter(const methodHandle& method);
+ static AdapterHandlerEntry* lookup(AdapterFingerPrint* fp);
+ static bool generate_adapter_code(AdapterBlob*& adapter_blob,
+ AdapterHandlerEntry* handler,
+ int total_args_passed,
+ BasicType* sig_bt,
+ bool is_transient);
static void print_handler(const CodeBlob* b) { print_handler_on(tty, b); }
static void print_handler_on(outputStream* st, const CodeBlob* b);
static bool contains(const CodeBlob* b);
+ static const char* name(AdapterFingerPrint* fingerprint);
+ static uint32_t id(AdapterFingerPrint* fingerprint);
#ifndef PRODUCT
- static void print_statistics();
+ static void print_statistics_on(outputStream* st);
#endif // PRODUCT
+ static bool is_abstract_method_adapter(AdapterHandlerEntry* adapter);
+
+ static bool link_adapter_handler(AdapterHandlerEntry* handler, AdapterBlob*& adapter_blob) NOT_CDS_RETURN_(false);
+ static size_t estimate_size_for_archive() NOT_CDS_RETURN_(0);
+ static void archive_adapter_table() NOT_CDS_RETURN;
+ static void serialize_shared_table_header(SerializeClosure* soc) NOT_CDS_RETURN;
};
#endif // SHARE_RUNTIME_SHAREDRUNTIME_HPP
< prev index next >