bool MethodComparator::methods_EMCP(methodOop old_method, methodOop new_method) {
  if (old_method->code_size() != new_method->code_size())
    return false;
  if (check_stack_and_locals_size(old_method, new_method) != 0) {
    // RC_TRACE macro has an embedded ResourceMark
    RC_TRACE(0x00800000, ("Methods %s non-comparable with diagnosis %d",
      old_method->name()->as_C_string(),
      check_stack_and_locals_size(old_method, new_method)));
    return false;
  }

  _old_cp = old_method->constants();
  _new_cp = new_method->constants();
  BytecodeStream s_old(old_method);
  BytecodeStream s_new(new_method);
  _s_old = &s_old;
  _s_new = &s_new;
  _switchable_test = false;
  Bytecodes::Code c_old, c_new;

  while ((c_old = s_old.next()) >= 0) {
    if ((c_new = s_new.next()) < 0 || c_old != c_new)
      return false;

    if (! args_same(c_old, c_new))
      return false;
  }
  return true;
}
bool MethodComparator::methods_switchable(methodOop old_method, methodOop new_method,
                                          BciMap &bci_map) {
  if (old_method->code_size() > new_method->code_size())
    // Something has definitely been deleted in the new method, compared to the old one.
    return false;

  if (! check_stack_and_locals_size(old_method, new_method))
    return false;

  _old_cp = old_method->constants();
  _new_cp = new_method->constants();
  BytecodeStream s_old(old_method);
  BytecodeStream s_new(new_method);
  _s_old = &s_old;
  _s_new = &s_new;
  _bci_map = &bci_map;
  _switchable_test = true;
  GrowableArray<int> fwd_jmps(16);
  _fwd_jmps = &fwd_jmps;
  Bytecodes::Code c_old, c_new;

  while ((c_old = s_old.next()) >= 0) {
    if ((c_new = s_new.next()) < 0)
      return false;
    if (! (c_old == c_new && args_same(c_old, c_new))) {
      int old_bci = s_old.bci();
      int new_st_bci = s_new.bci();
      bool found_match = false;
      do {
        c_new = s_new.next();
        if (c_new == c_old && args_same(c_old, c_new)) {
          found_match = true;
          break;
        }
      } while (c_new >= 0);
      if (! found_match)
        return false;
      int new_end_bci = s_new.bci();
      bci_map.store_fragment_location(old_bci, new_st_bci, new_end_bci);
    }
  }

  // Now we can test all forward jumps
  for (int i = 0; i < fwd_jmps.length() / 2; i++) {
    if (! bci_map.old_and_new_locations_same(fwd_jmps.at(i*2), fwd_jmps.at(i*2+1))) {
      RC_TRACE(0x00800000,
        ("Fwd jump miss: old dest = %d, calc new dest = %d, act new dest = %d",
        fwd_jmps.at(i*2), bci_map.new_bci_for_old(fwd_jmps.at(i*2)),
        fwd_jmps.at(i*2+1)));
      return false;
    }
  }

  return true;
}
// Simple methods are as good being compiled with C1 as C2.
// Determine if a given method is such a case.
bool SimpleThresholdPolicy::is_trivial(methodOop method) {
  if (method->is_accessor()) return true;
  if (method->code() != NULL) {
    methodDataOop mdo = method->method_data();
    if (mdo != NULL && mdo->num_loops() == 0 &&
        (method->code_size() < 5  || (mdo->num_blocks() < 4) && (method->code_size() < 15))) {
      return !mdo->would_profile();
    }
  }
  return false;
}
Esempio n. 4
0
 // for hashing into the table
 static int hash(methodOop method) {
     // The point here is to try to make something fairly unique
     // out of the fields we can read without grabbing any locks
     // since the method may be locked when we need the hash.
     return (
         method->code_size() ^
         method->max_stack() ^
         method->max_locals() ^
         method->size_of_parameters());
 }
Esempio n. 5
0
// Rewrites a method given the index_map information
void Rewriter::scan_method(methodOop method, bool reverse) {

  int nof_jsrs = 0;
  bool has_monitor_bytecodes = false;

  {
    // We cannot tolerate a GC in this block, because we've
    // cached the bytecodes in 'code_base'. If the methodOop
    // moves, the bytecodes will also move.
    No_Safepoint_Verifier nsv;
    Bytecodes::Code c;

    // Bytecodes and their length
    const address code_base = method->code_base();
    const int code_length = method->code_size();

    int bc_length;
    for (int bci = 0; bci < code_length; bci += bc_length) {
      address bcp = code_base + bci;
      int prefix_length = 0;
      c = (Bytecodes::Code)(*bcp);

      // Since we have the code, see if we can get the length
      // directly. Some more complicated bytecodes will report
      // a length of zero, meaning we need to make another method
      // call to calculate the length.
      bc_length = Bytecodes::length_for(c);
      if (bc_length == 0) {
        bc_length = Bytecodes::length_at(method, bcp);

        // length_at will put us at the bytecode after the one modified
        // by 'wide'. We don't currently examine any of the bytecodes
        // modified by wide, but in case we do in the future...
        if (c == Bytecodes::_wide) {
          prefix_length = 1;
          c = (Bytecodes::Code)bcp[1];
        }
      }

      assert(bc_length != 0, "impossible bytecode length");

      switch (c) {
        case Bytecodes::_lookupswitch   : {
#ifndef CC_INTERP
          Bytecode_lookupswitch bc(method, bcp);
          (*bcp) = (
            bc.number_of_pairs() < BinarySwitchThreshold
            ? Bytecodes::_fast_linearswitch
            : Bytecodes::_fast_binaryswitch
          );
#endif
          break;
        }
        case Bytecodes::_fast_linearswitch:
        case Bytecodes::_fast_binaryswitch: {
#ifndef CC_INTERP
          (*bcp) = Bytecodes::_lookupswitch;
#endif
          break;
        }
        case Bytecodes::_getstatic      : // fall through
        case Bytecodes::_putstatic      : // fall through
        case Bytecodes::_getfield       : // fall through
        case Bytecodes::_putfield       : // fall through
        case Bytecodes::_invokevirtual  : // fall through
        case Bytecodes::_invokespecial  : // fall through
        case Bytecodes::_invokestatic   :
        case Bytecodes::_invokeinterface:
          rewrite_member_reference(bcp, prefix_length+1, reverse);
          break;
        case Bytecodes::_invokedynamic:
          rewrite_invokedynamic(bcp, prefix_length+1, reverse);
          break;
        case Bytecodes::_ldc:
        case Bytecodes::_fast_aldc:
          maybe_rewrite_ldc(bcp, prefix_length+1, false, reverse);
          break;
        case Bytecodes::_ldc_w:
        case Bytecodes::_fast_aldc_w:
          maybe_rewrite_ldc(bcp, prefix_length+1, true, reverse);
          break;
        case Bytecodes::_jsr            : // fall through
        case Bytecodes::_jsr_w          : nof_jsrs++;                   break;
        case Bytecodes::_monitorenter   : // fall through
        case Bytecodes::_monitorexit    : has_monitor_bytecodes = true; break;
      }
    }
  }

  // Update access flags
  if (has_monitor_bytecodes) {
    method->set_has_monitor_bytecodes();
  }

  // The present of a jsr bytecode implies that the method might potentially
  // have to be rewritten, so we run the oopMapGenerator on the method
  if (nof_jsrs > 0) {
    method->set_has_jsrs();
    // Second pass will revisit this method.
    assert(method->has_jsrs(), "didn't we just set this?");
  }
}