src/share/vm/classfile/dictionary.hpp

changeset 5862
82af7d7a0128
parent 5100
43083e670adf
child 5865
aa6f2ea19d8f
     1.1 --- a/src/share/vm/classfile/dictionary.hpp	Wed Oct 09 11:18:53 2013 -0700
     1.2 +++ b/src/share/vm/classfile/dictionary.hpp	Wed Oct 09 10:57:01 2013 +0200
     1.3 @@ -1,5 +1,5 @@
     1.4  /*
     1.5 - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
     1.6 + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
     1.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.8   *
     1.9   * This code is free software; you can redistribute it and/or modify it
    1.10 @@ -27,11 +27,14 @@
    1.11  
    1.12  #include "classfile/systemDictionary.hpp"
    1.13  #include "oops/instanceKlass.hpp"
    1.14 -#include "oops/oop.hpp"
    1.15 +#include "oops/oop.inline.hpp"
    1.16  #include "utilities/hashtable.hpp"
    1.17  
    1.18  class DictionaryEntry;
    1.19  class PSPromotionManager;
    1.20 +class ProtectionDomainCacheTable;
    1.21 +class ProtectionDomainCacheEntry;
    1.22 +class BoolObjectClosure;
    1.23  
    1.24  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    1.25  // The data structure for the system dictionary (and the shared system
    1.26 @@ -45,6 +48,8 @@
    1.27    // pointer to the current hash table entry.
    1.28    static DictionaryEntry*       _current_class_entry;
    1.29  
    1.30 +  ProtectionDomainCacheTable*   _pd_cache_table;
    1.31 +
    1.32    DictionaryEntry* get_entry(int index, unsigned int hash,
    1.33                               Symbol* name, ClassLoaderData* loader_data);
    1.34  
    1.35 @@ -93,6 +98,7 @@
    1.36  
    1.37    void methods_do(void f(Method*));
    1.38  
    1.39 +  void unlink(BoolObjectClosure* is_alive);
    1.40  
    1.41    // Classes loaded by the bootstrap loader are always strongly reachable.
    1.42    // If we're not doing class unloading, all classes are strongly reachable.
    1.43 @@ -118,6 +124,7 @@
    1.44    // Sharing support
    1.45    void reorder_dictionary();
    1.46  
    1.47 +  ProtectionDomainCacheEntry* cache_get(oop protection_domain);
    1.48  
    1.49  #ifndef PRODUCT
    1.50    void print();
    1.51 @@ -126,21 +133,112 @@
    1.52  };
    1.53  
    1.54  // The following classes can be in dictionary.cpp, but we need these
    1.55 -// to be in header file so that SA's vmStructs can access.
    1.56 +// to be in header file so that SA's vmStructs can access them.
    1.57 +class ProtectionDomainCacheEntry : public HashtableEntry<oop, mtClass> {
    1.58 +  friend class VMStructs;
    1.59 + private:
    1.60 +  // Flag indicating whether this protection domain entry is strongly reachable.
    1.61 +  // Used during iterating over the system dictionary to remember oops that need
    1.62 +  // to be updated.
    1.63 +  bool _strongly_reachable;
    1.64 + public:
    1.65 +  oop protection_domain() { return literal(); }
    1.66 +
    1.67 +  void init() {
    1.68 +    _strongly_reachable = false;
    1.69 +  }
    1.70 +
    1.71 +  ProtectionDomainCacheEntry* next() {
    1.72 +    return (ProtectionDomainCacheEntry*)HashtableEntry<oop, mtClass>::next();
    1.73 +  }
    1.74 +
    1.75 +  ProtectionDomainCacheEntry** next_addr() {
    1.76 +    return (ProtectionDomainCacheEntry**)HashtableEntry<oop, mtClass>::next_addr();
    1.77 +  }
    1.78 +
    1.79 +  void oops_do(OopClosure* f) {
    1.80 +    f->do_oop(literal_addr());
    1.81 +  }
    1.82 +
    1.83 +  void set_strongly_reachable()   { _strongly_reachable = true; }
    1.84 +  bool is_strongly_reachable()    { return _strongly_reachable; }
    1.85 +  void reset_strongly_reachable() { _strongly_reachable = false; }
    1.86 +
    1.87 +  void print() PRODUCT_RETURN;
    1.88 +  void verify();
    1.89 +};
    1.90 +
    1.91 +// The ProtectionDomainCacheTable contains all protection domain oops. The system
    1.92 +// dictionary entries reference its entries instead of having references to oops
    1.93 +// directly.
    1.94 +// This is used to speed up system dictionary iteration: the oops in the
    1.95 +// protection domain are the only ones referring the Java heap. So when there is
    1.96 +// need to update these, instead of going over every entry of the system dictionary,
    1.97 +// we only need to iterate over this set.
    1.98 +// The amount of different protection domains used is typically magnitudes smaller
    1.99 +// than the number of system dictionary entries (loaded classes).
   1.100 +class ProtectionDomainCacheTable : public Hashtable<oop, mtClass> {
   1.101 +  friend class VMStructs;
   1.102 +private:
   1.103 +  ProtectionDomainCacheEntry* bucket(int i) {
   1.104 +    return (ProtectionDomainCacheEntry*) Hashtable<oop, mtClass>::bucket(i);
   1.105 +  }
   1.106 +
   1.107 +  // The following method is not MT-safe and must be done under lock.
   1.108 +  ProtectionDomainCacheEntry** bucket_addr(int i) {
   1.109 +    return (ProtectionDomainCacheEntry**) Hashtable<oop, mtClass>::bucket_addr(i);
   1.110 +  }
   1.111 +
   1.112 +  ProtectionDomainCacheEntry* new_entry(unsigned int hash, oop protection_domain) {
   1.113 +    ProtectionDomainCacheEntry* entry = (ProtectionDomainCacheEntry*) Hashtable<oop, mtClass>::new_entry(hash, protection_domain);
   1.114 +    entry->init();
   1.115 +    return entry;
   1.116 +  }
   1.117 +
   1.118 +  static unsigned int compute_hash(oop protection_domain) {
   1.119 +    return (unsigned int)(protection_domain->identity_hash());
   1.120 +  }
   1.121 +
   1.122 +  int index_for(oop protection_domain) {
   1.123 +    return hash_to_index(compute_hash(protection_domain));
   1.124 +  }
   1.125 +
   1.126 +  ProtectionDomainCacheEntry* add_entry(int index, unsigned int hash, oop protection_domain);
   1.127 +  ProtectionDomainCacheEntry* find_entry(int index, oop protection_domain);
   1.128 +
   1.129 +public:
   1.130 +
   1.131 +  ProtectionDomainCacheTable(int table_size);
   1.132 +
   1.133 +  ProtectionDomainCacheEntry* get(oop protection_domain);
   1.134 +  void free(ProtectionDomainCacheEntry* entry);
   1.135 +
   1.136 +  void unlink(BoolObjectClosure* cl);
   1.137 +
   1.138 +  // GC support
   1.139 +  void oops_do(OopClosure* f);
   1.140 +  void always_strong_oops_do(OopClosure* f);
   1.141 +
   1.142 +  static uint bucket_size();
   1.143 +
   1.144 +  void print() PRODUCT_RETURN;
   1.145 +  void verify();
   1.146 +};
   1.147 +
   1.148  
   1.149  class ProtectionDomainEntry :public CHeapObj<mtClass> {
   1.150    friend class VMStructs;
   1.151   public:
   1.152    ProtectionDomainEntry* _next;
   1.153 -  oop                    _protection_domain;
   1.154 +  ProtectionDomainCacheEntry* _pd_cache;
   1.155  
   1.156 -  ProtectionDomainEntry(oop protection_domain, ProtectionDomainEntry* next) {
   1.157 -    _protection_domain = protection_domain;
   1.158 -    _next              = next;
   1.159 +  ProtectionDomainEntry(ProtectionDomainCacheEntry* pd_cache, ProtectionDomainEntry* next) {
   1.160 +    _pd_cache = pd_cache;
   1.161 +    _next     = next;
   1.162    }
   1.163  
   1.164    ProtectionDomainEntry* next() { return _next; }
   1.165 -  oop protection_domain() { return _protection_domain; }
   1.166 +  oop protection_domain() { return _pd_cache->protection_domain(); }
   1.167  };
   1.168  
   1.169  // An entry in the system dictionary, this describes a class as
   1.170 @@ -151,6 +249,24 @@
   1.171   private:
   1.172    // Contains the set of approved protection domains that can access
   1.173    // this system dictionary entry.
   1.174 +  //
   1.175 +  // This protection domain set is a set of tuples:
   1.176 +  //
   1.177 +  // (InstanceKlass C, initiating class loader ICL, Protection Domain PD)
   1.178 +  //
   1.179 +  // [Note that C.protection_domain(), which is stored in the java.lang.Class
   1.180 +  // mirror of C, is NOT the same as PD]
   1.181 +  //
   1.182 +  // If such an entry (C, ICL, PD) exists in the table, it means that
   1.183 +  // it is okay for a class Foo to reference C, where
   1.184 +  //
   1.185 +  //    Foo.protection_domain() == PD, and
   1.186 +  //    Foo's defining class loader == ICL
   1.187 +  //
   1.188 +  // The usage of the PD set can be seen in SystemDictionary::validate_protection_domain()
   1.189 +  // It is essentially a cache to avoid repeated Java up-calls to
   1.190 +  // ClassLoader.checkPackageAccess().
   1.191 +  //
   1.192    ProtectionDomainEntry* _pd_set;
   1.193    ClassLoaderData*       _loader_data;
   1.194  
   1.195 @@ -158,7 +274,7 @@
   1.196    // Tells whether a protection is in the approved set.
   1.197    bool contains_protection_domain(oop protection_domain) const;
   1.198    // Adds a protection domain to the approved set.
   1.199 -  void add_protection_domain(oop protection_domain);
   1.200 +  void add_protection_domain(Dictionary* dict, oop protection_domain);
   1.201  
   1.202    Klass* klass() const { return (Klass*)literal(); }
   1.203    Klass** klass_addr() { return (Klass**)literal_addr(); }
   1.204 @@ -189,12 +305,11 @@
   1.205           : contains_protection_domain(protection_domain());
   1.206    }
   1.207  
   1.208 -
   1.209 -  void protection_domain_set_oops_do(OopClosure* f) {
   1.210 +  void set_strongly_reachable() {
   1.211      for (ProtectionDomainEntry* current = _pd_set;
   1.212                                  current != NULL;
   1.213                                  current = current->_next) {
   1.214 -      f->do_oop(&(current->_protection_domain));
   1.215 +      current->_pd_cache->set_strongly_reachable();
   1.216      }
   1.217    }
   1.218  
   1.219 @@ -202,7 +317,7 @@
   1.220      for (ProtectionDomainEntry* current = _pd_set;
   1.221                                  current != NULL;
   1.222                                  current = current->_next) {
   1.223 -      current->_protection_domain->verify();
   1.224 +      current->_pd_cache->protection_domain()->verify();
   1.225      }
   1.226    }
   1.227  

mercurial