8224162: assert(profile.count() == 0) failed: sanity in InlineTree::is_not_reached
Reviewed-by: vlivanov, kvn
This commit is contained in:
parent
72daa46d46
commit
d738e209f3
@ -461,6 +461,27 @@ const BitMap& ciMethod::bci_block_start() {
|
||||
#endif // COMPILER1
|
||||
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// ciMethod::check_overflow
|
||||
//
|
||||
// Check whether the profile counter is overflowed and adjust 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, Bytecodes::Code code) {
|
||||
switch (code) {
|
||||
case Bytecodes::_aastore: // fall-through
|
||||
case Bytecodes::_checkcast: // fall-through
|
||||
case Bytecodes::_instanceof: {
|
||||
return (c > 0 ? min_jint : c); // always non-positive
|
||||
}
|
||||
default: {
|
||||
assert(Bytecodes::is_invoke(code), "%s", Bytecodes::name(code));
|
||||
return (c < 0 ? max_jint : c); // always non-negative
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// ciMethod::call_profile_at_bci
|
||||
//
|
||||
@ -473,7 +494,7 @@ ciCallProfile ciMethod::call_profile_at_bci(int bci) {
|
||||
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();
|
||||
int count = check_overflow(data->as_CounterData()->count(), java_code_at_bci(bci));
|
||||
|
||||
if (!data->is_ReceiverTypeData()) {
|
||||
result._receiver_count[0] = 0; // that's a definite zero
|
||||
@ -502,9 +523,9 @@ ciCallProfile ciMethod::call_profile_at_bci(int bci) {
|
||||
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;
|
||||
int rcount = saturated_add(call->receiver_count(i), epsilon);
|
||||
if (rcount == 0) rcount = 1; // Should be valid value
|
||||
receivers_count_total += rcount;
|
||||
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,
|
||||
@ -534,7 +555,7 @@ ciCallProfile ciMethod::call_profile_at_bci(int bci) {
|
||||
// do nothing. Otherwise, increase count to be the sum of all
|
||||
// receiver's counts.
|
||||
if (count >= 0) {
|
||||
count += receivers_count_total;
|
||||
count = saturated_add(count, receivers_count_total);
|
||||
}
|
||||
}
|
||||
result._count = count;
|
||||
|
@ -126,6 +126,9 @@ class ciMethod : public ciMetadata {
|
||||
void assert_virtual_call_type_ok(int bci);
|
||||
void assert_call_type_ok(int bci);
|
||||
|
||||
// Check and update the profile counter in case of overflow
|
||||
static int check_overflow(int c, Bytecodes::Code code);
|
||||
|
||||
public:
|
||||
void check_is_loaded() const { assert(is_loaded(), "not loaded"); }
|
||||
|
||||
|
@ -558,8 +558,14 @@ public:
|
||||
}
|
||||
|
||||
// Direct accessor
|
||||
uint count() const {
|
||||
return uint_at(count_off);
|
||||
int count() const {
|
||||
intptr_t raw_data = intptr_at(count_off);
|
||||
if (raw_data > max_jint) {
|
||||
raw_data = max_jint;
|
||||
} else if (raw_data < min_jint) {
|
||||
raw_data = min_jint;
|
||||
}
|
||||
return int(raw_data);
|
||||
}
|
||||
|
||||
// Code generation support
|
||||
@ -570,8 +576,8 @@ public:
|
||||
return cell_offset(counter_cell_count);
|
||||
}
|
||||
|
||||
void set_count(uint count) {
|
||||
set_uint_at(count_off, count);
|
||||
void set_count(int count) {
|
||||
set_int_at(count_off, count);
|
||||
}
|
||||
|
||||
void print_data_on(outputStream* st, const char* extra = NULL) const;
|
||||
|
@ -1085,6 +1085,28 @@ JAVA_INTEGER_OP(*, java_multiply, jlong, julong)
|
||||
|
||||
#undef JAVA_INTEGER_OP
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
// The goal of this code is to provide saturating operations for int/uint.
|
||||
// Checks overflow conditions and saturates the result to min_jint/max_jint.
|
||||
#define SATURATED_INTEGER_OP(OP, NAME, TYPE1, TYPE2) \
|
||||
inline int NAME (TYPE1 in1, TYPE2 in2) { \
|
||||
jlong res = static_cast<jlong>(in1); \
|
||||
res OP ## = static_cast<jlong>(in2); \
|
||||
if (res > max_jint) { \
|
||||
res = max_jint; \
|
||||
} else if (res < min_jint) { \
|
||||
res = min_jint; \
|
||||
} \
|
||||
return static_cast<int>(res); \
|
||||
}
|
||||
|
||||
SATURATED_INTEGER_OP(+, saturated_add, int, int)
|
||||
SATURATED_INTEGER_OP(+, saturated_add, int, uint)
|
||||
SATURATED_INTEGER_OP(+, saturated_add, uint, int)
|
||||
SATURATED_INTEGER_OP(+, saturated_add, uint, uint)
|
||||
|
||||
#undef SATURATED_INTEGER_OP
|
||||
|
||||
// Dereference vptr
|
||||
// All C++ compilers that we know of have the vtbl pointer in the first
|
||||
// word. If there are exceptions, this function needs to be made compiler
|
||||
|
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Loongson Technology Co. Ltd. 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8224162
|
||||
* @summary Profile counter for a call site may overflow.
|
||||
* @run main/othervm -Xbatch -XX:-UseOnStackReplacement -XX:MaxTrivialSize=0 compiler.profiling.TestProfileCounterOverflow
|
||||
*/
|
||||
|
||||
package compiler.profiling;
|
||||
|
||||
public class TestProfileCounterOverflow {
|
||||
public static void test(long iterations) {
|
||||
for (long j = 0; j < iterations; j++) {
|
||||
call();
|
||||
}
|
||||
}
|
||||
|
||||
public static void call() {}
|
||||
|
||||
public static void main(String[] args) {
|
||||
// trigger profiling on tier3
|
||||
for (int i = 0; i < 500; i++) {
|
||||
test(1);
|
||||
}
|
||||
|
||||
test(Integer.MAX_VALUE + 10000L); // overflow call counter
|
||||
|
||||
// trigger c2 compilation
|
||||
for (int i = 0; i < 10_000; i++) {
|
||||
test(1);
|
||||
}
|
||||
System.out.println("TEST PASSED");
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user