1/*
2 * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25#ifndef SHARE_CLASSFILE_PROTECTIONDOMAINCACHE_HPP
26#define SHARE_CLASSFILE_PROTECTIONDOMAINCACHE_HPP
27
28#include "oops/oop.hpp"
29#include "oops/weakHandle.hpp"
30#include "memory/iterator.hpp"
31#include "utilities/hashtable.hpp"
32
33// This class caches the approved protection domains that can access loaded classes.
34// Dictionary entry pd_set point to entries in this hashtable. Please refer
35// to dictionary.hpp pd_set for more information about how protection domain entries
36// are used.
37// This table is walked during GC, rather than the class loader data graph dictionaries.
38class ProtectionDomainCacheEntry : public HashtableEntry<WeakHandle<vm_class_loader_data>, mtClass> {
39 friend class VMStructs;
40 public:
41 oop object();
42 oop object_no_keepalive();
43
44 ProtectionDomainCacheEntry* next() {
45 return (ProtectionDomainCacheEntry*)HashtableEntry<WeakHandle<vm_class_loader_data>, mtClass>::next();
46 }
47
48 ProtectionDomainCacheEntry** next_addr() {
49 return (ProtectionDomainCacheEntry**)HashtableEntry<WeakHandle<vm_class_loader_data>, mtClass>::next_addr();
50 }
51
52 void verify();
53};
54
55// The ProtectionDomainCacheTable contains all protection domain oops. The
56// dictionary entries reference its entries instead of having references to oops
57// directly.
58// This is used to speed up system dictionary iteration: the oops in the
59// protection domain are the only ones referring the Java heap. So when there is
60// need to update these, instead of going over every entry of the system dictionary,
61// we only need to iterate over this set.
62// The amount of different protection domains used is typically magnitudes smaller
63// than the number of system dictionary entries (loaded classes).
64class ProtectionDomainCacheTable : public Hashtable<WeakHandle<vm_class_loader_data>, mtClass> {
65 friend class VMStructs;
66private:
67 ProtectionDomainCacheEntry* bucket(int i) const {
68 return (ProtectionDomainCacheEntry*) Hashtable<WeakHandle<vm_class_loader_data>, mtClass>::bucket(i);
69 }
70
71 // The following method is not MT-safe and must be done under lock.
72 ProtectionDomainCacheEntry** bucket_addr(int i) {
73 return (ProtectionDomainCacheEntry**) Hashtable<WeakHandle<vm_class_loader_data>, mtClass>::bucket_addr(i);
74 }
75
76 ProtectionDomainCacheEntry* new_entry(unsigned int hash, WeakHandle<vm_class_loader_data> protection_domain) {
77 ProtectionDomainCacheEntry* entry = (ProtectionDomainCacheEntry*)
78 Hashtable<WeakHandle<vm_class_loader_data>, mtClass>::new_entry(hash, protection_domain);
79 return entry;
80 }
81
82 static unsigned int compute_hash(Handle protection_domain);
83
84 int index_for(Handle protection_domain);
85 ProtectionDomainCacheEntry* add_entry(int index, unsigned int hash, Handle protection_domain);
86 ProtectionDomainCacheEntry* find_entry(int index, Handle protection_domain);
87
88 bool _dead_entries;
89 int _total_oops_removed;
90
91public:
92 ProtectionDomainCacheTable(int table_size);
93 ProtectionDomainCacheEntry* get(Handle protection_domain);
94
95 void unlink();
96
97 void print_on(outputStream* st) const;
98 void verify();
99
100 bool has_work() { return _dead_entries; }
101 void trigger_cleanup();
102
103 int removed_entries_count() { return _total_oops_removed; };
104};
105
106
107class ProtectionDomainEntry :public CHeapObj<mtClass> {
108 friend class VMStructs;
109 public:
110 ProtectionDomainEntry* _next;
111 ProtectionDomainCacheEntry* _pd_cache;
112
113 ProtectionDomainEntry(ProtectionDomainCacheEntry* pd_cache, ProtectionDomainEntry* next) {
114 _pd_cache = pd_cache;
115 _next = next;
116 }
117
118 ProtectionDomainEntry* next() { return _next; }
119 void set_next(ProtectionDomainEntry* entry) { _next = entry; }
120 oop object();
121 oop object_no_keepalive();
122};
123#endif // SHARE_CLASSFILE_PROTECTIONDOMAINCACHE_HPP
124