src/share/vm/classfile/systemDictionary.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File

## src/share/vm/classfile/systemDictionary.cpp

Print this page

    *** 76,86 ****
      SymbolPropertyTable*   SystemDictionary::_invoke_method_table = NULL;

      int         SystemDictionary::_number_of_modifications = 0;
      int         SystemDictionary::_sdgeneration               = 0;
    ! const int   SystemDictionary::_primelist[_prime_array_size] = {1009,2017,4049,5051,10103,
                    20201,40423,99991};

      oop         SystemDictionary::_system_loader_lock_obj     =  NULL;

      Klass*      SystemDictionary::_well_known_klasses[SystemDictionary::WKID_LIMIT]
    --- 76,86 ----
      SymbolPropertyTable*   SystemDictionary::_invoke_method_table = NULL;

      int         SystemDictionary::_number_of_modifications    = 0;
      int         SystemDictionary::_sdgeneration               = 0;
    ! const int   SystemDictionary::_primelist[_prime_array_size] = {defaultSystemDictionarySize,2017,4049,5051,10103,
        20201,40423,99991};

      oop         SystemDictionary::_system_loader_lock_obj     =  NULL;

      Klass*      SystemDictionary::_well_known_klasses[SystemDictionary::WKID_LIMIT]
    *** 331,349 ****
        // Bugs 4643874, 4715493
        // compute_hash can have a safepoint

        ClassLoaderData* loader_data = class_loader_data(class_loader);
        unsigned int d_hash = dictionary()->compute_hash(child_name, loader_data);
    -   int d_index = dictionary()->hash_to_index(d_hash);
        unsigned int p_hash = placeholders()->compute_hash(child_name, loader_data);
    -   int p_index = placeholders()->hash_to_index(p_hash);
        // can't throw error holding a lock
        bool child_already_loaded = false;
        bool throw_circularity_error = false;
        {
          MutexLocker mu(SystemDictionary_lock, THREAD);
    !     Klass* childk = find_class(d_index, d_hash, child_name, loader_data);
          Klass* quicksuperk;
          // to support // loading: if child done loading, just return superclass
          // if class_name, & class_loader don't match:
          // if initial define, SD update will give LinkageError
          // if redefine: compare_class_versions will give HIERARCHY_CHANGED
    --- 331,348 ----
        // Bugs 4643874, 4715493
        // compute_hash can have a safepoint

        ClassLoaderData* loader_data = class_loader_data(class_loader);
        unsigned int d_hash = dictionary()->compute_hash(child_name, loader_data);
        unsigned int p_hash = placeholders()->compute_hash(child_name, loader_data);
        // can't throw error holding a lock
        bool child_already_loaded = false;
        bool throw_circularity_error = false;
        {
          MutexLocker mu(SystemDictionary_lock, THREAD);
    !     int p_index = placeholders()->hash_to_index(p_hash);
    !     Klass* childk = find_class(d_hash, child_name, loader_data);
          Klass* quicksuperk;
          // to support // loading: if child done loading, just return superclass
          // if class_name, & class_loader don't match:
          // if initial define, SD update will give LinkageError
          // if redefine: compare_class_versions will give HIERARCHY_CHANGED
    *** 386,395 ****
    --- 385,395 ----
        // The instanceKlass is kept alive because the class loader is on the stack,
        // which keeps the loader_data alive, as well as all instanceKlasses in
        // the loader_data. parseClassFile adds the instanceKlass to loader_data.
        {
          MutexLocker mu(SystemDictionary_lock, THREAD);
    +     int p_index = placeholders()->hash_to_index(p_hash);
          placeholders()->find_and_remove(p_index, p_hash, child_name, loader_data, PlaceholderTable::LOAD_SUPER, THREAD);
          SystemDictionary_lock->notify_all();
        }
        if (HAS_PENDING_EXCEPTION || superk_h() == NULL) {
          // can null superk
    *** 443,453 ****
          // the last time it was calculated.
          ClassLoaderData* loader_data = class_loader_data(class_loader);

          Symbol*  kn = klass->name();
          unsigned int d_hash = dictionary()->compute_hash(kn, loader_data);
    -     int d_index = dictionary()->hash_to_index(d_hash);

          MutexLocker mu(SystemDictionary_lock, THREAD);
          {
            // Note that we have an entry, and entries can be deleted only during GC,
            // so we cannot allow GC to occur while we're holding this entry.
    --- 443,452 ----
    *** 455,465 ****
            // We're using a No_Safepoint_Verifier to catch any place where we
            // might potentially do a GC at all.
            // Dictionary::do_unloading() asserts that classes in SD are only
            // unloaded at a safepoint. Anonymous classes are not in SD.
            No_Safepoint_Verifier nosafepoint;
    !       dictionary()->add_protection_domain(d_index, d_hash, klass, loader_data,
                                                protection_domain, THREAD);
          }
        }
      }

    --- 454,464 ----
            // We're using a No_Safepoint_Verifier to catch any place where we
            // might potentially do a GC at all.
            // Dictionary::do_unloading() asserts that classes in SD are only
            // unloaded at a safepoint. Anonymous classes are not in SD.
            No_Safepoint_Verifier nosafepoint;
    !       dictionary()->add_protection_domain(d_hash, klass, loader_data,
                                                protection_domain, THREAD);
          }
        }
      }

    *** 521,533 ****
          Handle protection_domain, Handle lockObject, TRAPS) {

        instanceKlassHandle nh = instanceKlassHandle(); // null Handle
        ClassLoaderData* loader_data = class_loader_data(class_loader);
        unsigned int d_hash = dictionary()->compute_hash(name, loader_data);
    -   int d_index = dictionary()->hash_to_index(d_hash);
        unsigned int p_hash = placeholders()->compute_hash(name, loader_data);
    -   int p_index = placeholders()->hash_to_index(p_hash);

        // superk is not used, resolve_super called for circularity check only
        // This code is reached in two situations. One if this thread
        // is loading the same class twice (e.g. ClassCircularity, or
        // java.lang.instrument).
    --- 520,530 ----
    *** 545,555 ****
        // parallelCapable class loaders do NOT wait for parallel superclass loads to complete
        // Serial class loaders and bootstrap classloader do wait for superclass loads
       if (!class_loader.is_null() && is_parallelCapable(class_loader)) {
          MutexLocker mu(SystemDictionary_lock, THREAD);
          // Check if classloading completed while we were loading superclass or waiting
    !     Klass* check = find_class(d_index, d_hash, name, loader_data);
          if (check != NULL) {
            // Klass is already loaded, so just return it
            return(instanceKlassHandle(THREAD, check));
          } else {
            return nh;
    --- 542,552 ----
        // parallelCapable class loaders do NOT wait for parallel superclass loads to complete
        // Serial class loaders and bootstrap classloader do wait for superclass loads
       if (!class_loader.is_null() && is_parallelCapable(class_loader)) {
          MutexLocker mu(SystemDictionary_lock, THREAD);
          // Check if classloading completed while we were loading superclass or waiting
    !     Klass* check = find_class(d_hash, name, loader_data);
          if (check != NULL) {
            // Klass is already loaded, so just return it
            return(instanceKlassHandle(THREAD, check));
          } else {
            return nh;
    *** 560,571 ****
        // and spurious notifications
        bool super_load_in_progress = true;
        PlaceholderEntry* placeholder;
        while (super_load_in_progress) {
          MutexLocker mu(SystemDictionary_lock, THREAD);
          // Check if classloading completed while we were loading superclass or waiting
    !     Klass* check = find_class(d_index, d_hash, name, loader_data);
          if (check != NULL) {
            // Klass is already loaded, so just return it
            return(instanceKlassHandle(THREAD, check));
          } else {
            placeholder = placeholders()->get_entry(p_index, p_hash, name, loader_data);
    --- 557,569 ----
        // and spurious notifications
        bool super_load_in_progress = true;
        PlaceholderEntry* placeholder;
        while (super_load_in_progress) {
          MutexLocker mu(SystemDictionary_lock, THREAD);
    +     int p_index = placeholders()->hash_to_index(p_hash);
          // Check if classloading completed while we were loading superclass or waiting
    !     Klass* check = find_class(d_hash, name, loader_data);
          if (check != NULL) {
            // Klass is already loaded, so just return it
            return(instanceKlassHandle(THREAD, check));
          } else {
            placeholder = placeholders()->get_entry(p_index, p_hash, name, loader_data);
    *** 618,629 ****
        // This call uses find which checks protection domain already matches
        // All subsequent calls use find_class, and set has_loaded_class so that
        // before we return a result we call out to java to check for valid protection domain
        // to allow returning the Klass* and add it to the pd_set if it is valid
        unsigned int d_hash = dictionary()->compute_hash(name, loader_data);
    !   int d_index = dictionary()->hash_to_index(d_hash);
    !   Klass* probe = dictionary()->find(d_index, d_hash, name, loader_data,
                                            protection_domain, THREAD);
        if (probe != NULL) return probe;

        // Non-bootstrap class loaders will call out to class loader and
    --- 616,626 ----
        // This call uses find which checks protection domain already matches
        // All subsequent calls use find_class, and set has_loaded_class so that
        // before we return a result we call out to java to check for valid protection domain
        // to allow returning the Klass* and add it to the pd_set if it is valid
        unsigned int d_hash = dictionary()->compute_hash(name, loader_data);
    !   Klass* probe = dictionary()->find(d_hash, name, loader_data,
                                            protection_domain, THREAD);
        if (probe != NULL) return probe;

        // Non-bootstrap class loaders will call out to class loader and
    *** 639,649 ****
        if (is_parallelCapable(class_loader)) {
          DoObjectLock = false;
        }

        unsigned int p_hash = placeholders()->compute_hash(name, loader_data);
    -   int p_index = placeholders()->hash_to_index(p_hash);

        // Class is not in SystemDictionary so we have to do loading.
        // Make sure we are synchronized on the class loader before we proceed
        Handle lockObject = compute_loader_lock_object(class_loader, THREAD);
        check_loader_lock_contention(lockObject, THREAD);
    --- 636,645 ----
    *** 657,667 ****
        PlaceholderEntry* placeholder;
        Symbol* superclassname = NULL;

        {
          MutexLocker mu(SystemDictionary_lock, THREAD);
    !     Klass* check = find_class(d_index, d_hash, name, loader_data);
          if (check != NULL) {
            // Klass is already loaded, so just return it
            class_has_been_loaded = true;
            k = instanceKlassHandle(THREAD, check);
          } else {
    --- 653,664 ----
        PlaceholderEntry* placeholder;
        Symbol* superclassname = NULL;

        {
          MutexLocker mu(SystemDictionary_lock, THREAD);
    !     int p_index = placeholders()->hash_to_index(p_hash);
    !     Klass* check = find_class(d_hash, name, loader_data);
          if (check != NULL) {
            // Klass is already loaded, so just return it
            class_has_been_loaded = true;
            k = instanceKlassHandle(THREAD, check);
          } else {
    *** 717,726 ****
    --- 714,724 ----
          // case 5. parallelCapable user level classloaders - without objectLocker
          //    Allow parallel classloading of a class/classloader pair

          {
            MutexLocker mu(SystemDictionary_lock, THREAD);
    +       int p_index = placeholders()->hash_to_index(p_hash);
            if (class_loader.is_null() || !is_parallelCapable(class_loader)) {
              PlaceholderEntry* oldprobe = placeholders()->get_entry(p_index, p_hash, name, loader_data);
              if (oldprobe) {
                // only need check_seen_thread once, not on each loop
                // 6341374 java/lang/Instrument with -Xcomp
    *** 738,748 ****
                    // case 2: traditional with broken classloader lock. wait on first
                    // requestor.
                      double_lock_wait(lockObject, THREAD);
                    }
                    // Check if classloading completed while we were waiting
    !               Klass* check = find_class(d_index, d_hash, name, loader_data);
                    if (check != NULL) {
                      // Klass is already loaded, so just return it
                      k = instanceKlassHandle(THREAD, check);
                      class_has_been_loaded = true;
                    }
    --- 736,746 ----
                    // case 2: traditional with broken classloader lock. wait on first
                    // requestor.
                      double_lock_wait(lockObject, THREAD);
                    }
                    // Check if classloading completed while we were waiting
    !               Klass* check = find_class(d_hash, name, loader_data);
                    if (check != NULL) {
                      // Klass is already loaded, so just return it
                      k = instanceKlassHandle(THREAD, check);
                      class_has_been_loaded = true;
                    }
    *** 763,773 ****
              // if they did not catch another thread holding LOAD_INSTANCE,
              // need a check analogous to the acquire ObjectLocker/find_class
              // i.e. now that we hold the LOAD_INSTANCE token on loading this class/CL
              // one final check if the load has already completed
              // class loaders holding the ObjectLock shouldn't find the class here
    !         Klass* check = find_class(d_index, d_hash, name, loader_data);
              if (check != NULL) {
              // Klass is already loaded, so return it after checking/adding protection domain
                k = instanceKlassHandle(THREAD, check);
                class_has_been_loaded = true;
              }
    --- 761,771 ----
              // if they did not catch another thread holding LOAD_INSTANCE,
              // need a check analogous to the acquire ObjectLocker/find_class
              // i.e. now that we hold the LOAD_INSTANCE token on loading this class/CL
              // one final check if the load has already completed
              // class loaders holding the ObjectLock shouldn't find the class here
    !         Klass* check = find_class(d_hash, name, loader_data);
              if (check != NULL) {
              // Klass is already loaded, so return it after checking/adding protection domain
                k = instanceKlassHandle(THREAD, check);
                class_has_been_loaded = true;
              }
    *** 796,806 ****
            // Bootstrap goes through here to allow for an extra guarantee check
            if (UnsyncloadClass || (class_loader.is_null())) {
              if (k.is_null() && HAS_PENDING_EXCEPTION
                && PENDING_EXCEPTION->is_a(SystemDictionary::LinkageError_klass())) {
                MutexLocker mu(SystemDictionary_lock, THREAD);
    !           Klass* check = find_class(d_index, d_hash, name, loader_data);
                if (check != NULL) {
                  // Klass is already loaded, so just use it
                  k = instanceKlassHandle(THREAD, check);
                  CLEAR_PENDING_EXCEPTION;
                  guarantee((!class_loader.is_null()), "dup definition for bootstrap loader?");
    --- 794,804 ----
            // Bootstrap goes through here to allow for an extra guarantee check
            if (UnsyncloadClass || (class_loader.is_null())) {
              if (k.is_null() && HAS_PENDING_EXCEPTION
                && PENDING_EXCEPTION->is_a(SystemDictionary::LinkageError_klass())) {
                MutexLocker mu(SystemDictionary_lock, THREAD);
    !           Klass* check = find_class(d_hash, name, loader_data);
                if (check != NULL) {
                  // Klass is already loaded, so just use it
                  k = instanceKlassHandle(THREAD, check);
                  CLEAR_PENDING_EXCEPTION;
                  guarantee((!class_loader.is_null()), "dup definition for bootstrap loader?");
    *** 811,829 ****
            // If everything was OK (no exceptions, no null return value), and
            // class_loader is NOT the defining loader, do a little more bookkeeping.
            if (!HAS_PENDING_EXCEPTION && !k.is_null() &&
              k->class_loader() != class_loader()) {

    !         check_constraints(d_index, d_hash, k, class_loader, false, THREAD);

              // Need to check for a PENDING_EXCEPTION again; check_constraints
              // can throw and doesn't use the CHECK macro.
              if (!HAS_PENDING_EXCEPTION) {
                { // Grabbing the Compile_lock prevents systemDictionary updates
                  // during compilations.
                  MutexLocker mu(Compile_lock, THREAD);
    !             update_dictionary(d_index, d_hash, p_index, p_hash,
                                    k, class_loader, THREAD);
                }

                if (JvmtiExport::should_post_class_load()) {
                  Thread *thread = THREAD;
    --- 809,827 ----
            // If everything was OK (no exceptions, no null return value), and
            // class_loader is NOT the defining loader, do a little more bookkeeping.
            if (!HAS_PENDING_EXCEPTION && !k.is_null() &&
              k->class_loader() != class_loader()) {

    !         check_constraints(d_hash, k, class_loader, false, THREAD);

              // Need to check for a PENDING_EXCEPTION again; check_constraints
              // can throw and doesn't use the CHECK macro.
              if (!HAS_PENDING_EXCEPTION) {
                { // Grabbing the Compile_lock prevents systemDictionary updates
                  // during compilations.
                  MutexLocker mu(Compile_lock, THREAD);
    !             update_dictionary(d_hash, p_hash,
                                    k, class_loader, THREAD);
                }

                if (JvmtiExport::should_post_class_load()) {
                  Thread *thread = THREAD;
    *** 837,846 ****
    --- 835,845 ----
          if (load_instance_added == true) {
            // clean up placeholder entries for LOAD_INSTANCE success or error
            // This brackets the SystemDictionary updates for both defining
            // and initiating loaders
            MutexLocker mu(SystemDictionary_lock, THREAD);
    +       int p_index = placeholders()->hash_to_index(p_hash);
            placeholders()->find_and_remove(p_index, p_hash, name, loader_data, PlaceholderTable::LOAD_INSTANCE, THREAD);
            SystemDictionary_lock->notify_all();
          }
        }

    *** 870,880 ****
          // We're using a No_Safepoint_Verifier to catch any place where we
          // might potentially do a GC at all.
          // Dictionary::do_unloading() asserts that classes in SD are only
          // unloaded at a safepoint. Anonymous classes are not in SD.
          No_Safepoint_Verifier nosafepoint;
    !     if (dictionary()->is_valid_protection_domain(d_index, d_hash, name,
                                                       loader_data,
                                                       protection_domain)) {
            return k();
          }
        }
    --- 869,879 ----
          // We're using a No_Safepoint_Verifier to catch any place where we
          // might potentially do a GC at all.
          // Dictionary::do_unloading() asserts that classes in SD are only
          // unloaded at a safepoint. Anonymous classes are not in SD.
          No_Safepoint_Verifier nosafepoint;
    !     if (dictionary()->is_valid_protection_domain(d_hash, name,
                                                       loader_data,
                                                       protection_domain)) {
            return k();
          }
        }
    *** 914,934 ****
          // then the class loader has no entries in the dictionary.
          return NULL;
        }

        unsigned int d_hash = dictionary()->compute_hash(class_name, loader_data);
    -   int d_index = dictionary()->hash_to_index(d_hash);

        {
          // Note that we have an entry, and entries can be deleted only during GC,
          // so we cannot allow GC to occur while we're holding this entry.
          // We're using a No_Safepoint_Verifier to catch any place where we
          // might potentially do a GC at all.
          // Dictionary::do_unloading() asserts that classes in SD are only
          // unloaded at a safepoint. Anonymous classes are not in SD.
          No_Safepoint_Verifier nosafepoint;
    !     return dictionary()->find(d_index, d_hash, class_name, loader_data,
                                    protection_domain, THREAD);
        }
      }

    --- 913,932 ----
          // then the class loader has no entries in the dictionary.
          return NULL;
        }

        unsigned int d_hash = dictionary()->compute_hash(class_name, loader_data);

        {
          // Note that we have an entry, and entries can be deleted only during GC,
          // so we cannot allow GC to occur while we're holding this entry.
          // We're using a No_Safepoint_Verifier to catch any place where we
          // might potentially do a GC at all.
          // Dictionary::do_unloading() asserts that classes in SD are only
          // unloaded at a safepoint. Anonymous classes are not in SD.
          No_Safepoint_Verifier nosafepoint;
    !     return dictionary()->find(d_hash, class_name, loader_data,
                                    protection_domain, THREAD);
        }
      }

    *** 1156,1168 ****
      // given shared system class, if any.

      Klass* SystemDictionary::find_shared_class(Symbol* class_name) {
        if (shared_dictionary() != NULL) {
          unsigned int d_hash = shared_dictionary()->compute_hash(class_name, NULL);
    -     int d_index = shared_dictionary()->hash_to_index(d_hash);

    !     return shared_dictionary()->find_shared_class(d_index, d_hash, class_name);
        } else {
          return NULL;
        }
      }

    --- 1154,1165 ----
      // given shared system class, if any.

      Klass* SystemDictionary::find_shared_class(Symbol* class_name) {
        if (shared_dictionary() != NULL) {
          unsigned int d_hash = shared_dictionary()->compute_hash(class_name, NULL);

    !     return shared_dictionary()->find_shared_class(d_hash, class_name);
        } else {
          return NULL;
        }
      }

    *** 1390,1401 ****
        // classloader lock held
        // Parallel classloaders will call find_or_define_instance_class
        // which will require a token to perform the define class
        Symbol*  name_h = k->name();
        unsigned int d_hash = dictionary()->compute_hash(name_h, loader_data);
    !   int d_index = dictionary()->hash_to_index(d_hash);
    !   check_constraints(d_index, d_hash, k, class_loader_h, true, CHECK);

        // Register class just loaded with class loader (placed in Vector)
        // Note we do this before updating the dictionary, as this can
        // fail with an OutOfMemoryError (if it does, we will *not* put this
        // class in the dictionary and will not update the class hierarchy).
    --- 1387,1397 ----
        // classloader lock held
        // Parallel classloaders will call find_or_define_instance_class
        // which will require a token to perform the define class
        Symbol*  name_h = k->name();
        unsigned int d_hash = dictionary()->compute_hash(name_h, loader_data);
    !   check_constraints(d_hash, k, class_loader_h, true, CHECK);

        // Register class just loaded with class loader (placed in Vector)
        // Note we do this before updating the dictionary, as this can
        // fail with an OutOfMemoryError (if it does, we will *not* put this
        // class in the dictionary and will not update the class hierarchy).
    *** 1409,1429 ****
        }

        // Add the new class. We need recompile lock during update of CHA.
        {
          unsigned int p_hash = placeholders()->compute_hash(name_h, loader_data);
    -     int p_index = placeholders()->hash_to_index(p_hash);

          MutexLocker mu_r(Compile_lock, THREAD);

          // Add to class hierarchy, initialize vtables, and do possible
          // deoptimizations.
          add_to_hierarchy(k, CHECK); // No exception, but can block

          // Add to systemDictionary - so other classes can see it.
          // Grabs and releases SystemDictionary_lock
    !     update_dictionary(d_index, d_hash, p_index, p_hash,
                            k, class_loader_h, THREAD);
        }
        k->eager_initialize(THREAD);

        // notify jvmti
    --- 1405,1424 ----
        }

        // Add the new class. We need recompile lock during update of CHA.
        {
          unsigned int p_hash = placeholders()->compute_hash(name_h, loader_data);

          MutexLocker mu_r(Compile_lock, THREAD);

          // Add to class hierarchy, initialize vtables, and do possible
          // deoptimizations.
          add_to_hierarchy(k, CHECK); // No exception, but can block

          // Add to systemDictionary - so other classes can see it.
          // Grabs and releases SystemDictionary_lock
    !     update_dictionary(d_hash, p_hash,
                            k, class_loader_h, THREAD);
        }
        k->eager_initialize(THREAD);

        // notify jvmti
    *** 1456,1477 ****
        instanceKlassHandle nh = instanceKlassHandle(); // null Handle
        Symbol*  name_h = k->name(); // passed in class_name may be null
        ClassLoaderData* loader_data = class_loader_data(class_loader);

        unsigned int d_hash = dictionary()->compute_hash(name_h, loader_data);
    -   int d_index = dictionary()->hash_to_index(d_hash);

      // Hold SD lock around find_class and placeholder creation for DEFINE_CLASS
        unsigned int p_hash = placeholders()->compute_hash(name_h, loader_data);
    -   int p_index = placeholders()->hash_to_index(p_hash);
        PlaceholderEntry* probe;

        {
          MutexLocker mu(SystemDictionary_lock, THREAD);
          // First check if class already defined
          if (UnsyncloadClass || (is_parallelDefine(class_loader))) {
    !       Klass* check = find_class(d_index, d_hash, name_h, loader_data);
            if (check != NULL) {
              return(instanceKlassHandle(THREAD, check));
            }
          }

    --- 1451,1471 ----
        instanceKlassHandle nh = instanceKlassHandle(); // null Handle
        Symbol*  name_h = k->name(); // passed in class_name may be null
        ClassLoaderData* loader_data = class_loader_data(class_loader);

        unsigned int d_hash = dictionary()->compute_hash(name_h, loader_data);

      // Hold SD lock around find_class and placeholder creation for DEFINE_CLASS
        unsigned int p_hash = placeholders()->compute_hash(name_h, loader_data);
        PlaceholderEntry* probe;

        {
          MutexLocker mu(SystemDictionary_lock, THREAD);
    +     int p_index = placeholders()->hash_to_index(p_hash);
          // First check if class already defined
          if (UnsyncloadClass || (is_parallelDefine(class_loader))) {
    !       Klass* check = find_class(d_hash, name_h, loader_data);
            if (check != NULL) {
              return(instanceKlassHandle(THREAD, check));
            }
          }

    *** 1479,1499 ****
          probe = placeholders()->find_and_add(p_index, p_hash, name_h, loader_data, PlaceholderTable::DEFINE_CLASS, NULL, THREAD);
          // Wait if another thread defining in parallel
          // All threads wait - even those that will throw duplicate class: otherwise
          // caller is surprised by LinkageError: duplicate, but findLoadedClass fails
          // if other thread has not finished updating dictionary
    !     while (probe->definer() != NULL) {
            SystemDictionary_lock->wait();
          }
          // Only special cases allow parallel defines and can use other thread's results
          // Other cases fall through, and may run into duplicate defines
          // caught by finding an entry in the SystemDictionary
          if ((UnsyncloadClass || is_parallelDefine(class_loader)) && (probe->instance_klass() != NULL)) {
              placeholders()->find_and_remove(p_index, p_hash, name_h, loader_data, PlaceholderTable::DEFINE_CLASS, THREAD);
              SystemDictionary_lock->notify_all();
      #ifdef ASSERT
    !         Klass* check = find_class(d_index, d_hash, name_h, loader_data);
              assert(check != NULL, "definer missed recording success");
      #endif
              return(instanceKlassHandle(THREAD, probe->instance_klass()));
          } else {
            // This thread will define the class (even if earlier thread tried and had an error)
    --- 1473,1493 ----
          probe = placeholders()->find_and_add(p_index, p_hash, name_h, loader_data, PlaceholderTable::DEFINE_CLASS, NULL, THREAD);
          // Wait if another thread defining in parallel
          // All threads wait - even those that will throw duplicate class: otherwise
          // caller is surprised by LinkageError: duplicate, but findLoadedClass fails
          // if other thread has not finished updating dictionary
    !     while (probe->definer() != NULL) { // gznote: we're already holding SystemDictionary_lock, so why spin?
            SystemDictionary_lock->wait();
          }
          // Only special cases allow parallel defines and can use other thread's results
          // Other cases fall through, and may run into duplicate defines
          // caught by finding an entry in the SystemDictionary
          if ((UnsyncloadClass || is_parallelDefine(class_loader)) && (probe->instance_klass() != NULL)) {
              placeholders()->find_and_remove(p_index, p_hash, name_h, loader_data, PlaceholderTable::DEFINE_CLASS, THREAD);
              SystemDictionary_lock->notify_all();
      #ifdef ASSERT
    !         Klass* check = find_class(d_hash, name_h, loader_data);
              assert(check != NULL, "definer missed recording success");
      #endif
              return(instanceKlassHandle(THREAD, probe->instance_klass()));
          } else {
            // This thread will define the class (even if earlier thread tried and had an error)
    *** 1506,1515 ****
    --- 1500,1510 ----
        Handle linkage_exception = Handle(); // null handle

        // definer must notify any waiting threads
        {
          MutexLocker mu(SystemDictionary_lock, THREAD);
    +     int p_index = placeholders()->hash_to_index(p_hash);
          PlaceholderEntry* probe = placeholders()->get_entry(p_index, p_hash, name_h, loader_data);
          assert(probe != NULL, "DEFINE_CLASS placeholder lost?");
          if (probe != NULL) {
            if (HAS_PENDING_EXCEPTION) {
              linkage_exception = Handle(THREAD,PENDING_EXCEPTION);
    *** 1563,1580 ****
      }

      // ----------------------------------------------------------------------------
      // Lookup

    ! Klass* SystemDictionary::find_class(int index, unsigned int hash,
                                            Symbol* class_name,
                                            ClassLoaderData* loader_data) {
        assert_locked_or_safepoint(SystemDictionary_lock);
    !   assert (index == dictionary()->index_for(class_name, loader_data),
    !           "incorrect index?");
    !
    !   Klass* k = dictionary()->find_class(index, hash, class_name, loader_data);
        return k;
      }

      // Basic find on classes in the midst of being loaded
    --- 1558,1572 ----
      }

      // ----------------------------------------------------------------------------
      // Lookup

    ! Klass* SystemDictionary::find_class(unsigned int hash,
                                            Symbol* class_name,
                                            ClassLoaderData* loader_data) {
        assert_locked_or_safepoint(SystemDictionary_lock);
    !   Klass* k = dictionary()->find_class(hash, class_name, loader_data);
        return k;
      }

      // Basic find on classes in the midst of being loaded
    *** 1598,1609 ****
        #endif
        assert_locked_or_safepoint(SystemDictionary_lock);

        // First look in the loaded class array
        unsigned int d_hash = dictionary()->compute_hash(class_name, loader_data);
    !   int d_index = dictionary()->hash_to_index(d_hash);
    !   return find_class(d_index, d_hash, class_name, loader_data);
      }

      // Get the next class in the diictionary.
      Klass* SystemDictionary::try_get_next_class() {
    --- 1590,1600 ----
        #endif
        assert_locked_or_safepoint(SystemDictionary_lock);

        // First look in the loaded class array
        unsigned int d_hash = dictionary()->compute_hash(class_name, loader_data);
    !   return find_class(d_hash, class_name, loader_data);
      }

      // Get the next class in the diictionary.
      Klass* SystemDictionary::try_get_next_class() {
    *** 1813,1828 ****
    --- 1804,1834 ----

      void SystemDictionary::initialize(TRAPS) {
        // Allocate arrays
        assert(dictionary() == NULL,
               "SystemDictionary should only be initialized once");
    + #ifdef PRINT_HASHTABLES_CREATION
    +   fprintf(stderr, ">>>>> Creating SystemDictionary Dictionary\n");
    + #endif
        _sdgeneration        = 0;
        _dictionary          = new Dictionary(calculate_systemdictionary_size(PredictedLoadedClassCount));
    + #ifdef PRINT_HASHTABLES_CREATION
    +   fprintf(stderr, ">>>>> Creating SystemDictionary PlaceholderTable\n");
    + #endif
        _placeholders        = new PlaceholderTable(_nof_buckets);
        _number_of_modifications = 0;
    + #ifdef PRINT_HASHTABLES_CREATION
    +   fprintf(stderr, ">>>>> Creating SystemDictionary LoaderConstraintTable\n");
    + #endif
        _loader_constraints  = new LoaderConstraintTable(_loader_constraint_size);
    + #ifdef PRINT_HASHTABLES_CREATION
    +   fprintf(stderr, ">>>>> Creating SystemDictionary ResolutionErrorTable\n");
    + #endif
        _resolution_errors   = new ResolutionErrorTable(_resolution_error_size);
    + #ifdef PRINT_HASHTABLES_CREATION
    +   fprintf(stderr, ">>>>> Creating SystemDictionary SymbolPropertyTable\n");
    + #endif
        _invoke_method_table = new SymbolPropertyTable(_invoke_method_size);

        // Allocate private object used as system class loader lock
        _system_loader_lock_obj = oopFactory::new_intArray(0, CHECK);
        // Initialize basic classes
    *** 1964,1985 ****
      // that the system dictionary needs to maintain a set of contraints that
      // must be satisfied by all classes in the dictionary.
      // if defining is true, then LinkageError if already in systemDictionary
      // if initiating loader, then ok if InstanceKlass matches existing entry

    ! void SystemDictionary::check_constraints(int d_index, unsigned int d_hash,
                                               instanceKlassHandle k,
                                               Handle class_loader, bool defining,
                                               TRAPS) {
        const char *linkage_error = NULL;
        {
          Symbol*  name  = k->name();
          ClassLoaderData *loader_data = class_loader_data(class_loader);

          MutexLocker mu(SystemDictionary_lock, THREAD);

    !     Klass* check = find_class(d_index, d_hash, name, loader_data);
          if (check != (Klass*)NULL) {
            // if different InstanceKlass - duplicate class definition,
            // else - ok, class loaded by a different thread in parallel,
            // we should only have found it if it was done loading and ok to use
            // system dictionary only holds instance classes, placeholders
    --- 1970,1991 ----
      // that the system dictionary needs to maintain a set of contraints that
      // must be satisfied by all classes in the dictionary.
      // if defining is true, then LinkageError if already in systemDictionary
      // if initiating loader, then ok if InstanceKlass matches existing entry

    ! void SystemDictionary::check_constraints(unsigned int d_hash,
                                               instanceKlassHandle k,
                                               Handle class_loader, bool defining,
                                               TRAPS) {
        const char *linkage_error = NULL;
        {
          Symbol*  name  = k->name();
          ClassLoaderData *loader_data = class_loader_data(class_loader);

          MutexLocker mu(SystemDictionary_lock, THREAD);

    !     Klass* check = find_class(d_hash, name, loader_data);
          if (check != (Klass*)NULL) {
            // if different InstanceKlass - duplicate class definition,
            // else - ok, class loaded by a different thread in parallel,
            // we should only have found it if it was done loading and ok to use
            // system dictionary only holds instance classes, placeholders
    *** 2023,2034 ****
      }

      // Update system dictionary - done after check_constraint and add_to_hierachy
      // have been called.
    ! void SystemDictionary::update_dictionary(int d_index, unsigned int d_hash,
    !                                          int p_index, unsigned int p_hash,
                                               instanceKlassHandle k,
                                               Handle class_loader,
                                               TRAPS) {
        // Compile_lock prevents systemDictionary updates during compilations
        assert_locked_or_safepoint(Compile_lock);
    --- 2029,2040 ----
      }

      // Update system dictionary - done after check_constraint and add_to_hierachy
      // have been called.
    ! void SystemDictionary::update_dictionary(unsigned int d_hash,
    !                                          unsigned int p_hash,
                                               instanceKlassHandle k,
                                               Handle class_loader,
                                               TRAPS) {
        // Compile_lock prevents systemDictionary updates during compilations
        assert_locked_or_safepoint(Compile_lock);
    *** 2057,2073 ****
            k->set_prototype_header(markOopDesc::biased_locking_prototype());
          }
        }

        // Make a new system dictionary entry.
    !   Klass* sd_check = find_class(d_index, d_hash, name, loader_data);
        if (sd_check == NULL) {
          dictionary()->add_klass(name, loader_data, k);
          notice_modification();
        }
      #ifdef ASSERT
    !   sd_check = find_class(d_index, d_hash, name, loader_data);
        assert (sd_check != NULL, "should have entry in system dictionary");
        // Note: there may be a placeholder entry: for circularity testing
        // or for parallel defines
      #endif
          SystemDictionary_lock->notify_all();
    --- 2063,2079 ----
            k->set_prototype_header(markOopDesc::biased_locking_prototype());
          }
        }

        // Make a new system dictionary entry.
    !   Klass* sd_check = find_class(d_hash, name, loader_data);
        if (sd_check == NULL) {
          dictionary()->add_klass(name, loader_data, k);
          notice_modification();
        }
      #ifdef ASSERT
    !   sd_check = find_class(d_hash, name, loader_data);
        assert (sd_check != NULL, "should have entry in system dictionary");
        // Note: there may be a placeholder entry: for circularity testing
        // or for parallel defines
      #endif
          SystemDictionary_lock->notify_all();
    *** 2138,2171 ****
          } else {
            constraint_name = fd.object_key();
          }
        }
        unsigned int d_hash1 = dictionary()->compute_hash(constraint_name, loader_data1);
    -   int d_index1 = dictionary()->hash_to_index(d_hash1);
    -
        unsigned int d_hash2 = dictionary()->compute_hash(constraint_name, loader_data2);
    -   int d_index2 = dictionary()->hash_to_index(d_hash2);
        {
        MutexLocker mu_s(SystemDictionary_lock, THREAD);

        // Better never do a GC while we're holding these oops
        No_Safepoint_Verifier nosafepoint;

    !   Klass* klass1 = find_class(d_index1, d_hash1, constraint_name, loader_data1);
    !   Klass* klass2 = find_class(d_index2, d_hash2, constraint_name, loader_data2);
        return constraints()->add_entry(constraint_name, klass1, class_loader1,
                                        klass2, class_loader2);
        }
      }

      // Add entry to resolution error table to record the error when the first
      // attempt to resolve a reference to a class has failed.
      void SystemDictionary::add_resolution_error(constantPoolHandle pool, int which, Symbol* error) {
        unsigned int hash = resolution_errors()->compute_hash(pool, which);
    -   int index = resolution_errors()->hash_to_index(hash);
        {
          MutexLocker ml(SystemDictionary_lock, Thread::current());
          resolution_errors()->add_entry(index, hash, pool, which, error);
        }
      }

      // Delete a resolution error for RedefineClasses for a constant pool is going away
    --- 2144,2174 ----
          } else {
            constraint_name = fd.object_key();
          }
        }
        unsigned int d_hash1 = dictionary()->compute_hash(constraint_name, loader_data1);
        unsigned int d_hash2 = dictionary()->compute_hash(constraint_name, loader_data2);
        {
          MutexLocker mu_s(SystemDictionary_lock, THREAD);

          // Better never do a GC while we're holding these oops
          No_Safepoint_Verifier nosafepoint;

    !     Klass* klass1 = find_class(d_hash1, constraint_name, loader_data1);
    !     Klass* klass2 = find_class(d_hash2, constraint_name, loader_data2);
          return constraints()->add_entry(constraint_name, klass1, class_loader1,
                                          klass2, class_loader2);
        }
      }

      // Add entry to resolution error table to record the error when the first
      // attempt to resolve a reference to a class has failed.
      void SystemDictionary::add_resolution_error(constantPoolHandle pool, int which, Symbol* error) {
        unsigned int hash = resolution_errors()->compute_hash(pool, which);
        {
          MutexLocker ml(SystemDictionary_lock, Thread::current());
    +     int index = resolution_errors()->hash_to_index(hash);
          resolution_errors()->add_entry(index, hash, pool, which, error);
        }
      }

      // Delete a resolution error for RedefineClasses for a constant pool is going away
    *** 2174,2186 ****
      }

      // Lookup resolution error table. Returns error if found, otherwise NULL.
      Symbol* SystemDictionary::find_resolution_error(constantPoolHandle pool, int which) {
        unsigned int hash = resolution_errors()->compute_hash(pool, which);
    -   int index = resolution_errors()->hash_to_index(hash);
        {
          MutexLocker ml(SystemDictionary_lock, Thread::current());
          ResolutionErrorEntry* entry = resolution_errors()->find_entry(index, hash, pool, which);
          return (entry != NULL) ? entry->error() : (Symbol*)NULL;
        }
      }

    --- 2177,2189 ----
      }

      // Lookup resolution error table. Returns error if found, otherwise NULL.
      Symbol* SystemDictionary::find_resolution_error(constantPoolHandle pool, int which) {
        unsigned int hash = resolution_errors()->compute_hash(pool, which);
        {
          MutexLocker ml(SystemDictionary_lock, Thread::current());
    +     int index = resolution_errors()->hash_to_index(hash);
          ResolutionErrorEntry* entry = resolution_errors()->find_entry(index, hash, pool, which);
          return (entry != NULL) ? entry->error() : (Symbol*)NULL;
        }
      }

    *** 2286,2295 ****
    --- 2289,2299 ----
          }
          // Now grab the lock.  We might have to throw away the new method,
          // if a racing thread has managed to install one at the same time.
          {
            MutexLocker ml(SystemDictionary_lock, THREAD);
    +       index = invoke_method_table()->hash_to_index(hash);
            spe = invoke_method_table()->find_entry(index, hash, signature, iid);
            if (spe == NULL)
              spe = invoke_method_table()->add_entry(index, hash, signature, iid);
            if (spe->method() == NULL)
              spe->set_method(m());
    *** 2462,2471 ****
    --- 2466,2476 ----
        Handle method_type(THREAD, (oop) result.get_jobject());

        if (is_on_bcp) {
          // We can cache this MethodType inside the JVM.
          MutexLocker ml(SystemDictionary_lock, THREAD);
    +     index = invoke_method_table()->hash_to_index(hash);
          spe = invoke_method_table()->find_entry(index, hash, signature, null_iid);
          if (spe == NULL)
            spe = invoke_method_table()->add_entry(index, hash, signature, null_iid);
          if (spe->method_type() == NULL) {
            spe->set_method_type(method_type());
    *** 2617,2631 ****

      void SystemDictionary::print(bool details) {
        dictionary()->print(details);

        // Placeholders
    !   GCMutexLocker mu(SystemDictionary_lock);
    !   placeholders()->print();

        // loader constraints - print under SD_lock
    !   constraints()->print();
      }

      void SystemDictionary::verify() {
        guarantee(dictionary() != NULL, "Verify of system dictionary failed");
    --- 2622,2636 ----

      void SystemDictionary::print(bool details) {
        dictionary()->print(details);

        // Placeholders
    ! //  GCMutexLocker mu(SystemDictionary_lock);
    ! //  placeholders()->print();

        // loader constraints - print under SD_lock
    ! //  constraints()->print();
      }

      void SystemDictionary::verify() {
        guarantee(dictionary() != NULL, "Verify of system dictionary failed");

src/share/vm/classfile/systemDictionary.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File