(original) (raw)

src/share/vm/oops/methodData.hpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File

*** old/src/share/vm/oops/methodData.hpp Wed Sep 16 15🔞49 2015** --- new/src/share/vm/oops/methodData.hpp Wed Sep 16 15🔞48 2015


*** 538,547 **** --- 538,551 ---- protected: enum { // null_seen: // saw a null operand (cast/aastore/instanceof) null_seen_flag = DataLayout::first_flag + 0 + #if INCLUDE_JVMCI + // bytecode threw any exception + , exception_seen_flag = null_seen_flag + 1 + #endif }; enum { bit_cell_count = 0 }; // no additional data fields needed. public: BitData(DataLayout* layout) : ProfileData(layout) { }


*** 561,570 **** --- 565,579 ---- // The null_seen flag bit is specially known to the interpreter. // Consulting it allows the compiler to avoid setting up null_check traps. bool null_seen() { return flag_at(null_seen_flag); } void set_null_seen() { set_flag_at(null_seen_flag); }

+ #if INCLUDE_JVMCI + // true if an exception was thrown at the specific BCI + bool exception_seen() { return flag_at(exception_seen_flag); } + void set_exception_seen() { set_flag_at(exception_seen_flag); } + #endif

// Code generation support
static int null_seen_byte_constant() {
  return flag_number_to_byte_constant(null_seen_flag);
}

*** 1164,1174 **** --- 1173,1198 ---- // that the check is reached, and a series of (Klass*, count) pairs // which are used to store a type profile for the receiver of the check. class ReceiverTypeData : public CounterData { protected: enum { + #if INCLUDE_JVMCI + // Description of the different counters + // ReceiverTypeData for instanceof/checkcast/aastore: + // C1/C2: count is incremented on type overflow and decremented for failed type checks + // JVMCI: count decremented for failed type checks and nonprofiled_count is incremented on type overflow + // TODO (chaeubl): in fact, JVMCI should also increment the count for failed type checks to mimic the C1/C2 behavior + // VirtualCallData for invokevirtual/invokeinterface: + // C1/C2: count is incremented on type overflow + // JVMCI: count is incremented on type overflow, nonprofiled_count is incremented on method overflow + + // JVMCI is interested in knowing the percentage of type checks involving a type not explicitly in the profile + nonprofiled_count_off_set = counter_cell_count, + receiver0_offset, + #else receiver0_offset = counter_cell_count, + #endif count0_offset, receiver_type_row_cell_count = (count0_offset + 1) - receiver0_offset };

public:


*** 1179,1189 **** --- 1203,1213 ---- }

virtual bool is_ReceiverTypeData() const { return true; }

static int static_cell_count() {

! return counter_cell_count + (uint) TypeProfileWidth * receiver_type_row_cell_count JVMCI_ONLY(+ 1); }

virtual int cell_count() const {
  return static_cell_count();
}

*** 1241,1259 **** --- 1265,1301 ---- // We do sorting a profiling info (ciCallProfile) for compilation. // set_count(0); set_receiver(row, NULL); set_receiver_count(row, 0); + #if INCLUDE_JVMCI + if (!this->is_VirtualCallData()) { + // if this is a ReceiverTypeData for JVMCI, the nonprofiled_count + // must also be reset (see "Description of the different counters" above) + set_nonprofiled_count(0); + } + #endif }

// Code generation support
static ByteSize receiver_offset(uint row) {
  return cell_offset(receiver_cell_index(row));
}
static ByteSize receiver_count_offset(uint row) {
  return cell_offset(receiver_count_cell_index(row));
}

+ #if INCLUDE_JVMCI + static ByteSize nonprofiled_receiver_count_offset() { + return cell_offset(nonprofiled_count_off_set); + } + uint nonprofiled_count() const { + return uint_at(nonprofiled_count_off_set); + } + void set_nonprofiled_count(uint count) { + set_uint_at(nonprofiled_count_off_set, count); + } + #endif static ByteSize receiver_type_data_size() { return cell_offset(static_cell_count()); }

// GC support

*** 1314,1324 **** --- 1356,1366 ---- virtual bool is_VirtualCallData() const { return true; }

static int static_cell_count() {
  // At this point we could add more profile state, e.g., for arguments.
  // But for now it's the same size as the base record type.

! return ReceiverTypeData::static_cell_count() JVMCI_ONLY(+ (uint) MethodProfileWidth * receiver_type_row_cell_count); }

virtual int cell_count() const {
  return static_cell_count();
}

*** 1336,1345 **** --- 1378,1445 ---- static DataLayout* advance(DataLayout* layout) { return (DataLayout*) (((address)layout) + (ssize_t)VirtualCallData::virtual_call_data_size_in_bytes()); } #endif // CC_INTERP

+ #if INCLUDE_JVMCI + static ByteSize method_offset(uint row) { + return cell_offset(method_cell_index(row)); + } + static ByteSize method_count_offset(uint row) { + return cell_offset(method_count_cell_index(row)); + } + static int method_cell_index(uint row) { + return receiver0_offset + (row + TypeProfileWidth) * receiver_type_row_cell_count; + } + static int method_count_cell_index(uint row) { + return count0_offset + (row + TypeProfileWidth) * receiver_type_row_cell_count; + } + static uint method_row_limit() { + return MethodProfileWidth; + } + + Method method(uint row) const {* + assert(row < method_row_limit(), "oob");** **+** **+ Method* method = (Method*)intptr_at(method_cell_index(row));** **+ assert(method == NULL || method->is_method(), "must be"); + return method; + } + + uint method_count(uint row) const { + assert(row < method_row_limit(), "oob"); + return uint_at(method_count_cell_index(row)); + } + + void set_method(uint row, Method m) {* + assert((uint)row < method_row_limit(), "oob"); + set_intptr_at(method_cell_index(row), (uintptr_t)m); + } + + void set_method_count(uint row, uint count) { + assert(row < method_row_limit(), "oob"); + set_uint_at(method_count_cell_index(row), count); + } + + void clear_method_row(uint row) { + assert(row < method_row_limit(), "oob"); + // Clear total count - indicator of polymorphic call site (see comment for clear_row() in ReceiverTypeData). + set_nonprofiled_count(0); + set_method(row, NULL); + set_method_count(row, 0); + } + + // GC support + virtual void clean_weak_klass_links(BoolObjectClosure is_alive_closure);* + + // Redefinition support + virtual void clean_weak_method_links(); + #endif + + #if INCLUDE_JVMCI + void print_method_data_on(outputStream st) const;* + #endif void print_data_on(outputStream* st, const char* extra = NULL) const; };

// VirtualCallTypeData //


*** 2051,2064 **** --- 2151,2165 ---- public: static MethodData* allocate(ClassLoaderData* loader_data, methodHandle method, TRAPS); MethodData() : _extra_data_lock(Monitor::leaf, "MDO extra data lock") {}; // For ciMethodData

bool is_methodData() const volatile { return true; }

+ void initialize();

// Whole-method sticky bits and flags
enum {

! _trap_hist_limit = 22 JVMCI_ONLY(+5), // decoupled from Deoptimization::Reason_LIMIT _trap_hist_mask = max_jubyte, _extra_data_count = 4 // extra DataLayout headers, for trap history }; // Public flag values private: uint _nof_decompiles; // count of all nmethod removals


*** 2102,2111 **** --- 2203,2217 ---- short _num_blocks; // Does this method contain anything worth profiling? enum WouldProfile {unknown, no_profile, profile}; WouldProfile _would_profile;

+ #if INCLUDE_JVMCI + // Support for HotSpotMethodData.setCompiledIRSize(int) + int _jvmci_ir_size; + #endif + // Size of _data array in bytes. (Excludes header and extra_data fields.) int _data_size;

// data index for the area dedicated to parameters. -1 if no
// parameter profiling.

*** 2380,2410 **** --- 2486,2512 ---- int extra_data_size() const { return (address)extra_data_limit() - (address)extra_data_base(); } static DataLayout* next_extra(DataLayout* dp);

// 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; } // For loops: static uint trap_reason_limit() { return _trap_hist_limit; } static uint trap_count_limit() { return _trap_hist_mask; } uint inc_trap_count(int reason) { // Count another trap, anywhere in this method. assert(reason >= 0, "must be single trap"); if ((uint)reason < _trap_hist_limit) { + 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); } ~~*} else {~~ ~~// Could not represent the count in the histogram.~~ return (++_nof_overflow_traps); ~~}**~~ }

uint overflow_trap_count() const {
  return _nof_overflow_traps;
}

*** 2444,2453 **** --- 2546,2559 ---- // Support for code generation static ByteSize data_offset() { return byte_offset_of(MethodData, _data[0]); }

+ static ByteSize trap_history_offset() { + return byte_offset_of(MethodData, _trap_hist._array); + } + static ByteSize invocation_counter_offset() { return byte_offset_of(MethodData, _invocation_counter); }

static ByteSize backedge_counter_offset() {

src/share/vm/oops/methodData.hpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File