Пример #1
0
void JvmtiBreakpoint::each_method_version_do(method_action meth_act) {
  ((Method*)_method->*meth_act)(_bci);

  // add/remove breakpoint to/from versions of the method that
  // are EMCP. Directly or transitively obsolete methods are
  // not saved in the PreviousVersionNodes.
  Thread *thread = Thread::current();
  instanceKlassHandle ikh = instanceKlassHandle(thread, _method->method_holder());
  Symbol* m_name = _method->name();
  Symbol* m_signature = _method->signature();

  // search previous versions if they exist
  PreviousVersionWalker pvw(thread, (InstanceKlass *)ikh());
  for (PreviousVersionNode * pv_node = pvw.next_previous_version();
       pv_node != NULL; pv_node = pvw.next_previous_version()) {
    GrowableArray<Method*>* methods = pv_node->prev_EMCP_methods();

    if (methods == NULL) {
      // We have run into a PreviousVersion generation where
      // all methods were made obsolete during that generation's
      // RedefineClasses() operation. At the time of that
      // operation, all EMCP methods were flushed so we don't
      // have to go back any further.
      //
      // A NULL methods array is different than an empty methods
      // array. We cannot infer any optimizations about older
      // generations from an empty methods array for the current
      // generation.
      break;
    }

    for (int i = methods->length() - 1; i >= 0; i--) {
      Method* method = methods->at(i);
      // obsolete methods that are running are not deleted from
      // previous version array, but they are skipped here.
      if (!method->is_obsolete() &&
          method->name() == m_name &&
          method->signature() == m_signature) {
        RC_TRACE(0x00000800, ("%sing breakpoint in %s(%s)",
          meth_act == &Method::set_breakpoint ? "sett" : "clear",
          method->name()->as_C_string(),
          method->signature()->as_C_string()));

        (method->*meth_act)(_bci);
        break;
      }
    }
  }
}