mirror of
https://github.com/openjdk/jdk.git
synced 2026-01-28 12:09:14 +00:00
8349088: De-virtualize Codeblob and nmethod
Co-authored-by: Stefan Karlsson <stefank@openjdk.org> Co-authored-by: Chris Plummer <cjplummer@openjdk.org> Reviewed-by: cjplummer, aboldtch, dlong
This commit is contained in:
parent
62d93f2a22
commit
46d4a601e0
@ -53,6 +53,53 @@
|
||||
#include "c1/c1_Runtime1.hpp"
|
||||
#endif
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
// Virtual methods are not allowed in code blobs to simplify caching compiled code.
|
||||
// Check all "leaf" subclasses of CodeBlob class.
|
||||
|
||||
static_assert(!std::is_polymorphic<nmethod>::value, "no virtual methods are allowed in nmethod");
|
||||
static_assert(!std::is_polymorphic<AdapterBlob>::value, "no virtual methods are allowed in code blobs");
|
||||
static_assert(!std::is_polymorphic<VtableBlob>::value, "no virtual methods are allowed in code blobs");
|
||||
static_assert(!std::is_polymorphic<MethodHandlesAdapterBlob>::value, "no virtual methods are allowed in code blobs");
|
||||
static_assert(!std::is_polymorphic<RuntimeStub>::value, "no virtual methods are allowed in code blobs");
|
||||
static_assert(!std::is_polymorphic<DeoptimizationBlob>::value, "no virtual methods are allowed in code blobs");
|
||||
static_assert(!std::is_polymorphic<SafepointBlob>::value, "no virtual methods are allowed in code blobs");
|
||||
static_assert(!std::is_polymorphic<UpcallStub>::value, "no virtual methods are allowed in code blobs");
|
||||
#ifdef COMPILER2
|
||||
static_assert(!std::is_polymorphic<ExceptionBlob>::value, "no virtual methods are allowed in code blobs");
|
||||
static_assert(!std::is_polymorphic<UncommonTrapBlob>::value, "no virtual methods are allowed in code blobs");
|
||||
#endif
|
||||
|
||||
// Add proxy vtables.
|
||||
// We need only few for now - they are used only from prints.
|
||||
const nmethod::Vptr nmethod::_vptr;
|
||||
const BufferBlob::Vptr BufferBlob::_vptr;
|
||||
const RuntimeStub::Vptr RuntimeStub::_vptr;
|
||||
const SingletonBlob::Vptr SingletonBlob::_vptr;
|
||||
const DeoptimizationBlob::Vptr DeoptimizationBlob::_vptr;
|
||||
const UpcallStub::Vptr UpcallStub::_vptr;
|
||||
|
||||
const CodeBlob::Vptr* CodeBlob::vptr() const {
|
||||
constexpr const CodeBlob::Vptr* array[(size_t)CodeBlobKind::Number_Of_Kinds] = {
|
||||
nullptr/* None */,
|
||||
&nmethod::_vptr,
|
||||
&BufferBlob::_vptr,
|
||||
&AdapterBlob::_vptr,
|
||||
&VtableBlob::_vptr,
|
||||
&MethodHandlesAdapterBlob::_vptr,
|
||||
&RuntimeStub::_vptr,
|
||||
&DeoptimizationBlob::_vptr,
|
||||
&SafepointBlob::_vptr,
|
||||
#ifdef COMPILER2
|
||||
&ExceptionBlob::_vptr,
|
||||
&UncommonTrapBlob::_vptr,
|
||||
#endif
|
||||
&UpcallStub::_vptr
|
||||
};
|
||||
|
||||
return array[(size_t)_kind];
|
||||
}
|
||||
|
||||
unsigned int CodeBlob::align_code_offset(int offset) {
|
||||
// align the size to CodeEntryAlignment
|
||||
@ -386,7 +433,7 @@ RuntimeStub::RuntimeStub(
|
||||
OopMapSet* oop_maps,
|
||||
bool caller_must_gc_arguments
|
||||
)
|
||||
: RuntimeBlob(name, CodeBlobKind::Runtime_Stub, cb, size, sizeof(RuntimeStub),
|
||||
: RuntimeBlob(name, CodeBlobKind::RuntimeStub, cb, size, sizeof(RuntimeStub),
|
||||
frame_complete, frame_size, oop_maps, caller_must_gc_arguments)
|
||||
{
|
||||
}
|
||||
@ -482,18 +529,18 @@ DeoptimizationBlob* DeoptimizationBlob::create(
|
||||
return blob;
|
||||
}
|
||||
|
||||
#ifdef COMPILER2
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
// Implementation of UncommonTrapBlob
|
||||
|
||||
#ifdef COMPILER2
|
||||
UncommonTrapBlob::UncommonTrapBlob(
|
||||
CodeBuffer* cb,
|
||||
int size,
|
||||
OopMapSet* oop_maps,
|
||||
int frame_size
|
||||
)
|
||||
: SingletonBlob("UncommonTrapBlob", CodeBlobKind::Uncommon_Trap, cb,
|
||||
: SingletonBlob("UncommonTrapBlob", CodeBlobKind::UncommonTrap, cb,
|
||||
size, sizeof(UncommonTrapBlob), frame_size, oop_maps)
|
||||
{}
|
||||
|
||||
@ -516,14 +563,9 @@ UncommonTrapBlob* UncommonTrapBlob::create(
|
||||
return blob;
|
||||
}
|
||||
|
||||
|
||||
#endif // COMPILER2
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
// Implementation of ExceptionBlob
|
||||
|
||||
#ifdef COMPILER2
|
||||
ExceptionBlob::ExceptionBlob(
|
||||
CodeBuffer* cb,
|
||||
int size,
|
||||
@ -553,10 +595,8 @@ ExceptionBlob* ExceptionBlob::create(
|
||||
return blob;
|
||||
}
|
||||
|
||||
|
||||
#endif // COMPILER2
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
// Implementation of SafepointBlob
|
||||
|
||||
@ -644,17 +684,45 @@ void UpcallStub::free(UpcallStub* blob) {
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
// Verification and printing
|
||||
|
||||
void CodeBlob::verify() {
|
||||
if (is_nmethod()) {
|
||||
as_nmethod()->verify();
|
||||
}
|
||||
}
|
||||
|
||||
void CodeBlob::print_on(outputStream* st) const {
|
||||
st->print_cr("[CodeBlob (" INTPTR_FORMAT ")]", p2i(this));
|
||||
st->print_cr("Framesize: %d", _frame_size);
|
||||
vptr()->print_on(this, st);
|
||||
}
|
||||
|
||||
void CodeBlob::print() const { print_on(tty); }
|
||||
|
||||
void CodeBlob::print_value_on(outputStream* st) const {
|
||||
vptr()->print_value_on(this, st);
|
||||
}
|
||||
|
||||
void CodeBlob::print_on_impl(outputStream* st) const {
|
||||
st->print_cr("[CodeBlob (" INTPTR_FORMAT ")]", p2i(this));
|
||||
st->print_cr("Framesize: %d", _frame_size);
|
||||
}
|
||||
|
||||
void CodeBlob::print_value_on_impl(outputStream* st) const {
|
||||
st->print_cr("[CodeBlob]");
|
||||
}
|
||||
|
||||
void CodeBlob::print_block_comment(outputStream* stream, address block_begin) const {
|
||||
#if defined(SUPPORT_ASSEMBLY) || defined(SUPPORT_ABSTRACT_ASSEMBLY)
|
||||
if (is_nmethod()) {
|
||||
as_nmethod()->print_nmethod_labels(stream, block_begin);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef PRODUCT
|
||||
ptrdiff_t offset = block_begin - code_begin();
|
||||
assert(offset >= 0, "Expecting non-negative offset!");
|
||||
_asm_remarks.print(uint(offset), stream);
|
||||
#endif
|
||||
}
|
||||
|
||||
void CodeBlob::dump_for_addr(address addr, outputStream* st, bool verbose) const {
|
||||
if (is_buffer_blob() || is_adapter_blob() || is_vtable_blob() || is_method_handles_adapter_blob()) {
|
||||
// the interpreter is generated into a buffer blob
|
||||
@ -708,7 +776,7 @@ void CodeBlob::dump_for_addr(address addr, outputStream* st, bool verbose) const
|
||||
// verbose is only ever true when called from findpc in debug.cpp
|
||||
nm->print_nmethod(true);
|
||||
} else {
|
||||
nm->print(st);
|
||||
nm->print_on(st);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -716,61 +784,45 @@ void CodeBlob::dump_for_addr(address addr, outputStream* st, bool verbose) const
|
||||
print_on(st);
|
||||
}
|
||||
|
||||
void BufferBlob::verify() {
|
||||
// unimplemented
|
||||
void BufferBlob::print_on_impl(outputStream* st) const {
|
||||
RuntimeBlob::print_on_impl(st);
|
||||
print_value_on_impl(st);
|
||||
}
|
||||
|
||||
void BufferBlob::print_on(outputStream* st) const {
|
||||
RuntimeBlob::print_on(st);
|
||||
print_value_on(st);
|
||||
}
|
||||
|
||||
void BufferBlob::print_value_on(outputStream* st) const {
|
||||
void BufferBlob::print_value_on_impl(outputStream* st) const {
|
||||
st->print_cr("BufferBlob (" INTPTR_FORMAT ") used for %s", p2i(this), name());
|
||||
}
|
||||
|
||||
void RuntimeStub::verify() {
|
||||
// unimplemented
|
||||
}
|
||||
|
||||
void RuntimeStub::print_on(outputStream* st) const {
|
||||
void RuntimeStub::print_on_impl(outputStream* st) const {
|
||||
ttyLocker ttyl;
|
||||
RuntimeBlob::print_on(st);
|
||||
RuntimeBlob::print_on_impl(st);
|
||||
st->print("Runtime Stub (" INTPTR_FORMAT "): ", p2i(this));
|
||||
st->print_cr("%s", name());
|
||||
Disassembler::decode((RuntimeBlob*)this, st);
|
||||
}
|
||||
|
||||
void RuntimeStub::print_value_on(outputStream* st) const {
|
||||
void RuntimeStub::print_value_on_impl(outputStream* st) const {
|
||||
st->print("RuntimeStub (" INTPTR_FORMAT "): ", p2i(this)); st->print("%s", name());
|
||||
}
|
||||
|
||||
void SingletonBlob::verify() {
|
||||
// unimplemented
|
||||
}
|
||||
|
||||
void SingletonBlob::print_on(outputStream* st) const {
|
||||
void SingletonBlob::print_on_impl(outputStream* st) const {
|
||||
ttyLocker ttyl;
|
||||
RuntimeBlob::print_on(st);
|
||||
RuntimeBlob::print_on_impl(st);
|
||||
st->print_cr("%s", name());
|
||||
Disassembler::decode((RuntimeBlob*)this, st);
|
||||
}
|
||||
|
||||
void SingletonBlob::print_value_on(outputStream* st) const {
|
||||
void SingletonBlob::print_value_on_impl(outputStream* st) const {
|
||||
st->print_cr("%s", name());
|
||||
}
|
||||
|
||||
void DeoptimizationBlob::print_value_on(outputStream* st) const {
|
||||
void DeoptimizationBlob::print_value_on_impl(outputStream* st) const {
|
||||
st->print_cr("Deoptimization (frame not available)");
|
||||
}
|
||||
|
||||
void UpcallStub::verify() {
|
||||
// unimplemented
|
||||
}
|
||||
|
||||
void UpcallStub::print_on(outputStream* st) const {
|
||||
RuntimeBlob::print_on(st);
|
||||
print_value_on(st);
|
||||
void UpcallStub::print_on_impl(outputStream* st) const {
|
||||
RuntimeBlob::print_on_impl(st);
|
||||
print_value_on_impl(st);
|
||||
st->print_cr("Frame data offset: %d", (int) _frame_data_offset);
|
||||
oop recv = JNIHandles::resolve(_receiver);
|
||||
st->print("Receiver MH=");
|
||||
@ -778,6 +830,6 @@ void UpcallStub::print_on(outputStream* st) const {
|
||||
Disassembler::decode((RuntimeBlob*)this, st);
|
||||
}
|
||||
|
||||
void UpcallStub::print_value_on(outputStream* st) const {
|
||||
void UpcallStub::print_value_on_impl(outputStream* st) const {
|
||||
st->print_cr("UpcallStub (" INTPTR_FORMAT ") used for %s", p2i(this), name());
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2025, 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
|
||||
@ -61,8 +61,8 @@ enum class CodeBlobType {
|
||||
// RuntimeStub : Call to VM runtime methods
|
||||
// SingletonBlob : Super-class for all blobs that exist in only one instance
|
||||
// DeoptimizationBlob : Used for deoptimization
|
||||
// ExceptionBlob : Used for stack unrolling
|
||||
// SafepointBlob : Used to handle illegal instruction exceptions
|
||||
// ExceptionBlob : Used for stack unrolling
|
||||
// UncommonTrapBlob : Used to handle uncommon traps
|
||||
// UpcallStub : Used for upcalls from native code
|
||||
//
|
||||
@ -80,12 +80,14 @@ enum class CodeBlobKind : u1 {
|
||||
Buffer,
|
||||
Adapter,
|
||||
Vtable,
|
||||
MH_Adapter,
|
||||
Runtime_Stub,
|
||||
MHAdapter,
|
||||
RuntimeStub,
|
||||
Deoptimization,
|
||||
Exception,
|
||||
Safepoint,
|
||||
Uncommon_Trap,
|
||||
#ifdef COMPILER2
|
||||
Exception,
|
||||
UncommonTrap,
|
||||
#endif
|
||||
Upcall,
|
||||
Number_Of_Kinds
|
||||
};
|
||||
@ -128,6 +130,17 @@ protected:
|
||||
DbgStrings _dbg_strings;
|
||||
#endif
|
||||
|
||||
void print_on_impl(outputStream* st) const;
|
||||
void print_value_on_impl(outputStream* st) const;
|
||||
|
||||
class Vptr {
|
||||
public:
|
||||
virtual void print_on(const CodeBlob* instance, outputStream* st) const = 0;
|
||||
virtual void print_value_on(const CodeBlob* instance, outputStream* st) const = 0;
|
||||
};
|
||||
|
||||
const Vptr* vptr() const;
|
||||
|
||||
CodeBlob(const char* name, CodeBlobKind kind, CodeBuffer* cb, int size, uint16_t header_size,
|
||||
int16_t frame_complete_offset, int frame_size, OopMapSet* oop_maps, bool caller_must_gc_arguments);
|
||||
|
||||
@ -138,7 +151,7 @@ protected:
|
||||
|
||||
public:
|
||||
|
||||
virtual ~CodeBlob() {
|
||||
~CodeBlob() {
|
||||
assert(_oop_maps == nullptr, "Not flushed");
|
||||
}
|
||||
|
||||
@ -152,20 +165,25 @@ public:
|
||||
// Typing
|
||||
bool is_nmethod() const { return _kind == CodeBlobKind::Nmethod; }
|
||||
bool is_buffer_blob() const { return _kind == CodeBlobKind::Buffer; }
|
||||
bool is_runtime_stub() const { return _kind == CodeBlobKind::Runtime_Stub; }
|
||||
bool is_runtime_stub() const { return _kind == CodeBlobKind::RuntimeStub; }
|
||||
bool is_deoptimization_stub() const { return _kind == CodeBlobKind::Deoptimization; }
|
||||
bool is_uncommon_trap_stub() const { return _kind == CodeBlobKind::Uncommon_Trap; }
|
||||
#ifdef COMPILER2
|
||||
bool is_uncommon_trap_stub() const { return _kind == CodeBlobKind::UncommonTrap; }
|
||||
bool is_exception_stub() const { return _kind == CodeBlobKind::Exception; }
|
||||
#else
|
||||
bool is_uncommon_trap_stub() const { return false; }
|
||||
bool is_exception_stub() const { return false; }
|
||||
#endif
|
||||
bool is_safepoint_stub() const { return _kind == CodeBlobKind::Safepoint; }
|
||||
bool is_adapter_blob() const { return _kind == CodeBlobKind::Adapter; }
|
||||
bool is_vtable_blob() const { return _kind == CodeBlobKind::Vtable; }
|
||||
bool is_method_handles_adapter_blob() const { return _kind == CodeBlobKind::MH_Adapter; }
|
||||
bool is_method_handles_adapter_blob() const { return _kind == CodeBlobKind::MHAdapter; }
|
||||
bool is_upcall_stub() const { return _kind == CodeBlobKind::Upcall; }
|
||||
|
||||
// Casting
|
||||
nmethod* as_nmethod_or_null() { return is_nmethod() ? (nmethod*) this : nullptr; }
|
||||
nmethod* as_nmethod() { assert(is_nmethod(), "must be nmethod"); return (nmethod*) this; }
|
||||
CodeBlob* as_codeblob_or_null() const { return (CodeBlob*) this; }
|
||||
nmethod* as_nmethod_or_null() const { return is_nmethod() ? (nmethod*) this : nullptr; }
|
||||
nmethod* as_nmethod() const { assert(is_nmethod(), "must be nmethod"); return (nmethod*) this; }
|
||||
CodeBlob* as_codeblob() const { return (CodeBlob*) this; }
|
||||
UpcallStub* as_upcall_stub() const { assert(is_upcall_stub(), "must be upcall stub"); return (UpcallStub*) this; }
|
||||
RuntimeStub* as_runtime_stub() const { assert(is_runtime_stub(), "must be runtime blob"); return (RuntimeStub*) this; }
|
||||
|
||||
@ -233,21 +251,16 @@ public:
|
||||
void set_name(const char* name) { _name = name; }
|
||||
|
||||
// Debugging
|
||||
virtual void verify() = 0;
|
||||
virtual void print() const;
|
||||
virtual void print_on(outputStream* st) const;
|
||||
virtual void print_value_on(outputStream* st) const;
|
||||
void verify();
|
||||
void print() const;
|
||||
void print_on(outputStream* st) const;
|
||||
void print_value_on(outputStream* st) const;
|
||||
|
||||
void dump_for_addr(address addr, outputStream* st, bool verbose) const;
|
||||
void print_code_on(outputStream* st);
|
||||
|
||||
// Print to stream, any comments associated with offset.
|
||||
virtual void print_block_comment(outputStream* stream, address block_begin) const {
|
||||
#ifndef PRODUCT
|
||||
ptrdiff_t offset = block_begin - code_begin();
|
||||
assert(offset >= 0, "Expecting non-negative offset!");
|
||||
_asm_remarks.print(uint(offset), stream);
|
||||
#endif
|
||||
}
|
||||
void print_block_comment(outputStream* stream, address block_begin) const;
|
||||
|
||||
#ifndef PRODUCT
|
||||
AsmRemarks &asm_remarks() { return _asm_remarks; }
|
||||
@ -290,6 +303,9 @@ class RuntimeBlob : public CodeBlob {
|
||||
|
||||
// Deal with Disassembler, VTune, Forte, JvmtiExport, MemoryService.
|
||||
static void trace_new_stub(RuntimeBlob* blob, const char* name1, const char* name2 = "");
|
||||
|
||||
class Vptr : public CodeBlob::Vptr {
|
||||
};
|
||||
};
|
||||
|
||||
class WhiteBox;
|
||||
@ -318,11 +334,19 @@ class BufferBlob: public RuntimeBlob {
|
||||
|
||||
static void free(BufferBlob* buf);
|
||||
|
||||
// Verification support
|
||||
void verify() override;
|
||||
void print_on_impl(outputStream* st) const;
|
||||
void print_value_on_impl(outputStream* st) const;
|
||||
|
||||
void print_on(outputStream* st) const override;
|
||||
void print_value_on(outputStream* st) const override;
|
||||
class Vptr : public RuntimeBlob::Vptr {
|
||||
void print_on(const CodeBlob* instance, outputStream* st) const override {
|
||||
((const BufferBlob*)instance)->print_on_impl(st);
|
||||
}
|
||||
void print_value_on(const CodeBlob* instance, outputStream* st) const override {
|
||||
((const BufferBlob*)instance)->print_value_on_impl(st);
|
||||
}
|
||||
};
|
||||
|
||||
static const Vptr _vptr;
|
||||
};
|
||||
|
||||
|
||||
@ -355,7 +379,7 @@ public:
|
||||
|
||||
class MethodHandlesAdapterBlob: public BufferBlob {
|
||||
private:
|
||||
MethodHandlesAdapterBlob(int size): BufferBlob("MethodHandles adapters", CodeBlobKind::MH_Adapter, size) {}
|
||||
MethodHandlesAdapterBlob(int size): BufferBlob("MethodHandles adapters", CodeBlobKind::MHAdapter, size) {}
|
||||
|
||||
public:
|
||||
// Creation
|
||||
@ -396,13 +420,21 @@ class RuntimeStub: public RuntimeBlob {
|
||||
|
||||
static void free(RuntimeStub* stub) { RuntimeBlob::free(stub); }
|
||||
|
||||
address entry_point() const { return code_begin(); }
|
||||
address entry_point() const { return code_begin(); }
|
||||
|
||||
// Verification support
|
||||
void verify() override;
|
||||
void print_on_impl(outputStream* st) const;
|
||||
void print_value_on_impl(outputStream* st) const;
|
||||
|
||||
void print_on(outputStream* st) const override;
|
||||
void print_value_on(outputStream* st) const override;
|
||||
class Vptr : public RuntimeBlob::Vptr {
|
||||
void print_on(const CodeBlob* instance, outputStream* st) const override {
|
||||
instance->as_runtime_stub()->print_on_impl(st);
|
||||
}
|
||||
void print_value_on(const CodeBlob* instance, outputStream* st) const override {
|
||||
instance->as_runtime_stub()->print_value_on_impl(st);
|
||||
}
|
||||
};
|
||||
|
||||
static const Vptr _vptr;
|
||||
};
|
||||
|
||||
|
||||
@ -430,11 +462,19 @@ class SingletonBlob: public RuntimeBlob {
|
||||
|
||||
address entry_point() { return code_begin(); }
|
||||
|
||||
// Verification support
|
||||
void verify() override; // does nothing
|
||||
void print_on_impl(outputStream* st) const;
|
||||
void print_value_on_impl(outputStream* st) const;
|
||||
|
||||
void print_on(outputStream* st) const override;
|
||||
void print_value_on(outputStream* st) const override;
|
||||
class Vptr : public RuntimeBlob::Vptr {
|
||||
void print_on(const CodeBlob* instance, outputStream* st) const override {
|
||||
((const SingletonBlob*)instance)->print_on_impl(st);
|
||||
}
|
||||
void print_value_on(const CodeBlob* instance, outputStream* st) const override {
|
||||
((const SingletonBlob*)instance)->print_value_on_impl(st);
|
||||
}
|
||||
};
|
||||
|
||||
static const Vptr _vptr;
|
||||
};
|
||||
|
||||
|
||||
@ -479,9 +519,6 @@ class DeoptimizationBlob: public SingletonBlob {
|
||||
int frame_size
|
||||
);
|
||||
|
||||
// Printing
|
||||
void print_value_on(outputStream* st) const override;
|
||||
|
||||
address unpack() const { return code_begin() + _unpack_offset; }
|
||||
address unpack_with_exception() const { return code_begin() + _unpack_with_exception; }
|
||||
address unpack_with_reexecution() const { return code_begin() + _unpack_with_reexecution; }
|
||||
@ -511,6 +548,16 @@ class DeoptimizationBlob: public SingletonBlob {
|
||||
}
|
||||
address implicit_exception_uncommon_trap() const { return code_begin() + _implicit_exception_uncommon_trap_offset; }
|
||||
#endif // INCLUDE_JVMCI
|
||||
|
||||
void print_value_on_impl(outputStream* st) const;
|
||||
|
||||
class Vptr : public SingletonBlob::Vptr {
|
||||
void print_value_on(const CodeBlob* instance, outputStream* st) const override {
|
||||
((const DeoptimizationBlob*)instance)->print_value_on_impl(st);
|
||||
}
|
||||
};
|
||||
|
||||
static const Vptr _vptr;
|
||||
};
|
||||
|
||||
|
||||
@ -623,13 +670,22 @@ class UpcallStub: public RuntimeBlob {
|
||||
|
||||
JavaFrameAnchor* jfa_for_frame(const frame& frame) const;
|
||||
|
||||
// GC/Verification support
|
||||
// GC support
|
||||
void oops_do(OopClosure* f, const frame& frame);
|
||||
void verify() override;
|
||||
|
||||
// Misc.
|
||||
void print_on(outputStream* st) const override;
|
||||
void print_value_on(outputStream* st) const override;
|
||||
void print_on_impl(outputStream* st) const;
|
||||
void print_value_on_impl(outputStream* st) const;
|
||||
|
||||
class Vptr : public RuntimeBlob::Vptr {
|
||||
void print_on(const CodeBlob* instance, outputStream* st) const override {
|
||||
instance->as_upcall_stub()->print_on_impl(st);
|
||||
}
|
||||
void print_value_on(const CodeBlob* instance, outputStream* st) const override {
|
||||
instance->as_upcall_stub()->print_value_on_impl(st);
|
||||
}
|
||||
};
|
||||
|
||||
static const Vptr _vptr;
|
||||
};
|
||||
|
||||
#endif // SHARE_CODE_CODEBLOB_HPP
|
||||
|
||||
@ -218,7 +218,7 @@ void DependencyContext::print_dependent_nmethods(bool verbose) {
|
||||
nmethod* nm = b->get_nmethod();
|
||||
tty->print("[%d] { ", idx++);
|
||||
if (!verbose) {
|
||||
nm->print_on(tty, "nmethod");
|
||||
nm->print_on_with_msg(tty, "nmethod");
|
||||
tty->print_cr(" } ");
|
||||
} else {
|
||||
nm->print();
|
||||
|
||||
@ -1619,7 +1619,7 @@ void nmethod::log_new_nmethod() const {
|
||||
|
||||
|
||||
// Print out more verbose output usually for a newly created nmethod.
|
||||
void nmethod::print_on(outputStream* st, const char* msg) const {
|
||||
void nmethod::print_on_with_msg(outputStream* st, const char* msg) const {
|
||||
if (st != nullptr) {
|
||||
ttyLocker ttyl;
|
||||
if (WizardMode) {
|
||||
@ -1971,7 +1971,7 @@ void nmethod::log_state_change() const {
|
||||
|
||||
CompileTask::print_ul(this, "made not entrant");
|
||||
if (PrintCompilation) {
|
||||
print_on(tty, "made not entrant");
|
||||
print_on_with_msg(tty, "made not entrant");
|
||||
}
|
||||
}
|
||||
|
||||
@ -3033,12 +3033,7 @@ void nmethod::verify_scopes() {
|
||||
// -----------------------------------------------------------------------------
|
||||
// Printing operations
|
||||
|
||||
void nmethod::print() const {
|
||||
ttyLocker ttyl; // keep the following output all in one block
|
||||
print(tty);
|
||||
}
|
||||
|
||||
void nmethod::print(outputStream* st) const {
|
||||
void nmethod::print_on_impl(outputStream* st) const {
|
||||
ResourceMark rm;
|
||||
|
||||
st->print("Compiled method ");
|
||||
@ -3053,7 +3048,7 @@ void nmethod::print(outputStream* st) const {
|
||||
st->print("(n/a) ");
|
||||
}
|
||||
|
||||
print_on(st, nullptr);
|
||||
print_on_with_msg(st, nullptr);
|
||||
|
||||
if (WizardMode) {
|
||||
st->print("((nmethod*) " INTPTR_FORMAT ") ", p2i(this));
|
||||
@ -3404,7 +3399,7 @@ void nmethod::decode2(outputStream* ost) const {
|
||||
#endif
|
||||
|
||||
st->cr();
|
||||
this->print(st);
|
||||
this->print_on(st);
|
||||
st->cr();
|
||||
|
||||
#if defined(SUPPORT_ASSEMBLY)
|
||||
@ -3953,12 +3948,12 @@ address nmethod::call_instruction_address(address pc) const {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void nmethod::print_value_on_impl(outputStream* st) const {
|
||||
st->print_cr("nmethod");
|
||||
#if defined(SUPPORT_DATA_STRUCTS)
|
||||
void nmethod::print_value_on(outputStream* st) const {
|
||||
st->print("nmethod");
|
||||
print_on(st, nullptr);
|
||||
}
|
||||
print_on_with_msg(st, nullptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef PRODUCT
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2025, 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
|
||||
@ -900,7 +900,7 @@ public:
|
||||
void post_compiled_method_load_event(JvmtiThreadState* state = nullptr);
|
||||
|
||||
// verify operations
|
||||
void verify() override;
|
||||
void verify();
|
||||
void verify_scopes();
|
||||
void verify_interrupt_point(address interrupt_point, bool is_inline_cache);
|
||||
|
||||
@ -912,9 +912,9 @@ public:
|
||||
void decode(outputStream* st) const { decode2(st); } // just delegate here.
|
||||
|
||||
// printing support
|
||||
void print() const override;
|
||||
void print(outputStream* st) const;
|
||||
void print_on_impl(outputStream* st) const;
|
||||
void print_code();
|
||||
void print_value_on_impl(outputStream* st) const;
|
||||
|
||||
#if defined(SUPPORT_DATA_STRUCTS)
|
||||
// print output in opt build for disassembler library
|
||||
@ -922,7 +922,6 @@ public:
|
||||
void print_pcs_on(outputStream* st);
|
||||
void print_scopes() { print_scopes_on(tty); }
|
||||
void print_scopes_on(outputStream* st) PRODUCT_RETURN;
|
||||
void print_value_on(outputStream* st) const override;
|
||||
void print_handler_table();
|
||||
void print_nul_chk_table();
|
||||
void print_recorded_oop(int log_n, int index);
|
||||
@ -941,9 +940,7 @@ public:
|
||||
void maybe_print_nmethod(const DirectiveSet* directive);
|
||||
void print_nmethod(bool print_code);
|
||||
|
||||
// need to re-define this from CodeBlob else the overload hides it
|
||||
void print_on(outputStream* st) const override { CodeBlob::print_on(st); }
|
||||
void print_on(outputStream* st, const char* msg) const;
|
||||
void print_on_with_msg(outputStream* st, const char* msg) const;
|
||||
|
||||
// Logging
|
||||
void log_identity(xmlStream* log) const;
|
||||
@ -951,13 +948,6 @@ public:
|
||||
void log_state_change() const;
|
||||
|
||||
// Prints block-level comments, including nmethod specific block labels:
|
||||
void print_block_comment(outputStream* stream, address block_begin) const override {
|
||||
#if defined(SUPPORT_ASSEMBLY) || defined(SUPPORT_ABSTRACT_ASSEMBLY)
|
||||
print_nmethod_labels(stream, block_begin);
|
||||
CodeBlob::print_block_comment(stream, block_begin);
|
||||
#endif
|
||||
}
|
||||
|
||||
void print_nmethod_labels(outputStream* stream, address block_begin, bool print_section_labels=true) const;
|
||||
const char* nmethod_section_label(address pos) const;
|
||||
|
||||
@ -995,6 +985,18 @@ public:
|
||||
|
||||
void make_deoptimized();
|
||||
void finalize_relocations();
|
||||
|
||||
class Vptr : public CodeBlob::Vptr {
|
||||
void print_on(const CodeBlob* instance, outputStream* st) const override {
|
||||
ttyLocker ttyl;
|
||||
instance->as_nmethod()->print_on_impl(st);
|
||||
}
|
||||
void print_value_on(const CodeBlob* instance, outputStream* st) const override {
|
||||
instance->as_nmethod()->print_value_on_impl(st);
|
||||
}
|
||||
};
|
||||
|
||||
static const Vptr _vptr;
|
||||
};
|
||||
|
||||
#endif // SHARE_CODE_NMETHOD_HPP
|
||||
|
||||
@ -549,6 +549,7 @@
|
||||
\
|
||||
nonstatic_field(CodeBlob, _name, const char*) \
|
||||
nonstatic_field(CodeBlob, _size, int) \
|
||||
nonstatic_field(CodeBlob, _kind, CodeBlobKind) \
|
||||
nonstatic_field(CodeBlob, _header_size, u2) \
|
||||
nonstatic_field(CodeBlob, _relocation_size, int) \
|
||||
nonstatic_field(CodeBlob, _content_offset, int) \
|
||||
@ -1916,6 +1917,7 @@
|
||||
\
|
||||
declare_integer_type(CompLevel) \
|
||||
declare_integer_type(ByteSize) \
|
||||
declare_integer_type(CodeBlobKind) \
|
||||
JVMTI_ONLY(declare_toplevel_type(BreakpointInfo)) \
|
||||
JVMTI_ONLY(declare_toplevel_type(BreakpointInfo*)) \
|
||||
declare_toplevel_type(CodeBlob*) \
|
||||
@ -2373,6 +2375,23 @@
|
||||
declare_constant(CompLevel_full_profile) \
|
||||
declare_constant(CompLevel_full_optimization) \
|
||||
\
|
||||
/****************/ \
|
||||
/* CodeBlobKind */ \
|
||||
/****************/ \
|
||||
\
|
||||
declare_constant(CodeBlobKind::Nmethod) \
|
||||
declare_constant(CodeBlobKind::Buffer) \
|
||||
declare_constant(CodeBlobKind::Adapter) \
|
||||
declare_constant(CodeBlobKind::Vtable) \
|
||||
declare_constant(CodeBlobKind::MHAdapter) \
|
||||
declare_constant(CodeBlobKind::RuntimeStub) \
|
||||
declare_constant(CodeBlobKind::Deoptimization) \
|
||||
declare_constant(CodeBlobKind::Safepoint) \
|
||||
COMPILER2_PRESENT(declare_constant(CodeBlobKind::Exception)) \
|
||||
COMPILER2_PRESENT(declare_constant(CodeBlobKind::UncommonTrap)) \
|
||||
declare_constant(CodeBlobKind::Upcall) \
|
||||
declare_constant(CodeBlobKind::Number_Of_Kinds) \
|
||||
\
|
||||
/***************/ \
|
||||
/* OopMapValue */ \
|
||||
/***************/ \
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2025, 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
|
||||
@ -62,6 +62,6 @@ public class Runtime1 {
|
||||
/** FIXME: consider making argument "type-safe" in Java port */
|
||||
public CodeBlob blobFor(int id) {
|
||||
Address blobAddr = blobsField.getStaticFieldAddress().getAddressAt(id * VM.getVM().getAddressSize());
|
||||
return VM.getVM().getCodeCache().createCodeBlobWrapper(blobAddr);
|
||||
return VM.getVM().getCodeCache().createCodeBlobWrapper(blobAddr, blobAddr);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 2025, 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
|
||||
@ -50,10 +50,6 @@ public class AdapterBlob extends RuntimeBlob {
|
||||
super(addr);
|
||||
}
|
||||
|
||||
public boolean isAdapterBlob() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return "AdapterBlob: " + super.getName();
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2025, 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
|
||||
@ -49,8 +49,4 @@ public class BufferBlob extends RuntimeBlob {
|
||||
public BufferBlob(Address addr) {
|
||||
super(addr);
|
||||
}
|
||||
|
||||
public boolean isBufferBlob() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 2025, 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
|
||||
@ -43,6 +43,7 @@ import sun.jvm.hotspot.utilities.Observer;
|
||||
public class CodeBlob extends VMObject {
|
||||
private static AddressField nameField;
|
||||
private static CIntegerField sizeField;
|
||||
private static CIntegerField kindField;
|
||||
private static CIntegerField relocationSizeField;
|
||||
private static CIntField headerSizeField;
|
||||
private static CIntegerField contentOffsetField;
|
||||
@ -52,6 +53,22 @@ public class CodeBlob extends VMObject {
|
||||
private static CIntegerField frameSizeField;
|
||||
private static AddressField oopMapsField;
|
||||
|
||||
// Kinds of Codeblob
|
||||
private static int NMethodKind;
|
||||
private static int BufferKind;
|
||||
private static int AdapterKind;
|
||||
private static int VtableKind;
|
||||
private static int MHAdapterKind;
|
||||
private static int RuntimeStubKind;
|
||||
private static int DeoptimizationKind;
|
||||
private static int ExceptionKind;
|
||||
private static int SafepointKind;
|
||||
private static int UncommonTrapKind;
|
||||
private static int UpcallKind;
|
||||
private static int NumberOfKinds;
|
||||
|
||||
private static Class[] wrapperClasses;
|
||||
|
||||
public CodeBlob(Address addr) {
|
||||
super(addr);
|
||||
}
|
||||
@ -63,6 +80,7 @@ public class CodeBlob extends VMObject {
|
||||
|
||||
nameField = type.getAddressField("_name");
|
||||
sizeField = type.getCIntegerField("_size");
|
||||
kindField = type.getCIntegerField("_kind");
|
||||
relocationSizeField = type.getCIntegerField("_relocation_size");
|
||||
headerSizeField = new CIntField(type.getCIntegerField("_header_size"), 0);
|
||||
contentOffsetField = type.getCIntegerField("_content_offset");
|
||||
@ -76,6 +94,40 @@ public class CodeBlob extends VMObject {
|
||||
matcherInterpreterFramePointerReg =
|
||||
db.lookupIntConstant("Matcher::interpreter_frame_pointer_reg").intValue();
|
||||
}
|
||||
|
||||
NMethodKind = db.lookupIntConstant("CodeBlobKind::Nmethod").intValue();
|
||||
BufferKind = db.lookupIntConstant("CodeBlobKind::Buffer").intValue();
|
||||
AdapterKind = db.lookupIntConstant("CodeBlobKind::Adapter").intValue();
|
||||
VtableKind = db.lookupIntConstant("CodeBlobKind::Vtable").intValue();
|
||||
MHAdapterKind = db.lookupIntConstant("CodeBlobKind::MHAdapter").intValue();
|
||||
RuntimeStubKind = db.lookupIntConstant("CodeBlobKind::RuntimeStub").intValue();
|
||||
DeoptimizationKind = db.lookupIntConstant("CodeBlobKind::Deoptimization").intValue();
|
||||
SafepointKind = db.lookupIntConstant("CodeBlobKind::Safepoint").intValue();
|
||||
UpcallKind = db.lookupIntConstant("CodeBlobKind::Upcall").intValue();
|
||||
NumberOfKinds = db.lookupIntConstant("CodeBlobKind::Number_Of_Kinds").intValue();
|
||||
if (VM.getVM().isServerCompiler()) {
|
||||
ExceptionKind = db.lookupIntConstant("CodeBlobKind::Exception").intValue();
|
||||
UncommonTrapKind = db.lookupIntConstant("CodeBlobKind::UncommonTrap").intValue();
|
||||
} else {
|
||||
// Set invalid value to not match default.
|
||||
ExceptionKind = NumberOfKinds + 1;
|
||||
UncommonTrapKind = NumberOfKinds + 1;
|
||||
}
|
||||
|
||||
wrapperClasses = new Class[NumberOfKinds];
|
||||
wrapperClasses[NMethodKind] = NMethod.class;
|
||||
wrapperClasses[BufferKind] = BufferBlob.class;
|
||||
wrapperClasses[AdapterKind] = AdapterBlob.class;
|
||||
wrapperClasses[VtableKind] = VtableBlob.class;
|
||||
wrapperClasses[MHAdapterKind] = MethodHandlesAdapterBlob.class;
|
||||
wrapperClasses[RuntimeStubKind] = RuntimeStub.class;
|
||||
wrapperClasses[DeoptimizationKind] = DeoptimizationBlob.class;
|
||||
wrapperClasses[SafepointKind] = SafepointBlob.class;
|
||||
wrapperClasses[UpcallKind] = UpcallStub.class;
|
||||
if (VM.getVM().isServerCompiler()) {
|
||||
wrapperClasses[ExceptionKind] = ExceptionBlob.class;
|
||||
wrapperClasses[UncommonTrapKind] = UncommonTrapBlob.class;
|
||||
}
|
||||
}
|
||||
|
||||
static {
|
||||
@ -86,6 +138,11 @@ public class CodeBlob extends VMObject {
|
||||
});
|
||||
}
|
||||
|
||||
public static Class<?> getClassFor(Address addr) {
|
||||
CodeBlob cb = new CodeBlob(addr);
|
||||
return wrapperClasses[cb.getKind()];
|
||||
}
|
||||
|
||||
public Address headerBegin() { return getAddress(); }
|
||||
|
||||
public Address headerEnd() { return getAddress().addOffsetTo(getHeaderSize()); }
|
||||
@ -124,6 +181,10 @@ public class CodeBlob extends VMObject {
|
||||
return CStringUtilities.getString(nameField.getValue(addr));
|
||||
}
|
||||
|
||||
public int getKind() {
|
||||
return (int) kindField.getValue(addr);
|
||||
}
|
||||
|
||||
/** OopMap for frame; can return null if none available */
|
||||
public ImmutableOopMapSet getOopMaps() {
|
||||
Address value = oopMapsField.getValue(addr);
|
||||
@ -135,27 +196,29 @@ public class CodeBlob extends VMObject {
|
||||
|
||||
|
||||
// Typing
|
||||
public boolean isBufferBlob() { return false; }
|
||||
public boolean isBufferBlob() { return getKind() == BufferKind; }
|
||||
|
||||
public boolean isCompiled() { return false; }
|
||||
public boolean isNMethod() { return getKind() == NMethodKind; }
|
||||
|
||||
public boolean isNMethod() { return false; }
|
||||
public boolean isRuntimeStub() { return getKind() == RuntimeStubKind; }
|
||||
|
||||
public boolean isRuntimeStub() { return false; }
|
||||
public boolean isUpcallStub() { return getKind() == UpcallKind; }
|
||||
|
||||
public boolean isUpcallStub() { return false; }
|
||||
public boolean isDeoptimizationBlob() { return getKind() == DeoptimizationKind; }
|
||||
|
||||
public boolean isDeoptimizationStub() { return false; }
|
||||
public boolean isUncommonTrapBlob() { return getKind() == UncommonTrapKind; }
|
||||
|
||||
public boolean isUncommonTrapStub() { return false; }
|
||||
public boolean isExceptionBlob() { return getKind() == ExceptionKind; }
|
||||
|
||||
public boolean isExceptionStub() { return false; }
|
||||
public boolean isSafepointBlob() { return getKind() == SafepointKind; }
|
||||
|
||||
public boolean isSafepointStub() { return false; }
|
||||
public boolean isAdapterBlob() { return getKind() == AdapterKind; }
|
||||
|
||||
public boolean isAdapterBlob() { return false; }
|
||||
public boolean isMHAdapterBlob() { return getKind() == MHAdapterKind; }
|
||||
|
||||
// Fine grain nmethod support: isNmethod() == isJavaMethod() || isNativeMethod() || isOSRMethod()
|
||||
public boolean isVtableBlob() { return getKind() == VtableKind; }
|
||||
|
||||
// Fine grain nmethod support: isNMethod() == isJavaMethod() || isNativeMethod() || isOSRMethod()
|
||||
public boolean isJavaMethod() { return false; }
|
||||
|
||||
public boolean isNativeMethod() { return false; }
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2025, 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
|
||||
@ -35,7 +35,6 @@ import sun.jvm.hotspot.utilities.Observer;
|
||||
|
||||
public class CodeCache {
|
||||
private static GrowableArray<CodeHeap> heapArray;
|
||||
private static VirtualConstructor virtualConstructor;
|
||||
|
||||
static {
|
||||
VM.registerVMInitializedObserver(new Observer() {
|
||||
@ -51,22 +50,6 @@ public class CodeCache {
|
||||
// Get array of CodeHeaps
|
||||
AddressField heapsField = type.getAddressField("_heaps");
|
||||
heapArray = GrowableArray.create(heapsField.getValue(), new StaticBaseConstructor<>(CodeHeap.class));
|
||||
|
||||
virtualConstructor = new VirtualConstructor(db);
|
||||
// Add mappings for all possible CodeBlob subclasses
|
||||
virtualConstructor.addMapping("BufferBlob", BufferBlob.class);
|
||||
virtualConstructor.addMapping("nmethod", NMethod.class);
|
||||
virtualConstructor.addMapping("RuntimeStub", RuntimeStub.class);
|
||||
virtualConstructor.addMapping("AdapterBlob", AdapterBlob.class);
|
||||
virtualConstructor.addMapping("MethodHandlesAdapterBlob", MethodHandlesAdapterBlob.class);
|
||||
virtualConstructor.addMapping("VtableBlob", VtableBlob.class);
|
||||
virtualConstructor.addMapping("UpcallStub", UpcallStub.class);
|
||||
virtualConstructor.addMapping("SafepointBlob", SafepointBlob.class);
|
||||
virtualConstructor.addMapping("DeoptimizationBlob", DeoptimizationBlob.class);
|
||||
if (VM.getVM().isServerCompiler()) {
|
||||
virtualConstructor.addMapping("ExceptionBlob", ExceptionBlob.class);
|
||||
virtualConstructor.addMapping("UncommonTrapBlob", UncommonTrapBlob.class);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean contains(Address p) {
|
||||
@ -80,8 +63,8 @@ public class CodeCache {
|
||||
|
||||
/** When VM.getVM().isDebugging() returns true, this behaves like
|
||||
findBlobUnsafe */
|
||||
public CodeBlob findBlob(Address start) {
|
||||
CodeBlob result = findBlobUnsafe(start);
|
||||
public CodeBlob findBlob(Address addr) {
|
||||
CodeBlob result = findBlobUnsafe(addr);
|
||||
if (result == null) return null;
|
||||
if (VM.getVM().isDebugging()) {
|
||||
return result;
|
||||
@ -91,11 +74,10 @@ public class CodeCache {
|
||||
return result;
|
||||
}
|
||||
|
||||
public CodeBlob findBlobUnsafe(Address start) {
|
||||
CodeBlob result = null;
|
||||
public CodeBlob findBlobUnsafe(Address addr) {
|
||||
CodeHeap containing_heap = null;
|
||||
for (int i = 0; i < heapArray.length(); ++i) {
|
||||
if (heapArray.at(i).contains(start)) {
|
||||
if (heapArray.at(i).contains(addr)) {
|
||||
containing_heap = heapArray.at(i);
|
||||
break;
|
||||
}
|
||||
@ -104,76 +86,52 @@ public class CodeCache {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
result = (CodeBlob) virtualConstructor.instantiateWrapperFor(containing_heap.findStart(start));
|
||||
}
|
||||
catch (WrongTypeException wte) {
|
||||
Address cbAddr = null;
|
||||
try {
|
||||
cbAddr = containing_heap.findStart(start);
|
||||
}
|
||||
catch (Exception findEx) {
|
||||
findEx.printStackTrace();
|
||||
}
|
||||
Address cbStart = containing_heap.findStart(addr);
|
||||
if (cbStart == null) return null;
|
||||
|
||||
return createCodeBlobWrapper(cbStart, addr);
|
||||
}
|
||||
|
||||
// cbStart - address of a code blob
|
||||
// addr - address inside of a code blob
|
||||
public CodeBlob createCodeBlobWrapper(Address cbStart, Address addr) {
|
||||
Class<?> cbClass = CodeBlob.getClassFor(cbStart);
|
||||
if (cbClass == null) {
|
||||
String message = "Couldn't deduce type of CodeBlob ";
|
||||
if (cbAddr != null) {
|
||||
message = message + "@" + cbAddr + " ";
|
||||
}
|
||||
message = message + "for PC=" + start;
|
||||
message = message + "@" + cbStart + " ";
|
||||
message = message + "for PC=" + addr;
|
||||
|
||||
throw new RuntimeException(message, wte);
|
||||
throw new RuntimeException(message);
|
||||
}
|
||||
if (result == null) return null;
|
||||
CodeBlob result = (CodeBlob) VMObjectFactory.newObject(cbClass, cbStart);
|
||||
if (Assert.ASSERTS_ENABLED) {
|
||||
// The pointer to the HeapBlock that contains this blob is outside of the blob,
|
||||
// but it shouldn't be an error to find a blob based on the pointer to the HeapBlock.
|
||||
// The heap block header is padded out to an 8-byte boundary. See heap.hpp. The
|
||||
// simplest way to compute the header size is just 2 * addressSize.
|
||||
Assert.that(result.blobContains(start) ||
|
||||
result.blobContains(start.addOffsetTo(2 * VM.getVM().getAddressSize())),
|
||||
Assert.that(result.blobContains(addr) ||
|
||||
result.blobContains(addr.addOffsetTo(2 * VM.getVM().getAddressSize())),
|
||||
"found wrong CodeBlob");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public NMethod findNMethod(Address start) {
|
||||
CodeBlob cb = findBlob(start);
|
||||
public NMethod findNMethod(Address addr) {
|
||||
CodeBlob cb = findBlob(addr);
|
||||
if (Assert.ASSERTS_ENABLED) {
|
||||
Assert.that(cb == null || cb.isNMethod(), "did not find an nmethod");
|
||||
}
|
||||
return (NMethod) cb;
|
||||
}
|
||||
|
||||
public NMethod findNMethodUnsafe(Address start) {
|
||||
CodeBlob cb = findBlobUnsafe(start);
|
||||
public NMethod findNMethodUnsafe(Address addr) {
|
||||
CodeBlob cb = findBlobUnsafe(addr);
|
||||
if (Assert.ASSERTS_ENABLED) {
|
||||
Assert.that(cb == null || cb.isNMethod(), "did not find an nmethod");
|
||||
}
|
||||
return (NMethod) cb;
|
||||
}
|
||||
|
||||
/** Routine for instantiating appropriately-typed wrapper for a
|
||||
CodeBlob. Used by CodeCache, Runtime1, etc. */
|
||||
public CodeBlob createCodeBlobWrapper(Address codeBlobAddr) {
|
||||
try {
|
||||
return (CodeBlob) virtualConstructor.instantiateWrapperFor(codeBlobAddr);
|
||||
}
|
||||
catch (Exception e) {
|
||||
String message = "Unable to deduce type of CodeBlob from address " + codeBlobAddr +
|
||||
" (expected type nmethod, RuntimeStub, VtableBlob, ";
|
||||
if (VM.getVM().isClientCompiler()) {
|
||||
message = message + " or ";
|
||||
}
|
||||
message = message + "SafepointBlob";
|
||||
if (VM.getVM().isServerCompiler()) {
|
||||
message = message + ", DeoptimizationBlob, or ExceptionBlob";
|
||||
}
|
||||
message = message + ")";
|
||||
throw new RuntimeException(message);
|
||||
}
|
||||
}
|
||||
|
||||
public void iterate(CodeCacheVisitor visitor) {
|
||||
visitor.prologue(lowBound(), highBound());
|
||||
for (int i = 0; i < heapArray.length(); ++i) {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2025, 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
|
||||
@ -49,8 +49,4 @@ public class DeoptimizationBlob extends SingletonBlob {
|
||||
public DeoptimizationBlob(Address addr) {
|
||||
super(addr);
|
||||
}
|
||||
|
||||
public boolean isDeoptimizationStub() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2025, 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
|
||||
@ -52,8 +52,4 @@ public class ExceptionBlob extends SingletonBlob {
|
||||
public ExceptionBlob(Address addr) {
|
||||
super(addr);
|
||||
}
|
||||
|
||||
public boolean isExceptionStub() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 2025, 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
|
||||
@ -50,10 +50,6 @@ public class MethodHandlesAdapterBlob extends AdapterBlob {
|
||||
super(addr);
|
||||
}
|
||||
|
||||
public boolean isMethodHandlesAdapterBlob() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return "MethodHandlesAdapterBlob: " + super.getName();
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2025, 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
|
||||
@ -117,7 +117,6 @@ public class NMethod extends CodeBlob {
|
||||
}
|
||||
|
||||
// Type info
|
||||
public boolean isNMethod() { return true; }
|
||||
public boolean isJavaMethod() { return !getMethod().isNative(); }
|
||||
public boolean isNativeMethod() { return getMethod().isNative(); }
|
||||
public boolean isOSRMethod() { return getEntryBCI() != VM.getVM().getInvocationEntryBCI(); }
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2025, 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
|
||||
@ -53,10 +53,6 @@ public class RuntimeStub extends RuntimeBlob {
|
||||
super(addr);
|
||||
}
|
||||
|
||||
public boolean isRuntimeStub() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean callerMustGCArguments() {
|
||||
return callerMustGCArgumentsField.getValue(addr) != 0;
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2025, 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
|
||||
@ -51,8 +51,4 @@ public class SafepointBlob extends SingletonBlob {
|
||||
public SafepointBlob(Address addr) {
|
||||
super(addr);
|
||||
}
|
||||
|
||||
public boolean isSafepointStub() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2025, 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
|
||||
@ -49,6 +49,4 @@ public class SingletonBlob extends RuntimeBlob {
|
||||
public SingletonBlob(Address addr) {
|
||||
super(addr);
|
||||
}
|
||||
|
||||
public boolean isSingletonBlob() { return true; }
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2025, 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
|
||||
@ -51,8 +51,4 @@ public class UncommonTrapBlob extends SingletonBlob {
|
||||
public UncommonTrapBlob(Address addr) {
|
||||
super(addr);
|
||||
}
|
||||
|
||||
public boolean isUncommonTrapStub() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2024, 2025, 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
|
||||
@ -85,10 +85,6 @@ public class UpcallStub extends RuntimeBlob {
|
||||
return lastJavaPCField.getValue(getJavaFrameAnchor(frame));
|
||||
}
|
||||
|
||||
public boolean isUpcallStub() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static class FrameData extends VMObject {
|
||||
|
||||
private static AddressField jfaField;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, NTT DATA.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -33,10 +33,6 @@ public class VtableBlob extends BufferBlob {
|
||||
super(addr);
|
||||
}
|
||||
|
||||
public boolean isVtableBlob() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return "VtableBlob: " + super.getName();
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2025, 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
|
||||
@ -108,7 +108,7 @@ public class CodeHeap extends VMObject {
|
||||
while (ptr != null && ptr.lessThan(end())) {
|
||||
try {
|
||||
// Use findStart to get a pointer inside blob other findBlob asserts
|
||||
CodeBlob blob = cache.createCodeBlobWrapper(findStart(ptr));
|
||||
CodeBlob blob = cache.createCodeBlobWrapper(findStart(ptr), ptr);
|
||||
if (blob != null) {
|
||||
visitor.visit(blob);
|
||||
if (blob == lastBlob) {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2025, 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
|
||||
@ -162,16 +162,24 @@ public class PStack extends Tool {
|
||||
}
|
||||
} else if (cb.isBufferBlob()) {
|
||||
out.println("<StubRoutines>");
|
||||
} else if (cb.isAdapterBlob()) {
|
||||
out.println("<AdapterBlob>");
|
||||
} else if (cb.isVtableBlob()) {
|
||||
out.println("<VtableBlob>");
|
||||
} else if (cb.isMHAdapterBlob()) {
|
||||
out.println("<MethodHandlesAdapterBlob>");
|
||||
} else if (cb.isRuntimeStub()) {
|
||||
out.println("<RuntimeStub>");
|
||||
} else if (cb.isDeoptimizationStub()) {
|
||||
out.println("<DeoptimizationStub>");
|
||||
} else if (cb.isUncommonTrapStub()) {
|
||||
out.println("<UncommonTrap>");
|
||||
} else if (cb.isExceptionStub()) {
|
||||
out.println("<ExceptionStub>");
|
||||
} else if (cb.isSafepointStub()) {
|
||||
out.println("<SafepointStub>");
|
||||
} else if (cb.isUpcallStub()) {
|
||||
out.println("<UpcallStub>");
|
||||
} else if (cb.isDeoptimizationBlob()) {
|
||||
out.println("<DeoptimizationBlob>");
|
||||
} else if (cb.isUncommonTrapBlob()) {
|
||||
out.println("<UncommonTrapBlob>");
|
||||
} else if (cb.isExceptionBlob()) {
|
||||
out.println("<ExceptionBlob>");
|
||||
} else if (cb.isSafepointBlob()) {
|
||||
out.println("<SafepointBlob>");
|
||||
} else {
|
||||
out.println("<Unknown code blob>");
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user