//----------------------increment_and_test_invocation_counter------------------- void Parse::increment_and_test_invocation_counter(int limit) { if (!count_invocations()) return; // Get the Method* node. const TypePtr* adr_type = TypeMetadataPtr::make(method()); Node *method_node = makecon(adr_type); // Load the interpreter_invocation_counter from the Method*. int offset = Method::interpreter_invocation_counter_offset_in_bytes(); Node* adr_node = basic_plus_adr(method_node, method_node, offset); Node* cnt = make_load(NULL, adr_node, TypeInt::INT, T_INT, adr_type); test_counter_against_threshold(cnt, limit); // Add one to the counter and store Node* incr = _gvn.transform(new (C) AddINode(cnt, _gvn.intcon(1))); store_to_memory( NULL, adr_node, incr, T_INT, adr_type ); }
//----------------------------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); }
//----------------------increment_and_test_invocation_counter------------------- void Parse::increment_and_test_invocation_counter(int limit) { if (!count_invocations()) return; // Get the Method* node. ciMethod* m = method(); MethodCounters* counters_adr = m->ensure_method_counters(); if (counters_adr == NULL) { C->record_failure("method counters allocation failed"); return; } Node* ctrl = control(); const TypePtr* adr_type = TypeRawPtr::make((address) counters_adr); Node *counters_node = makecon(adr_type); Node* adr_iic_node = basic_plus_adr(counters_node, counters_node, MethodCounters::interpreter_invocation_counter_offset_in_bytes()); Node* cnt = make_load(ctrl, adr_iic_node, TypeInt::INT, T_INT, adr_type, MemNode::unordered); test_counter_against_threshold(cnt, limit); // Add one to the counter and store Node* incr = _gvn.transform(new AddINode(cnt, _gvn.intcon(1))); store_to_memory(ctrl, adr_iic_node, incr, T_INT, adr_type, MemNode::unordered); }