-
Notifications
You must be signed in to change notification settings - Fork 5.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
8292375: Convert ProtectionDomainCacheTable to ResourceHashtable #10043
Conversation
👋 Welcome back coleenp! A progress list of the required criteria for merging this PR into |
Webrevs
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi Coleen,
Probably due to my lack of understanding of the existing code I found this conversion very hard to follow. A number of comments below.
Thanks.
unsigned int ProtectionDomainCacheTable::compute_hash(Handle protection_domain) { | ||
// Identity hash can safepoint, so keep protection domain in a Handle. | ||
return (unsigned int)(protection_domain->identity_hash()); | ||
unsigned int ProtectionDomainCacheTable::compute_hash(const WeakHandle& protection_domain) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are we now using WeakHandle
everywhere?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
WeakHandle is the object we're storing as the value in the hashtable. It also turns out to be the key.
Thanks for reading through this. I was going to make a larger change, then changed my mind. This conversion is limited. It is able to take advantage of the ability to copy WeakHandle without side effects, so that we don't have to store ProtectionDomainCacheEntry into the pd_set linked list, which makes it nicer. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good overall and seems to be equivalent to the old code. Just a couple of nits.
@coleenp This change now passes all automated pre-integration checks. ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details. After integration, the commit message for the final commit will be:
You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed. At the time when this comment was updated there had been 85 new commits pushed to the
As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details. ➡️ To integrate this PR with the above commit message to the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for reviewing, Ioi.
// The ProtectionDomainCacheTable maps all java.security.ProtectionDomain objects that are | ||
// registered by DictionaryEntry::add_protection_domain() to a unique WeakHandle. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that I understand what this table does, this comment is confusing to me. The table maps each PD to itself (using the WeakHandle as the actual key and value) as a means to track which PDs have been seen/registered. I would describe it thus:
// The ProtectionDomainCacheTable records all of the java.security.ProtectionDomain instances that have
// been registered by DictionaryEntry::add_protection_domain(). We use a hashtable to
map each PD
// instance to itself (using WeakHandles) to allow for fast lookup.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
“Mapping to itself” is how this table works internally. I am not sure if this information is useful here. But the purpose of this table is really to keep track of all PDs that have been registered and not yet garbage collected.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"mapping to itself" is more useful than "mapping ... to a unique Weakhandle" - which is even more of an internal implementation detail. I found the use of this table very hard to discern based on the internal use of the hashtable, as there is no real mapping operation - we simply track if a PD has been seen or not. The use of the hashtable is purely for lookup convenience - we could instead have a linked-list of PD's that we traverse for lookup.
So perhaps we drop my second sentence above, and move it to where the hashtable itself is declared?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"mapping a PD to a unique Weakhandle" is not an implementation detail. It's the only useful API provided by this class:
WeakHandle obj = ProtectionDomainCacheTable::add_if_absent(protection_domain);
and that's the reason I question why this table is needed at all.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The fact it is a weakhandle is an implementation detail. The table simply records whether a PD (wrapped in a WeakHandle) has been seen.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since I know what this table does, either comment is fine if it helps someone understand it.
The "map each PD to itself" is pretty odd to me too. How about collect each PD for fast lookup in a hashtable? The code says how it's mapped. There isn't that much code and it's easy to see how the Key is mapped.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// The ProtectionDomainCacheTable maps all java.security.ProtectionDomain objects that are
// registered by DictionaryEntry::add_protection_domain() to a unique entry. The entry
// is a WeakHandle that holds the protection domain oop.
or points to.... either is accurate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is the "maps ... to a unique entry" that I find most problematic - it begs the question as to what the unique entry is, when in reality it maps a PD instance (wrapped in a WeakHandle) to itself (wrapped in a WeakHandle).
For the sake of progress, approved.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The "unique" means there's only one value in the table for this protection domain oop. So the oop is unique. The use of word "mapping" might be what's confusing.
If we ever have to visit this code again (which I hope not, except to remove it because the security manager is finally removed since not many use it), we can see if this comment still makes sense to at least some of us.
Thanks for approving for progress.
I am utterly confused about why we need ProtectionDomainCacheTable at all. The only interface between this class and the rest of the world is:
(and there's code elsewhere for cleaning up this table, but that wouldn't be necessary if no one calls Why doesn't DictionaryEntry::add_protection_domain allocate the WeakHandle itself? I am looking at the JDK 8 code. It seems like ProtectionDomainCacheTable was needed before we had WeakHandle, so we had to do all the reference management by hand: But for today, is ProtectionDomainCacheTable a relic that can be thrown away? |
It tracks whether we have seen this PD before so that |
The reason we have the table is that you can have the same instance of java.security.ProtectionDomain used on multiple DictionaryEntry._pd_set lists. That is, multiple classes in the class loader data have had their loading initiated with the same protection domain, which is common. Creating WeakHandles for each is redundant and wasteful, so we want to have one WeakHandle for multiple entries to point to. The table is a place to store it. I had another version that stored the WeakHandle entries in the ClassLoaderData of the Dictionary of loaded classes that had them in their pd_set, but they had a linear lookup to determine if they were unique. We even performance tested that. In the end, I just translated the table to ResourceHashtable to make it easier to review and understand what this does. As an example, if you run hello world with the security manager allowed, you see this: java -Xlog:protectiondomain=trace -Djava.security.manager=allow -cp ~/work Hello Whenever we initiate loading (for example) java.lang.Object in a non bootstrap class loader with the SecureClassLoader, we pass this protection domain. Notice how the same protection domain is added to each class. Then if we lookup java.lang.Object again on this loader with this protection domain, it's quickly found. In JDK8 we pointed to the oop itself which required the GC to walk the global SystemDictionary. We definitely never want that, so moved it to a table, and made several other changes to enable concurrent class unloading after that - moved the Dictionaries of loaded classes to each class loader data. |
Thank you David and Ioi for approving and reviewing. |
Going to push as commit fcc0cf9.
Your commit was automatically rebased without conflicts. |
Please review this simple conversion for the ProtectionDomainCacheTable from Old Hashtable to ResourceHashtable. There are specific tests for this table in test/hotspot/jtreg/runtime/Dictionary and serviceability/dcmd/vm/DictionaryStatsTest.java.
Also tested with tier1-7.
Progress
Issue
Reviewers
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk pull/10043/head:pull/10043
$ git checkout pull/10043
Update a local copy of the PR:
$ git checkout pull/10043
$ git pull https://git.openjdk.org/jdk pull/10043/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 10043
View PR using the GUI difftool:
$ git pr show -t 10043
Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/10043.diff