src/share/vm/c1/c1_GraphBuilder.cpp

changeset 2138
d5d065957597
parent 1957
136b78722a08
child 2146
3a294e483abc
     1.1 --- a/src/share/vm/c1/c1_GraphBuilder.cpp	Thu Sep 02 11:40:02 2010 -0700
     1.2 +++ b/src/share/vm/c1/c1_GraphBuilder.cpp	Fri Sep 03 17:51:07 2010 -0700
     1.3 @@ -1144,8 +1144,16 @@
     1.4  
     1.5  
     1.6  void GraphBuilder::_goto(int from_bci, int to_bci) {
     1.7 -  profile_bci(from_bci);
     1.8 -  append(new Goto(block_at(to_bci), to_bci <= from_bci));
     1.9 +  Goto *x = new Goto(block_at(to_bci), to_bci <= from_bci);
    1.10 +  if (is_profiling()) {
    1.11 +    compilation()->set_would_profile(true);
    1.12 +  }
    1.13 +  if (profile_branches()) {
    1.14 +    x->set_profiled_method(method());
    1.15 +    x->set_profiled_bci(bci());
    1.16 +    x->set_should_profile(true);
    1.17 +  }
    1.18 +  append(x);
    1.19  }
    1.20  
    1.21  
    1.22 @@ -1153,11 +1161,45 @@
    1.23    BlockBegin* tsux = block_at(stream()->get_dest());
    1.24    BlockBegin* fsux = block_at(stream()->next_bci());
    1.25    bool is_bb = tsux->bci() < stream()->cur_bci() || fsux->bci() < stream()->cur_bci();
    1.26 -  If* if_node = append(new If(x, cond, false, y, tsux, fsux, is_bb ? state_before : NULL, is_bb))->as_If();
    1.27 -  if (profile_branches() && (if_node != NULL)) {
    1.28 -    if_node->set_profiled_method(method());
    1.29 -    if_node->set_profiled_bci(bci());
    1.30 -    if_node->set_should_profile(true);
    1.31 +  Instruction *i = append(new If(x, cond, false, y, tsux, fsux, is_bb ? state_before : NULL, is_bb));
    1.32 +
    1.33 +  if (is_profiling()) {
    1.34 +    If* if_node = i->as_If();
    1.35 +    if (if_node != NULL) {
    1.36 +      // Note that we'd collect profile data in this method if we wanted it.
    1.37 +      compilation()->set_would_profile(true);
    1.38 +      // At level 2 we need the proper bci to count backedges
    1.39 +      if_node->set_profiled_bci(bci());
    1.40 +      if (profile_branches()) {
    1.41 +        // Successors can be rotated by the canonicalizer, check for this case.
    1.42 +        if_node->set_profiled_method(method());
    1.43 +        if_node->set_should_profile(true);
    1.44 +        if (if_node->tsux() == fsux) {
    1.45 +          if_node->set_swapped(true);
    1.46 +        }
    1.47 +      }
    1.48 +      return;
    1.49 +    }
    1.50 +
    1.51 +    // Check if this If was reduced to Goto.
    1.52 +    Goto *goto_node = i->as_Goto();
    1.53 +    if (goto_node != NULL) {
    1.54 +      compilation()->set_would_profile(true);
    1.55 +      if (profile_branches()) {
    1.56 +        goto_node->set_profiled_method(method());
    1.57 +        goto_node->set_profiled_bci(bci());
    1.58 +        goto_node->set_should_profile(true);
    1.59 +        // Find out which successor is used.
    1.60 +        if (goto_node->default_sux() == tsux) {
    1.61 +          goto_node->set_direction(Goto::taken);
    1.62 +        } else if (goto_node->default_sux() == fsux) {
    1.63 +          goto_node->set_direction(Goto::not_taken);
    1.64 +        } else {
    1.65 +          ShouldNotReachHere();
    1.66 +        }
    1.67 +      }
    1.68 +      return;
    1.69 +    }
    1.70    }
    1.71  }
    1.72  
    1.73 @@ -1698,8 +1740,7 @@
    1.74  
    1.75    if (recv != NULL &&
    1.76        (code == Bytecodes::_invokespecial ||
    1.77 -       !is_loaded || target->is_final() ||
    1.78 -       profile_calls())) {
    1.79 +       !is_loaded || target->is_final())) {
    1.80      // invokespecial always needs a NULL check.  invokevirtual where
    1.81      // the target is final or where it's not known that whether the
    1.82      // target is final requires a NULL check.  Otherwise normal
    1.83 @@ -1709,15 +1750,23 @@
    1.84      null_check(recv);
    1.85    }
    1.86  
    1.87 -  if (profile_calls()) {
    1.88 -    assert(cha_monomorphic_target == NULL || exact_target == NULL, "both can not be set");
    1.89 -    ciKlass* target_klass = NULL;
    1.90 -    if (cha_monomorphic_target != NULL) {
    1.91 -      target_klass = cha_monomorphic_target->holder();
    1.92 -    } else if (exact_target != NULL) {
    1.93 -      target_klass = exact_target->holder();
    1.94 +  if (is_profiling()) {
    1.95 +    if (recv != NULL && profile_calls()) {
    1.96 +      null_check(recv);
    1.97      }
    1.98 -    profile_call(recv, target_klass);
    1.99 +    // Note that we'd collect profile data in this method if we wanted it.
   1.100 +    compilation()->set_would_profile(true);
   1.101 +
   1.102 +    if (profile_calls()) {
   1.103 +      assert(cha_monomorphic_target == NULL || exact_target == NULL, "both can not be set");
   1.104 +      ciKlass* target_klass = NULL;
   1.105 +      if (cha_monomorphic_target != NULL) {
   1.106 +        target_klass = cha_monomorphic_target->holder();
   1.107 +      } else if (exact_target != NULL) {
   1.108 +        target_klass = exact_target->holder();
   1.109 +      }
   1.110 +      profile_call(recv, target_klass);
   1.111 +    }
   1.112    }
   1.113  
   1.114    Invoke* result = new Invoke(code, result_type, recv, args, vtable_index, target, state_before);
   1.115 @@ -1782,10 +1831,16 @@
   1.116    CheckCast* c = new CheckCast(klass, apop(), state_before);
   1.117    apush(append_split(c));
   1.118    c->set_direct_compare(direct_compare(klass));
   1.119 -  if (profile_checkcasts()) {
   1.120 -    c->set_profiled_method(method());
   1.121 -    c->set_profiled_bci(bci());
   1.122 -    c->set_should_profile(true);
   1.123 +
   1.124 +  if (is_profiling()) {
   1.125 +    // Note that we'd collect profile data in this method if we wanted it.
   1.126 +    compilation()->set_would_profile(true);
   1.127 +
   1.128 +    if (profile_checkcasts()) {
   1.129 +      c->set_profiled_method(method());
   1.130 +      c->set_profiled_bci(bci());
   1.131 +      c->set_should_profile(true);
   1.132 +    }
   1.133    }
   1.134  }
   1.135  
   1.136 @@ -1868,7 +1923,7 @@
   1.137  
   1.138  
   1.139  Instruction* GraphBuilder::append_with_bci(Instruction* instr, int bci) {
   1.140 -  Canonicalizer canon(instr, bci);
   1.141 +  Canonicalizer canon(compilation(), instr, bci);
   1.142    Instruction* i1 = canon.canonical();
   1.143    if (i1->bci() != -99) {
   1.144      // Canonicalizer returned an instruction which was already
   1.145 @@ -2651,18 +2706,6 @@
   1.146    h->set_depth_first_number(0);
   1.147  
   1.148    Value l = h;
   1.149 -  if (profile_branches()) {
   1.150 -    // Increment the invocation count on entry to the method.  We
   1.151 -    // can't use profile_invocation here because append isn't setup to
   1.152 -    // work properly at this point.  The instruction have to be
   1.153 -    // appended to the instruction stream by hand.
   1.154 -    Value m = new Constant(new ObjectConstant(compilation()->method()));
   1.155 -    h->set_next(m, 0);
   1.156 -    Value p = new ProfileCounter(m, methodOopDesc::interpreter_invocation_counter_offset_in_bytes(), 1);
   1.157 -    m->set_next(p, 0);
   1.158 -    l = p;
   1.159 -  }
   1.160 -
   1.161    BlockEnd* g = new Goto(entry, false);
   1.162    l->set_next(g, entry->bci());
   1.163    h->set_end(g);
   1.164 @@ -2688,10 +2731,10 @@
   1.165    // also necessary when profiling so that there's a single block that
   1.166    // can increment the interpreter_invocation_count.
   1.167    BlockBegin* new_header_block;
   1.168 -  if (std_entry->number_of_preds() == 0 && !profile_branches()) {
   1.169 +  if (std_entry->number_of_preds() > 0 || count_invocations() || count_backedges()) {
   1.170 +    new_header_block = header_block(std_entry, BlockBegin::std_entry_flag, state);
   1.171 +  } else {
   1.172      new_header_block = std_entry;
   1.173 -  } else {
   1.174 -    new_header_block = header_block(std_entry, BlockBegin::std_entry_flag, state);
   1.175    }
   1.176  
   1.177    // setup start block (root for the IR graph)
   1.178 @@ -3115,16 +3158,21 @@
   1.179  
   1.180    Values* args = state()->pop_arguments(callee->arg_size());
   1.181    ValueStack* locks = lock_stack();
   1.182 -  if (profile_calls()) {
   1.183 +
   1.184 +  if (is_profiling()) {
   1.185      // Don't profile in the special case where the root method
   1.186      // is the intrinsic
   1.187      if (callee != method()) {
   1.188 -      Value recv = NULL;
   1.189 -      if (has_receiver) {
   1.190 -        recv = args->at(0);
   1.191 -        null_check(recv);
   1.192 +      // Note that we'd collect profile data in this method if we wanted it.
   1.193 +      compilation()->set_would_profile(true);
   1.194 +      if (profile_calls()) {
   1.195 +        Value recv = NULL;
   1.196 +        if (has_receiver) {
   1.197 +          recv = args->at(0);
   1.198 +          null_check(recv);
   1.199 +        }
   1.200 +        profile_call(recv, NULL);
   1.201        }
   1.202 -      profile_call(recv, NULL);
   1.203      }
   1.204    }
   1.205  
   1.206 @@ -3296,7 +3344,9 @@
   1.207  
   1.208  bool GraphBuilder::try_inline_full(ciMethod* callee, bool holder_known) {
   1.209    assert(!callee->is_native(), "callee must not be native");
   1.210 -
   1.211 +  if (count_backedges() && callee->has_loops()) {
   1.212 +    INLINE_BAILOUT("too complex for tiered");
   1.213 +  }
   1.214    // first perform tests of things it's not possible to inline
   1.215    if (callee->has_exception_handlers() &&
   1.216        !InlineMethodsWithExceptionHandlers) INLINE_BAILOUT("callee has exception handlers");
   1.217 @@ -3365,12 +3415,19 @@
   1.218      null_check(recv);
   1.219    }
   1.220  
   1.221 -  if (profile_inlined_calls()) {
   1.222 -    profile_call(recv, holder_known ? callee->holder() : NULL);
   1.223 +  if (is_profiling()) {
   1.224 +    // Note that we'd collect profile data in this method if we wanted it.
   1.225 +    // this may be redundant here...
   1.226 +    compilation()->set_would_profile(true);
   1.227 +
   1.228 +    if (profile_calls()) {
   1.229 +      profile_call(recv, holder_known ? callee->holder() : NULL);
   1.230 +    }
   1.231 +    if (profile_inlined_calls()) {
   1.232 +      profile_invocation(callee, state(), 0);
   1.233 +    }
   1.234    }
   1.235  
   1.236 -  profile_invocation(callee);
   1.237 -
   1.238    // Introduce a new callee continuation point - if the callee has
   1.239    // more than one return instruction or the return does not allow
   1.240    // fall-through of control flow, all return instructions of the
   1.241 @@ -3755,30 +3812,10 @@
   1.242  }
   1.243  #endif // PRODUCT
   1.244  
   1.245 -
   1.246  void GraphBuilder::profile_call(Value recv, ciKlass* known_holder) {
   1.247    append(new ProfileCall(method(), bci(), recv, known_holder));
   1.248  }
   1.249  
   1.250 -
   1.251 -void GraphBuilder::profile_invocation(ciMethod* callee) {
   1.252 -  if (profile_calls()) {
   1.253 -    // increment the interpreter_invocation_count for the inlinee
   1.254 -    Value m = append(new Constant(new ObjectConstant(callee)));
   1.255 -    append(new ProfileCounter(m, methodOopDesc::interpreter_invocation_counter_offset_in_bytes(), 1));
   1.256 -  }
   1.257 +void GraphBuilder::profile_invocation(ciMethod* callee, ValueStack* state, int bci) {
   1.258 +  append(new ProfileInvoke(callee, state, bci));
   1.259  }
   1.260 -
   1.261 -
   1.262 -void GraphBuilder::profile_bci(int bci) {
   1.263 -  if (profile_branches()) {
   1.264 -    ciMethodData* md = method()->method_data();
   1.265 -    if (md == NULL) {
   1.266 -      BAILOUT("out of memory building methodDataOop");
   1.267 -    }
   1.268 -    ciProfileData* data = md->bci_to_data(bci);
   1.269 -    assert(data != NULL && data->is_JumpData(), "need JumpData for goto");
   1.270 -    Value mdo = append(new Constant(new ObjectConstant(md)));
   1.271 -    append(new ProfileCounter(mdo, md->byte_offset_of_slot(data, JumpData::taken_offset()), 1));
   1.272 -  }
   1.273 -}

mercurial