mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-23 12:34:32 +02:00
6939861: JVM should handle more conversion operations
Reviewed-by: twisti, jrose
This commit is contained in:
parent
bb2c21a025
commit
6aeaca98d1
29 changed files with 3011 additions and 645 deletions
|
@ -152,6 +152,32 @@ void CodeBlob::set_oop_maps(OopMapSet* p) {
|
|||
}
|
||||
|
||||
|
||||
void CodeBlob::trace_new_stub(CodeBlob* stub, const char* name1, const char* name2) {
|
||||
// Do not hold the CodeCache lock during name formatting.
|
||||
assert(!CodeCache_lock->owned_by_self(), "release CodeCache before registering the stub");
|
||||
|
||||
if (stub != NULL) {
|
||||
char stub_id[256];
|
||||
assert(strlen(name1) + strlen(name2) < sizeof(stub_id), "");
|
||||
jio_snprintf(stub_id, sizeof(stub_id), "%s%s", name1, name2);
|
||||
if (PrintStubCode) {
|
||||
tty->print_cr("Decoding %s " INTPTR_FORMAT, stub_id, (intptr_t) stub);
|
||||
Disassembler::decode(stub->code_begin(), stub->code_end());
|
||||
}
|
||||
Forte::register_stub(stub_id, stub->code_begin(), stub->code_end());
|
||||
|
||||
if (JvmtiExport::should_post_dynamic_code_generated()) {
|
||||
const char* stub_name = name2;
|
||||
if (name2[0] == '\0') stub_name = name1;
|
||||
JvmtiExport::post_dynamic_code_generated(stub_name, stub->code_begin(), stub->code_end());
|
||||
}
|
||||
}
|
||||
|
||||
// Track memory usage statistic after releasing CodeCache_lock
|
||||
MemoryService::track_code_cache_memory_usage();
|
||||
}
|
||||
|
||||
|
||||
void CodeBlob::flush() {
|
||||
if (_oop_maps) {
|
||||
FREE_C_HEAP_ARRAY(unsigned char, _oop_maps);
|
||||
|
@ -312,23 +338,7 @@ RuntimeStub* RuntimeStub::new_runtime_stub(const char* stub_name,
|
|||
stub = new (size) RuntimeStub(stub_name, cb, size, frame_complete, frame_size, oop_maps, caller_must_gc_arguments);
|
||||
}
|
||||
|
||||
// Do not hold the CodeCache lock during name formatting.
|
||||
if (stub != NULL) {
|
||||
char stub_id[256];
|
||||
jio_snprintf(stub_id, sizeof(stub_id), "RuntimeStub - %s", stub_name);
|
||||
if (PrintStubCode) {
|
||||
tty->print_cr("Decoding %s " INTPTR_FORMAT, stub_id, stub);
|
||||
Disassembler::decode(stub->code_begin(), stub->code_end());
|
||||
}
|
||||
Forte::register_stub(stub_id, stub->code_begin(), stub->code_end());
|
||||
|
||||
if (JvmtiExport::should_post_dynamic_code_generated()) {
|
||||
JvmtiExport::post_dynamic_code_generated(stub_name, stub->code_begin(), stub->code_end());
|
||||
}
|
||||
}
|
||||
|
||||
// Track memory usage statistic after releasing CodeCache_lock
|
||||
MemoryService::track_code_cache_memory_usage();
|
||||
trace_new_stub(stub, "RuntimeStub - ", stub_name);
|
||||
|
||||
return stub;
|
||||
}
|
||||
|
@ -340,6 +350,50 @@ void* RuntimeStub::operator new(size_t s, unsigned size) {
|
|||
return p;
|
||||
}
|
||||
|
||||
// operator new shared by all singletons:
|
||||
void* SingletonBlob::operator new(size_t s, unsigned size) {
|
||||
void* p = CodeCache::allocate(size);
|
||||
if (!p) fatal("Initial size of CodeCache is too small");
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
// Implementation of RicochetBlob
|
||||
|
||||
RicochetBlob::RicochetBlob(
|
||||
CodeBuffer* cb,
|
||||
int size,
|
||||
int bounce_offset,
|
||||
int exception_offset,
|
||||
int frame_size
|
||||
)
|
||||
: SingletonBlob("RicochetBlob", cb, sizeof(RicochetBlob), size, frame_size, (OopMapSet*) NULL)
|
||||
{
|
||||
_bounce_offset = bounce_offset;
|
||||
_exception_offset = exception_offset;
|
||||
}
|
||||
|
||||
|
||||
RicochetBlob* RicochetBlob::create(
|
||||
CodeBuffer* cb,
|
||||
int bounce_offset,
|
||||
int exception_offset,
|
||||
int frame_size)
|
||||
{
|
||||
RicochetBlob* blob = NULL;
|
||||
ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock
|
||||
{
|
||||
MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
|
||||
unsigned int size = allocation_size(cb, sizeof(RicochetBlob));
|
||||
blob = new (size) RicochetBlob(cb, size, bounce_offset, exception_offset, frame_size);
|
||||
}
|
||||
|
||||
trace_new_stub(blob, "RicochetBlob");
|
||||
|
||||
return blob;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
// Implementation of DeoptimizationBlob
|
||||
|
@ -386,34 +440,12 @@ DeoptimizationBlob* DeoptimizationBlob::create(
|
|||
frame_size);
|
||||
}
|
||||
|
||||
// Do not hold the CodeCache lock during name formatting.
|
||||
if (blob != NULL) {
|
||||
char blob_id[256];
|
||||
jio_snprintf(blob_id, sizeof(blob_id), "DeoptimizationBlob@" PTR_FORMAT, blob->code_begin());
|
||||
if (PrintStubCode) {
|
||||
tty->print_cr("Decoding %s " INTPTR_FORMAT, blob_id, blob);
|
||||
Disassembler::decode(blob->code_begin(), blob->code_end());
|
||||
}
|
||||
Forte::register_stub(blob_id, blob->code_begin(), blob->code_end());
|
||||
|
||||
if (JvmtiExport::should_post_dynamic_code_generated()) {
|
||||
JvmtiExport::post_dynamic_code_generated("DeoptimizationBlob", blob->code_begin(), blob->code_end());
|
||||
}
|
||||
}
|
||||
|
||||
// Track memory usage statistic after releasing CodeCache_lock
|
||||
MemoryService::track_code_cache_memory_usage();
|
||||
trace_new_stub(blob, "DeoptimizationBlob");
|
||||
|
||||
return blob;
|
||||
}
|
||||
|
||||
|
||||
void* DeoptimizationBlob::operator new(size_t s, unsigned size) {
|
||||
void* p = CodeCache::allocate(size);
|
||||
if (!p) fatal("Initial size of CodeCache is too small");
|
||||
return p;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
// Implementation of UncommonTrapBlob
|
||||
|
||||
|
@ -441,33 +473,12 @@ UncommonTrapBlob* UncommonTrapBlob::create(
|
|||
blob = new (size) UncommonTrapBlob(cb, size, oop_maps, frame_size);
|
||||
}
|
||||
|
||||
// Do not hold the CodeCache lock during name formatting.
|
||||
if (blob != NULL) {
|
||||
char blob_id[256];
|
||||
jio_snprintf(blob_id, sizeof(blob_id), "UncommonTrapBlob@" PTR_FORMAT, blob->code_begin());
|
||||
if (PrintStubCode) {
|
||||
tty->print_cr("Decoding %s " INTPTR_FORMAT, blob_id, blob);
|
||||
Disassembler::decode(blob->code_begin(), blob->code_end());
|
||||
}
|
||||
Forte::register_stub(blob_id, blob->code_begin(), blob->code_end());
|
||||
|
||||
if (JvmtiExport::should_post_dynamic_code_generated()) {
|
||||
JvmtiExport::post_dynamic_code_generated("UncommonTrapBlob", blob->code_begin(), blob->code_end());
|
||||
}
|
||||
}
|
||||
|
||||
// Track memory usage statistic after releasing CodeCache_lock
|
||||
MemoryService::track_code_cache_memory_usage();
|
||||
trace_new_stub(blob, "UncommonTrapBlob");
|
||||
|
||||
return blob;
|
||||
}
|
||||
|
||||
|
||||
void* UncommonTrapBlob::operator new(size_t s, unsigned size) {
|
||||
void* p = CodeCache::allocate(size);
|
||||
if (!p) fatal("Initial size of CodeCache is too small");
|
||||
return p;
|
||||
}
|
||||
#endif // COMPILER2
|
||||
|
||||
|
||||
|
@ -498,33 +509,12 @@ ExceptionBlob* ExceptionBlob::create(
|
|||
blob = new (size) ExceptionBlob(cb, size, oop_maps, frame_size);
|
||||
}
|
||||
|
||||
// We do not need to hold the CodeCache lock during name formatting
|
||||
if (blob != NULL) {
|
||||
char blob_id[256];
|
||||
jio_snprintf(blob_id, sizeof(blob_id), "ExceptionBlob@" PTR_FORMAT, blob->code_begin());
|
||||
if (PrintStubCode) {
|
||||
tty->print_cr("Decoding %s " INTPTR_FORMAT, blob_id, blob);
|
||||
Disassembler::decode(blob->code_begin(), blob->code_end());
|
||||
}
|
||||
Forte::register_stub(blob_id, blob->code_begin(), blob->code_end());
|
||||
|
||||
if (JvmtiExport::should_post_dynamic_code_generated()) {
|
||||
JvmtiExport::post_dynamic_code_generated("ExceptionBlob", blob->code_begin(), blob->code_end());
|
||||
}
|
||||
}
|
||||
|
||||
// Track memory usage statistic after releasing CodeCache_lock
|
||||
MemoryService::track_code_cache_memory_usage();
|
||||
trace_new_stub(blob, "ExceptionBlob");
|
||||
|
||||
return blob;
|
||||
}
|
||||
|
||||
|
||||
void* ExceptionBlob::operator new(size_t s, unsigned size) {
|
||||
void* p = CodeCache::allocate(size);
|
||||
if (!p) fatal("Initial size of CodeCache is too small");
|
||||
return p;
|
||||
}
|
||||
#endif // COMPILER2
|
||||
|
||||
|
||||
|
@ -554,35 +544,12 @@ SafepointBlob* SafepointBlob::create(
|
|||
blob = new (size) SafepointBlob(cb, size, oop_maps, frame_size);
|
||||
}
|
||||
|
||||
// We do not need to hold the CodeCache lock during name formatting.
|
||||
if (blob != NULL) {
|
||||
char blob_id[256];
|
||||
jio_snprintf(blob_id, sizeof(blob_id), "SafepointBlob@" PTR_FORMAT, blob->code_begin());
|
||||
if (PrintStubCode) {
|
||||
tty->print_cr("Decoding %s " INTPTR_FORMAT, blob_id, blob);
|
||||
Disassembler::decode(blob->code_begin(), blob->code_end());
|
||||
}
|
||||
Forte::register_stub(blob_id, blob->code_begin(), blob->code_end());
|
||||
|
||||
if (JvmtiExport::should_post_dynamic_code_generated()) {
|
||||
JvmtiExport::post_dynamic_code_generated("SafepointBlob", blob->code_begin(), blob->code_end());
|
||||
}
|
||||
}
|
||||
|
||||
// Track memory usage statistic after releasing CodeCache_lock
|
||||
MemoryService::track_code_cache_memory_usage();
|
||||
trace_new_stub(blob, "SafepointBlob");
|
||||
|
||||
return blob;
|
||||
}
|
||||
|
||||
|
||||
void* SafepointBlob::operator new(size_t s, unsigned size) {
|
||||
void* p = CodeCache::allocate(size);
|
||||
if (!p) fatal("Initial size of CodeCache is too small");
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
// Verification and printing
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
// Suptypes are:
|
||||
// nmethod : Compiled Java methods (include method that calls to native code)
|
||||
// RuntimeStub : Call to VM runtime methods
|
||||
// RicochetBlob : Used for blocking MethodHandle adapters
|
||||
// DeoptimizationBlob : Used for deoptimizatation
|
||||
// ExceptionBlob : Used for stack unrolling
|
||||
// SafepointBlob : Used to handle illegal instruction exceptions
|
||||
|
@ -95,12 +96,13 @@ class CodeBlob VALUE_OBJ_CLASS_SPEC {
|
|||
void flush();
|
||||
|
||||
// Typing
|
||||
virtual bool is_buffer_blob() const { return false; }
|
||||
virtual bool is_nmethod() const { return false; }
|
||||
virtual bool is_runtime_stub() const { return false; }
|
||||
virtual bool is_deoptimization_stub() const { return false; }
|
||||
virtual bool is_uncommon_trap_stub() const { return false; }
|
||||
virtual bool is_exception_stub() const { return false; }
|
||||
virtual bool is_buffer_blob() const { return false; }
|
||||
virtual bool is_nmethod() const { return false; }
|
||||
virtual bool is_runtime_stub() const { return false; }
|
||||
virtual bool is_ricochet_stub() const { return false; }
|
||||
virtual bool is_deoptimization_stub() const { return false; }
|
||||
virtual bool is_uncommon_trap_stub() const { return false; }
|
||||
virtual bool is_exception_stub() const { return false; }
|
||||
virtual bool is_safepoint_stub() const { return false; }
|
||||
virtual bool is_adapter_blob() const { return false; }
|
||||
virtual bool is_method_handles_adapter_blob() const { return false; }
|
||||
|
@ -182,6 +184,9 @@ class CodeBlob VALUE_OBJ_CLASS_SPEC {
|
|||
virtual void print_on(outputStream* st) const;
|
||||
virtual void print_value_on(outputStream* st) const;
|
||||
|
||||
// Deal with Disassembler, VTune, Forte, JvmtiExport, MemoryService.
|
||||
static void trace_new_stub(CodeBlob* blob, const char* name1, const char* name2 = "");
|
||||
|
||||
// Print the comment associated with offset on stream, if there is one
|
||||
virtual void print_block_comment(outputStream* stream, address block_begin) {
|
||||
intptr_t offset = (intptr_t)(block_begin - code_begin());
|
||||
|
@ -318,7 +323,11 @@ class RuntimeStub: public CodeBlob {
|
|||
|
||||
class SingletonBlob: public CodeBlob {
|
||||
friend class VMStructs;
|
||||
public:
|
||||
|
||||
protected:
|
||||
void* operator new(size_t s, unsigned size);
|
||||
|
||||
public:
|
||||
SingletonBlob(
|
||||
const char* name,
|
||||
CodeBuffer* cb,
|
||||
|
@ -340,6 +349,50 @@ class SingletonBlob: public CodeBlob {
|
|||
};
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
// RicochetBlob
|
||||
// Holds an arbitrary argument list indefinitely while Java code executes recursively.
|
||||
|
||||
class RicochetBlob: public SingletonBlob {
|
||||
friend class VMStructs;
|
||||
private:
|
||||
|
||||
int _bounce_offset;
|
||||
int _exception_offset;
|
||||
|
||||
// Creation support
|
||||
RicochetBlob(
|
||||
CodeBuffer* cb,
|
||||
int size,
|
||||
int bounce_offset,
|
||||
int exception_offset,
|
||||
int frame_size
|
||||
);
|
||||
|
||||
public:
|
||||
// Creation
|
||||
static RicochetBlob* create(
|
||||
CodeBuffer* cb,
|
||||
int bounce_offset,
|
||||
int exception_offset,
|
||||
int frame_size
|
||||
);
|
||||
|
||||
// Typing
|
||||
bool is_ricochet_stub() const { return true; }
|
||||
|
||||
// GC for args
|
||||
void preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map, OopClosure* f) { /* Nothing to do */ }
|
||||
|
||||
address bounce_addr() const { return code_begin() + _bounce_offset; }
|
||||
address exception_addr() const { return code_begin() + _exception_offset; }
|
||||
bool returns_to_bounce_addr(address pc) const {
|
||||
address bounce_pc = bounce_addr();
|
||||
return (pc == bounce_pc || (pc + frame::pc_return_offset) == bounce_pc);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
// DeoptimizationBlob
|
||||
|
||||
|
@ -363,8 +416,6 @@ class DeoptimizationBlob: public SingletonBlob {
|
|||
int frame_size
|
||||
);
|
||||
|
||||
void* operator new(size_t s, unsigned size);
|
||||
|
||||
public:
|
||||
// Creation
|
||||
static DeoptimizationBlob* create(
|
||||
|
@ -378,7 +429,6 @@ class DeoptimizationBlob: public SingletonBlob {
|
|||
|
||||
// Typing
|
||||
bool is_deoptimization_stub() const { return true; }
|
||||
const DeoptimizationBlob *as_deoptimization_stub() const { return this; }
|
||||
bool exception_address_is_unpack_entry(address pc) const {
|
||||
address unpack_pc = unpack();
|
||||
return (pc == unpack_pc || (pc + frame::pc_return_offset) == unpack_pc);
|
||||
|
@ -426,8 +476,6 @@ class UncommonTrapBlob: public SingletonBlob {
|
|||
int frame_size
|
||||
);
|
||||
|
||||
void* operator new(size_t s, unsigned size);
|
||||
|
||||
public:
|
||||
// Creation
|
||||
static UncommonTrapBlob* create(
|
||||
|
@ -458,8 +506,6 @@ class ExceptionBlob: public SingletonBlob {
|
|||
int frame_size
|
||||
);
|
||||
|
||||
void* operator new(size_t s, unsigned size);
|
||||
|
||||
public:
|
||||
// Creation
|
||||
static ExceptionBlob* create(
|
||||
|
@ -491,8 +537,6 @@ class SafepointBlob: public SingletonBlob {
|
|||
int frame_size
|
||||
);
|
||||
|
||||
void* operator new(size_t s, unsigned size);
|
||||
|
||||
public:
|
||||
// Creation
|
||||
static SafepointBlob* create(
|
||||
|
|
|
@ -796,6 +796,7 @@ void CodeCache::print_internals() {
|
|||
int nmethodCount = 0;
|
||||
int runtimeStubCount = 0;
|
||||
int adapterCount = 0;
|
||||
int ricochetStubCount = 0;
|
||||
int deoptimizationStubCount = 0;
|
||||
int uncommonTrapStubCount = 0;
|
||||
int bufferBlobCount = 0;
|
||||
|
@ -840,6 +841,8 @@ void CodeCache::print_internals() {
|
|||
}
|
||||
} else if (cb->is_runtime_stub()) {
|
||||
runtimeStubCount++;
|
||||
} else if (cb->is_ricochet_stub()) {
|
||||
ricochetStubCount++;
|
||||
} else if (cb->is_deoptimization_stub()) {
|
||||
deoptimizationStubCount++;
|
||||
} else if (cb->is_uncommon_trap_stub()) {
|
||||
|
@ -876,6 +879,7 @@ void CodeCache::print_internals() {
|
|||
tty->print_cr("runtime_stubs: %d",runtimeStubCount);
|
||||
tty->print_cr("adapters: %d",adapterCount);
|
||||
tty->print_cr("buffer blobs: %d",bufferBlobCount);
|
||||
tty->print_cr("ricochet_stubs: %d",ricochetStubCount);
|
||||
tty->print_cr("deoptimization_stubs: %d",deoptimizationStubCount);
|
||||
tty->print_cr("uncommon_traps: %d",uncommonTrapStubCount);
|
||||
tty->print_cr("\nnmethod size distribution (non-zombie java)");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue