//-----------------------------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_virtual_call--------------------------- void Parse::profile_virtual_call(Node* receiver) { assert(method_data_update(), "must be generating profile code"); // Skip if we aren't tracking receivers 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_VirtualCallData(), "need VirtualCallData at call site"); ciVirtualCallData* call_data = (ciVirtualCallData*)data->as_VirtualCallData(); Node* method_data = method_data_addressing(md, call_data, in_ByteSize(0)); // The following construction of the CallLeafNode is almost identical to // make_slow_call(). However, with make_slow_call(), the merge mem // characteristics were causing incorrect anti-deps to be added. CallRuntimeNode *call = new CallLeafNode(OptoRuntime::profile_virtual_call_Type(), CAST_FROM_FN_PTR(address, OptoRuntime::profile_virtual_call_C), "profile_virtual_call_C"); set_predefined_input_for_runtime_call(call); call->set_req( TypeFunc::Parms+0, method_data ); call->set_req( TypeFunc::Parms+1, receiver ); Node* c = _gvn.transform(call); set_predefined_output_for_runtime_call(c); }
//-------------------------------set_md_flag_at-------------------------------- void Parse::set_md_flag_at(ciMethodData* md, ciProfileData* data, int flag_constant) { Node* adr_node = method_data_addressing(md, data, DataLayout::flags_offset()); const TypePtr* adr_type = _gvn.type(adr_node)->is_ptr(); Node* flags = make_load(NULL, adr_node, TypeInt::BYTE, T_BYTE, adr_type); Node* incr = _gvn.transform(new (C) OrINode(flags, _gvn.intcon(flag_constant))); store_to_memory(NULL, adr_node, incr, T_BYTE, adr_type); }
//--------------------------test_for_osr_md_counter_at------------------------- void Parse::test_for_osr_md_counter_at(ciMethodData* md, ciProfileData* data, ByteSize counter_offset, int limit) { Node* adr_node = method_data_addressing(md, data, counter_offset); const TypePtr* adr_type = _gvn.type(adr_node)->is_ptr(); Node* cnt = make_load(NULL, adr_node, TypeInt::INT, T_INT, adr_type); test_counter_against_threshold(cnt, limit); }
//--------------------------increment_md_counter_at---------------------------- void Parse::increment_md_counter_at(ciMethodData* md, ciProfileData* data, ByteSize counter_offset, Node* idx, uint stride) { Node* adr_node = method_data_addressing(md, data, counter_offset, idx, stride); const TypePtr* adr_type = _gvn.type(adr_node)->is_ptr(); Node* cnt = make_load(NULL, adr_node, TypeInt::INT, T_INT, adr_type); Node* incr = _gvn.transform(new (C) AddINode(cnt, _gvn.intcon(DataLayout::counter_increment))); store_to_memory(NULL, adr_node, incr, T_INT, adr_type ); }