< prev index next >

src/hotspot/share/ci/ciMethod.cpp

Print this page

        

*** 460,469 **** --- 460,515 ---- } #endif // COMPILER1 // ------------------------------------------------------------------ + // ciMethod::saturated_add + // + // Update profile counters with saturating addition + // Wil check and handle the overflow condition + template <typename L, typename R> + int ciMethod::saturated_add(L a, R b) { + jlong src1 = a; + jlong src2 = b; + jlong sum = src1 + src2; + if (sum > max_jint) { + sum = max_jint; + } else if (sum < min_jint) { + sum = min_jint; + } + + return (int)sum; + } + + + // ------------------------------------------------------------------ + // ciMethod::check_overflow + // + // Check whether the profile counter is overflow and update it if true. + // For invoke* it will turn negative values into max_jint, + // and for checkcast/aastore/instanceof turn positive values into min_jint. + int ciMethod::check_overflow(int c, int bci) { + check_is_loaded(); + VM_ENTRY_MARK; + + BytecodeStream bcs(methodHandle(THREAD, get_Method()), bci); + Bytecodes::Code code = bcs.next(); + + if (Bytecodes::is_invoke(code)) { + return c < 0 ? max_jint : c; + } else { + switch (code) { + case Bytecodes::_aastore: // fall-through + case Bytecodes::_checkcast: // fall-through + case Bytecodes::_instanceof: return c > 0 ? min_jint : c; + default: return c; + } + } + } + + + // ------------------------------------------------------------------ // ciMethod::call_profile_at_bci // // Get the ciCallProfile for the invocation of this method. // Also reports receiver types for non-call type checks (if TypeProfileCasts). ciCallProfile ciMethod::call_profile_at_bci(int bci) {
*** 471,481 **** ciCallProfile result; if (method_data() != NULL && method_data()->is_mature()) { ciProfileData* data = method_data()->bci_to_data(bci); if (data != NULL && data->is_CounterData()) { // Every profiled call site has a counter. ! int count = data->as_CounterData()->count(); if (!data->is_ReceiverTypeData()) { result._receiver_count[0] = 0; // that's a definite zero } else { // ReceiverTypeData is a subclass of CounterData ciReceiverTypeData* call = (ciReceiverTypeData*)data->as_ReceiverTypeData(); --- 517,527 ---- ciCallProfile result; if (method_data() != NULL && method_data()->is_mature()) { ciProfileData* data = method_data()->bci_to_data(bci); if (data != NULL && data->is_CounterData()) { // Every profiled call site has a counter. ! int count = check_overflow(data->as_CounterData()->count(), bci); if (!data->is_ReceiverTypeData()) { result._receiver_count[0] = 0; // that's a definite zero } else { // ReceiverTypeData is a subclass of CounterData ciReceiverTypeData* call = (ciReceiverTypeData*)data->as_ReceiverTypeData();
*** 500,512 **** } } for (uint i = 0; i < call->row_limit(); i++) { ciKlass* receiver = call->receiver(i); if (receiver == NULL) continue; ! int rcount = call->receiver_count(i) + epsilon; if (rcount == 0) rcount = 1; // Should be valid value ! receivers_count_total += rcount; // Add the receiver to result data. result.add_receiver(receiver, rcount); // If we extend profiling to record methods, // we will set result._method also. } --- 546,558 ---- } } for (uint i = 0; i < call->row_limit(); i++) { ciKlass* receiver = call->receiver(i); if (receiver == NULL) continue; ! int rcount = saturated_add(call->receiver_count(i), epsilon); if (rcount == 0) rcount = 1; // Should be valid value ! receivers_count_total = saturated_add(receivers_count_total, rcount); // Add the receiver to result data. result.add_receiver(receiver, rcount); // If we extend profiling to record methods, // we will set result._method also. }
*** 532,542 **** // Make the count consistent if this is a call profile. If count is // zero or less, presume that this is a typecheck profile and // do nothing. Otherwise, increase count to be the sum of all // receiver's counts. if (count >= 0) { ! count += receivers_count_total; } } result._count = count; } } --- 578,588 ---- // Make the count consistent if this is a call profile. If count is // zero or less, presume that this is a typecheck profile and // do nothing. Otherwise, increase count to be the sum of all // receiver's counts. if (count >= 0) { ! count = saturated_add(count, receivers_count_total); } } result._count = count; } }
< prev index next >