# HG changeset patch # User twisti # Date 1371750994 25200 # Node ID 63e44cdabb9134c3311b6357e3d7a12c93958eb7 # Parent fb95519008d6351e7c32b08fd8e35b4cd444ab30 fixed SPARC interpreter diff -r fb95519008d6 -r 63e44cdabb91 src/cpu/sparc/vm/interp_masm_sparc.cpp --- a/src/cpu/sparc/vm/interp_masm_sparc.cpp Thu Jun 20 10:55:42 2013 -0700 +++ b/src/cpu/sparc/vm/interp_masm_sparc.cpp Thu Jun 20 10:56:34 2013 -0700 @@ -1646,26 +1646,75 @@ bind(skip_receiver_profile); // The method data pointer needs to be updated to reflect the new target. +#ifdef GRAAL + if (MethodProfileWidth == 0) { + update_mdp_by_constant(in_bytes(VirtualCallData::virtual_call_data_size())); + } +#else update_mdp_by_constant(in_bytes(VirtualCallData::virtual_call_data_size())); - bind (profile_continue); +#endif + bind(profile_continue); } } -void InterpreterMacroAssembler::record_klass_in_profile_helper( - Register receiver, Register scratch, - int start_row, Label& done, bool is_virtual_call) { +#ifdef GRAAL +void InterpreterMacroAssembler::profile_called_method(Register method, Register scratch) { + assert_different_registers(method, scratch); + if (ProfileInterpreter && MethodProfileWidth > 0) { + Label profile_continue; + + // If no method data exists, go to profile_continue. + test_method_data_pointer(profile_continue); + + Label done; + record_item_in_profile_helper(method, scratch, 0, done, MethodProfileWidth, + &VirtualCallData::method_offset, &VirtualCallData::method_count_offset, in_bytes(VirtualCallData::nonprofiled_receiver_count_offset())); + bind(done); + + update_mdp_by_constant(in_bytes(VirtualCallData::virtual_call_data_size())); + bind(profile_continue); + } +} +#endif + +void InterpreterMacroAssembler::record_klass_in_profile_helper(Register receiver, Register scratch, + Label& done, bool is_virtual_call) { if (TypeProfileWidth == 0) { if (is_virtual_call) { increment_mdp_data_at(in_bytes(CounterData::count_offset()), scratch); } - return; +#ifdef GRAAL + else { + increment_mdp_data_at(in_bytes(ReceiverTypeData::nonprofiled_receiver_count_offset()), scratch); + } +#endif + } else { + bool use_non_profiled_counter = !is_virtual_call || IS_GRAAL_DEFINED; + int non_profiled_offset = -1; + if (use_non_profiled_counter) { + non_profiled_offset = in_bytes(CounterData::count_offset()); + #ifdef GRAAL + if (!is_virtual_call) { + non_profiled_offset = in_bytes(ReceiverTypeData::nonprofiled_receiver_count_offset()); + } + #endif + assert(non_profiled_offset >= 0, "must be"); + } + + record_item_in_profile_helper(receiver, scratch, 0, done, TypeProfileWidth, + &VirtualCallData::receiver_offset, &VirtualCallData::receiver_count_offset, non_profiled_offset); } - - int last_row = VirtualCallData::row_limit() - 1; +} + +void InterpreterMacroAssembler::record_item_in_profile_helper(Register item, + Register scratch, int start_row, Label& done, int total_rows, + OffsetFunction item_offset_fn, OffsetFunction item_count_offset_fn, + int non_profiled_offset) { + int last_row = total_rows - 1; assert(start_row <= last_row, "must be work left to do"); - // Test this row for both the receiver and for null. + // Test this row for both the item and for null. // Take any of three different outcomes: - // 1. found receiver => increment count and goto done + // 1. found item => increment count and goto done // 2. found null => keep looking for case 1, maybe allocate this cell // 3. found something else => keep looking for cases 1 and 2 // Case 3 is handled by a recursive call. @@ -1673,28 +1722,28 @@ Label next_test; bool test_for_null_also = (row == start_row); - // See if the receiver is receiver[n]. - int recvr_offset = in_bytes(VirtualCallData::receiver_offset(row)); - test_mdp_data_at(recvr_offset, receiver, next_test, scratch); + // See if the item is item[n]. + int item_offset = in_bytes(item_offset_fn(row)); + test_mdp_data_at(item_offset, item, next_test, scratch); // delayed()->tst(scratch); - // The receiver is receiver[n]. Increment count[n]. - int count_offset = in_bytes(VirtualCallData::receiver_count_offset(row)); + // The receiver is item[n]. Increment count[n]. + int count_offset = in_bytes(item_count_offset_fn(row)); increment_mdp_data_at(count_offset, scratch); ba_short(done); bind(next_test); if (test_for_null_also) { Label found_null; - // Failed the equality check on receiver[n]... Test for null. + // Failed the equality check on item[n]... Test for null. if (start_row == last_row) { // The only thing left to do is handle the null case. - if (is_virtual_call) { + if (non_profiled_offset >= 0) { brx(Assembler::zero, false, Assembler::pn, found_null); delayed()->nop(); - // Receiver did not match any saved receiver and there is no empty row for it. + // Item did not match any saved item and there is no empty row for it. // Increment total counter to indicate polymorphic case. - increment_mdp_data_at(in_bytes(CounterData::count_offset()), scratch); + increment_mdp_data_at(non_profiled_offset, scratch); ba_short(done); bind(found_null); } else { @@ -1708,21 +1757,22 @@ delayed()->nop(); // Put all the "Case 3" tests here. - record_klass_in_profile_helper(receiver, scratch, start_row + 1, done, is_virtual_call); - - // Found a null. Keep searching for a matching receiver, + record_item_in_profile_helper(item, scratch, start_row + 1, done, total_rows, + item_offset_fn, item_count_offset_fn, non_profiled_offset); + + // Found a null. Keep searching for a matching item, // but remember that this is an empty (unused) slot. bind(found_null); } } - // In the fall-through case, we found no matching receiver, but we - // observed the receiver[start_row] is NULL. - - // Fill in the receiver field and increment the count. - int recvr_offset = in_bytes(VirtualCallData::receiver_offset(start_row)); - set_mdp_data_at(recvr_offset, receiver); - int count_offset = in_bytes(VirtualCallData::receiver_count_offset(start_row)); + // In the fall-through case, we found no matching item, but we + // observed the item[start_row] is NULL. + + // Fill in the item field and increment the count. + int item_offset = in_bytes(item_offset_fn(start_row)); + set_mdp_data_at(item_offset, item); + int count_offset = in_bytes(item_count_offset_fn(start_row)); mov(DataLayout::counter_increment, scratch); set_mdp_data_at(count_offset, scratch); if (start_row > 0) { @@ -1735,7 +1785,7 @@ assert(ProfileInterpreter, "must be profiling"); Label done; - record_klass_in_profile_helper(receiver, scratch, 0, done, is_virtual_call); + record_klass_in_profile_helper(receiver, scratch, done, is_virtual_call); bind (done); } @@ -1791,7 +1841,7 @@ // The method data pointer needs to be updated. int mdp_delta = in_bytes(BitData::bit_data_size()); if (TypeProfileCasts) { - mdp_delta = in_bytes(VirtualCallData::virtual_call_data_size()); + mdp_delta = in_bytes(ReceiverTypeData::receiver_type_data_size()); } update_mdp_by_constant(mdp_delta); @@ -1809,7 +1859,7 @@ int mdp_delta = in_bytes(BitData::bit_data_size()); if (TypeProfileCasts) { - mdp_delta = in_bytes(VirtualCallData::virtual_call_data_size()); + mdp_delta = in_bytes(ReceiverTypeData::receiver_type_data_size()); // Record the object type. record_klass_in_profile(klass, scratch, false); @@ -1831,7 +1881,7 @@ int count_offset = in_bytes(CounterData::count_offset()); // Back up the address, since we have already bumped the mdp. - count_offset -= in_bytes(VirtualCallData::virtual_call_data_size()); + count_offset -= in_bytes(ReceiverTypeData::receiver_type_data_size()); // *Decrement* the counter. We expect to see zero or small negatives. increment_mdp_data_at(count_offset, scratch, true); diff -r fb95519008d6 -r 63e44cdabb91 src/cpu/sparc/vm/interp_masm_sparc.hpp --- a/src/cpu/sparc/vm/interp_masm_sparc.hpp Thu Jun 20 10:55:42 2013 -0700 +++ b/src/cpu/sparc/vm/interp_masm_sparc.hpp Thu Jun 20 10:56:34 2013 -0700 @@ -30,6 +30,8 @@ // This file specializes the assember with interpreter-specific macros +typedef ByteSize (*OffsetFunction)(uint); + REGISTER_DECLARATION( Register, Otos_i , O0); // tos for ints, etc REGISTER_DECLARATION( Register, Otos_l , O0); // for longs REGISTER_DECLARATION( Register, Otos_l1, O0); // for 1st part of longs @@ -300,7 +302,11 @@ void record_klass_in_profile(Register receiver, Register scratch, bool is_virtual_call); void record_klass_in_profile_helper(Register receiver, Register scratch, - int start_row, Label& done, bool is_virtual_call); + Label& done, bool is_virtual_call); + void record_item_in_profile_helper(Register item, + Register scratch, int start_row, Label& done, int total_rows, + OffsetFunction item_offset_fn, OffsetFunction item_count_offset_fn, + int non_profiled_offset); void update_mdp_by_offset(int offset_of_disp, Register scratch); void update_mdp_by_offset(Register reg, int offset_of_disp, @@ -313,6 +319,7 @@ void profile_call(Register scratch); void profile_final_call(Register scratch); void profile_virtual_call(Register receiver, Register scratch, bool receiver_can_be_null = false); + void profile_called_method(Register method, Register scratch); void profile_ret(TosState state, Register return_bci, Register scratch); void profile_null_seen(Register scratch); void profile_typecheck(Register klass, Register scratch); diff -r fb95519008d6 -r 63e44cdabb91 src/cpu/sparc/vm/templateTable_sparc.cpp --- a/src/cpu/sparc/vm/templateTable_sparc.cpp Thu Jun 20 10:55:42 2013 -0700 +++ b/src/cpu/sparc/vm/templateTable_sparc.cpp Thu Jun 20 10:56:34 2013 -0700 @@ -2983,6 +2983,9 @@ // get target Method* & entry point __ lookup_virtual_method(Rrecv, Rindex, G5_method); +#ifdef GRAAL + __ profile_called_method(G5_method, Rtemp); +#endif __ call_from_interpreter(Rcall, Gargs, Rret); } @@ -3232,6 +3235,10 @@ Register Rcall = Rinterface; assert_different_registers(Rcall, G5_method, Gargs, Rret); +#ifdef GRAAL + __ profile_called_method(G5_method, Rscratch); +#endif + __ call_from_interpreter(Rcall, Gargs, Rret); } @@ -3524,7 +3531,8 @@ Register RspecifiedKlass = O4; // Check for casting a NULL - __ br_null_short(Otos_i, Assembler::pn, is_null); + __ br_null(Otos_i, false, Assembler::pn, is_null); + __ delayed()->nop(); // Get value klass in RobjKlass __ load_klass(Otos_i, RobjKlass); // get value klass @@ -3580,7 +3588,8 @@ Register RspecifiedKlass = O4; // Check for casting a NULL - __ br_null_short(Otos_i, Assembler::pt, is_null); + __ br_null(Otos_i, false, Assembler::pt, is_null); + __ delayed()->nop(); // Get value klass in RobjKlass __ load_klass(Otos_i, RobjKlass); // get value klass diff -r fb95519008d6 -r 63e44cdabb91 src/cpu/x86/vm/interp_masm_x86_64.cpp --- a/src/cpu/x86/vm/interp_masm_x86_64.cpp Thu Jun 20 10:55:42 2013 -0700 +++ b/src/cpu/x86/vm/interp_masm_x86_64.cpp Thu Jun 20 10:56:34 2013 -0700 @@ -1154,13 +1154,12 @@ Label done; record_item_in_profile_helper(method, mdp, reg2, 0, done, MethodProfileWidth, &VirtualCallData::method_offset, &VirtualCallData::method_count_offset, in_bytes(VirtualCallData::nonprofiled_receiver_count_offset())); - bind (done); + bind(done); update_mdp_by_constant(mdp, in_bytes(VirtualCallData::virtual_call_data_size())); bind(profile_continue); } } - #endif // This routine creates a state machine for updating the multi-row