bool Dictionary::do_unloading() {
  assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
  bool class_was_unloaded = false;
  int  index = 0; // Defined here for portability! Do not move

  // Remove unloadable entries and classes from system dictionary
  // The placeholder array has been handled in always_strong_oops_do.
  DictionaryEntry* probe = NULL;
  for (index = 0; index < table_size(); index++) {
    for (DictionaryEntry** p = bucket_addr(index); *p != NULL; ) {
      probe = *p;
      Klass* e = probe->klass();
      ClassLoaderData* loader_data = probe->loader_data();

      InstanceKlass* ik = InstanceKlass::cast(e);

      // Non-unloadable classes were handled in always_strong_oops_do
      if (!is_strongly_reachable(loader_data, e)) {
        // Entry was not visited in phase1 (negated test from phase1)
        assert(!loader_data->is_the_null_class_loader_data(), "unloading entry with null class loader");
        ClassLoaderData* k_def_class_loader_data = ik->class_loader_data();

        // Do we need to delete this system dictionary entry?
        bool purge_entry = false;

        // Do we need to delete this system dictionary entry?
        if (loader_data->is_unloading()) {
          // If the loader is not live this entry should always be
          // removed (will never be looked up again). Note that this is
          // not the same as unloading the referred class.
          if (k_def_class_loader_data == loader_data) {
            // This is the defining entry, so the referred class is about
            // to be unloaded.
            class_was_unloaded = true;
          }
          // Also remove this system dictionary entry.
          purge_entry = true;

        } else {
          // The loader in this entry is alive. If the klass is dead,
          // (determined by checking the defining class loader)
          // the loader must be an initiating loader (rather than the
          // defining loader). Remove this entry.
          if (k_def_class_loader_data->is_unloading()) {
            // If we get here, the class_loader_data must not be the defining
            // loader, it must be an initiating one.
            assert(k_def_class_loader_data != loader_data,
                   "cannot have live defining loader and unreachable klass");
            // Loader is live, but class and its defining loader are dead.
            // Remove the entry. The class is going away.
            purge_entry = true;
          }
        }

        if (purge_entry) {
          *p = probe->next();
          if (probe == _current_class_entry) {
            _current_class_entry = NULL;
          }
          free_entry(probe);
          continue;
        }
      }
      p = probe->next_addr();
    }
  }
  return class_was_unloaded;
}