8024468: PPC64 (part 201): cppInterpreter: implement bytecode profiling

Implement profiling for c2 jit compilation. Also enable new cppInterpreter features.

Reviewed-by: kvn
This commit is contained in:
Goetz Lindenmaier 2013-09-15 15:28:58 +02:00
parent 34c8023949
commit 0732a739b3
11 changed files with 790 additions and 103 deletions

View file

@ -225,6 +225,11 @@ public:
static ByteSize cell_offset(int index) {
return byte_offset_of(DataLayout, _cells) + in_ByteSize(index * cell_size);
}
#ifdef CC_INTERP
static int cell_offset_in_bytes(int index) {
return (int)offset_of(DataLayout, _cells[index]);
}
#endif // CC_INTERP
// Return a value which, when or-ed as a byte into _flags, sets the flag.
static int flag_number_to_byte_constant(int flag_number) {
assert(0 <= flag_number && flag_number < flag_limit, "oob");
@ -356,6 +361,41 @@ protected:
_data = data;
}
#ifdef CC_INTERP
// Static low level accessors for DataLayout with ProfileData's semantics.
static int cell_offset_in_bytes(int index) {
return DataLayout::cell_offset_in_bytes(index);
}
static void increment_uint_at_no_overflow(DataLayout* layout, int index,
int inc = DataLayout::counter_increment) {
uint count = ((uint)layout->cell_at(index)) + inc;
if (count == 0) return;
layout->set_cell_at(index, (intptr_t) count);
}
static int int_at(DataLayout* layout, int index) {
return (int)layout->cell_at(index);
}
static int uint_at(DataLayout* layout, int index) {
return (uint)layout->cell_at(index);
}
static oop oop_at(DataLayout* layout, int index) {
return (oop)layout->cell_at(index);
}
static void set_intptr_at(DataLayout* layout, int index, intptr_t value) {
layout->set_cell_at(index, (intptr_t) value);
}
static void set_flag_at(DataLayout* layout, int flag_number) {
layout->set_flag_at(flag_number);
}
#endif // CC_INTERP
public:
// Constructor for invalid ProfileData.
ProfileData();
@ -495,6 +535,20 @@ public:
return cell_offset(bit_cell_count);
}
#ifdef CC_INTERP
static int bit_data_size_in_bytes() {
return cell_offset_in_bytes(bit_cell_count);
}
static void set_null_seen(DataLayout* layout) {
set_flag_at(layout, null_seen_flag);
}
static DataLayout* advance(DataLayout* layout) {
return (DataLayout*) (((address)layout) + (ssize_t)BitData::bit_data_size_in_bytes());
}
#endif // CC_INTERP
#ifndef PRODUCT
void print_data_on(outputStream* st);
#endif
@ -539,6 +593,25 @@ public:
set_uint_at(count_off, count);
}
#ifdef CC_INTERP
static int counter_data_size_in_bytes() {
return cell_offset_in_bytes(counter_cell_count);
}
static void increment_count_no_overflow(DataLayout* layout) {
increment_uint_at_no_overflow(layout, count_off);
}
// Support counter decrementation at checkcast / subtype check failed.
static void decrement_count(DataLayout* layout) {
increment_uint_at_no_overflow(layout, count_off, -1);
}
static DataLayout* advance(DataLayout* layout) {
return (DataLayout*) (((address)layout) + (ssize_t)CounterData::counter_data_size_in_bytes());
}
#endif // CC_INTERP
#ifndef PRODUCT
void print_data_on(outputStream* st);
#endif
@ -609,6 +682,20 @@ public:
return cell_offset(displacement_off_set);
}
#ifdef CC_INTERP
static void increment_taken_count_no_overflow(DataLayout* layout) {
increment_uint_at_no_overflow(layout, taken_off_set);
}
static DataLayout* advance_taken(DataLayout* layout) {
return (DataLayout*) (((address)layout) + (ssize_t)int_at(layout, displacement_off_set));
}
static uint taken_count(DataLayout* layout) {
return (uint) uint_at(layout, taken_off_set);
}
#endif // CC_INTERP
// Specific initialization.
void post_initialize(BytecodeStream* stream, MethodData* mdo);
@ -718,6 +805,43 @@ public:
// GC support
virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure);
#ifdef CC_INTERP
static int receiver_type_data_size_in_bytes() {
return cell_offset_in_bytes(static_cell_count());
}
static Klass *receiver_unchecked(DataLayout* layout, uint row) {
oop recv = oop_at(layout, receiver_cell_index(row));
return (Klass *)recv;
}
static void increment_receiver_count_no_overflow(DataLayout* layout, Klass *rcvr) {
const int num_rows = row_limit();
// Receiver already exists?
for (int row = 0; row < num_rows; row++) {
if (receiver_unchecked(layout, row) == rcvr) {
increment_uint_at_no_overflow(layout, receiver_count_cell_index(row));
return;
}
}
// New receiver, find a free slot.
for (int row = 0; row < num_rows; row++) {
if (receiver_unchecked(layout, row) == NULL) {
set_intptr_at(layout, receiver_cell_index(row), (intptr_t)rcvr);
increment_uint_at_no_overflow(layout, receiver_count_cell_index(row));
return;
}
}
// Receiver did not match any saved receiver and there is no empty row for it.
// Increment total counter to indicate polymorphic case.
increment_count_no_overflow(layout);
}
static DataLayout* advance(DataLayout* layout) {
return (DataLayout*) (((address)layout) + (ssize_t)ReceiverTypeData::receiver_type_data_size_in_bytes());
}
#endif // CC_INTERP
#ifndef PRODUCT
void print_receiver_data_on(outputStream* st);
void print_data_on(outputStream* st);
@ -751,6 +875,16 @@ public:
return cell_offset(static_cell_count());
}
#ifdef CC_INTERP
static int virtual_call_data_size_in_bytes() {
return cell_offset_in_bytes(static_cell_count());
}
static DataLayout* advance(DataLayout* layout) {
return (DataLayout*) (((address)layout) + (ssize_t)VirtualCallData::virtual_call_data_size_in_bytes());
}
#endif // CC_INTERP
#ifndef PRODUCT
void print_data_on(outputStream* st);
#endif
@ -847,6 +981,10 @@ public:
return cell_offset(bci_displacement_cell_index(row));
}
#ifdef CC_INTERP
static DataLayout* advance(MethodData *md, int bci);
#endif // CC_INTERP
// Specific initialization.
void post_initialize(BytecodeStream* stream, MethodData* mdo);
@ -911,6 +1049,20 @@ public:
return cell_offset(branch_cell_count);
}
#ifdef CC_INTERP
static int branch_data_size_in_bytes() {
return cell_offset_in_bytes(branch_cell_count);
}
static void increment_not_taken_count_no_overflow(DataLayout* layout) {
increment_uint_at_no_overflow(layout, not_taken_off_set);
}
static DataLayout* advance_not_taken(DataLayout* layout) {
return (DataLayout*) (((address)layout) + (ssize_t)BranchData::branch_data_size_in_bytes());
}
#endif // CC_INTERP
// Specific initialization.
void post_initialize(BytecodeStream* stream, MethodData* mdo);
@ -950,6 +1102,20 @@ protected:
set_int_at(aindex, value);
}
#ifdef CC_INTERP
// Static low level accessors for DataLayout with ArrayData's semantics.
static void increment_array_uint_at_no_overflow(DataLayout* layout, int index) {
int aindex = index + array_start_off_set;
increment_uint_at_no_overflow(layout, aindex);
}
static int array_int_at(DataLayout* layout, int index) {
int aindex = index + array_start_off_set;
return int_at(layout, aindex);
}
#endif // CC_INTERP
// Code generation support for subclasses.
static ByteSize array_element_offset(int index) {
return cell_offset(array_start_off_set + index);
@ -1068,6 +1234,28 @@ public:
return in_ByteSize(relative_displacement_off_set) * cell_size;
}
#ifdef CC_INTERP
static void increment_count_no_overflow(DataLayout* layout, int index) {
if (index == -1) {
increment_array_uint_at_no_overflow(layout, default_count_off_set);
} else {
increment_array_uint_at_no_overflow(layout, case_array_start +
index * per_case_cell_count +
relative_count_off_set);
}
}
static DataLayout* advance(DataLayout* layout, int index) {
if (index == -1) {
return (DataLayout*) (((address)layout) + (ssize_t)array_int_at(layout, default_disaplacement_off_set));
} else {
return (DataLayout*) (((address)layout) + (ssize_t)array_int_at(layout, case_array_start +
index * per_case_cell_count +
relative_displacement_off_set));
}
}
#endif // CC_INTERP
// Specific initialization.
void post_initialize(BytecodeStream* stream, MethodData* mdo);
@ -1146,8 +1334,11 @@ public:
// adjusted in the event of a change in control flow.
//
CC_INTERP_ONLY(class BytecodeInterpreter;)
class MethodData : public Metadata {
friend class VMStructs;
CC_INTERP_ONLY(friend class BytecodeInterpreter;)
private:
friend class ProfileData;