//-----------------------------profile_switch_case----------------------------- void Parse::profile_switch_case(int table_index) { if (!method_data_update()) return; ciMethodData* md = method()->method_data(); assert(md != NULL, "expected valid ciMethodData"); ciProfileData* data = md->bci_to_data(bci()); assert(data->is_MultiBranchData(), "need MultiBranchData for switch case"); if (table_index >= 0) { increment_md_counter_at(md, data, MultiBranchData::case_count_offset(table_index)); } else { increment_md_counter_at(md, data, MultiBranchData::default_count_offset()); } }
//---------------------------------profile_ret--------------------------------- void Parse::profile_ret(int target_bci) { if (!method_data_update()) return; // Skip if we aren't tracking ret targets if (TypeProfileWidth < 1) return; ciMethodData* md = method()->method_data(); assert(md != NULL, "expected valid ciMethodData"); ciProfileData* data = md->bci_to_data(bci()); assert(data->is_RetData(), "need RetData for ret"); ciRetData* ret_data = (ciRetData*)data->as_RetData(); // Look for the target_bci is already in the table uint row; bool table_full = true; for (row = 0; row < ret_data->row_limit(); row++) { int key = ret_data->bci(row); table_full &= (key != RetData::no_bci); if (key == target_bci) break; } if (row >= ret_data->row_limit()) { // The target_bci was not found in the table. if (!table_full) { // XXX: Make slow call to update RetData } return; } // the target_bci is already in the table increment_md_counter_at(md, data, RetData::bci_count_offset(row)); }
//-----------------------------profile_receiver_type--------------------------- void Parse::profile_receiver_type(Node* receiver) { assert(method_data_update(), "must be generating profile code"); ciMethodData* md = method()->method_data(); assert(md != NULL, "expected valid ciMethodData"); ciProfileData* data = md->bci_to_data(bci()); assert(data->is_ReceiverTypeData(), "need ReceiverTypeData here"); // Skip if we aren't tracking receivers if (TypeProfileWidth < 1) { increment_md_counter_at(md, data, CounterData::count_offset()); return; } ciReceiverTypeData* rdata = (ciReceiverTypeData*)data->as_ReceiverTypeData(); Node* method_data = method_data_addressing(md, rdata, in_ByteSize(0)); // Using an adr_type of TypePtr::BOTTOM to work around anti-dep problems. // A better solution might be to use TypeRawPtr::BOTTOM with RC_NARROW_MEM. make_runtime_call(RC_LEAF, OptoRuntime::profile_receiver_type_Type(), CAST_FROM_FN_PTR(address, OptoRuntime::profile_receiver_type_C), "profile_receiver_type_C", TypePtr::BOTTOM, method_data, receiver); }
//------------------------------profile_generic_call--------------------------- void Parse::profile_generic_call() { assert(method_data_update(), "must be generating profile code"); ciMethodData* md = method()->method_data(); assert(md != NULL, "expected valid ciMethodData"); ciProfileData* data = md->bci_to_data(bci()); assert(data->is_CounterData(), "need CounterData for not taken branch"); increment_md_counter_at(md, data, CounterData::count_offset()); }
//--------------------------profile_not_taken_branch--------------------------- void Parse::profile_not_taken_branch() { if (!method_data_update()) return; ciMethodData* md = method()->method_data(); assert(md != NULL, "expected valid ciMethodData"); ciProfileData* data = md->bci_to_data(bci()); assert(data->is_BranchData(), "need BranchData for not taken branch"); increment_md_counter_at(md, data, BranchData::not_taken_offset()); }
//----------------------------profile_taken_branch----------------------------- void Parse::profile_taken_branch(int target_bci, bool force_update) { // This is a potential osr_site if we have a backedge. int cur_bci = bci(); bool osr_site = (target_bci <= cur_bci) && count_invocations() && UseOnStackReplacement; // If we are going to OSR, restart at the target bytecode. set_bci(target_bci); // To do: factor out the the limit calculations below. These duplicate // the similar limit calculations in the interpreter. if (method_data_update() || force_update) { ciMethodData* md = method()->method_data(); assert(md != NULL, "expected valid ciMethodData"); ciProfileData* data = md->bci_to_data(cur_bci); assert(data->is_JumpData(), "need JumpData for taken branch"); increment_md_counter_at(md, data, JumpData::taken_offset()); } // In the new tiered system this is all we need to do. In the old // (c2 based) tiered sytem we must do the code below. #ifndef TIERED if (method_data_update()) { ciMethodData* md = method()->method_data(); if (osr_site) { ciProfileData* data = md->bci_to_data(cur_bci); int limit = (CompileThreshold * (OnStackReplacePercentage - InterpreterProfilePercentage)) / 100; test_for_osr_md_counter_at(md, data, JumpData::taken_offset(), limit); } } else { // With method data update off, use the invocation counter to trigger an // OSR compilation, as done in the interpreter. if (osr_site) { int limit = (CompileThreshold * OnStackReplacePercentage) / 100; increment_and_test_invocation_counter(limit); } } #endif // TIERED // Restore the original bytecode. set_bci(cur_bci); }