@@ -77,16 +77,17 @@ public HotSpotSpeculationLog(long failedSpeculationsAddress) {
7777 }
7878
7979 /**
80- * Gets the address of the pointer to the native failed speculations list.
80+ * Gets the address of the pointer to the native failed speculations list. This always returns a non-zero address.
8181 *
8282 * @see #managesFailedSpeculations()
8383 */
8484 public long getFailedSpeculationsAddress () {
8585 if (managesFailedSpeculations ) {
8686 synchronized (this ) {
8787 if (failedSpeculationsAddress == 0L ) {
88- failedSpeculationsAddress = UnsafeAccess .UNSAFE .allocateMemory (HotSpotJVMCIRuntime .getHostWordKind ().getByteCount ());
89- UnsafeAccess .UNSAFE .putAddress (failedSpeculationsAddress , 0L );
88+ long address = UnsafeAccess .UNSAFE .allocateMemory (HotSpotJVMCIRuntime .getHostWordKind ().getByteCount ());
89+ UnsafeAccess .UNSAFE .putAddress (address , 0L );
90+ failedSpeculationsAddress = address ;
9091 LogCleaner c = new LogCleaner (this , failedSpeculationsAddress );
9192 assert c .address == failedSpeculationsAddress ;
9293 }
@@ -171,8 +172,16 @@ public String toString() {
171172
172173 @ Override
173174 public void collectFailedSpeculations () {
174- if (failedSpeculationsAddress != 0 && UnsafeAccess .UNSAFE .getLong (failedSpeculationsAddress ) != 0 ) {
175- failedSpeculations = compilerToVM ().getFailedSpeculations (failedSpeculationsAddress , failedSpeculations );
175+ if (failedSpeculationsAddress == 0 ) {
176+ // If no memory has been allocated then don't force its creation
177+ return ;
178+ }
179+
180+ // Go through getFailedSpeculationsAddress() to ensure that any concurrent
181+ // initialization of failedSpeculationsAddress is seen by this thread.
182+ long address = getFailedSpeculationsAddress ();
183+ if (UnsafeAccess .UNSAFE .getLong (address ) != 0 ) {
184+ failedSpeculations = compilerToVM ().getFailedSpeculations (address , failedSpeculations );
176185 assert failedSpeculations .getClass () == byte [][].class ;
177186 }
178187 }
0 commit comments