mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 06:45:07 +02:00
8252049: Native memory leak in ciMethodData ctor
Reviewed-by: kbarrett, coleenp
This commit is contained in:
parent
fab6158c19
commit
044616bd71
8 changed files with 132 additions and 110 deletions
|
@ -37,46 +37,21 @@
|
||||||
// ------------------------------------------------------------------
|
// ------------------------------------------------------------------
|
||||||
// ciMethodData::ciMethodData
|
// ciMethodData::ciMethodData
|
||||||
//
|
//
|
||||||
ciMethodData::ciMethodData(MethodData* md) : ciMetadata(md) {
|
ciMethodData::ciMethodData(MethodData* md)
|
||||||
assert(md != NULL, "no null method data");
|
: ciMetadata(md),
|
||||||
Copy::zero_to_words((HeapWord*) &_orig, sizeof(_orig) / sizeof(HeapWord));
|
_data_size(0), _extra_data_size(0), _data(NULL),
|
||||||
_data = NULL;
|
|
||||||
_data_size = 0;
|
|
||||||
_extra_data_size = 0;
|
|
||||||
_current_mileage = 0;
|
|
||||||
_invocation_counter = 0;
|
|
||||||
_backedge_counter = 0;
|
|
||||||
_state = empty_state;
|
|
||||||
_saw_free_extra_data = false;
|
|
||||||
// Set an initial hint. Don't use set_hint_di() because
|
// Set an initial hint. Don't use set_hint_di() because
|
||||||
// first_di() may be out of bounds if data_size is 0.
|
// first_di() may be out of bounds if data_size is 0.
|
||||||
_hint_di = first_di();
|
_hint_di(first_di()),
|
||||||
|
_state(empty_state),
|
||||||
|
_saw_free_extra_data(false),
|
||||||
// Initialize the escape information (to "don't know.");
|
// Initialize the escape information (to "don't know.");
|
||||||
_eflags = _arg_local = _arg_stack = _arg_returned = 0;
|
_eflags(0), _arg_local(0), _arg_stack(0), _arg_returned(0),
|
||||||
_parameters = NULL;
|
_current_mileage(0),
|
||||||
}
|
_invocation_counter(0),
|
||||||
|
_backedge_counter(0),
|
||||||
// ------------------------------------------------------------------
|
_orig(),
|
||||||
// ciMethodData::ciMethodData
|
_parameters(NULL) {}
|
||||||
//
|
|
||||||
// No MethodData*.
|
|
||||||
ciMethodData::ciMethodData() : ciMetadata(NULL) {
|
|
||||||
Copy::zero_to_words((HeapWord*) &_orig, sizeof(_orig) / sizeof(HeapWord));
|
|
||||||
_data = NULL;
|
|
||||||
_data_size = 0;
|
|
||||||
_extra_data_size = 0;
|
|
||||||
_current_mileage = 0;
|
|
||||||
_invocation_counter = 0;
|
|
||||||
_backedge_counter = 0;
|
|
||||||
_state = empty_state;
|
|
||||||
_saw_free_extra_data = false;
|
|
||||||
// Set an initial hint. Don't use set_hint_di() because
|
|
||||||
// first_di() may be out of bounds if data_size is 0.
|
|
||||||
_hint_di = first_di();
|
|
||||||
// Initialize the escape information (to "don't know.");
|
|
||||||
_eflags = _arg_local = _arg_stack = _arg_returned = 0;
|
|
||||||
_parameters = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for entries that reference an unloaded method
|
// Check for entries that reference an unloaded method
|
||||||
class PrepareExtraDataClosure : public CleanExtraDataClosure {
|
class PrepareExtraDataClosure : public CleanExtraDataClosure {
|
||||||
|
@ -226,7 +201,8 @@ void ciMethodData::load_data() {
|
||||||
// _extra_data_size = extra_data_limit - extra_data_base
|
// _extra_data_size = extra_data_limit - extra_data_base
|
||||||
// total_size = _data_size + _extra_data_size
|
// total_size = _data_size + _extra_data_size
|
||||||
// args_data_limit = data_base + total_size - parameter_data_size
|
// args_data_limit = data_base + total_size - parameter_data_size
|
||||||
Copy::disjoint_words_atomic((HeapWord*) mdo,
|
static_assert(sizeof(_orig) % HeapWordSize == 0, "align");
|
||||||
|
Copy::disjoint_words_atomic((HeapWord*) &mdo->_compiler_counters,
|
||||||
(HeapWord*) &_orig,
|
(HeapWord*) &_orig,
|
||||||
sizeof(_orig) / HeapWordSize);
|
sizeof(_orig) / HeapWordSize);
|
||||||
Arena* arena = CURRENT_ENV->arena();
|
Arena* arena = CURRENT_ENV->arena();
|
||||||
|
|
|
@ -390,10 +390,10 @@ private:
|
||||||
u_char _saw_free_extra_data;
|
u_char _saw_free_extra_data;
|
||||||
|
|
||||||
// Support for interprocedural escape analysis
|
// Support for interprocedural escape analysis
|
||||||
intx _eflags; // flags on escape information
|
intx _eflags; // flags on escape information
|
||||||
intx _arg_local; // bit set of non-escaping arguments
|
intx _arg_local; // bit set of non-escaping arguments
|
||||||
intx _arg_stack; // bit set of stack-allocatable arguments
|
intx _arg_stack; // bit set of stack-allocatable arguments
|
||||||
intx _arg_returned; // bit set of returned arguments
|
intx _arg_returned; // bit set of returned arguments
|
||||||
|
|
||||||
// Maturity of the oop when the snapshot is taken.
|
// Maturity of the oop when the snapshot is taken.
|
||||||
int _current_mileage;
|
int _current_mileage;
|
||||||
|
@ -405,17 +405,15 @@ private:
|
||||||
int _backedge_counter;
|
int _backedge_counter;
|
||||||
|
|
||||||
// Coherent snapshot of original header.
|
// Coherent snapshot of original header.
|
||||||
MethodData _orig;
|
MethodData::CompilerCounters _orig;
|
||||||
|
|
||||||
// Area dedicated to parameters. NULL if no parameter profiling for
|
// Area dedicated to parameters. NULL if no parameter profiling for this method.
|
||||||
// this method.
|
|
||||||
DataLayout* _parameters;
|
DataLayout* _parameters;
|
||||||
int parameters_size() const {
|
int parameters_size() const {
|
||||||
return _parameters == NULL ? 0 : parameters_type_data()->size_in_bytes();
|
return _parameters == NULL ? 0 : parameters_type_data()->size_in_bytes();
|
||||||
}
|
}
|
||||||
|
|
||||||
ciMethodData(MethodData* md);
|
ciMethodData(MethodData* md = NULL);
|
||||||
ciMethodData();
|
|
||||||
|
|
||||||
// Accessors
|
// Accessors
|
||||||
int data_size() const { return _data_size; }
|
int data_size() const { return _data_size; }
|
||||||
|
@ -544,8 +542,8 @@ public:
|
||||||
uint trap_count(int reason) const {
|
uint trap_count(int reason) const {
|
||||||
return _orig.trap_count(reason);
|
return _orig.trap_count(reason);
|
||||||
}
|
}
|
||||||
uint trap_reason_limit() const { return _orig.trap_reason_limit(); }
|
uint trap_reason_limit() const { return MethodData::trap_reason_limit(); }
|
||||||
uint trap_count_limit() const { return _orig.trap_count_limit(); }
|
uint trap_count_limit() const { return MethodData::trap_count_limit(); }
|
||||||
|
|
||||||
// Helpful query functions that decode trap_state.
|
// Helpful query functions that decode trap_state.
|
||||||
int has_trap_at(ciProfileData* data, int reason);
|
int has_trap_at(ciProfileData* data, int reason);
|
||||||
|
|
|
@ -286,7 +286,7 @@ class CompileReplay : public StackObj {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int actual_size = sizeof(MethodData);
|
int actual_size = sizeof(MethodData::CompilerCounters);
|
||||||
char *result = NEW_RESOURCE_ARRAY(char, actual_size);
|
char *result = NEW_RESOURCE_ARRAY(char, actual_size);
|
||||||
int i = 0;
|
int i = 0;
|
||||||
if (read_size != actual_size) {
|
if (read_size != actual_size) {
|
||||||
|
|
|
@ -237,10 +237,10 @@
|
||||||
nonstatic_field(MethodData, _data_size, int) \
|
nonstatic_field(MethodData, _data_size, int) \
|
||||||
nonstatic_field(MethodData, _data[0], intptr_t) \
|
nonstatic_field(MethodData, _data[0], intptr_t) \
|
||||||
nonstatic_field(MethodData, _parameters_type_data_di, int) \
|
nonstatic_field(MethodData, _parameters_type_data_di, int) \
|
||||||
nonstatic_field(MethodData, _nof_decompiles, uint) \
|
nonstatic_field(MethodData, _compiler_counters._nof_decompiles, uint) \
|
||||||
nonstatic_field(MethodData, _nof_overflow_recompiles, uint) \
|
nonstatic_field(MethodData, _compiler_counters._nof_overflow_recompiles, uint) \
|
||||||
nonstatic_field(MethodData, _nof_overflow_traps, uint) \
|
nonstatic_field(MethodData, _compiler_counters._nof_overflow_traps, uint) \
|
||||||
nonstatic_field(MethodData, _trap_hist._array[0], u1) \
|
nonstatic_field(MethodData, _compiler_counters._trap_hist._array[0], u1) \
|
||||||
nonstatic_field(MethodData, _eflags, intx) \
|
nonstatic_field(MethodData, _eflags, intx) \
|
||||||
nonstatic_field(MethodData, _arg_local, intx) \
|
nonstatic_field(MethodData, _arg_local, intx) \
|
||||||
nonstatic_field(MethodData, _arg_stack, intx) \
|
nonstatic_field(MethodData, _arg_stack, intx) \
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "precompiled.hpp"
|
#include "precompiled.hpp"
|
||||||
|
#include "ci/ciMethodData.hpp"
|
||||||
#include "classfile/systemDictionary.hpp"
|
#include "classfile/systemDictionary.hpp"
|
||||||
#include "compiler/compilationPolicy.hpp"
|
#include "compiler/compilationPolicy.hpp"
|
||||||
#include "compiler/compilerOracle.hpp"
|
#include "compiler/compilerOracle.hpp"
|
||||||
|
@ -656,7 +657,7 @@ MethodData* MethodData::allocate(ClassLoaderData* loader_data, const methodHandl
|
||||||
int size = MethodData::compute_allocation_size_in_words(method);
|
int size = MethodData::compute_allocation_size_in_words(method);
|
||||||
|
|
||||||
return new (loader_data, size, MetaspaceObj::MethodDataType, THREAD)
|
return new (loader_data, size, MetaspaceObj::MethodDataType, THREAD)
|
||||||
MethodData(method, size, THREAD);
|
MethodData(method);
|
||||||
}
|
}
|
||||||
|
|
||||||
int MethodData::bytecode_cell_count(Bytecodes::Code code) {
|
int MethodData::bytecode_cell_count(Bytecodes::Code code) {
|
||||||
|
@ -1202,11 +1203,11 @@ void MethodData::post_initialize(BytecodeStream* stream) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize the MethodData* corresponding to a given method.
|
// Initialize the MethodData* corresponding to a given method.
|
||||||
MethodData::MethodData(const methodHandle& method, int size, TRAPS)
|
MethodData::MethodData(const methodHandle& method)
|
||||||
: _extra_data_lock(Mutex::leaf, "MDO extra data lock"),
|
: _method(method()),
|
||||||
|
_extra_data_lock(Mutex::leaf, "MDO extra data lock"),
|
||||||
|
_compiler_counters(method()),
|
||||||
_parameters_type_data_di(parameters_uninitialized) {
|
_parameters_type_data_di(parameters_uninitialized) {
|
||||||
// Set the method back-pointer.
|
|
||||||
_method = method();
|
|
||||||
initialize();
|
initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1216,7 +1217,6 @@ void MethodData::initialize() {
|
||||||
ResourceMark rm(thread);
|
ResourceMark rm(thread);
|
||||||
|
|
||||||
init();
|
init();
|
||||||
set_creation_mileage(mileage_of(method()));
|
|
||||||
|
|
||||||
// Go through the bytecodes and allocate and initialize the
|
// Go through the bytecodes and allocate and initialize the
|
||||||
// corresponding data cells.
|
// corresponding data cells.
|
||||||
|
@ -1318,14 +1318,8 @@ void MethodData::init() {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Initialize flags and trap history.
|
// Initialize escape flags.
|
||||||
_nof_decompiles = 0;
|
|
||||||
_nof_overflow_recompiles = 0;
|
|
||||||
_nof_overflow_traps = 0;
|
|
||||||
clear_escape_info();
|
clear_escape_info();
|
||||||
assert(sizeof(_trap_hist) % sizeof(HeapWord) == 0, "align");
|
|
||||||
Copy::zero_to_words((HeapWord*) &_trap_hist,
|
|
||||||
sizeof(_trap_hist) / sizeof(HeapWord));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get a measure of how much mileage the method has on it.
|
// Get a measure of how much mileage the method has on it.
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include "oops/oop.hpp"
|
#include "oops/oop.hpp"
|
||||||
#include "runtime/atomic.hpp"
|
#include "runtime/atomic.hpp"
|
||||||
#include "utilities/align.hpp"
|
#include "utilities/align.hpp"
|
||||||
|
#include "utilities/copy.hpp"
|
||||||
|
|
||||||
class BytecodeStream;
|
class BytecodeStream;
|
||||||
|
|
||||||
|
@ -1930,12 +1931,15 @@ class FailedSpeculation: public CHeapObj<mtCompiler> {
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
class ciMethodData;
|
||||||
|
|
||||||
class MethodData : public Metadata {
|
class MethodData : public Metadata {
|
||||||
friend class VMStructs;
|
friend class VMStructs;
|
||||||
friend class JVMCIVMStructs;
|
friend class JVMCIVMStructs;
|
||||||
private:
|
private:
|
||||||
friend class ProfileData;
|
friend class ProfileData;
|
||||||
friend class TypeEntriesAtCall;
|
friend class TypeEntriesAtCall;
|
||||||
|
friend class ciMethodData;
|
||||||
|
|
||||||
// If you add a new field that points to any metaspace object, you
|
// If you add a new field that points to any metaspace object, you
|
||||||
// must add this field to MethodData::metaspace_pointers_do().
|
// must add this field to MethodData::metaspace_pointers_do().
|
||||||
|
@ -1951,10 +1955,9 @@ private:
|
||||||
|
|
||||||
Mutex _extra_data_lock;
|
Mutex _extra_data_lock;
|
||||||
|
|
||||||
MethodData(const methodHandle& method, int size, TRAPS);
|
MethodData(const methodHandle& method);
|
||||||
public:
|
public:
|
||||||
static MethodData* allocate(ClassLoaderData* loader_data, const methodHandle& method, TRAPS);
|
static MethodData* allocate(ClassLoaderData* loader_data, const methodHandle& method, TRAPS);
|
||||||
MethodData() : _extra_data_lock(Mutex::leaf, "MDO extra data lock") {}; // For ciMethodData
|
|
||||||
|
|
||||||
virtual bool is_methodData() const { return true; }
|
virtual bool is_methodData() const { return true; }
|
||||||
void initialize();
|
void initialize();
|
||||||
|
@ -1965,14 +1968,75 @@ public:
|
||||||
_trap_hist_mask = max_jubyte,
|
_trap_hist_mask = max_jubyte,
|
||||||
_extra_data_count = 4 // extra DataLayout headers, for trap history
|
_extra_data_count = 4 // extra DataLayout headers, for trap history
|
||||||
}; // Public flag values
|
}; // Public flag values
|
||||||
|
|
||||||
|
// Compiler-related counters.
|
||||||
|
class CompilerCounters {
|
||||||
|
friend class VMStructs;
|
||||||
|
friend class JVMCIVMStructs;
|
||||||
|
|
||||||
|
int _creation_mileage; // method mileage at MDO creation
|
||||||
|
uint _nof_decompiles; // count of all nmethod removals
|
||||||
|
uint _nof_overflow_recompiles; // recompile count, excluding recomp. bits
|
||||||
|
uint _nof_overflow_traps; // trap count, excluding _trap_hist
|
||||||
|
union {
|
||||||
|
intptr_t _align;
|
||||||
|
u1 _array[JVMCI_ONLY(2 *) MethodData::_trap_hist_limit];
|
||||||
|
} _trap_hist;
|
||||||
|
|
||||||
|
CompilerCounters(int current_mileage) : _creation_mileage(current_mileage), _nof_decompiles(0), _nof_overflow_recompiles(0), _nof_overflow_traps(0) {
|
||||||
|
static_assert(sizeof(_trap_hist) % HeapWordSize == 0, "align");
|
||||||
|
uint size_in_words = sizeof(_trap_hist) / HeapWordSize;
|
||||||
|
Copy::zero_to_words((HeapWord*) &_trap_hist, size_in_words);
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
CompilerCounters(Method* m) : CompilerCounters(MethodData::mileage_of(m)) {}
|
||||||
|
CompilerCounters() : CompilerCounters(0) {} // for ciMethodData
|
||||||
|
|
||||||
|
int creation_mileage() const { return _creation_mileage; }
|
||||||
|
|
||||||
|
// Return (uint)-1 for overflow.
|
||||||
|
uint trap_count(int reason) const {
|
||||||
|
assert((uint)reason < JVMCI_ONLY(2*) _trap_hist_limit, "oob");
|
||||||
|
return (int)((_trap_hist._array[reason]+1) & _trap_hist_mask) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint inc_trap_count(int reason) {
|
||||||
|
// Count another trap, anywhere in this method.
|
||||||
|
assert(reason >= 0, "must be single trap");
|
||||||
|
assert((uint)reason < JVMCI_ONLY(2*) _trap_hist_limit, "oob");
|
||||||
|
uint cnt1 = 1 + _trap_hist._array[reason];
|
||||||
|
if ((cnt1 & _trap_hist_mask) != 0) { // if no counter overflow...
|
||||||
|
_trap_hist._array[reason] = cnt1;
|
||||||
|
return cnt1;
|
||||||
|
} else {
|
||||||
|
return _trap_hist_mask + (++_nof_overflow_traps);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint overflow_trap_count() const {
|
||||||
|
return _nof_overflow_traps;
|
||||||
|
}
|
||||||
|
uint overflow_recompile_count() const {
|
||||||
|
return _nof_overflow_recompiles;
|
||||||
|
}
|
||||||
|
uint inc_overflow_recompile_count() {
|
||||||
|
return ++_nof_overflow_recompiles;
|
||||||
|
}
|
||||||
|
uint decompile_count() const {
|
||||||
|
return _nof_decompiles;
|
||||||
|
}
|
||||||
|
uint inc_decompile_count() {
|
||||||
|
return ++_nof_decompiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Support for code generation
|
||||||
|
static ByteSize trap_history_offset() {
|
||||||
|
return byte_offset_of(CompilerCounters, _trap_hist._array);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint _nof_decompiles; // count of all nmethod removals
|
CompilerCounters _compiler_counters;
|
||||||
uint _nof_overflow_recompiles; // recompile count, excluding recomp. bits
|
|
||||||
uint _nof_overflow_traps; // trap count, excluding _trap_hist
|
|
||||||
union {
|
|
||||||
intptr_t _align;
|
|
||||||
u1 _array[JVMCI_ONLY(2 *) _trap_hist_limit];
|
|
||||||
} _trap_hist;
|
|
||||||
|
|
||||||
// Support for interprocedural escape analysis, from Thomas Kotzmann.
|
// Support for interprocedural escape analysis, from Thomas Kotzmann.
|
||||||
intx _eflags; // flags on escape information
|
intx _eflags; // flags on escape information
|
||||||
|
@ -1980,8 +2044,6 @@ private:
|
||||||
intx _arg_stack; // bit set of stack-allocatable arguments
|
intx _arg_stack; // bit set of stack-allocatable arguments
|
||||||
intx _arg_returned; // bit set of returned arguments
|
intx _arg_returned; // bit set of returned arguments
|
||||||
|
|
||||||
int _creation_mileage; // method mileage at MDO creation
|
|
||||||
|
|
||||||
// How many invocations has this MDO seen?
|
// How many invocations has this MDO seen?
|
||||||
// These counters are used to determine the exact age of MDO.
|
// These counters are used to determine the exact age of MDO.
|
||||||
// We need those because in tiered a method can be concurrently
|
// We need those because in tiered a method can be concurrently
|
||||||
|
@ -2126,8 +2188,7 @@ public:
|
||||||
int size_in_bytes() const { return _size; }
|
int size_in_bytes() const { return _size; }
|
||||||
int size() const { return align_metadata_size(align_up(_size, BytesPerWord)/BytesPerWord); }
|
int size() const { return align_metadata_size(align_up(_size, BytesPerWord)/BytesPerWord); }
|
||||||
|
|
||||||
int creation_mileage() const { return _creation_mileage; }
|
int creation_mileage() const { return _compiler_counters.creation_mileage(); }
|
||||||
void set_creation_mileage(int x) { _creation_mileage = x; }
|
|
||||||
|
|
||||||
int invocation_count() {
|
int invocation_count() {
|
||||||
if (invocation_counter()->carry()) {
|
if (invocation_counter()->carry()) {
|
||||||
|
@ -2302,42 +2363,33 @@ public:
|
||||||
|
|
||||||
// Return (uint)-1 for overflow.
|
// Return (uint)-1 for overflow.
|
||||||
uint trap_count(int reason) const {
|
uint trap_count(int reason) const {
|
||||||
assert((uint)reason < JVMCI_ONLY(2*) _trap_hist_limit, "oob");
|
return _compiler_counters.trap_count(reason);
|
||||||
return (int)((_trap_hist._array[reason]+1) & _trap_hist_mask) - 1;
|
|
||||||
}
|
}
|
||||||
// For loops:
|
// For loops:
|
||||||
static uint trap_reason_limit() { return _trap_hist_limit; }
|
static uint trap_reason_limit() { return _trap_hist_limit; }
|
||||||
static uint trap_count_limit() { return _trap_hist_mask; }
|
static uint trap_count_limit() { return _trap_hist_mask; }
|
||||||
uint inc_trap_count(int reason) {
|
uint inc_trap_count(int reason) {
|
||||||
// Count another trap, anywhere in this method.
|
return _compiler_counters.inc_trap_count(reason);
|
||||||
assert(reason >= 0, "must be single trap");
|
|
||||||
assert((uint)reason < JVMCI_ONLY(2*) _trap_hist_limit, "oob");
|
|
||||||
uint cnt1 = 1 + _trap_hist._array[reason];
|
|
||||||
if ((cnt1 & _trap_hist_mask) != 0) { // if no counter overflow...
|
|
||||||
_trap_hist._array[reason] = cnt1;
|
|
||||||
return cnt1;
|
|
||||||
} else {
|
|
||||||
return _trap_hist_mask + (++_nof_overflow_traps);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint overflow_trap_count() const {
|
uint overflow_trap_count() const {
|
||||||
return _nof_overflow_traps;
|
return _compiler_counters.overflow_trap_count();
|
||||||
}
|
}
|
||||||
uint overflow_recompile_count() const {
|
uint overflow_recompile_count() const {
|
||||||
return _nof_overflow_recompiles;
|
return _compiler_counters.overflow_recompile_count();
|
||||||
}
|
}
|
||||||
void inc_overflow_recompile_count() {
|
uint inc_overflow_recompile_count() {
|
||||||
_nof_overflow_recompiles += 1;
|
return _compiler_counters.inc_overflow_recompile_count();
|
||||||
}
|
}
|
||||||
uint decompile_count() const {
|
uint decompile_count() const {
|
||||||
return _nof_decompiles;
|
return _compiler_counters.decompile_count();
|
||||||
}
|
}
|
||||||
void inc_decompile_count() {
|
uint inc_decompile_count() {
|
||||||
_nof_decompiles += 1;
|
uint dec_count = _compiler_counters.inc_decompile_count();
|
||||||
if (decompile_count() > (uint)PerMethodRecompilationCutoff) {
|
if (dec_count > (uint)PerMethodRecompilationCutoff) {
|
||||||
method()->set_not_compilable("decompile_count > PerMethodRecompilationCutoff", CompLevel_full_optimization);
|
method()->set_not_compilable("decompile_count > PerMethodRecompilationCutoff", CompLevel_full_optimization);
|
||||||
}
|
}
|
||||||
|
return dec_count;
|
||||||
}
|
}
|
||||||
uint tenure_traps() const {
|
uint tenure_traps() const {
|
||||||
return _tenure_traps;
|
return _tenure_traps;
|
||||||
|
@ -2363,7 +2415,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
static ByteSize trap_history_offset() {
|
static ByteSize trap_history_offset() {
|
||||||
return byte_offset_of(MethodData, _trap_hist._array);
|
return byte_offset_of(MethodData, _compiler_counters) + CompilerCounters::trap_history_offset();
|
||||||
}
|
}
|
||||||
|
|
||||||
static ByteSize invocation_counter_offset() {
|
static ByteSize invocation_counter_offset() {
|
||||||
|
|
|
@ -270,10 +270,10 @@ typedef HashtableEntry<InstanceKlass*, mtClass> KlassHashtableEntry;
|
||||||
nonstatic_field(MethodData, _data_size, int) \
|
nonstatic_field(MethodData, _data_size, int) \
|
||||||
nonstatic_field(MethodData, _data[0], intptr_t) \
|
nonstatic_field(MethodData, _data[0], intptr_t) \
|
||||||
nonstatic_field(MethodData, _parameters_type_data_di, int) \
|
nonstatic_field(MethodData, _parameters_type_data_di, int) \
|
||||||
nonstatic_field(MethodData, _nof_decompiles, uint) \
|
nonstatic_field(MethodData, _compiler_counters._nof_decompiles, uint) \
|
||||||
nonstatic_field(MethodData, _nof_overflow_recompiles, uint) \
|
nonstatic_field(MethodData, _compiler_counters._nof_overflow_recompiles, uint) \
|
||||||
nonstatic_field(MethodData, _nof_overflow_traps, uint) \
|
nonstatic_field(MethodData, _compiler_counters._nof_overflow_traps, uint) \
|
||||||
nonstatic_field(MethodData, _trap_hist._array[0], u1) \
|
nonstatic_field(MethodData, _compiler_counters._trap_hist._array[0], u1) \
|
||||||
nonstatic_field(MethodData, _eflags, intx) \
|
nonstatic_field(MethodData, _eflags, intx) \
|
||||||
nonstatic_field(MethodData, _arg_local, intx) \
|
nonstatic_field(MethodData, _arg_local, intx) \
|
||||||
nonstatic_field(MethodData, _arg_stack, intx) \
|
nonstatic_field(MethodData, _arg_stack, intx) \
|
||||||
|
@ -856,7 +856,7 @@ typedef HashtableEntry<InstanceKlass*, mtClass> KlassHashtableEntry;
|
||||||
nonstatic_field(ciMethodData, _arg_stack, intx) \
|
nonstatic_field(ciMethodData, _arg_stack, intx) \
|
||||||
nonstatic_field(ciMethodData, _arg_returned, intx) \
|
nonstatic_field(ciMethodData, _arg_returned, intx) \
|
||||||
nonstatic_field(ciMethodData, _current_mileage, int) \
|
nonstatic_field(ciMethodData, _current_mileage, int) \
|
||||||
nonstatic_field(ciMethodData, _orig, MethodData) \
|
nonstatic_field(ciMethodData, _orig, MethodData::CompilerCounters) \
|
||||||
\
|
\
|
||||||
nonstatic_field(ciField, _holder, ciInstanceKlass*) \
|
nonstatic_field(ciField, _holder, ciInstanceKlass*) \
|
||||||
nonstatic_field(ciField, _name, ciSymbol*) \
|
nonstatic_field(ciField, _name, ciSymbol*) \
|
||||||
|
@ -1264,6 +1264,8 @@ typedef HashtableEntry<InstanceKlass*, mtClass> KlassHashtableEntry;
|
||||||
declare_type(MethodCounters, MetaspaceObj) \
|
declare_type(MethodCounters, MetaspaceObj) \
|
||||||
declare_type(ConstMethod, MetaspaceObj) \
|
declare_type(ConstMethod, MetaspaceObj) \
|
||||||
\
|
\
|
||||||
|
declare_toplevel_type(MethodData::CompilerCounters) \
|
||||||
|
\
|
||||||
declare_toplevel_type(narrowKlass) \
|
declare_toplevel_type(narrowKlass) \
|
||||||
\
|
\
|
||||||
declare_toplevel_type(vtableEntry) \
|
declare_toplevel_type(vtableEntry) \
|
||||||
|
|
|
@ -177,12 +177,12 @@ class HotSpotVMConfig extends HotSpotVMConfigAccess {
|
||||||
final int methodDataSize = getFieldOffset("MethodData::_size", Integer.class, "int");
|
final int methodDataSize = getFieldOffset("MethodData::_size", Integer.class, "int");
|
||||||
final int methodDataDataSize = getFieldOffset("MethodData::_data_size", Integer.class, "int");
|
final int methodDataDataSize = getFieldOffset("MethodData::_data_size", Integer.class, "int");
|
||||||
final int methodDataOopDataOffset = getFieldOffset("MethodData::_data[0]", Integer.class, "intptr_t");
|
final int methodDataOopDataOffset = getFieldOffset("MethodData::_data[0]", Integer.class, "intptr_t");
|
||||||
final int methodDataOopTrapHistoryOffset = getFieldOffset("MethodData::_trap_hist._array[0]", Integer.class, "u1");
|
final int methodDataOopTrapHistoryOffset = getFieldOffset("MethodData::_compiler_counters._trap_hist._array[0]", Integer.class, "u1");
|
||||||
final int methodDataIRSizeOffset = getFieldOffset("MethodData::_jvmci_ir_size", Integer.class, "int");
|
final int methodDataIRSizeOffset = getFieldOffset("MethodData::_jvmci_ir_size", Integer.class, "int");
|
||||||
|
|
||||||
final int methodDataDecompiles = getFieldOffset("MethodData::_nof_decompiles", Integer.class, "uint");
|
final int methodDataDecompiles = getFieldOffset("MethodData::_compiler_counters._nof_decompiles", Integer.class, "uint");
|
||||||
final int methodDataOverflowRecompiles = getFieldOffset("MethodData::_nof_overflow_recompiles", Integer.class, "uint");
|
final int methodDataOverflowRecompiles = getFieldOffset("MethodData::_compiler_counters._nof_overflow_recompiles", Integer.class, "uint");
|
||||||
final int methodDataOverflowTraps = getFieldOffset("MethodData::_nof_overflow_traps", Integer.class, "uint");
|
final int methodDataOverflowTraps = getFieldOffset("MethodData::_compiler_counters._nof_overflow_traps", Integer.class, "uint");
|
||||||
|
|
||||||
final int nmethodCompLevelOffset = getFieldOffset("nmethod::_comp_level", Integer.class, "int");
|
final int nmethodCompLevelOffset = getFieldOffset("nmethod::_comp_level", Integer.class, "int");
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue