src/share/vm/ci/ciMethod.cpp

changeset 2138
d5d065957597
parent 2103
3e8fbc61cee8
child 2173
c93c652551b5
     1.1 --- a/src/share/vm/ci/ciMethod.cpp	Thu Sep 02 11:40:02 2010 -0700
     1.2 +++ b/src/share/vm/ci/ciMethod.cpp	Fri Sep 03 17:51:07 2010 -0700
     1.3 @@ -49,7 +49,8 @@
     1.4    _handler_count      = h_m()->exception_table()->length() / 4;
     1.5    _uses_monitors      = h_m()->access_flags().has_monitor_bytecodes();
     1.6    _balanced_monitors  = !_uses_monitors || h_m()->access_flags().is_monitor_matching();
     1.7 -  _is_compilable      = !h_m()->is_not_compilable();
     1.8 +  _is_c1_compilable   = !h_m()->is_not_c1_compilable();
     1.9 +  _is_c2_compilable   = !h_m()->is_not_c2_compilable();
    1.10    // Lazy fields, filled in on demand.  Require allocation.
    1.11    _code               = NULL;
    1.12    _exception_handlers = NULL;
    1.13 @@ -61,11 +62,12 @@
    1.14  #endif // COMPILER2 || SHARK
    1.15  
    1.16    ciEnv *env = CURRENT_ENV;
    1.17 -  if (env->jvmti_can_hotswap_or_post_breakpoint() && _is_compilable) {
    1.18 +  if (env->jvmti_can_hotswap_or_post_breakpoint() && can_be_compiled()) {
    1.19      // 6328518 check hotswap conditions under the right lock.
    1.20      MutexLocker locker(Compile_lock);
    1.21      if (Dependencies::check_evol_method(h_m()) != NULL) {
    1.22 -      _is_compilable = false;
    1.23 +      _is_c1_compilable = false;
    1.24 +      _is_c2_compilable = false;
    1.25      }
    1.26    } else {
    1.27      CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops());
    1.28 @@ -93,7 +95,7 @@
    1.29    _signature = new (env->arena()) ciSignature(_holder, sig_symbol);
    1.30    _method_data = NULL;
    1.31    // Take a snapshot of these values, so they will be commensurate with the MDO.
    1.32 -  if (ProfileInterpreter) {
    1.33 +  if (ProfileInterpreter || TieredCompilation) {
    1.34      int invcnt = h_m()->interpreter_invocation_count();
    1.35      // if the value overflowed report it as max int
    1.36      _interpreter_invocation_count = invcnt < 0 ? max_jint : invcnt ;
    1.37 @@ -437,11 +439,26 @@
    1.38          // In addition, virtual call sites have receiver type information
    1.39          int receivers_count_total = 0;
    1.40          int morphism = 0;
    1.41 +        // Precompute morphism for the possible fixup
    1.42          for (uint i = 0; i < call->row_limit(); i++) {
    1.43            ciKlass* receiver = call->receiver(i);
    1.44            if (receiver == NULL)  continue;
    1.45 -          morphism += 1;
    1.46 -          int rcount = call->receiver_count(i);
    1.47 +          morphism++;
    1.48 +        }
    1.49 +        int epsilon = 0;
    1.50 +        if (TieredCompilation && ProfileInterpreter) {
    1.51 +          // Interpreter and C1 treat final and special invokes differently.
    1.52 +          // C1 will record a type, whereas the interpreter will just
    1.53 +          // increment the count. Detect this case.
    1.54 +          if (morphism == 1 && count > 0) {
    1.55 +            epsilon = count;
    1.56 +            count = 0;
    1.57 +          }
    1.58 +        }
    1.59 +        for (uint i = 0; i < call->row_limit(); i++) {
    1.60 +          ciKlass* receiver = call->receiver(i);
    1.61 +          if (receiver == NULL)  continue;
    1.62 +          int rcount = call->receiver_count(i) + epsilon;
    1.63            if (rcount == 0) rcount = 1; // Should be valid value
    1.64            receivers_count_total += rcount;
    1.65            // Add the receiver to result data.
    1.66 @@ -687,10 +704,17 @@
    1.67  // invocation counts in methods.
    1.68  int ciMethod::scale_count(int count, float prof_factor) {
    1.69    if (count > 0 && method_data() != NULL) {
    1.70 -    int current_mileage = method_data()->current_mileage();
    1.71 -    int creation_mileage = method_data()->creation_mileage();
    1.72 -    int counter_life = current_mileage - creation_mileage;
    1.73 +    int counter_life;
    1.74      int method_life = interpreter_invocation_count();
    1.75 +    if (TieredCompilation) {
    1.76 +      // In tiered the MDO's life is measured directly, so just use the snapshotted counters
    1.77 +      counter_life = MAX2(method_data()->invocation_count(), method_data()->backedge_count());
    1.78 +    } else {
    1.79 +      int current_mileage = method_data()->current_mileage();
    1.80 +      int creation_mileage = method_data()->creation_mileage();
    1.81 +      counter_life = current_mileage - creation_mileage;
    1.82 +    }
    1.83 +
    1.84      // counter_life due to backedge_counter could be > method_life
    1.85      if (counter_life > method_life)
    1.86        counter_life = method_life;
    1.87 @@ -778,7 +802,8 @@
    1.88    Thread* my_thread = JavaThread::current();
    1.89    methodHandle h_m(my_thread, get_methodOop());
    1.90  
    1.91 -  if (Tier1UpdateMethodData && is_tier1_compile(env->comp_level())) {
    1.92 +  // Create an MDO for the inlinee
    1.93 +  if (TieredCompilation && is_c1_compile(env->comp_level())) {
    1.94      build_method_data(h_m);
    1.95    }
    1.96  
    1.97 @@ -885,7 +910,11 @@
    1.98  // Have previous compilations of this method succeeded?
    1.99  bool ciMethod::can_be_compiled() {
   1.100    check_is_loaded();
   1.101 -  return _is_compilable;
   1.102 +  ciEnv* env = CURRENT_ENV;
   1.103 +  if (is_c1_compile(env->comp_level())) {
   1.104 +    return _is_c1_compilable;
   1.105 +  }
   1.106 +  return _is_c2_compilable;
   1.107  }
   1.108  
   1.109  // ------------------------------------------------------------------
   1.110 @@ -895,8 +924,13 @@
   1.111  void ciMethod::set_not_compilable() {
   1.112    check_is_loaded();
   1.113    VM_ENTRY_MARK;
   1.114 -  _is_compilable = false;
   1.115 -  get_methodOop()->set_not_compilable();
   1.116 +  ciEnv* env = CURRENT_ENV;
   1.117 +  if (is_c1_compile(env->comp_level())) {
   1.118 +    _is_c1_compilable = false;
   1.119 +  } else {
   1.120 +    _is_c2_compilable = false;
   1.121 +  }
   1.122 +  get_methodOop()->set_not_compilable(env->comp_level());
   1.123  }
   1.124  
   1.125  // ------------------------------------------------------------------
   1.126 @@ -910,7 +944,8 @@
   1.127  bool ciMethod::can_be_osr_compiled(int entry_bci) {
   1.128    check_is_loaded();
   1.129    VM_ENTRY_MARK;
   1.130 -  return !get_methodOop()->access_flags().is_not_osr_compilable();
   1.131 +  ciEnv* env = CURRENT_ENV;
   1.132 +  return !get_methodOop()->is_not_osr_compilable(env->comp_level());
   1.133  }
   1.134  
   1.135  // ------------------------------------------------------------------
   1.136 @@ -920,6 +955,14 @@
   1.137    return get_methodOop()->code() != NULL;
   1.138  }
   1.139  
   1.140 +int ciMethod::comp_level() {
   1.141 +  check_is_loaded();
   1.142 +  VM_ENTRY_MARK;
   1.143 +  nmethod* nm = get_methodOop()->code();
   1.144 +  if (nm != NULL) return nm->comp_level();
   1.145 +  return 0;
   1.146 +}
   1.147 +
   1.148  // ------------------------------------------------------------------
   1.149  // ciMethod::instructions_size
   1.150  //
   1.151 @@ -928,18 +971,13 @@
   1.152  // junk like exception handler, stubs, and constant table, which are
   1.153  // not highly relevant to an inlined method.  So we use the more
   1.154  // specific accessor nmethod::insts_size.
   1.155 -int ciMethod::instructions_size() {
   1.156 +int ciMethod::instructions_size(int comp_level) {
   1.157    GUARDED_VM_ENTRY(
   1.158      nmethod* code = get_methodOop()->code();
   1.159 -    // if there's no compiled code or the code was produced by the
   1.160 -    // tier1 profiler return 0 for the code size.  This should
   1.161 -    // probably be based on the compilation level of the nmethod but
   1.162 -    // that currently isn't properly recorded.
   1.163 -    if (code == NULL ||
   1.164 -        (TieredCompilation && code->compiler() != NULL && code->compiler()->is_c1())) {
   1.165 -      return 0;
   1.166 +    if (code != NULL && (comp_level == CompLevel_any || comp_level == code->comp_level())) {
   1.167 +      return code->code_end() - code->verified_entry_point();
   1.168      }
   1.169 -    return code->insts_end() - code->verified_entry_point();
   1.170 +    return 0;
   1.171    )
   1.172  }
   1.173  

mercurial