< prev index next >

src/share/vm/oops/methodData.hpp

Print this page

        

*** 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 **** } virtual bool is_ReceiverTypeData() const { return true; } static int static_cell_count() { ! return counter_cell_count + (uint) TypeProfileWidth * receiver_type_row_cell_count; } virtual int cell_count() const { return static_cell_count(); } --- 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 // INCLUDE_JVMCI static ByteSize receiver_type_data_size() { return cell_offset(static_cell_count()); } // GC support
*** 1314,1324 **** 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(); } virtual int cell_count() const { return static_cell_count(); } --- 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,1443 ---- 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 // INCLUDE_JVMCI + + void print_method_data_on(outputStream* st) const NOT_JVMCI_RETURN; void print_data_on(outputStream* st, const char* extra = NULL) const; }; // VirtualCallTypeData //
*** 2051,2064 **** 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; } // Whole-method sticky bits and flags enum { ! _trap_hist_limit = 22, // 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 --- 2149,2163 ---- 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 **** --- 2201,2215 ---- 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 **** 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 < _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) { 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; } --- 2484,2510 ---- 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"); ! 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; }
*** 2444,2453 **** --- 2544,2557 ---- // 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() {
< prev index next >