Exemple #1
0
GrowableArray<MonitorInfo*>* javaVFrame::locked_monitors() {
  assert(SafepointSynchronize::is_at_safepoint() || JavaThread::current() == thread(),
         "must be at safepoint or it's a java frame of the current thread");

  GrowableArray<MonitorInfo*>* mons = monitors();
  GrowableArray<MonitorInfo*>* result = new GrowableArray<MonitorInfo*>(mons->length());
  if (mons->is_empty()) return result;

  bool found_first_monitor = false;
  ObjectMonitor *pending_monitor = thread()->current_pending_monitor();
  ObjectMonitor *waiting_monitor = thread()->current_waiting_monitor();
  oop pending_obj = (pending_monitor != NULL ? (oop) pending_monitor->object() : (oop) NULL);
  oop waiting_obj = (waiting_monitor != NULL ? (oop) waiting_monitor->object() : (oop) NULL);

  for (int index = (mons->length()-1); index >= 0; index--) {
    MonitorInfo* monitor = mons->at(index);
    if (monitor->eliminated() && is_compiled_frame()) continue; // skip eliminated monitor
    oop obj = monitor->owner();
    if (obj == NULL) continue; // skip unowned monitor
    //
    // Skip the monitor that the thread is blocked to enter or waiting on
    //
    if (!found_first_monitor && (obj == pending_obj || obj == waiting_obj)) {
      continue;
    }
    found_first_monitor = true;
    result->append(monitor);
  }
  return result;
}
// ------------------------------------------------------------------
// ciFieldLayout::ciFieldLayout
ciFieldLayout::ciFieldLayout(ciInstanceKlass* my_klass) {
  assert(my_klass->is_loaded(), "must be loaded");
  ASSERT_IN_VM;

  klassOop klass = my_klass->get_klassOop();

  Arena* arena = CURRENT_ENV->arena();
  GrowableArray<BasicType>* fieldtypes =
    new (arena) GrowableArray<BasicType>(arena, 8, 0, T_VOID);
  GrowableArray<int>* aflags =
    new (arena) GrowableArray<int>(arena, 8, 0, 0);
  GrowableArray<int>* fieldoffsets =
    new (arena) GrowableArray<int>(arena, 8, 0, 0);

  int pos = 0;

  fill_in_header_fields(fieldtypes, fieldoffsets, pos);
  _header_count = pos;
  fill_in_instance_fields(fieldtypes, fieldoffsets, aflags, pos, klass);

#if 0
  // [RGV] instance size is in word's but pos is number
  // of fields.
  int fill_to = my_klass->instance_size();
  if (fieldtypes->length() < fill_to)
    fields->at_put_grow(fill_to-1, T_VOID, T_VOID);
  if (aflags->length() < fill_to)
    aflags->at_put_grow(fill_to-1, 0, 0);
#endif

  _fieldtypes = fieldtypes;
  _access_flags = aflags;
  _fieldoffsets = fieldoffsets;
}
void ScopeDesc::print_on(outputStream* st) const {
  // header
  st->print("ScopeDesc[%d]@0x%lx ", _decode_offset, _code->instructions_begin());
  print_value_on(st);
  // decode offsets
  if (WizardMode) {
    st->print_cr("offset:     %d",    _decode_offset);
    st->print_cr("bci:        %d",    bci());
    st->print_cr("locals:     %d",    _locals_decode_offset);
    st->print_cr("stack:      %d",    _expressions_decode_offset);
    st->print_cr("monitor:    %d",    _monitors_decode_offset);
    st->print_cr("sender:     %d",    _sender_decode_offset);
  }
  // locals
  { GrowableArray<ScopeValue*>* l = ((ScopeDesc*) this)->locals();
    if (l != NULL) {
      tty->print_cr("Locals");
      for (int index = 0; index < l->length(); index++) {
        st->print(" - l%d: ", index);
        l->at(index)->print_on(st);
        st->cr();
      }
    }
  }
  // expressions
  { GrowableArray<ScopeValue*>* l = ((ScopeDesc*) this)->expressions();
    if (l != NULL) {
      st->print_cr("Expression stack");
      for (int index = 0; index < l->length(); index++) {
        st->print(" - @%d: ", index);
        l->at(index)->print_on(st);
        st->cr();
      }
    }
  }
  // monitors
  { GrowableArray<MonitorValue*>* l = ((ScopeDesc*) this)->monitors();
    if (l != NULL) {
      st->print_cr("Monitor stack");
      for (int index = 0; index < l->length(); index++) {
        st->print(" - @%d: ", index);
        l->at(index)->print_on(st);
        st->cr();
      }
    }
  }

  if (!is_top()) {
    st->print_cr("Sender:");
    sender()->print_on(st);
  }
}
 // iteration support - return next code blob
 JvmtiCodeBlobDesc* next() {
   assert(_pos >= 0, "iteration not started");
   if (_pos+1 >= _code_blobs->length()) {
     return NULL;
   }
   return _code_blobs->at(++_pos);
 }
Exemple #5
0
void InlinedScope::markLocalsDebugVisible(GrowableArray<PReg*>* exprStack) {
  // this scope has at least one send - mark params & locals as debug-visible
  int i;
  if (_nofSends <= 1) {
    // first time we're called
    self()->preg()->debug = true;
    for (i = nofArguments() - 1; i >= 0; i--) {
      argument(i)->preg()->debug = true;
    }
    for (i = nofTemporaries() - 1; i >= 0; i--) {
      temporary(i)->preg()->debug = true;
    }
    // if there's a context, mark all context variables as debug-visible too.
    GrowableArray<Expr*>*  ct = contextTemporaries();
    if (ct != NULL) {
      for (i = 0; i < ct->length(); i++) {
        ct->at(i)->preg()->debug = true;
      }
    }
  }
  // also mark expression stack as debug-visible (excluding arguments to
  // current send) (the args are already excluded from the CallNode's
  // expression stack, so just use that one instead of this->exprStack)
  for (i = 0; i < exprStack->length(); i++) {
    exprStack->at(i)->debug = true;
  }
}
Exemple #6
0
void SendInfo::computeNSends(RScope* rscope, int bci) {
  GrowableArray<RScope*>* lst = rscope->subScopes(bci);
  nsends = 0;
  for (int i = lst->length() - 1; i >= 0; i--) {
    nsends += lst->at(i)->nsends;
  }
}
Exemple #7
0
void CompactHashtableWriter::allocate_table() {
  int entries_space = 0;
  for (int index = 0; index < _num_buckets; index++) {
    GrowableArray<Entry>* bucket = _buckets[index];
    int bucket_size = bucket->length();
    if (bucket_size == 1) {
      entries_space++;
    } else {
      entries_space += 2 * bucket_size;
    }
  }

  if (entries_space & ~BUCKET_OFFSET_MASK) {
    vm_exit_during_initialization("CompactHashtableWriter::allocate_table: Overflow! "
                                  "Too many entries.");
  }

  Thread* THREAD = VMThread::vm_thread();
  ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
  _compact_buckets = MetadataFactory::new_array<u4>(loader_data, _num_buckets + 1, THREAD);
  _compact_entries = MetadataFactory::new_array<u4>(loader_data, entries_space, THREAD);

  _stats->hashentry_count = _num_entries;
  _stats->hashentry_bytes = entries_space * sizeof(u4);
}
Exemple #8
0
// Write the compact table's buckets
void CompactHashtableWriter::dump_table(NumberSeq* summary) {
  u4 offset = 0;
  for (int index = 0; index < _num_buckets; index++) {
    GrowableArray<Entry>* bucket = _buckets[index];
    int bucket_size = bucket->length();
    if (bucket_size == 1) {
      // bucket with one entry is compacted and only has the symbol offset
      _compact_buckets->at_put(index, BUCKET_INFO(offset, VALUE_ONLY_BUCKET_TYPE));

      Entry ent = bucket->at(0);
      _compact_entries->at_put(offset++, ent.value());
      _num_value_only_buckets++;
    } else {
      // regular bucket, each entry is a symbol (hash, offset) pair
      _compact_buckets->at_put(index, BUCKET_INFO(offset, REGULAR_BUCKET_TYPE));

      for (int i=0; i<bucket_size; i++) {
        Entry ent = bucket->at(i);
        _compact_entries->at_put(offset++, u4(ent.hash())); // write entry hash
        _compact_entries->at_put(offset++, ent.value());
      }
      if (bucket_size == 0) {
        _num_empty_buckets++;
      } else {
        _num_other_buckets++;
      }
    }
    summary->add(bucket_size);
  }

  // Mark the end of the buckets
  _compact_buckets->at_put(_num_buckets, BUCKET_INFO(offset, TABLEEND_BUCKET_TYPE));
  assert(offset == (u4)_compact_entries->length(), "sanity");
}
void CodeBlobCollector::do_blob(CodeBlob* cb) {

  // ignore nmethods
  if (cb->is_nmethod()) {
    return;
  }
  // exclude VtableStubs, which are processed separately
  if (cb->is_buffer_blob() && strcmp(cb->name(), "vtable chunks") == 0) {
    return;
  }

  // check if this starting address has been seen already - the
  // assumption is that stubs are inserted into the list before the
  // enclosing BufferBlobs.
  address addr = cb->code_begin();
  for (int i=0; i<_global_code_blobs->length(); i++) {
    JvmtiCodeBlobDesc* scb = _global_code_blobs->at(i);
    if (addr == scb->code_begin()) {
      return;
    }
  }

  // record the CodeBlob details as a JvmtiCodeBlobDesc
  JvmtiCodeBlobDesc* scb = new JvmtiCodeBlobDesc(cb->name(), cb->code_begin(), cb->code_end());
  _global_code_blobs->append(scb);
}
 // iteration support - return next code blob
 nmethodDesc* next() {
   assert(_pos >= 0, "iteration not started");
   if (_pos+1 >= _nmethods->length()) {
     return NULL;
   }
   return _nmethods->at(++_pos);
 }  
 // address of an element in _nodes.  Used when the element is to be modified
 PointsToNode *ptnode_adr(uint idx) {
   if ((uint)_nodes->length() <= idx) {
     // expand _nodes array
     PointsToNode dummy = _nodes->at_grow(idx);
   }
   return _nodes->adr_at(idx);
 }
Exemple #12
0
void BytecodeHistogram::print(float cutoff) {
  ResourceMark rm;
  GrowableArray<HistoEntry*>* profile = sorted_array(_counters, Bytecodes::number_of_codes);
  // print profile
  int tot     = total_count(profile);
  int abs_sum = 0;
  tty->cr();   //0123456789012345678901234567890123456789012345678901234567890123456789
  tty->print_cr("Histogram of %d executed bytecodes:", tot);
  tty->cr();
  tty->print_cr("  absolute  relative  code    name");
  tty->print_cr("----------------------------------------------------------------------");
  int i = profile->length();
  while (i-- > 0) {
    HistoEntry* e = profile->at(i);
    int       abs = e->count();
    float     rel = abs * 100.0F / tot;
    if (cutoff <= rel) {
      tty->print_cr("%10d  %7.2f%%    %02x    %s", abs, rel, e->index(), name_for(e->index()));
      abs_sum += abs;
    }
  }
  tty->print_cr("----------------------------------------------------------------------");
  float rel_sum = abs_sum * 100.0F / tot;
  tty->print_cr("%10d  %7.2f%%    (cutoff = %.2f%%)", abs_sum, rel_sum, cutoff);
  tty->cr();
}
Exemple #13
0
// Returns MonitorInfos for all objects locked on this thread in youngest to oldest order
static GrowableArray<MonitorInfo*>* get_or_compute_monitor_info(JavaThread* thread) {
  GrowableArray<MonitorInfo*>* info = thread->cached_monitor_info();
  if (info != NULL) {
    return info;
  }

  info = new GrowableArray<MonitorInfo*>();

  // It's possible for the thread to not have any Java frames on it,
  // i.e., if it's the main thread and it's already returned from main()
  if (thread->has_last_Java_frame()) {
    RegisterMap rm(thread);
    for (javaVFrame* vf = thread->last_java_vframe(&rm); vf != NULL; vf = vf->java_sender()) {
      GrowableArray<MonitorInfo*> *monitors = vf->monitors();
      if (monitors != NULL) {
        int len = monitors->length();
        // Walk monitors youngest to oldest
        for (int i = len - 1; i >= 0; i--) {
          MonitorInfo* mon_info = monitors->at(i);
          if (mon_info->eliminated()) continue;
          oop owner = mon_info->owner();
          if (owner != NULL) {
            info->append(mon_info);
          }
        }
      }
    }
  }

  thread->set_cached_monitor_info(info);
  return info;
}
Exemple #14
0
void PerformanceDebugger::report_context(InlinedScope* s) {
  if (!DebugPerformance) return;
  Reporter r(this);
  GrowableArray<Expr*>* temps = s->contextTemporaries();
  const int len = temps->length();
  int nused = 0;
  for (int i = 0; i < len; i++) {
    PReg* r = temps->at(i)->preg();
    if (r->uplevelR() || r->uplevelW() || (r->isBlockPReg() && !r->isUnused())) nused++;
  }
  if (nused == 0) {
    str->print("  could not eliminate context of scope %s (fixable compiler restriction; should be eliminated)\n", s->key()->print_string());
  } else {
    str->print("  could not eliminate context of scope %s; temp(s) still used: ", s->key()->print_string());
    for (int j = 0; j < len; j++) {
      PReg* r = temps->at(j)->preg();
      if (r->uplevelR() || r->uplevelW()) {
	str->print("%d ", j);
      } else if (r->isBlockPReg() && !r->isUnused()) {
	str->print("%d (non-inlined block)", j);
      }
    }
    str->print("\n");
  } 
}
Exemple #15
0
//
// Count the number of objects for a lightweight monitor. The hobj
// parameter is object that owns the monitor so this routine will
// count the number of times the same object was locked by frames
// in java_thread.
//
jint
JvmtiEnvBase::count_locked_objects(JavaThread *java_thread, Handle hobj) {
  jint ret = 0;
  if (!java_thread->has_last_Java_frame()) {
    return ret;  // no Java frames so no monitors
  }

  ResourceMark rm;
  HandleMark   hm;
  RegisterMap  reg_map(java_thread);

  for(javaVFrame *jvf=java_thread->last_java_vframe(&reg_map); jvf != NULL;
                                                 jvf = jvf->java_sender()) {
    GrowableArray<MonitorInfo*>* mons = jvf->monitors();
    if (!mons->is_empty()) {
      for (int i = 0; i < mons->length(); i++) {
        MonitorInfo *mi = mons->at(i);
        if (mi->owner_is_scalar_replaced()) continue;

        // see if owner of the monitor is our object
        if (mi->owner() != NULL && mi->owner() == hobj()) {
          ret++;
        }
      }
    }
  }
  return ret;
}
Exemple #16
0
void javaVFrame::print() {
  ResourceMark rm;
  vframe::print();
  tty->print("\t");
  method()->print_value();
  tty->cr();
  tty->print_cr("\tbci:    %d", bci());

  print_stack_values("locals",      locals());
  print_stack_values("expressions", expressions());

  GrowableArray<MonitorInfo*>* list = monitors();
  if (list->is_empty()) return;
  tty->print_cr("\tmonitor list:");
  for (int index = (list->length()-1); index >= 0; index--) {
    MonitorInfo* monitor = list->at(index);
    tty->print("\t  obj\t");
    if (monitor->owner_is_scalar_replaced()) {
      Klass* k = java_lang_Class::as_Klass(monitor->owner_klass());
      tty->print("( is scalar replaced %s)", k->external_name());
    } else if (monitor->owner() == NULL) {
      tty->print("( null )");
    } else {
      monitor->owner()->print_value();
      tty->print("(" INTPTR_FORMAT ")", (address)monitor->owner());
    }
    if (monitor->eliminated() && is_compiled_frame())
      tty->print(" ( lock is eliminated )");
    tty->cr();
    tty->print("\t  ");
    monitor->lock()->print_on(tty);
    tty->cr();
  }
}
void PCRecorder::print() {
  if (counters == NULL) return;

  tty->cr();
  tty->print_cr("Printing compiled methods with PC buckets having more than %d ticks", ProfilerPCTickThreshold);
  tty->print_cr("===================================================================");
  tty->cr();

  GrowableArray<CodeBlob*>* candidates = new GrowableArray<CodeBlob*>(20);


  int s;
  {
    MutexLockerEx lm(CodeCache_lock, Mutex::_no_safepoint_check_flag);
    s = size();
  }

  for (int index = 0; index < s; index++) {
    int count = counters[index];
    if (count > ProfilerPCTickThreshold) {
      address pc = pc_for(index);
      CodeBlob* cb = CodeCache::find_blob_unsafe(pc);
      if (cb != NULL && candidates->find(cb) < 0) {
        candidates->push(cb);
      }
    }
  }
  for (int i = 0; i < candidates->length(); i++) {
    print_blobs(candidates->at(i));
  }
}
Exemple #18
0
void BytecodePairHistogram::print(float cutoff) {
  ResourceMark rm;
  GrowableArray<HistoEntry*>* profile = sorted_array(_counters, number_of_pairs);
  // print profile
  int tot     = total_count(profile);
  int abs_sum = 0;
  tty->cr();   //0123456789012345678901234567890123456789012345678901234567890123456789
  tty->print_cr("Histogram of %d executed bytecode pairs:", tot);
  tty->cr();
  tty->print_cr("  absolute  relative    codes    1st bytecode        2nd bytecode");
  tty->print_cr("----------------------------------------------------------------------");
  int i = profile->length();
  while (i-- > 0) {
    HistoEntry* e = profile->at(i);
    int       abs = e->count();
    float     rel = abs * 100.0F / tot;
    if (cutoff <= rel) {
      int   c1 = e->index() % number_of_codes;
      int   c2 = e->index() / number_of_codes;
      tty->print_cr("%10d   %6.3f%%    %02x %02x    %-19s %s", abs, rel, c1, c2, name_for(c1), name_for(c2));
      abs_sum += abs;
    }
  }
  tty->print_cr("----------------------------------------------------------------------");
  float rel_sum = abs_sum * 100.0F / tot;
  tty->print_cr("%10d   %6.3f%%    (cutoff = %.3f%%)", abs_sum, rel_sum, cutoff);
  tty->cr();
}
Exemple #19
0
void IdealGraphPrinter::print_method(ciMethod *method, int bci, InlineTree *tree) {
  begin_head(METHOD_ELEMENT);

  stringStream str;
  method->print_name(&str);

  stringStream shortStr;
  method->print_short_name(&shortStr);

  print_attr(METHOD_NAME_PROPERTY, str.as_string());
  print_attr(METHOD_SHORT_NAME_PROPERTY, shortStr.as_string());
  print_attr(METHOD_BCI_PROPERTY, bci);

  end_head();

  head(BYTECODES_ELEMENT);
  _xml->print_cr("<![CDATA[");
  method->print_codes_on(_xml);
  _xml->print_cr("]]>");
  tail(BYTECODES_ELEMENT);

  if (tree != NULL && tree->subtrees().length() > 0) {
    head(INLINE_ELEMENT);
    GrowableArray<InlineTree *> subtrees = tree->subtrees();
    for (int i = 0; i < subtrees.length(); i++) {
      print_inline_tree(subtrees.at(i));
    }
    tail(INLINE_ELEMENT);
  }

  tail(METHOD_ELEMENT);
  _xml->flush();
}
 bool contains_signature(Symbol* query) {
   for (int i = 0; i < _members.length(); ++i) {
     if (query == _members.at(i).first->signature()) {
       return true;
     }
   }
   return false;
 }
 ~KeepAliveRegistrar() {
   for (int i = _keep_alive.length() - 1; i >= 0; --i) {
     ConstantPool* cp = _keep_alive.at(i);
     int idx = _thread->metadata_handles()->find_from_end(cp);
     assert(idx > 0, "Must be in the list");
     _thread->metadata_handles()->remove_at(idx);
   }
 }
 // iteration support - return first code blob
 JvmtiCodeBlobDesc* first() {
   assert(_code_blobs != NULL, "not collected");
   if (_code_blobs->length() == 0) {
     return NULL;
   }
   _pos = 0;
   return _code_blobs->at(0);
 }
 void check_send(InterpretedIC* ic) {
   GrowableArray<RScope*>* sub = rs->subScopes(bci());
   if (sub->length() == 1 && sub->first()->isUntakenScope()) {
     // this send was never taken
   } else {
     was_executed = true;			// this send was taken in recompilee
   }
 }
 // iteration support - return first code blob
 nmethodDesc* first() {
   assert(_nmethods != NULL, "not collected");
   if (_nmethods->length() == 0) {
     return NULL;
   }
   _pos = 0;
   return _nmethods->at(0);
 }
  ~CodeBlobCollector() {
    if (_code_blobs != NULL) {
      for (int i=0; i<_code_blobs->length(); i++) {
	FreeHeap(_code_blobs->at(i));
      }
      delete _code_blobs;
    }
  }
Exemple #26
0
GrowableArray<MonitorInfo*>* compiledVFrame::monitors() const {
  // Natives has no scope
  if (scope() == NULL) {
    nmethod* nm = code();
    Method* method = nm->method();
    assert(method->is_native(), "");
    if (!method->is_synchronized()) {
      return new GrowableArray<MonitorInfo*>(0);
    }
    // This monitor is really only needed for UseBiasedLocking, but
    // return it in all cases for now as it might be useful for stack
    // traces and tools as well
    GrowableArray<MonitorInfo*> *monitors = new GrowableArray<MonitorInfo*>(1);
    // Casting away const
    frame& fr = (frame&) _fr;
    MonitorInfo* info = new MonitorInfo(
        fr.get_native_receiver(), fr.get_native_monitor(), false, false);
    monitors->push(info);
    return monitors;
  }
  GrowableArray<MonitorValue*>* monitors = scope()->monitors();
  if (monitors == NULL) {
    return new GrowableArray<MonitorInfo*>(0);
  }
  GrowableArray<MonitorInfo*>* result = new GrowableArray<MonitorInfo*>(monitors->length());
  for (int index = 0; index < monitors->length(); index++) {
    MonitorValue* mv = monitors->at(index);
    ScopeValue*   ov = mv->owner();
    StackValue *owner_sv = create_stack_value(ov); // it is an oop
    if (ov->is_object() && owner_sv->obj_is_scalar_replaced()) { // The owner object was scalar replaced
      assert(mv->eliminated(), "monitor should be eliminated for scalar replaced object");
      // Put klass for scalar replaced object.
      ScopeValue* kv = ((ObjectValue *)ov)->klass();
      assert(kv->is_constant_oop(), "klass should be oop constant for scalar replaced object");
      Handle k(((ConstantOopReadValue*)kv)->value()());
      assert(java_lang_Class::is_instance(k()), "must be");
      result->push(new MonitorInfo(k(), resolve_monitor_lock(mv->basic_lock()),
                                   mv->eliminated(), true));
    } else {
      result->push(new MonitorInfo(owner_sv->get_obj()(), resolve_monitor_lock(mv->basic_lock()),
                                   mv->eliminated(), false));
    }
  }
  return result;
}
Exemple #27
0
 static Thread* findThread(int thread_id) {
   for (int index = 0; index < threads->length(); index++) {
     Thread* thread = threads->at(index);
     if (thread == NULL) continue;
     if (thread->thread_id == thread_id)
       return thread;
   }
   return NULL;
 }
Exemple #28
0
void JvmtiBreakpoint::each_method_version_do(method_action meth_act) {
  ((methodOopDesc*)_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 PreviousVersionInfo.
  Thread *thread = Thread::current();
  instanceKlassHandle ikh = instanceKlassHandle(thread, _method->method_holder());
  Symbol* m_name = _method->name();
  Symbol* m_signature = _method->signature();

  {
    ResourceMark rm(thread);
    // PreviousVersionInfo objects returned via PreviousVersionWalker
    // contain a GrowableArray of handles. We have to clean up the
    // GrowableArray _after_ the PreviousVersionWalker destructor
    // has destroyed the handles.
    {
      // search previous versions if they exist
      PreviousVersionWalker pvw((instanceKlass *)ikh()->klass_part());
      for (PreviousVersionInfo * pv_info = pvw.next_previous_version();
           pv_info != NULL; pv_info = pvw.next_previous_version()) {
        GrowableArray<methodHandle>* methods =
          pv_info->prev_EMCP_method_handles();

        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--) {
          methodHandle method = methods->at(i);
          if (method->name() == m_name && method->signature() == m_signature) {
            RC_TRACE(0x00000800, ("%sing breakpoint in %s(%s)",
              meth_act == &methodOopDesc::set_breakpoint ? "sett" : "clear",
              method->name()->as_C_string(),
              method->signature()->as_C_string()));
            assert(!method->is_obsolete(), "only EMCP methods here");

            ((methodOopDesc*)method()->*meth_act)(_bci);
            break;
          }
        }
      }
    } // pvw is cleaned up
  } // rm is cleaned up
}
  ~nmethodCollector() {
    if (_nmethods != NULL) {
      for (int i=0; i<_nmethods->length(); i++) {
	nmethodDesc* blob = _nmethods->at(i);
	if (blob->map()!= NULL) {
	  FREE_C_HEAP_ARRAY(jvmtiAddrLocationMap, blob->map());
	}
      }
      delete _nmethods;
    }
  }
GrowableArray<ScopeValue*>* ScopeDesc::decode_object_values(int decode_offset) {
  if (decode_offset == DebugInformationRecorder::serialized_null) return NULL;
  GrowableArray<ScopeValue*>* result = new GrowableArray<ScopeValue*>();
  DebugInfoReadStream* stream = new DebugInfoReadStream(_code, decode_offset, result);
  int length = stream->read_int();
  for (int index = 0; index < length; index++) {
    // Objects values are pushed to 'result' array during read so that
    // object's fields could reference it (OBJECT_ID_CODE).
    (void)ScopeValue::read_from(stream);
  }
  assert(result->length() == length, "inconsistent debug information");
  return result;
}