Re: RFR: 8253495: CDS generates non-deterministic output [v8]

2022-03-15 Thread Calvin Cheung
On Tue, 15 Mar 2022 17:08:27 GMT, Ioi Lam  wrote:

>> This patch makes the result of "java -Xshare:dump" deterministic:
>> - Disabled new Java threads from launching. This is harmless. See comments 
>> in jvm.cpp
>> - Fixed a problem in hashtable ordering in heapShared.cpp
>> - BasicHashtableEntry has a gap on 64-bit platforms that may contain random 
>> bits. Added code to zero it.
>> - Enabled checking of $JAVA_HOME/lib/server/classes.jsa in 
>> make/scripts/compare.sh
>> 
>> Note:  $JAVA_HOME/lib/server/classes_ncoops.jsa is still non-deterministic. 
>> This will be fixed in 
>> [JDK-8282828](https://bugs.openjdk.java.net/browse/JDK-8282828).
>> 
>> Testing under way:
>> - tier1~tier5
>> - Run all *-cmp-baseline jobs 20 times each (linux-aarch64-cmp-baseline, 
>> windows-x86-cmp-baseline,  etc).
>
> Ioi Lam has updated the pull request incrementally with one additional commit 
> since the last revision:
> 
>   Avoid memset twice in os::malloc(); added comments about 
> NMTPreInit::handle_malloc vs DumpSharedSpaces

Marked as reviewed by ccheung (Reviewer).

-

PR: https://git.openjdk.java.net/jdk/pull/7748


Re: RFR: 8253495: CDS generates non-deterministic output [v8]

2022-03-15 Thread Ioi Lam
> This patch makes the result of "java -Xshare:dump" deterministic:
> - Disabled new Java threads from launching. This is harmless. See comments in 
> jvm.cpp
> - Fixed a problem in hashtable ordering in heapShared.cpp
> - BasicHashtableEntry has a gap on 64-bit platforms that may contain random 
> bits. Added code to zero it.
> - Enabled checking of $JAVA_HOME/lib/server/classes.jsa in 
> make/scripts/compare.sh
> 
> Note:  $JAVA_HOME/lib/server/classes_ncoops.jsa is still non-deterministic. 
> This will be fixed in 
> [JDK-8282828](https://bugs.openjdk.java.net/browse/JDK-8282828).
> 
> Testing under way:
> - tier1~tier5
> - Run all *-cmp-baseline jobs 20 times each (linux-aarch64-cmp-baseline, 
> windows-x86-cmp-baseline,  etc).

Ioi Lam has updated the pull request incrementally with one additional commit 
since the last revision:

  Avoid memset twice in os::malloc(); added comments about 
NMTPreInit::handle_malloc vs DumpSharedSpaces

-

Changes:
  - all: https://git.openjdk.java.net/jdk/pull/7748/files
  - new: https://git.openjdk.java.net/jdk/pull/7748/files/cd934f3c..f202bcbf

Webrevs:
 - full: https://webrevs.openjdk.java.net/?repo=jdk=7748=07
 - incr: https://webrevs.openjdk.java.net/?repo=jdk=7748=06-07

  Stats: 7 lines in 1 file changed: 5 ins; 2 del; 0 mod
  Patch: https://git.openjdk.java.net/jdk/pull/7748.diff
  Fetch: git fetch https://git.openjdk.java.net/jdk pull/7748/head:pull/7748

PR: https://git.openjdk.java.net/jdk/pull/7748


Re: RFR: 8253495: CDS generates non-deterministic output [v7]

2022-03-15 Thread Magnus Ihse Bursie
On Tue, 15 Mar 2022 08:17:24 GMT, Ioi Lam  wrote:

>> This patch makes the result of "java -Xshare:dump" deterministic:
>> - Disabled new Java threads from launching. This is harmless. See comments 
>> in jvm.cpp
>> - Fixed a problem in hashtable ordering in heapShared.cpp
>> - BasicHashtableEntry has a gap on 64-bit platforms that may contain random 
>> bits. Added code to zero it.
>> - Enabled checking of $JAVA_HOME/lib/server/classes.jsa in 
>> make/scripts/compare.sh
>> 
>> Note:  $JAVA_HOME/lib/server/classes_ncoops.jsa is still non-deterministic. 
>> This will be fixed in 
>> [JDK-8282828](https://bugs.openjdk.java.net/browse/JDK-8282828).
>> 
>> Testing under way:
>> - tier1~tier5
>> - Run all *-cmp-baseline jobs 20 times each (linux-aarch64-cmp-baseline, 
>> windows-x86-cmp-baseline,  etc).
>
> Ioi Lam has updated the pull request with a new target base due to a merge or 
> a rebase. The incremental webrev excludes the unrelated changes brought in by 
> the merge/rebase. The pull request contains 12 additional commits since the 
> last revision:
> 
>  - fixed copyright
>  - Merge branch 'master' into 
> 8253495-cds-generateds-non-deterministic-output-2
>  - @calvinccheung review: fixed typo
>  - Added helper function CollectedHeap::zap_filler_array_with
>  - @kimbarrett comments
>  - zero GC heap filler arrays
>  - improvement zeroing of alignment gaps
>  - Fixed zero build
>  - Merge branch 'master' into 
> 8253495-cds-generateds-non-deterministic-output-2
>  - fixed test
>  - ... and 2 more: 
> https://git.openjdk.java.net/jdk/compare/1ab17a39...cd934f3c

Build changes look good.

-

Marked as reviewed by ihse (Reviewer).

PR: https://git.openjdk.java.net/jdk/pull/7748


Re: RFR: 8253495: CDS generates non-deterministic output [v6]

2022-03-15 Thread Ioi Lam
On Mon, 14 Mar 2022 22:07:24 GMT, Calvin Cheung  wrote:

>> Ioi Lam has updated the pull request incrementally with one additional 
>> commit since the last revision:
>> 
>>   Added helper function CollectedHeap::zap_filler_array_with
>
> test/hotspot/jtreg/runtime/cds/appcds/javaldr/LockDuringDumpAgent.java line 
> 65:
> 
>> 63: if (elapsed >= timeout) {
>> 64: System.out.println("This JVM may decide to not 
>> launch any Java threads during -Xshare:dump.");
>> 65: System.out.println("This is OK because no string 
>> objects be in a locked state during heap dump.");
> 
> Should `no string objects be` be `no string objects could be`?

Thanks for the review. I've fixed the comment as you suggested.

-

PR: https://git.openjdk.java.net/jdk/pull/7748


Re: RFR: 8253495: CDS generates non-deterministic output [v7]

2022-03-15 Thread Ioi Lam
> This patch makes the result of "java -Xshare:dump" deterministic:
> - Disabled new Java threads from launching. This is harmless. See comments in 
> jvm.cpp
> - Fixed a problem in hashtable ordering in heapShared.cpp
> - BasicHashtableEntry has a gap on 64-bit platforms that may contain random 
> bits. Added code to zero it.
> - Enabled checking of $JAVA_HOME/lib/server/classes.jsa in 
> make/scripts/compare.sh
> 
> Note:  $JAVA_HOME/lib/server/classes_ncoops.jsa is still non-deterministic. 
> This will be fixed in 
> [JDK-8282828](https://bugs.openjdk.java.net/browse/JDK-8282828).
> 
> Testing under way:
> - tier1~tier5
> - Run all *-cmp-baseline jobs 20 times each (linux-aarch64-cmp-baseline, 
> windows-x86-cmp-baseline,  etc).

Ioi Lam has updated the pull request with a new target base due to a merge or a 
rebase. The incremental webrev excludes the unrelated changes brought in by the 
merge/rebase. The pull request contains 12 additional commits since the last 
revision:

 - fixed copyright
 - Merge branch 'master' into 8253495-cds-generateds-non-deterministic-output-2
 - @calvinccheung review: fixed typo
 - Added helper function CollectedHeap::zap_filler_array_with
 - @kimbarrett comments
 - zero GC heap filler arrays
 - improvement zeroing of alignment gaps
 - Fixed zero build
 - Merge branch 'master' into 8253495-cds-generateds-non-deterministic-output-2
 - fixed test
 - ... and 2 more: https://git.openjdk.java.net/jdk/compare/a6344ded...cd934f3c

-

Changes:
  - all: https://git.openjdk.java.net/jdk/pull/7748/files
  - new: https://git.openjdk.java.net/jdk/pull/7748/files/47e0238a..cd934f3c

Webrevs:
 - full: https://webrevs.openjdk.java.net/?repo=jdk=7748=06
 - incr: https://webrevs.openjdk.java.net/?repo=jdk=7748=05-06

  Stats: 6804 lines in 210 files changed: 3347 ins; 1802 del; 1655 mod
  Patch: https://git.openjdk.java.net/jdk/pull/7748.diff
  Fetch: git fetch https://git.openjdk.java.net/jdk pull/7748/head:pull/7748

PR: https://git.openjdk.java.net/jdk/pull/7748


Re: RFR: 8253495: CDS generates non-deterministic output [v6]

2022-03-14 Thread Calvin Cheung
On Fri, 11 Mar 2022 06:55:23 GMT, Ioi Lam  wrote:

>> This patch makes the result of "java -Xshare:dump" deterministic:
>> - Disabled new Java threads from launching. This is harmless. See comments 
>> in jvm.cpp
>> - Fixed a problem in hashtable ordering in heapShared.cpp
>> - BasicHashtableEntry has a gap on 64-bit platforms that may contain random 
>> bits. Added code to zero it.
>> - Enabled checking of $JAVA_HOME/lib/server/classes.jsa in 
>> make/scripts/compare.sh
>> 
>> Note:  $JAVA_HOME/lib/server/classes_ncoops.jsa is still non-deterministic. 
>> This will be fixed in 
>> [JDK-8282828](https://bugs.openjdk.java.net/browse/JDK-8282828).
>> 
>> Testing under way:
>> - tier1~tier5
>> - Run all *-cmp-baseline jobs 20 times each (linux-aarch64-cmp-baseline, 
>> windows-x86-cmp-baseline,  etc).
>
> Ioi Lam has updated the pull request incrementally with one additional commit 
> since the last revision:
> 
>   Added helper function CollectedHeap::zap_filler_array_with

CDS changes look good. One minor comment on a test.

test/hotspot/jtreg/runtime/cds/appcds/javaldr/LockDuringDumpAgent.java line 65:

> 63: if (elapsed >= timeout) {
> 64: System.out.println("This JVM may decide to not 
> launch any Java threads during -Xshare:dump.");
> 65: System.out.println("This is OK because no string 
> objects be in a locked state during heap dump.");

Should `no string objects be` be `no string objects could be`?

-

Marked as reviewed by ccheung (Reviewer).

PR: https://git.openjdk.java.net/jdk/pull/7748


Re: RFR: 8253495: CDS generates non-deterministic output [v2]

2022-03-11 Thread Thomas Stuefe
On Fri, 11 Mar 2022 08:28:32 GMT, Ioi Lam  wrote:

>> Is reproducibility also a topic for users calling -Xdump with custom JNI 
>> coding? Or maybe having the VM instrumented somehow? Since it seems such an 
>> easy fix, I would prevent attaching too. At least the user would get a clear 
>> error message.
>
>> Is reproducibility also a topic for users calling -Xdump with custom JNI 
>> coding? Or maybe having the VM instrumented somehow? Since it seems such an 
>> easy fix, I would prevent attaching too. At least the user would get a clear 
>> error message.
> 
> It's impossible to execute arbitrary Java code when running "java 
> -Xshare:dump", so this means there's no way to load a JNI library when 
> creating a *static* CDS archive. The loading of JVMTI agents is also not 
> supported. So this is not a case we need to handle. 
> 
> During *dynamic* CDS dumps, arbitrary Java code can execute, but we don't 
> have a requirement for the *dynamic* CDS archive to be deterministic (at 
> least not for now).

Thanks for that clarification. Never mind then :)

-

PR: https://git.openjdk.java.net/jdk/pull/7748


Re: RFR: 8253495: CDS generates non-deterministic output [v2]

2022-03-11 Thread Ioi Lam
On Fri, 11 Mar 2022 07:13:35 GMT, Thomas Stuefe  wrote:

> Is reproducibility also a topic for users calling -Xdump with custom JNI 
> coding? Or maybe having the VM instrumented somehow? Since it seems such an 
> easy fix, I would prevent attaching too. At least the user would get a clear 
> error message.

It's impossible to execute arbitrary Java code when running "java 
-Xshare:dump", so this means there's no way to load a JNI library when creating 
a *static* CDS archive. The loading of JVMTI agents is also not supported. So 
this is not a case we need to handle. 

During *dynamic* CDS dumps, arbitrary Java code can execute, but we don't have 
a requirement for the *dynamic* CDS archive to be deterministic (at least not 
for now).

-

PR: https://git.openjdk.java.net/jdk/pull/7748


Re: RFR: 8253495: CDS generates non-deterministic output

2022-03-10 Thread Thomas Stuefe
On Fri, 11 Mar 2022 07:03:00 GMT, David Holmes  wrote:

> > Well, he does it for `DumpSharedSpaces` only. Are you really worried about 
> > that one load+conditional jump?
> 
> As I said (and I'm not the only one who says this :) ) "death by a thousand 
> cuts".

Thank you, that is a good expression. I just wanted to clarify what you meant.

-

PR: https://git.openjdk.java.net/jdk/pull/7748


Re: RFR: 8253495: CDS generates non-deterministic output [v2]

2022-03-10 Thread Thomas Stuefe
On Thu, 10 Mar 2022 19:34:29 GMT, Ioi Lam  wrote:

>> src/hotspot/share/prims/jvm.cpp line 2887:
>> 
>>> 2885: return;
>>> 2886:   }
>>> 2887: #endif
>> 
>> Should we do this for jni_AttachCurrentThread too?
>
> This hasn't been necessary for me because jni_AttachCurrentThread is not 
> called during "java -Xshare:dump", which executes under a very strict 
> condition and doesn't normally allow arbitrary JNI libraries to be loaded.

Is reproducibility also a topic for users calling -Xdump with custom JNI 
coding? Or maybe having the VM instrumented somehow? Since it seems such an 
easy fix, I would prevent attaching too. At least the user would get a clear 
error message.

-

PR: https://git.openjdk.java.net/jdk/pull/7748


Re: RFR: 8253495: CDS generates non-deterministic output [v6]

2022-03-10 Thread Kim Barrett
On Fri, 11 Mar 2022 06:55:23 GMT, Ioi Lam  wrote:

>> This patch makes the result of "java -Xshare:dump" deterministic:
>> - Disabled new Java threads from launching. This is harmless. See comments 
>> in jvm.cpp
>> - Fixed a problem in hashtable ordering in heapShared.cpp
>> - BasicHashtableEntry has a gap on 64-bit platforms that may contain random 
>> bits. Added code to zero it.
>> - Enabled checking of $JAVA_HOME/lib/server/classes.jsa in 
>> make/scripts/compare.sh
>> 
>> Note:  $JAVA_HOME/lib/server/classes_ncoops.jsa is still non-deterministic. 
>> This will be fixed in 
>> [JDK-8282828](https://bugs.openjdk.java.net/browse/JDK-8282828).
>> 
>> Testing under way:
>> - tier1~tier5
>> - Run all *-cmp-baseline jobs 20 times each (linux-aarch64-cmp-baseline, 
>> windows-x86-cmp-baseline,  etc).
>
> Ioi Lam has updated the pull request incrementally with one additional commit 
> since the last revision:
> 
>   Added helper function CollectedHeap::zap_filler_array_with

GC changes look good.

-

Marked as reviewed by kbarrett (Reviewer).

PR: https://git.openjdk.java.net/jdk/pull/7748


Re: RFR: 8253495: CDS generates non-deterministic output

2022-03-10 Thread David Holmes

On 11/03/2022 4:50 pm, Thomas Stuefe wrote:

On Fri, 11 Mar 2022 05:59:00 GMT, David Holmes  wrote:


Thanks for pointing this out. I ran more tests and found that on certain 
platforms, there are other structures that have problems with uninitialized 
gaps. I ended up changing `os::malloc()` to zero the buffer when running with 
-Xshare:dump. Hopefully one extra check of `if (DumpSharedSpaces)` doesn't 
matter too much for regular VM executions because `os::malloc()` already has a 
high overhead.


This is raising red flags for me sorry. Every user of the JDK is now paying a penalty 
because of something only needed when dumping the shared archive. It might not be much 
but it is the old "death by a thousand cuts".


Well, he does it for `DumpSharedSpaces` only. Are you really worried about that 
one load+conditional jump?


As I said (and I'm not the only one who says this :) ) "death by a 
thousand cuts".



@iklam: I dislike the fact that CDS terminology is now in os::malloc. I would give this 
another flag, "ZapMalloc" or similar, and maybe merge it with the 
`DEBUG_ONLY(memset(..uninitBlockPad))` above.


Is there any way to tell the OS to pre-zero all memory provided to the current 
process, such that we could set that when dumping and not have to check on each 
allocation?


No. Malloced memory is not provided by the OS but by the glibc, and it may be 
polluted with whatever the allocator did with it (eg pointers to chain free 
blocks), or by prior user payload.

Glibc has a specific tunable, `glibc.malloc.perturb`, that initializes malloc 
memory to a given value, but you cannot directly set the value. It is very 
handy to check for uninitialized memory. Always wanted to add some tests that 
used it, but never got around. But obviously its nothing you could do in 
production.



And I have to wonder how easy it would be to re-introduce non-deterministic 
values in these data structures that are being dumped. Does malloc itself even 
guarantee to return the same set of addresses for the same sequence of requests 
in different executions of a program?


No, of course not. Non-Java threads may still run concurrently, no? System 
libraries do malloc too. But are pointer *values* even the problem?


I assumed that pointer values could be the problem, even if not 
presently, but apparently all the pointers get rewritten to use offsets 
from the known base of the shared archive - so not an issue.


Cheers,
David


-

PR: https://git.openjdk.java.net/jdk/pull/7748


Re: RFR: 8253495: CDS generates non-deterministic output [v6]

2022-03-10 Thread Ioi Lam
> This patch makes the result of "java -Xshare:dump" deterministic:
> - Disabled new Java threads from launching. This is harmless. See comments in 
> jvm.cpp
> - Fixed a problem in hashtable ordering in heapShared.cpp
> - BasicHashtableEntry has a gap on 64-bit platforms that may contain random 
> bits. Added code to zero it.
> - Enabled checking of $JAVA_HOME/lib/server/classes.jsa in 
> make/scripts/compare.sh
> 
> Note:  $JAVA_HOME/lib/server/classes_ncoops.jsa is still non-deterministic. 
> This will be fixed in 
> [JDK-8282828](https://bugs.openjdk.java.net/browse/JDK-8282828).
> 
> Testing under way:
> - tier1~tier5
> - Run all *-cmp-baseline jobs 20 times each (linux-aarch64-cmp-baseline, 
> windows-x86-cmp-baseline,  etc).

Ioi Lam has updated the pull request incrementally with one additional commit 
since the last revision:

  Added helper function CollectedHeap::zap_filler_array_with

-

Changes:
  - all: https://git.openjdk.java.net/jdk/pull/7748/files
  - new: https://git.openjdk.java.net/jdk/pull/7748/files/584c6572..47e0238a

Webrevs:
 - full: https://webrevs.openjdk.java.net/?repo=jdk=7748=05
 - incr: https://webrevs.openjdk.java.net/?repo=jdk=7748=04-05

  Stats: 10 lines in 2 files changed: 6 ins; 2 del; 2 mod
  Patch: https://git.openjdk.java.net/jdk/pull/7748.diff
  Fetch: git fetch https://git.openjdk.java.net/jdk pull/7748/head:pull/7748

PR: https://git.openjdk.java.net/jdk/pull/7748


Re: RFR: 8253495: CDS generates non-deterministic output

2022-03-10 Thread Thomas Stuefe
On Fri, 11 Mar 2022 06:50:00 GMT, David Holmes  wrote:

> I can combine the tests for `MemTracker::tracking_level()` and 
> `DumpSharedSpaces` into a single test and do more work only when the uncommon 
> path is taken. This would require some refactoring of the 
> MemTracker/MallocTracker code. I'd rather do that in a separate RFE.
> 
> In fact, `MemTracker::_tracking_level` is tested twice in the current 
> implementation. We can change it to do a single test in the most common case 
> (NMT_summary) if we really want to cut down the number of tests. But honestly 
> I don't think this makes any difference.
> 

Before going down that road, I would really like to see some measurements, 
whether this really matters. malloc is not blindingly fast. The malloc code in 
glibc does test a lot of conditions too. If you need fast allocation (or well 
packed, for that matter), you need another allocator. Thats why we have Arenas.

-

PR: https://git.openjdk.java.net/jdk/pull/7748


Re: RFR: 8253495: CDS generates non-deterministic output

2022-03-10 Thread Thomas Stuefe
On Fri, 11 Mar 2022 05:59:00 GMT, David Holmes  wrote:

> > Thanks for pointing this out. I ran more tests and found that on certain 
> > platforms, there are other structures that have problems with uninitialized 
> > gaps. I ended up changing `os::malloc()` to zero the buffer when running 
> > with -Xshare:dump. Hopefully one extra check of `if (DumpSharedSpaces)` 
> > doesn't matter too much for regular VM executions because `os::malloc()` 
> > already has a high overhead.
> 
> This is raising red flags for me sorry. Every user of the JDK is now paying a 
> penalty because of something only needed when dumping the shared archive. It 
> might not be much but it is the old "death by a thousand cuts".

Well, he does it for `DumpSharedSpaces` only. Are you really worried about that 
one load+conditional jump?

@iklam: I dislike the fact that CDS terminology is now in os::malloc. I would 
give this another flag, "ZapMalloc" or similar, and maybe merge it with the 
`DEBUG_ONLY(memset(..uninitBlockPad))` above.

> Is there any way to tell the OS to pre-zero all memory provided to the 
> current process, such that we could set that when dumping and not have to 
> check on each allocation?

No. Malloced memory is not provided by the OS but by the glibc, and it may be 
polluted with whatever the allocator did with it (eg pointers to chain free 
blocks), or by prior user payload.

Glibc has a specific tunable, `glibc.malloc.perturb`, that initializes malloc 
memory to a given value, but you cannot directly set the value. It is very 
handy to check for uninitialized memory. Always wanted to add some tests that 
used it, but never got around. But obviously its nothing you could do in 
production.

> 
> And I have to wonder how easy it would be to re-introduce non-deterministic 
> values in these data structures that are being dumped. Does malloc itself 
> even guarantee to return the same set of addresses for the same sequence of 
> requests in different executions of a program?

No, of course not. Non-Java threads may still run concurrently, no? System 
libraries do malloc too. But are pointer *values* even the problem?

-

PR: https://git.openjdk.java.net/jdk/pull/7748


Re: RFR: 8253495: CDS generates non-deterministic output

2022-03-10 Thread David Holmes

On 11/03/2022 4:40 pm, Ioi Lam wrote:

On Fri, 11 Mar 2022 05:59:00 GMT, David Holmes  wrote:


I ended up changing `os::malloc()` to zero the buffer when running with 
-Xshare:dump. Hopefully one extra check of `if (DumpSharedSpaces)` doesn't 
matter too much for regular VM executions because `os::malloc()` already has a 
high overhead.


This is raising red flags for me sorry. Every user of the JDK is now paying a penalty 
because of something only needed when dumping the shared archive. It might not be much 
but it is the old "death by a thousand cuts". Is there any way to tell the OS 
to pre-zero all memory provided to the current process, such that we could set that when 
dumping and not have to check on each allocation?


I don't know how to tell the OS (or C library) to zero out the buffer returned 
by malloc. However, in the current code path, we already have a test for an 
uncommon condition when `os::malloc()` calls `MemTracker::record_malloc()` 
which calls `MallocTracker::record_malloc()`


void* MallocTracker::record_malloc(void* malloc_base, size_t size, MEMFLAGS 
flags,
   const NativeCallStack& stack)
{
   if (MemTracker::tracking_level() == NMT_detail) {
 MallocSiteTable::allocation_at(stack, size, _marker, flags);
   }


I can combine the tests for `MemTracker::tracking_level()` and 
`DumpSharedSpaces` into a single test and do more work only when the uncommon 
path is taken. This would require some refactoring of the 
MemTracker/MallocTracker code. I'd rather do that in a separate RFE.

In fact, `MemTracker::_tracking_level` is tested twice in the current 
implementation. We can change it to do a single test in the most common case 
(NMT_summary) if we really want to cut down the number of tests. But honestly I 
don't think this makes any difference.


And I have to wonder how easy it would be to re-introduce non-deterministic 
values in these data structures that are being dumped. Does malloc itself even 
guarantee to return the same set of addresses for the same sequence of requests 
in different executions of a program?


The malloc'ed objects are copied into the CDS archive at deterministic 
addresses. Any pointers inside such objects will be relocated.



Okay. I won't object further but I really don't like it - c'est la vie! 
I'll let others review the actual code changes in detail.


Cheers,
David


-

PR: https://git.openjdk.java.net/jdk/pull/7748


Re: RFR: 8253495: CDS generates non-deterministic output

2022-03-10 Thread Ioi Lam
On Fri, 11 Mar 2022 05:59:00 GMT, David Holmes  wrote:

> > I ended up changing `os::malloc()` to zero the buffer when running with 
> > -Xshare:dump. Hopefully one extra check of `if (DumpSharedSpaces)` doesn't 
> > matter too much for regular VM executions because `os::malloc()` already 
> > has a high overhead.
> 
> This is raising red flags for me sorry. Every user of the JDK is now paying a 
> penalty because of something only needed when dumping the shared archive. It 
> might not be much but it is the old "death by a thousand cuts". Is there any 
> way to tell the OS to pre-zero all memory provided to the current process, 
> such that we could set that when dumping and not have to check on each 
> allocation?

I don't know how to tell the OS (or C library) to zero out the buffer returned 
by malloc. However, in the current code path, we already have a test for an 
uncommon condition when `os::malloc()` calls `MemTracker::record_malloc()` 
which calls `MallocTracker::record_malloc()`


void* MallocTracker::record_malloc(void* malloc_base, size_t size, MEMFLAGS 
flags,
  const NativeCallStack& stack)
{
  if (MemTracker::tracking_level() == NMT_detail) {
MallocSiteTable::allocation_at(stack, size, _marker, flags);
  }


I can combine the tests for `MemTracker::tracking_level()` and 
`DumpSharedSpaces` into a single test and do more work only when the uncommon 
path is taken. This would require some refactoring of the 
MemTracker/MallocTracker code. I'd rather do that in a separate RFE.

In fact, `MemTracker::_tracking_level` is tested twice in the current 
implementation. We can change it to do a single test in the most common case 
(NMT_summary) if we really want to cut down the number of tests. But honestly I 
don't think this makes any difference.

> And I have to wonder how easy it would be to re-introduce non-deterministic 
> values in these data structures that are being dumped. Does malloc itself 
> even guarantee to return the same set of addresses for the same sequence of 
> requests in different executions of a program?

The malloc'ed objects are copied into the CDS archive at deterministic 
addresses. Any pointers inside such objects will be relocated.

-

PR: https://git.openjdk.java.net/jdk/pull/7748


Re: RFR: 8253495: CDS generates non-deterministic output [v4]

2022-03-10 Thread Ioi Lam
On Fri, 11 Mar 2022 05:55:20 GMT, Kim Barrett  wrote:

>> Ioi Lam has updated the pull request incrementally with one additional 
>> commit since the last revision:
>> 
>>   zero GC heap filler arrays
>
> src/hotspot/share/gc/shared/collectedHeap.cpp line 449:
> 
>> 447:   allocator.initialize(start);
>> 448:   DEBUG_ONLY(zap_filler_array(start, words, zap);)
>> 449:   if (DumpSharedSpaces) {
> 
> Probably shouldn't both zap and clear for dumping, to avoid wasting time.

Fixed.

-

PR: https://git.openjdk.java.net/jdk/pull/7748


Re: RFR: 8253495: CDS generates non-deterministic output [v5]

2022-03-10 Thread Ioi Lam
> This patch makes the result of "java -Xshare:dump" deterministic:
> - Disabled new Java threads from launching. This is harmless. See comments in 
> jvm.cpp
> - Fixed a problem in hashtable ordering in heapShared.cpp
> - BasicHashtableEntry has a gap on 64-bit platforms that may contain random 
> bits. Added code to zero it.
> - Enabled checking of $JAVA_HOME/lib/server/classes.jsa in 
> make/scripts/compare.sh
> 
> Note:  $JAVA_HOME/lib/server/classes_ncoops.jsa is still non-deterministic. 
> This will be fixed in 
> [JDK-8282828](https://bugs.openjdk.java.net/browse/JDK-8282828).
> 
> Testing under way:
> - tier1~tier5
> - Run all *-cmp-baseline jobs 20 times each (linux-aarch64-cmp-baseline, 
> windows-x86-cmp-baseline,  etc).

Ioi Lam has updated the pull request incrementally with one additional commit 
since the last revision:

  @kimbarrett comments

-

Changes:
  - all: https://git.openjdk.java.net/jdk/pull/7748/files
  - new: https://git.openjdk.java.net/jdk/pull/7748/files/be7673af..584c6572

Webrevs:
 - full: https://webrevs.openjdk.java.net/?repo=jdk=7748=04
 - incr: https://webrevs.openjdk.java.net/?repo=jdk=7748=03-04

  Stats: 3 lines in 1 file changed: 2 ins; 1 del; 0 mod
  Patch: https://git.openjdk.java.net/jdk/pull/7748.diff
  Fetch: git fetch https://git.openjdk.java.net/jdk pull/7748/head:pull/7748

PR: https://git.openjdk.java.net/jdk/pull/7748


Re: RFR: 8253495: CDS generates non-deterministic output [v4]

2022-03-10 Thread Kim Barrett
On Fri, 11 Mar 2022 04:56:23 GMT, Ioi Lam  wrote:

>> This patch makes the result of "java -Xshare:dump" deterministic:
>> - Disabled new Java threads from launching. This is harmless. See comments 
>> in jvm.cpp
>> - Fixed a problem in hashtable ordering in heapShared.cpp
>> - BasicHashtableEntry has a gap on 64-bit platforms that may contain random 
>> bits. Added code to zero it.
>> - Enabled checking of $JAVA_HOME/lib/server/classes.jsa in 
>> make/scripts/compare.sh
>> 
>> Note:  $JAVA_HOME/lib/server/classes_ncoops.jsa is still non-deterministic. 
>> This will be fixed in 
>> [JDK-8282828](https://bugs.openjdk.java.net/browse/JDK-8282828).
>> 
>> Testing under way:
>> - tier1~tier5
>> - Run all *-cmp-baseline jobs 20 times each (linux-aarch64-cmp-baseline, 
>> windows-x86-cmp-baseline,  etc).
>
> Ioi Lam has updated the pull request incrementally with one additional commit 
> since the last revision:
> 
>   zero GC heap filler arrays

Changes requested by kbarrett (Reviewer).

src/hotspot/share/gc/shared/collectedHeap.cpp line 449:

> 447:   allocator.initialize(start);
> 448:   DEBUG_ONLY(zap_filler_array(start, words, zap);)
> 449:   if (DumpSharedSpaces) {

Probably shouldn't both zap and clear for dumping, to avoid wasting time.

-

PR: https://git.openjdk.java.net/jdk/pull/7748


Re: RFR: 8253495: CDS generates non-deterministic output [v2]

2022-03-10 Thread David Holmes

I can't find this comment in the PR so replying via email ...

On 11/03/2022 9:24 am, Ioi Lam wrote:

On Wed, 9 Mar 2022 07:47:19 GMT, Thomas Stuefe  wrote:


Ioi Lam has updated the pull request incrementally with one additional commit 
since the last revision:

   Fixed zero build


src/hotspot/share/utilities/hashtable.hpp line 42:


40:
41:   LP64_ONLY(unsigned int _gap;)
42:


For 64-bit, you now lose packing potential in the theoretical case the 
following payload does not have to be aligned to 64 bit. E.g. for T=char, where 
the whole entry would fit into 8 bytes. Probably does not matter as long as 
entries are allocated individually from C-heap which is a lot more wasteful 
anyway.

For 32-bit, I think you may have the same problem if the payload starts with a 
uint64_t. Would that not be aligned to a 64-bit boundary too? Whether or not 
you build on 64-bit?

I think setting the memory, or at least the first 8..16 bytes, of the entry to zero 
in BasicHashtable::new_entry could be more robust:

(16 bytes in case the payload starts with a long double but that may be 
overthinking it :)


template  BasicHashtableEntry* 
BasicHashtable::new_entry(unsigned int hashValue) {
   char* p = :new (NEW_C_HEAP_ARRAY(char, this->entry_size(), F);
   ::memset(p, 0, MIN2(this->entry_size(), 16)); // needs reproducable
   BasicHashtableEntry* entry = ::new (p) BasicHashtableEntry(hashValue);
   return entry;
}

If you are worried about performance, this may also be controlled by a template 
parameter, and then you do it just for the system dictionary.


Thanks for pointing this out. I ran more tests and found that on certain 
platforms, there are other structures that have problems with uninitialized 
gaps. I ended up changing `os::malloc()` to zero the buffer when running with 
-Xshare:dump. Hopefully one extra check of `if (DumpSharedSpaces)` doesn't 
matter too much for regular VM executions because `os::malloc()` already has a 
high overhead.


This is raising red flags for me sorry. Every user of the JDK is now 
paying a penalty because of something only needed when dumping the 
shared archive. It might not be much but it is the old "death by a 
thousand cuts". Is there any way to tell the OS to pre-zero all memory 
provided to the current process, such that we could set that when 
dumping and not have to check on each allocation?


And I have to wonder how easy it would be to re-introduce 
non-deterministic values in these data structures that are being dumped. 
Does malloc itself even guarantee to return the same set of addresses 
for the same sequence of requests in different executions of a program?


Cheers,
David
-


-

PR: https://git.openjdk.java.net/jdk/pull/7748


Re: RFR: 8253495: CDS generates non-deterministic output [v4]

2022-03-10 Thread Ioi Lam
> This patch makes the result of "java -Xshare:dump" deterministic:
> - Disabled new Java threads from launching. This is harmless. See comments in 
> jvm.cpp
> - Fixed a problem in hashtable ordering in heapShared.cpp
> - BasicHashtableEntry has a gap on 64-bit platforms that may contain random 
> bits. Added code to zero it.
> - Enabled checking of $JAVA_HOME/lib/server/classes.jsa in 
> make/scripts/compare.sh
> 
> Note:  $JAVA_HOME/lib/server/classes_ncoops.jsa is still non-deterministic. 
> This will be fixed in 
> [JDK-8282828](https://bugs.openjdk.java.net/browse/JDK-8282828).
> 
> Testing under way:
> - tier1~tier5
> - Run all *-cmp-baseline jobs 20 times each (linux-aarch64-cmp-baseline, 
> windows-x86-cmp-baseline,  etc).

Ioi Lam has updated the pull request incrementally with one additional commit 
since the last revision:

  zero GC heap filler arrays

-

Changes:
  - all: https://git.openjdk.java.net/jdk/pull/7748/files
  - new: https://git.openjdk.java.net/jdk/pull/7748/files/6974021f..be7673af

Webrevs:
 - full: https://webrevs.openjdk.java.net/?repo=jdk=7748=03
 - incr: https://webrevs.openjdk.java.net/?repo=jdk=7748=02-03

  Stats: 7 lines in 1 file changed: 6 ins; 0 del; 1 mod
  Patch: https://git.openjdk.java.net/jdk/pull/7748.diff
  Fetch: git fetch https://git.openjdk.java.net/jdk pull/7748/head:pull/7748

PR: https://git.openjdk.java.net/jdk/pull/7748


Re: RFR: 8253495: CDS generates non-deterministic output [v3]

2022-03-10 Thread Ioi Lam
> This patch makes the result of "java -Xshare:dump" deterministic:
> - Disabled new Java threads from launching. This is harmless. See comments in 
> jvm.cpp
> - Fixed a problem in hashtable ordering in heapShared.cpp
> - BasicHashtableEntry has a gap on 64-bit platforms that may contain random 
> bits. Added code to zero it.
> - Enabled checking of $JAVA_HOME/lib/server/classes.jsa in 
> make/scripts/compare.sh
> 
> Note:  $JAVA_HOME/lib/server/classes_ncoops.jsa is still non-deterministic. 
> This will be fixed in 
> [JDK-8282828](https://bugs.openjdk.java.net/browse/JDK-8282828).
> 
> Testing under way:
> - tier1~tier5
> - Run all *-cmp-baseline jobs 20 times each (linux-aarch64-cmp-baseline, 
> windows-x86-cmp-baseline,  etc).

Ioi Lam has updated the pull request incrementally with one additional commit 
since the last revision:

  improvement zeroing of alignment gaps

-

Changes:
  - all: https://git.openjdk.java.net/jdk/pull/7748/files
  - new: https://git.openjdk.java.net/jdk/pull/7748/files/44db40f1..6974021f

Webrevs:
 - full: https://webrevs.openjdk.java.net/?repo=jdk=7748=02
 - incr: https://webrevs.openjdk.java.net/?repo=jdk=7748=01-02

  Stats: 8 lines in 2 files changed: 3 ins; 2 del; 3 mod
  Patch: https://git.openjdk.java.net/jdk/pull/7748.diff
  Fetch: git fetch https://git.openjdk.java.net/jdk pull/7748/head:pull/7748

PR: https://git.openjdk.java.net/jdk/pull/7748


Re: RFR: 8253495: CDS generates non-deterministic output [v2]

2022-03-10 Thread Ioi Lam
On Wed, 9 Mar 2022 07:47:19 GMT, Thomas Stuefe  wrote:

>> Ioi Lam has updated the pull request incrementally with one additional 
>> commit since the last revision:
>> 
>>   Fixed zero build
>
> src/hotspot/share/utilities/hashtable.hpp line 42:
> 
>> 40: 
>> 41:   LP64_ONLY(unsigned int _gap;)
>> 42: 
> 
> For 64-bit, you now lose packing potential in the theoretical case the 
> following payload does not have to be aligned to 64 bit. E.g. for T=char, 
> where the whole entry would fit into 8 bytes. Probably does not matter as 
> long as entries are allocated individually from C-heap which is a lot more 
> wasteful anyway. 
> 
> For 32-bit, I think you may have the same problem if the payload starts with 
> a uint64_t. Would that not be aligned to a 64-bit boundary too? Whether or 
> not you build on 64-bit?
> 
> I think setting the memory, or at least the first 8..16 bytes, of the entry 
> to zero in BasicHashtable::new_entry could be more robust:
> 
> (16 bytes in case the payload starts with a long double but that may be 
> overthinking it :)
> 
> 
> template  BasicHashtableEntry* 
> BasicHashtable::new_entry(unsigned int hashValue) {
>   char* p = :new (NEW_C_HEAP_ARRAY(char, this->entry_size(), F);
>   ::memset(p, 0, MIN2(this->entry_size(), 16)); // needs reproducable
>   BasicHashtableEntry* entry = ::new (p) BasicHashtableEntry(hashValue);
>   return entry;
> }
> 
> If you are worried about performance, this may also be controlled by a 
> template parameter, and then you do it just for the system dictionary.

Thanks for pointing this out. I ran more tests and found that on certain 
platforms, there are other structures that have problems with uninitialized 
gaps. I ended up changing `os::malloc()` to zero the buffer when running with 
-Xshare:dump. Hopefully one extra check of `if (DumpSharedSpaces)` doesn't 
matter too much for regular VM executions because `os::malloc()` already has a 
high overhead.

-

PR: https://git.openjdk.java.net/jdk/pull/7748


Re: RFR: 8253495: CDS generates non-deterministic output [v2]

2022-03-10 Thread David Holmes
On Thu, 10 Mar 2022 19:41:03 GMT, Ioi Lam  wrote:

>> I think he already did. I'm quoting:
>> 
>>> However, the CDS archive also contains a heap dump, which includes Java 
>>> HashMaps. If I allow those 3 Java threads to start, some HashMaps in the 
>>> module graph will have unstable ordering. I think the reason is concurrent 
>>> thread execution causes unstable assignment of the identity_hash for 
>>> objects in the heap dump.
>
>> @magicus the issue is not the list of classes dumped, or their format in the 
>> dump. As Ioi indicated that list is fixed. The issue is with the heap dump 
>> part of the archive. Running these other threads affects the heap so by not 
>> running them with end up with a different heap. So the question is whether 
>> there is anything about having a different heap dumped that we need to be 
>> concerned about. We dump the heap into the archive for a reason and this 
>> changes what we dump,
> 
> To be clear, if multiple threads are running, classes could be loaded in a 
> different order and the symbols will have different orders. This would cause 
> the vtables in Klass objects to be laid out differently. Trying to fix this 
> is very difficult. I have a different patch that makes it work but it's just 
> too complicated.
> 
> So, disabling the threads is also necessary for (easily) sorting the 
> metaspace objects.

@iklam  thanks for clarifying.

-

PR: https://git.openjdk.java.net/jdk/pull/7748


Re: RFR: 8253495: CDS generates non-deterministic output [v2]

2022-03-10 Thread Ioi Lam
On Thu, 10 Mar 2022 13:51:56 GMT, Magnus Ihse Bursie  wrote:

>> Ioi Lam has updated the pull request incrementally with one additional 
>> commit since the last revision:
>> 
>>   Fixed zero build
>
> I think he already did. I'm quoting:
> 
>> However, the CDS archive also contains a heap dump, which includes Java 
>> HashMaps. If I allow those 3 Java threads to start, some HashMaps in the 
>> module graph will have unstable ordering. I think the reason is concurrent 
>> thread execution causes unstable assignment of the identity_hash for objects 
>> in the heap dump.

> @magicus the issue is not the list of classes dumped, or their format in the 
> dump. As Ioi indicated that list is fixed. The issue is with the heap dump 
> part of the archive. Running these other threads affects the heap so by not 
> running them with end up with a different heap. So the question is whether 
> there is anything about having a different heap dumped that we need to be 
> concerned about. We dump the heap into the archive for a reason and this 
> changes what we dump,

To be clear, if multiple threads are running, classes could be loaded in a 
different order and the symbols will have different orders. This would cause 
the vtables in Klass objects to be laid out differently. Trying to fix this is 
very difficult. I have a different patch that makes it work but it's just too 
complicated.

So, disabling the threads is also necessary for (easily) sorting the metaspace 
objects.

-

PR: https://git.openjdk.java.net/jdk/pull/7748


Re: RFR: 8253495: CDS generates non-deterministic output [v2]

2022-03-10 Thread Ioi Lam
On Wed, 9 Mar 2022 07:51:46 GMT, Thomas Stuefe  wrote:

>> Ioi Lam has updated the pull request incrementally with one additional 
>> commit since the last revision:
>> 
>>   Fixed zero build
>
> src/hotspot/share/prims/jvm.cpp line 2887:
> 
>> 2885: return;
>> 2886:   }
>> 2887: #endif
> 
> Should we do this for jni_AttachCurrentThread too?

This hasn't been necessary for me because jni_AttachCurrentThread is not called 
during "java -Xshare:dump", which executes under a very strict condition and 
doesn't normally allow arbitrary JNI libraries to be loaded.

-

PR: https://git.openjdk.java.net/jdk/pull/7748


Re: RFR: 8253495: CDS generates non-deterministic output [v2]

2022-03-10 Thread Ioi Lam
On Thu, 10 Mar 2022 13:51:56 GMT, Magnus Ihse Bursie  wrote:

>> Ioi Lam has updated the pull request incrementally with one additional 
>> commit since the last revision:
>> 
>>   Fixed zero build
>
> I think he already did. I'm quoting:
> 
>> However, the CDS archive also contains a heap dump, which includes Java 
>> HashMaps. If I allow those 3 Java threads to start, some HashMaps in the 
>> module graph will have unstable ordering. I think the reason is concurrent 
>> thread execution causes unstable assignment of the identity_hash for objects 
>> in the heap dump.

> @magicus I think we need @iklam to weigh in here and explain exactly what the 
> "heap dump" consists of and how not running those threads affects its 
> contents. Presently the heap dump is potentially different on each run, IIUC, 
> only due to the order of its contents, not the contents themselves.

CDS doesn't dump the entire Java heap. Instead, it dumps only a selected 
portion of the Java heap. For example, the module graph. The contents of the 
dumped objects are always the same, except that the identity hashcode may be 
different if multiple threads are executed. The identity hashcode is computed 
here, and its value is "sticky" to the first thread that tries to get the 
hashcode for an object.


static inline intptr_t get_next_hash(Thread* current, oop obj) {
  intptr_t value = 0;
  if (hashCode == 0) {
 ...
  } else if (hashCode == 4) {
 ...
  } else { // default hashCode is 5:
// Marsaglia's xor-shift scheme with thread-specific state
// This is probably the best overall implementation -- we'll
// likely make this the default in future releases.
unsigned t = current->_hashStateX;
t ^= (t << 11);
current->_hashStateX = current->_hashStateY;
current->_hashStateY = current->_hashStateZ;
current->_hashStateZ = current->_hashStateW;
unsigned v = current->_hashStateW;
v = (v ^ (v >> 19)) ^ (t ^ (t >> 8));
current->_hashStateW = v;
value = v;
  }


So, when the main Java thread tries to store an object `O` into a hashtable 
inside the module graph, if the hashcode of `O` has already been computed by a 
non-main thread, then the module graph will have unstable contents.

-

PR: https://git.openjdk.java.net/jdk/pull/7748


Re: RFR: 8253495: CDS generates non-deterministic output [v2]

2022-03-10 Thread Magnus Ihse Bursie
On Wed, 9 Mar 2022 05:10:44 GMT, Ioi Lam  wrote:

>> This patch makes the result of "java -Xshare:dump" deterministic:
>> - Disabled new Java threads from launching. This is harmless. See comments 
>> in jvm.cpp
>> - Fixed a problem in hashtable ordering in heapShared.cpp
>> - BasicHashtableEntry has a gap on 64-bit platforms that may contain random 
>> bits. Added code to zero it.
>> - Enabled checking of $JAVA_HOME/lib/server/classes.jsa in 
>> make/scripts/compare.sh
>> 
>> Note:  $JAVA_HOME/lib/server/classes_ncoops.jsa is still non-deterministic. 
>> This will be fixed in 
>> [JDK-8282828](https://bugs.openjdk.java.net/browse/JDK-8282828).
>> 
>> Testing under way:
>> - tier1~tier5
>> - Run all *-cmp-baseline jobs 20 times each (linux-aarch64-cmp-baseline, 
>> windows-x86-cmp-baseline,  etc).
>
> Ioi Lam has updated the pull request incrementally with one additional commit 
> since the last revision:
> 
>   Fixed zero build

I think he already did. I'm quoting:

> However, the CDS archive also contains a heap dump, which includes Java 
> HashMaps. If I allow those 3 Java threads to start, some HashMaps in the 
> module graph will have unstable ordering. I think the reason is concurrent 
> thread execution causes unstable assignment of the identity_hash for objects 
> in the heap dump.

-

PR: https://git.openjdk.java.net/jdk/pull/7748


Re: RFR: 8253495: CDS generates non-deterministic output [v2]

2022-03-10 Thread David Holmes
On Thu, 10 Mar 2022 12:50:58 GMT, Magnus Ihse Bursie  wrote:

>> Ioi Lam has updated the pull request incrementally with one additional 
>> commit since the last revision:
>> 
>>   Fixed zero build
>
> Well, previously we'd get different dumps on different runs. If that was an 
> issue, surely it would have manifested itself by now? With this change, we'll 
> just get the same dump each run. I fail to see how that could be a risk.

@magicus  I think we need @iklam to weigh in here and explain exactly what the 
"heap dump" consists of and how not running those threads affects its contents. 
Presently the heap dump is potentially different on each run, IIUC, only due to 
the order of its contents, not the contents themselves.

-

PR: https://git.openjdk.java.net/jdk/pull/7748


Re: RFR: 8253495: CDS generates non-deterministic output [v2]

2022-03-10 Thread Magnus Ihse Bursie
The Skara bots messed up this one badly. It was a reply to David's 
comment, not Ioi's latest push.


/Magnus

On 2022-03-10 13:56, Magnus Ihse Bursie wrote:

On Wed, 9 Mar 2022 05:10:44 GMT, Ioi Lam  wrote:


This patch makes the result of "java -Xshare:dump" deterministic:
- Disabled new Java threads from launching. This is harmless. See comments in 
jvm.cpp
- Fixed a problem in hashtable ordering in heapShared.cpp
- BasicHashtableEntry has a gap on 64-bit platforms that may contain random 
bits. Added code to zero it.
- Enabled checking of $JAVA_HOME/lib/server/classes.jsa in 
make/scripts/compare.sh

Note:  $JAVA_HOME/lib/server/classes_ncoops.jsa is still non-deterministic. 
This will be fixed in 
[JDK-8282828](https://bugs.openjdk.java.net/browse/JDK-8282828).

Testing under way:
- tier1~tier5
- Run all *-cmp-baseline jobs 20 times each (linux-aarch64-cmp-baseline, 
windows-x86-cmp-baseline,  etc).

Ioi Lam has updated the pull request incrementally with one additional commit 
since the last revision:

   Fixed zero build

Well, previously we'd get different dumps on different runs. If that was an 
issue, surely it would have manifested itself by now? With this change, we'll 
just get the same dump each run. I fail to see how that could be a risk.

-

PR: https://git.openjdk.java.net/jdk/pull/7748




Re: RFR: 8253495: CDS generates non-deterministic output [v2]

2022-03-10 Thread Thomas Stuefe
On Wed, 9 Mar 2022 07:58:51 GMT, Thomas Stuefe  wrote:

>> Ioi Lam has updated the pull request incrementally with one additional 
>> commit since the last revision:
>> 
>>   Fixed zero build
>
> Hi Ioi,
> 
> some questions, comments inline.
> 
> Like David in the comments, I am also a bit vague on the usefulness, but I 
> may not know the whole story. Is it to enable repackagers like Debian to 
> check the "reproducable" tickbox on their OpenJDK package? Or is there a 
> practical need for this?
> 
> Thanks, Thomas

> @tstuefe Without commenting on Ioi's actual implementation, let me explain a 
> bit on the importance of this fix.
> 
> Reproducible builds is not just a "checkbox", any more than "does not crash 
> on startup" is a checkbox. It is an important security tool. See e.g. 
> https://reproducible-builds.org/ for more information.
> 

Hi @magicus,

thanks for explaining, and for the link. That one was a good explanation. I had 
no idea, but I'm convinced now.

Cheers, Thomas

-

PR: https://git.openjdk.java.net/jdk/pull/7748


Re: RFR: 8253495: CDS generates non-deterministic output [v2]

2022-03-10 Thread Magnus Ihse Bursie
On Wed, 9 Mar 2022 05:10:44 GMT, Ioi Lam  wrote:

>> This patch makes the result of "java -Xshare:dump" deterministic:
>> - Disabled new Java threads from launching. This is harmless. See comments 
>> in jvm.cpp
>> - Fixed a problem in hashtable ordering in heapShared.cpp
>> - BasicHashtableEntry has a gap on 64-bit platforms that may contain random 
>> bits. Added code to zero it.
>> - Enabled checking of $JAVA_HOME/lib/server/classes.jsa in 
>> make/scripts/compare.sh
>> 
>> Note:  $JAVA_HOME/lib/server/classes_ncoops.jsa is still non-deterministic. 
>> This will be fixed in 
>> [JDK-8282828](https://bugs.openjdk.java.net/browse/JDK-8282828).
>> 
>> Testing under way:
>> - tier1~tier5
>> - Run all *-cmp-baseline jobs 20 times each (linux-aarch64-cmp-baseline, 
>> windows-x86-cmp-baseline,  etc).
>
> Ioi Lam has updated the pull request incrementally with one additional commit 
> since the last revision:
> 
>   Fixed zero build

Well, previously we'd get different dumps on different runs. If that was an 
issue, surely it would have manifested itself by now? With this change, we'll 
just get the same dump each run. I fail to see how that could be a risk.

-

PR: https://git.openjdk.java.net/jdk/pull/7748


Re: RFR: 8253495: CDS generates non-deterministic output [v2]

2022-03-10 Thread David Holmes
On Thu, 10 Mar 2022 12:11:06 GMT, Magnus Ihse Bursie  wrote:

>> The "heap dump" aspect of this is not something I'm familiar with, but if 
>> the threads don't affect the list of classes dumped, they surely must affect 
>> what is in the heap dump otherwise their execution would not be an issue. So 
>> you must be sacrificing something by not having these threads start.
>
> @dholmes-ora That something is "sacrificed" does not follow from that 
> something is "different". The list of classes to dump is specified in the 
> lib/classlist file, which is generated during the build. 
> 
> The process of creating this involves running a suitable "exercise most 
> important parts" java program, and logging the classes loaded. This class 
> file is then post-processed (sorted) to make sure it is reproducible for the 
> same JDK code base.
> 
> As Ioi say, in this case threads are started freely, and may run in any 
> non-deterministic order.
> 
> At the next stage, we take this file (which is just done implicitly by 
> -Xshare:dump), and generate the actual CDS archive, classes.jsa. Now it turns 
> out this generation is non-deterministic. And Ioi's analysis is that this is 
> due to thread non-determinism. So if we just disable threads during the dump 
> process (where we are not really running the JVM "actually" -- it's a special 
> mode, where we don't even have a Java program to run!), there's no harm in 
> that.

@magicus the issue is not the list of classes dumped, or their format in the 
dump. As Ioi indicated that list is fixed. The issue is with the heap dump part 
of the archive. Running these other threads affects the heap so by not running 
them with end up with a different heap. So the question is whether there is 
anything about having a different heap dumped that we need to be concerned 
about. We dump the heap into the archive for a reason and this changes what we 
dump,

-

PR: https://git.openjdk.java.net/jdk/pull/7748


Re: RFR: 8253495: CDS generates non-deterministic output [v2]

2022-03-10 Thread Magnus Ihse Bursie
On Wed, 9 Mar 2022 11:45:59 GMT, David Holmes  wrote:

>> Ioi Lam has updated the pull request incrementally with one additional 
>> commit since the last revision:
>> 
>>   Fixed zero build
>
> The "heap dump" aspect of this is not something I'm familiar with, but if the 
> threads don't affect the list of classes dumped, they surely must affect what 
> is in the heap dump otherwise their execution would not be an issue. So you 
> must be sacrificing something by not having these threads start.

@dholmes-ora That something is "sacrificed" does not follow from that something 
is "different". The list of classes to dump is specified in the lib/classlist 
file, which is generated during the build. 

The process of creating this involves running a suitable "exercise most 
important parts" java program, and logging the classes loaded. This class file 
is then post-processed (sorted) to make sure it is reproducible for the same 
JDK code base.

As Ioi say, in this case threads are started freely, and may run in any 
non-deterministic order.

At the next stage, we take this file (which is just done implicitly by 
-Xshare:dump), and generate the actual CDS archive, classes.jsa. Now it turns 
out this generation is non-deterministic. And Ioi's analysis is that this is 
due to thread non-determinism. So if we just disable threads during the dump 
process (where we are not really running the JVM "actually" -- it's a special 
mode, where we don't even have a Java program to run!), there's no harm in that.

-

PR: https://git.openjdk.java.net/jdk/pull/7748


Re: RFR: 8253495: CDS generates non-deterministic output [v2]

2022-03-10 Thread Magnus Ihse Bursie
On Wed, 9 Mar 2022 07:58:51 GMT, Thomas Stuefe  wrote:

>> Ioi Lam has updated the pull request incrementally with one additional 
>> commit since the last revision:
>> 
>>   Fixed zero build
>
> Hi Ioi,
> 
> some questions, comments inline.
> 
> Like David in the comments, I am also a bit vague on the usefulness, but I 
> may not know the whole story. Is it to enable repackagers like Debian to 
> check the "reproducable" tickbox on their OpenJDK package? Or is there a 
> practical need for this?
> 
> Thanks, Thomas

@tstuefe Without commenting on Ioi's actual implementation, let me explain a 
bit on the importance of this fix.

Reproducible builds is not just a "checkbox", any more than "does not crash on 
startup" is a checkbox. It is an important security tool. See e.g. 
https://reproducible-builds.org/ for more information. 

The problem with CDS generating non-deterministic output is that during the 
build process we generate the file classes.jsa (and classes_nocoops.jsa). These 
files in turn are included in the java.base jmod, which in turn is included in 
the entire jlinked image.

So if classes.jsa gets random bits, these random bits propagate to 
java.base.jmod and finally, to the entire jimage. This means that it is 
imposslbe to get bit-by-bit reproducibility verification of the entire JDK 
build.

For several years, we have relentlessly (albeit with an unfortunately low 
priority) addressed and fixed indeterminism in the build of the JDK. We are now 
at the point were the only major issue is the randomness of classes.jsa and 
classes_nocoops.jsa.

-

PR: https://git.openjdk.java.net/jdk/pull/7748


Re: RFR: 8253495: CDS generates non-deterministic output [v2]

2022-03-09 Thread David Holmes
On Wed, 9 Mar 2022 05:10:44 GMT, Ioi Lam  wrote:

>> This patch makes the result of "java -Xshare:dump" deterministic:
>> - Disabled new Java threads from launching. This is harmless. See comments 
>> in jvm.cpp
>> - Fixed a problem in hashtable ordering in heapShared.cpp
>> - BasicHashtableEntry has a gap on 64-bit platforms that may contain random 
>> bits. Added code to zero it.
>> - Enabled checking of $JAVA_HOME/lib/server/classes.jsa in 
>> make/scripts/compare.sh
>> 
>> Note:  $JAVA_HOME/lib/server/classes_ncoops.jsa is still non-deterministic. 
>> This will be fixed in 
>> [JDK-8282828](https://bugs.openjdk.java.net/browse/JDK-8282828).
>> 
>> Testing under way:
>> - tier1~tier5
>> - Run all *-cmp-baseline jobs 20 times each (linux-aarch64-cmp-baseline, 
>> windows-x86-cmp-baseline,  etc).
>
> Ioi Lam has updated the pull request incrementally with one additional commit 
> since the last revision:
> 
>   Fixed zero build

The "heap dump" aspect of this is not something I'm familiar with, but if the 
threads don't affect the list of classes dumped, they surely must affect what 
is in the heap dump otherwise their execution would not be an issue. So you 
must be sacrificing something by not having these threads start.

-

PR: https://git.openjdk.java.net/jdk/pull/7748


Re: RFR: 8253495: CDS generates non-deterministic output [v2]

2022-03-09 Thread Thomas Stuefe
On Wed, 9 Mar 2022 05:10:44 GMT, Ioi Lam  wrote:

>> This patch makes the result of "java -Xshare:dump" deterministic:
>> - Disabled new Java threads from launching. This is harmless. See comments 
>> in jvm.cpp
>> - Fixed a problem in hashtable ordering in heapShared.cpp
>> - BasicHashtableEntry has a gap on 64-bit platforms that may contain random 
>> bits. Added code to zero it.
>> - Enabled checking of $JAVA_HOME/lib/server/classes.jsa in 
>> make/scripts/compare.sh
>> 
>> Note:  $JAVA_HOME/lib/server/classes_ncoops.jsa is still non-deterministic. 
>> This will be fixed in 
>> [JDK-8282828](https://bugs.openjdk.java.net/browse/JDK-8282828).
>> 
>> Testing under way:
>> - tier1~tier5
>> - Run all *-cmp-baseline jobs 20 times each (linux-aarch64-cmp-baseline, 
>> windows-x86-cmp-baseline,  etc).
>
> Ioi Lam has updated the pull request incrementally with one additional commit 
> since the last revision:
> 
>   Fixed zero build

Hi Ioi,

some questions, comments inline.

Like David in the comments, I am also a bit vague on the usefulness, but I may 
not know the whole story. Is it to enable repackagers like Debian to check the 
"reproducable" tickbox on their OpenJDK package? Or is there a practical need 
for this?

Thanks, Thomas

src/hotspot/share/prims/jvm.cpp line 2887:

> 2885: return;
> 2886:   }
> 2887: #endif

Should we do this for jni_AttachCurrentThread too?

src/hotspot/share/utilities/hashtable.hpp line 42:

> 40: 
> 41:   LP64_ONLY(unsigned int _gap;)
> 42: 

For 64-bit, you now lose packing potential in the theoretical case the 
following payload does not have to be aligned to 64 bit. E.g. for T=char, where 
the whole entry would fit into 8 bytes. Probably does not matter as long as 
entries are allocated individually from C-heap which is a lot more wasteful 
anyway. 

For 32-bit, I think you may have the same problem if the payload starts with a 
uint64_t. Would that not be aligned to a 64-bit boundary too? Whether or not 
you build on 64-bit?

I think setting the memory, or at least the first 8..16 bytes, of the entry to 
zero in BasicHashtable::new_entry could be more robust:

(16 bytes in case the payload starts with a long double but that may be 
overthinking it :)


template  BasicHashtableEntry* 
BasicHashtable::new_entry(unsigned int hashValue) {
  char* p = :new (NEW_C_HEAP_ARRAY(char, this->entry_size(), F);
  ::memset(p, 0, MIN2(this->entry_size(), 16)); // needs reproducable
  BasicHashtableEntry* entry = ::new (p) BasicHashtableEntry(hashValue);
  return entry;
}

If you are worried about performance, this may also be controlled by a template 
parameter, and then you do it just for the system dictionary.

-

PR: https://git.openjdk.java.net/jdk/pull/7748


Re: RFR: 8253495: CDS generates non-deterministic output [v2]

2022-03-08 Thread Ioi Lam
On Wed, 9 Mar 2022 07:04:56 GMT, David Holmes  wrote:

> I have reservations about contorting things this way just to get 
> "deterministic output".
> 
> The VM needs to fully initialize and then become quiescent before the dump 
> occurs, and as I say below if you don't start other threads then you 
> potentially remove part of the archive because classes won't be loaded by 
> those threads.
> 
> I think if you care about the order of dumping classes then you should 
> control that order, you don't try to force the order of loading. Can't you 
> sort things before dumping? ie rehash/rebuild the hashtables etc so it has a 
> canonical ordering? I see this was mentioned in the bug report and is 
> considered a largish/complex fix, but it would be the proper fix IMO.
> 
> Thanks, David

I tried the "proper" approach but it's very complicated. I already have an 
implementation that sorts all the metadata. However, the CDS archive also 
contains a heap dump, which includes Java HashMaps. If I allow those 3 Java 
threads to start, some HashMaps in the module graph will have unstable 
ordering. I think the reason is concurrent thread execution causes unstable 
assignment of the identity_hash for objects in the heap dump. I cannot think of 
a clean way to fix this.

The alternative, disabling Java thread starts, is much simpler and much more 
appealing to me.

-

PR: https://git.openjdk.java.net/jdk/pull/7748


Re: RFR: 8253495: CDS generates non-deterministic output [v2]

2022-03-08 Thread Ioi Lam
On Wed, 9 Mar 2022 06:49:02 GMT, David Holmes  wrote:

>> Ioi Lam has updated the pull request incrementally with one additional 
>> commit since the last revision:
>> 
>>   Fixed zero build
>
> src/hotspot/share/prims/jvm.cpp line 2873:
> 
>> 2871: // execute in parallel, symbols and classes may be loaded in
>> 2872: // random orders which will make the resulting CDS archive
>> 2873: // non-deterministic.
> 
> Yes but by not starting these threads you are potentially excluding a range 
> of classes from the shared archive!

`java -Xshare:dump` loads all classes specified in a classlist, which is 
created without this thread-disabling hack.

The number of classes in the CDS archive is the same before/after this PR. The 
size of the CDS archive is identical.

-

PR: https://git.openjdk.java.net/jdk/pull/7748


Re: RFR: 8253495: CDS generates non-deterministic output [v2]

2022-03-08 Thread David Holmes
On Wed, 9 Mar 2022 05:10:44 GMT, Ioi Lam  wrote:

>> This patch makes the result of "java -Xshare:dump" deterministic:
>> - Disabled new Java threads from launching. This is harmless. See comments 
>> in jvm.cpp
>> - Fixed a problem in hashtable ordering in heapShared.cpp
>> - BasicHashtableEntry has a gap on 64-bit platforms that may contain random 
>> bits. Added code to zero it.
>> - Enabled checking of $JAVA_HOME/lib/server/classes.jsa in 
>> make/scripts/compare.sh
>> 
>> Note:  $JAVA_HOME/lib/server/classes_ncoops.jsa is still non-deterministic. 
>> This will be fixed in 
>> [JDK-8282828](https://bugs.openjdk.java.net/browse/JDK-8282828).
>> 
>> Testing under way:
>> - tier1~tier5
>> - Run all *-cmp-baseline jobs 20 times each (linux-aarch64-cmp-baseline, 
>> windows-x86-cmp-baseline,  etc).
>
> Ioi Lam has updated the pull request incrementally with one additional commit 
> since the last revision:
> 
>   Fixed zero build

I have reservations about contorting things this way just to get "deterministic 
output".

The VM needs to fully initialize and then become quiescent before the dump 
occurs, and as I say below if you don't start other threads then you 
potentially remove part of the archive because classes won't be loaded by those 
threads.

I think if you care about the order of dumping classes then you should control 
that order, you don't try to force the order of loading. Can't you sort things 
before dumping? ie rehash/rebuild the hashtables etc so it has a canonical 
ordering? I see this was mentioned in the bug report and is considered a 
largish/complex fix, but it would be the proper fix IMO.

Thanks,
David

src/hotspot/share/prims/jvm.cpp line 2873:

> 2871: // execute in parallel, symbols and classes may be loaded in
> 2872: // random orders which will make the resulting CDS archive
> 2873: // non-deterministic.

Yes but by not starting these threads you are potentially excluding a range of 
classes from the shared archive!

-

PR: https://git.openjdk.java.net/jdk/pull/7748


Re: RFR: 8253495: CDS generates non-deterministic output [v2]

2022-03-08 Thread Ioi Lam
> This patch makes the result of "java -Xshare:dump" deterministic:
> - Disabled new Java threads from launching. This is harmless. See comments in 
> jvm.cpp
> - Fixed a problem in hashtable ordering in heapShared.cpp
> - BasicHashtableEntry has a gap on 64-bit platforms that may contain random 
> bits. Added code to zero it.
> - Enabled checking of $JAVA_HOME/lib/server/classes.jsa in 
> make/scripts/compare.sh
> 
> Note:  $JAVA_HOME/lib/server/classes_ncoops.jsa is still non-deterministic. 
> This will be fixed in 
> [JDK-8282828](https://bugs.openjdk.java.net/browse/JDK-8282828).
> 
> Testing under way:
> - tier1~tier5
> - Run all *-cmp-baseline jobs 20 times each (linux-aarch64-cmp-baseline, 
> windows-x86-cmp-baseline,  etc).

Ioi Lam has updated the pull request incrementally with one additional commit 
since the last revision:

  Fixed zero build

-

Changes:
  - all: https://git.openjdk.java.net/jdk/pull/7748/files
  - new: https://git.openjdk.java.net/jdk/pull/7748/files/1fb3f830..44db40f1

Webrevs:
 - full: https://webrevs.openjdk.java.net/?repo=jdk=7748=01
 - incr: https://webrevs.openjdk.java.net/?repo=jdk=7748=00-01

  Stats: 5 lines in 2 files changed: 3 ins; 0 del; 2 mod
  Patch: https://git.openjdk.java.net/jdk/pull/7748.diff
  Fetch: git fetch https://git.openjdk.java.net/jdk pull/7748/head:pull/7748

PR: https://git.openjdk.java.net/jdk/pull/7748


Re: RFR: 8253495: CDS generates non-deterministic output

2022-03-08 Thread Erik Joelsson
On Tue, 8 Mar 2022 19:11:02 GMT, Ioi Lam  wrote:

> This patch makes the result of "java -Xshare:dump" deterministic:
> - Disabled new Java threads from launching. This is harmless. See comments in 
> jvm.cpp
> - Fixed a problem in hashtable ordering in heapShared.cpp
> - BasicHashtableEntry has a gap on 64-bit platforms that may contain random 
> bits. Added code to zero it.
> - Enabled checking of $JAVA_HOME/lib/server/classes.jsa in 
> make/scripts/compare.sh
> 
> Note:  $JAVA_HOME/lib/server/classes_ncoops.jsa is still non-deterministic. 
> This will be fixed in 
> [JDK-8282828](https://bugs.openjdk.java.net/browse/JDK-8282828).
> 
> Testing under way:
> - tier1~tier5
> - Run all *-cmp-baseline jobs 20 times each (linux-aarch64-cmp-baseline, 
> windows-x86-cmp-baseline,  etc).

compare.sh looks good. Can't comment on the rest. Thank you for fixing this!

-

Marked as reviewed by erikj (Reviewer).

PR: https://git.openjdk.java.net/jdk/pull/7748


RFR: 8253495: CDS generates non-deterministic output

2022-03-08 Thread Ioi Lam
This patch makes the result of "java -Xshare:dump" deterministic:
- Disabled new Java threads from launching. This is harmless. See comments in 
jvm.cpp
- Fixed a problem in hashtable ordering in heapShared.cpp
- BasicHashtableEntry has a gap on 64-bit platforms that may contain random 
bits. Added code to zero it.
- Enabled checking of $JAVA_HOME/lib/server/classes.jsa in 
make/scripts/compare.sh

Note:  $JAVA_HOME/lib/server/classes_ncoops.jsa is still non-deterministic. 
This will be fixed in 
[JDK-8282828](https://bugs.openjdk.java.net/browse/JDK-8282828).

Testing under way:
- tier1~tier5
- Run all *-cmp-baseline jobs 20 times each (linux-aarch64-cmp-baseline, 
windows-x86-cmp-baseline,  etc).

-

Commit messages:
 - Merge branch 'master' into 8253495-cds-generateds-non-deterministic-output-2
 - fixed test
 - more fixes
 - 8253495: CDS generates non-deterministic output

Changes: https://git.openjdk.java.net/jdk/pull/7748/files
 Webrev: https://webrevs.openjdk.java.net/?repo=jdk=7748=00
  Issue: https://bugs.openjdk.java.net/browse/JDK-8253495
  Stats: 73 lines in 12 files changed: 49 ins; 7 del; 17 mod
  Patch: https://git.openjdk.java.net/jdk/pull/7748.diff
  Fetch: git fetch https://git.openjdk.java.net/jdk pull/7748/head:pull/7748

PR: https://git.openjdk.java.net/jdk/pull/7748