mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-24 01:00:27 +00:00
8249276: CDS archived objects must have "neutral" markwords
Reviewed-by: coleenp, dholmes
This commit is contained in:
parent
a5ae1e306e
commit
178eea6065
@ -136,17 +136,23 @@ oop HeapShared::archive_heap_object(oop obj, Thread* THREAD) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Pre-compute object identity hash at CDS dump time.
|
||||
obj->identity_hash();
|
||||
|
||||
oop archived_oop = (oop)G1CollectedHeap::heap()->archive_mem_allocate(len);
|
||||
if (archived_oop != NULL) {
|
||||
Copy::aligned_disjoint_words(cast_from_oop<HeapWord*>(obj), cast_from_oop<HeapWord*>(archived_oop), len);
|
||||
MetaspaceShared::relocate_klass_ptr(archived_oop);
|
||||
// Clear age -- it might have been set if a GC happened during -Xshare:dump
|
||||
markWord mark = archived_oop->mark_raw();
|
||||
mark = mark.set_age(0);
|
||||
archived_oop->set_mark_raw(mark);
|
||||
// Reinitialize markword to remove age/marking/locking/etc.
|
||||
//
|
||||
// We need to retain the identity_hash, because it may have been used by some hashtables
|
||||
// in the shared heap. This also has the side effect of pre-initializing the
|
||||
// identity_hash for all shared objects, so they are less likely to be written
|
||||
// into during run time, increasing the potential of memory sharing.
|
||||
int hash_original = obj->identity_hash();
|
||||
archived_oop->set_mark_raw(markWord::prototype().copy_set_hash(hash_original));
|
||||
assert(archived_oop->mark().is_unlocked(), "sanity");
|
||||
|
||||
DEBUG_ONLY(int hash_archived = archived_oop->identity_hash());
|
||||
assert(hash_original == hash_archived, "Different hash codes: original %x, archived %x", hash_original, hash_archived);
|
||||
|
||||
ArchivedObjectCache* cache = archived_object_cache();
|
||||
cache->put(obj, archived_oop);
|
||||
log_debug(cds, heap)("Archived heap object " PTR_FORMAT " ==> " PTR_FORMAT,
|
||||
|
||||
@ -326,6 +326,7 @@ hotspot_appcds_dynamic = \
|
||||
-runtime/cds/appcds/javaldr/ArrayTest.java \
|
||||
-runtime/cds/appcds/javaldr/GCSharedStringsDuringDump.java \
|
||||
-runtime/cds/appcds/javaldr/HumongousDuringDump.java \
|
||||
-runtime/cds/appcds/javaldr/LockDuringDump.java \
|
||||
-runtime/cds/appcds/sharedStrings \
|
||||
-runtime/cds/appcds/ArchiveRelocationTest.java \
|
||||
-runtime/cds/appcds/DumpClassList.java \
|
||||
|
||||
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8249276
|
||||
* @summary When dumping the CDS archive, try to lock some objects. These objects should be archived
|
||||
* without the locking bits in the markWord.
|
||||
* @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds
|
||||
* @requires vm.cds
|
||||
* @requires vm.flavor != "minimal"
|
||||
* @modules java.instrument
|
||||
* @run driver LockDuringDump
|
||||
*/
|
||||
|
||||
import jdk.test.lib.process.OutputAnalyzer;
|
||||
|
||||
public class LockDuringDump {
|
||||
public static String appClasses[] = {
|
||||
LockDuringDumpApp.class.getName(),
|
||||
};
|
||||
public static String agentClasses[] = {
|
||||
LockDuringDumpAgent.class.getName(),
|
||||
};
|
||||
|
||||
private static final String MANIFEST =
|
||||
"Manifest-Version: 1.0\nPremain-Class: LockDuringDumpAgent\n";
|
||||
|
||||
public static void main(String[] args) throws Throwable {
|
||||
String agentJar =
|
||||
ClassFileInstaller.writeJar("LockDuringDumpAgent.jar",
|
||||
ClassFileInstaller.Manifest.fromString(MANIFEST),
|
||||
agentClasses);
|
||||
|
||||
String appJar =
|
||||
ClassFileInstaller.writeJar("LockDuringDumpApp.jar", appClasses);
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
// i = 0 -- dump without agent
|
||||
// i = 1 -- dump with agent = disable BiasedLocking
|
||||
// i = 2 -- dump with agent = enable BiasedLocking
|
||||
|
||||
String agentArg = (i == 0) ? "-showversion" : "-javaagent:" + agentJar;
|
||||
String agentArg2 = (i == 0) ? "-showversion" : "-XX:+AllowArchivingWithJavaAgent";
|
||||
String biasedLock = (i != 2) ? "-showversion" : "-XX:+UseBiasedLocking";
|
||||
|
||||
OutputAnalyzer out =
|
||||
TestCommon.testDump(appJar, TestCommon.list(LockDuringDumpApp.class.getName()),
|
||||
"-XX:+UnlockDiagnosticVMOptions",
|
||||
agentArg, agentArg2, biasedLock);
|
||||
if (i != 0) {
|
||||
out.shouldContain("Let's hold the lock on the literal string");
|
||||
}
|
||||
|
||||
TestCommon.run(
|
||||
"-cp", appJar,
|
||||
"-XX:+UnlockDiagnosticVMOptions", agentArg2, biasedLock,
|
||||
LockDuringDumpApp.class.getName())
|
||||
.assertNormalExit("I am able to lock the literal string");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
import java.lang.instrument.Instrumentation;
|
||||
|
||||
public class LockDuringDumpAgent implements Runnable {
|
||||
static boolean threadStarted = false;
|
||||
static Object lock = new Object();
|
||||
|
||||
// The following literal string will be stored into the VM's interned string table when this
|
||||
// class (or the LockDuringDumpApp class) is loaded during -Xshare:dump. As a result it will be
|
||||
// stored in the CDS archived heap (all strings in the dump-time interned string table are archived).
|
||||
//
|
||||
// We try to make sure this string is locked while the archived heap is dumped. CDS should
|
||||
// clear the lock states in this string's object header. See JDK-8249276.
|
||||
//
|
||||
// At run time, when LockDuringDumpApp loads this literal string (from the shared string table)
|
||||
// it should be able to lock it without problems.
|
||||
static String LITERAL = "@@LockDuringDump@@LITERAL"; // must be the same as in LockDuringDumpAgent
|
||||
|
||||
public static void premain(String agentArg, Instrumentation instrumentation) {
|
||||
System.out.println("inside LockDuringDumpAgent: " + LockDuringDumpAgent.class.getClassLoader());
|
||||
|
||||
Thread t = new Thread(new LockDuringDumpAgent());
|
||||
t.setDaemon(true);
|
||||
t.start();
|
||||
|
||||
waitForThreadStart();
|
||||
}
|
||||
|
||||
static void waitForThreadStart() {
|
||||
try {
|
||||
synchronized (lock) {
|
||||
while (!threadStarted) {
|
||||
lock.wait();
|
||||
}
|
||||
System.out.println("Thread has started");
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
System.err.println("Unexpected: " + t);
|
||||
throw new RuntimeException(t);
|
||||
}
|
||||
}
|
||||
|
||||
public void run() {
|
||||
try {
|
||||
synchronized (LITERAL) {
|
||||
System.out.println("Let's hold the lock on the literal string \"" + LITERAL + "\" + forever .....");
|
||||
synchronized (lock) {
|
||||
threadStarted = true;
|
||||
lock.notifyAll();
|
||||
}
|
||||
//if (false) {
|
||||
while (true) {
|
||||
Thread.sleep(1);
|
||||
}
|
||||
//}
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
System.err.println("Unexpected: " + t);
|
||||
throw new RuntimeException(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
public class LockDuringDumpApp {
|
||||
static String LITERAL = "@@LockDuringDump@@LITERAL"; // must be the same as in LockDuringDumpAgent
|
||||
|
||||
public static void main(String args[]) {
|
||||
synchronized (LITERAL) { // See comments in LockDuringDumpAgent.java
|
||||
System.out.println("I am able to lock the literal string \"" + LITERAL + "\"");
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user