diff -r 7373e44fa207 -r abe03600372a src/share/vm/oops/methodData.hpp --- a/src/share/vm/oops/methodData.hpp Thu Sep 19 17:31:42 2013 +0200 +++ b/src/share/vm/oops/methodData.hpp Sun Sep 15 15:28:58 2013 +0200 @@ -225,6 +225,11 @@ 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 @@ _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 @@ 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 @@ 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 @@ 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 @@ // 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ // 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;