From 3b3529c4b0e2c599bee53e5ac34fe5178b6a966e Mon Sep 17 00:00:00 2001 From: Liang Mao Date: Tue, 14 Nov 2023 15:19:42 +0800 Subject: [PATCH] Cleanup and tests --- .../cpu/aarch64/c1_MacroAssembler_aarch64.cpp | 4 +- .../cpu/aarch64/macroAssembler_aarch64.cpp | 2 + src/hotspot/share/oops/klass.cpp | 5 + src/hotspot/share/oops/markOop.hpp | 2 +- src/hotspot/share/runtime/arguments.cpp | 1 - src/hotspot/share/runtime/globals.hpp | 5 +- .../runtime/FieldLayout/BaseOffsets.java | 130 ++++++++++++++++++ .../cds/CdsDifferentCompactObjectHeaders.java | 66 +++++++++ 8 files changed, 207 insertions(+), 8 deletions(-) create mode 100644 test/hotspot/jtreg/runtime/FieldLayout/BaseOffsets.java create mode 100644 test/hotspot/jtreg/runtime/cds/CdsDifferentCompactObjectHeaders.java diff --git a/src/hotspot/cpu/aarch64/c1_MacroAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/c1_MacroAssembler_aarch64.cpp index 95fa549d971..083d33af930 100644 --- a/src/hotspot/cpu/aarch64/c1_MacroAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/c1_MacroAssembler_aarch64.cpp @@ -347,9 +347,7 @@ void C1_MacroAssembler::inline_cache_check(Register receiver, Register iCache) { verify_oop(receiver); // explicit NULL check not needed since load from [klass_offset] causes a trap // check against inline cache - if (UseCompactObjectHeaders) { - assert(!MacroAssembler::needs_explicit_null_check(oopDesc::mark_offset_in_bytes()), "must add explicit null check"); - } else { + if (!UseCompactObjectHeaders) { assert(!MacroAssembler::needs_explicit_null_check(oopDesc::klass_offset_in_bytes()), "must add explicit null check"); } diff --git a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp index a59e6cdf831..cebff9be3f6 100644 --- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp @@ -3907,6 +3907,7 @@ void MacroAssembler::load_prototype_header(Register dst, Register src) { void MacroAssembler::store_klass(Register dst, Register src) { // FIXME: Should this be a store release? concurrent gcs assumes // klass length is valid if klass field is not null. + assert(!UseCompactObjectHeaders, "not with compact headers"); if (UseCompressedClassPointers) { encode_klass_not_null(src); strw(src, Address(dst, oopDesc::klass_offset_in_bytes())); @@ -3916,6 +3917,7 @@ void MacroAssembler::store_klass(Register dst, Register src) { } void MacroAssembler::store_klass_gap(Register dst, Register src) { + assert(!UseCompactObjectHeaders, "not with compact headers"); if (UseCompressedClassPointers) { // Store to klass gap in destination strw(src, Address(dst, oopDesc::klass_gap_offset_in_bytes())); diff --git a/src/hotspot/share/oops/klass.cpp b/src/hotspot/share/oops/klass.cpp index 811a70877a8..df1b5bacd82 100644 --- a/src/hotspot/share/oops/klass.cpp +++ b/src/hotspot/share/oops/klass.cpp @@ -696,6 +696,11 @@ void Klass::oop_print_on(oop obj, outputStream* st) { if (WizardMode) { // print header obj->mark()->print_on(st); + if (UseCompactObjectHeaders) { + st->cr(); + st->print(" - prototype_header: " INTPTR_FORMAT, _prototype_header->value()); + st->cr(); + } } // print class diff --git a/src/hotspot/share/oops/markOop.hpp b/src/hotspot/share/oops/markOop.hpp index 163e52ef193..83939244f74 100644 --- a/src/hotspot/share/oops/markOop.hpp +++ b/src/hotspot/share/oops/markOop.hpp @@ -45,7 +45,7 @@ // -------- // unused:25 hash:31 -->| unused:1 age:4 biased_lock:1 lock:2 (normal object) // Compact headers: -// nklass:32 hash:25 -->| age:4 biased_lock/self-fwded:1 lock:2 (normal object) +// nklass:32 hash:25 -->| age:4 self-fwded:1 lock:2 (normal object) // // JavaThread*:54 epoch:2 unused:1 age:4 biased_lock:1 lock:2 (biased object) // PromotedObject*:61 --------------------->| promo_bits:3 ----->| (CMS promoted object) diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp index f7d509fa57e..d12664bff37 100644 --- a/src/hotspot/share/runtime/arguments.cpp +++ b/src/hotspot/share/runtime/arguments.cpp @@ -4184,7 +4184,6 @@ jint Arguments::apply_ergo() { warning("UseAltGCForwarding is not supported with current GC setting" "; ignoring UseAltGCForwarding flag."); FLAG_SET_DEFAULT(UseAltGCForwarding, false); - FLAG_SET_DEFAULT(UseCompactObjectHeaders, false); } } diff --git a/src/hotspot/share/runtime/globals.hpp b/src/hotspot/share/runtime/globals.hpp index d65d12b5944..a29971ba679 100644 --- a/src/hotspot/share/runtime/globals.hpp +++ b/src/hotspot/share/runtime/globals.hpp @@ -2693,9 +2693,8 @@ define_pd_global(uint64_t,MaxRAM, 1ULL*G); diagnostic(bool, UseAltFastLocking, false, \ "Alternative lightweight locking") \ \ - lp64_product(bool, UseCompactObjectHeaders, true, \ - "Use 64-bit object headers instead of 96-bit headers. " \ - "lp64_product means flag is always constant in 32 bit VM") \ + experimental(bool, UseCompactObjectHeaders, true, \ + "Use compact 64-bit object headers in 64-bit VM.") \ #define VM_FLAGS(develop, \ develop_pd, \ diff --git a/test/hotspot/jtreg/runtime/FieldLayout/BaseOffsets.java b/test/hotspot/jtreg/runtime/FieldLayout/BaseOffsets.java new file mode 100644 index 00000000000..1bb7fe15de2 --- /dev/null +++ b/test/hotspot/jtreg/runtime/FieldLayout/BaseOffsets.java @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2022, 2023, 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 id=default + * @library /test/lib / + * @modules java.base/jdk.internal.misc + * java.management + * @build sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI BaseOffsets + */ +/* + * @test id=no-coops + * @library /test/lib / + * @requires vm.bits == "64" + * @modules java.base/jdk.internal.misc + * java.management + * @build sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:-UseCompressedOops BaseOffsets + */ +/* + * @test id=no-ccp + * @library /test/lib / + * @requires vm.bits == "64" + * @modules java.base/jdk.internal.misc + * java.management + * @build sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:-UseCompressedClassPointers BaseOffsets + */ +/* + * @test id=no-compact-headers + * @library /test/lib / + * @requires vm.bits == "64" + * @modules java.base/jdk.internal.misc + * java.management + * @build sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+UnlockExperimentalVMOptions -XX:+UseCompactObjectHeaders BaseOffsets + */ + +import java.lang.reflect.Field; +import java.util.Arrays; +import java.util.Comparator; +import jdk.internal.misc.Unsafe; + +import jdk.test.lib.Asserts; +import jdk.test.lib.Platform; +import sun.hotspot.WhiteBox; + +public class BaseOffsets { + + static class LIClass { + public int i; + } + + public static final WhiteBox WB = WhiteBox.getWhiteBox(); + + static final long INT_OFFSET; + static final int INT_ARRAY_OFFSET; + static final int LONG_ARRAY_OFFSET; + static { + if (!Platform.is64bit()) { + INT_OFFSET = 8; + INT_ARRAY_OFFSET = 12; + LONG_ARRAY_OFFSET = 16; + } else if (WB.getBooleanVMFlag("UseCompactObjectHeaders")) { + INT_OFFSET = 8; + INT_ARRAY_OFFSET = 16; // Should be 12 once JDK-8139457 lands. + LONG_ARRAY_OFFSET = 16; + } else if (WB.getBooleanVMFlag("UseCompressedClassPointers")) { + INT_OFFSET = 12; + INT_ARRAY_OFFSET = 16; + LONG_ARRAY_OFFSET = 16; + } else { + INT_OFFSET = 16; + INT_ARRAY_OFFSET = 24; // Should be 20 once JDK-8139457 lands. + LONG_ARRAY_OFFSET = 24; + } + } + + static public void main(String[] args) { + Unsafe unsafe = Unsafe.getUnsafe(); + Class c = LIClass.class; + Field[] fields = c.getFields(); + for (int i = 0; i < fields.length; i++) { + long offset = unsafe.objectFieldOffset(fields[i]); + if (fields[i].getType() == int.class) { + Asserts.assertEquals(offset, INT_OFFSET, "Misplaced int field"); + } else { + Asserts.fail("Unexpected field type"); + } + } + + Asserts.assertEquals(unsafe.arrayBaseOffset(boolean[].class), INT_ARRAY_OFFSET, "Misplaced boolean array base"); + Asserts.assertEquals(unsafe.arrayBaseOffset(byte[].class), INT_ARRAY_OFFSET, "Misplaced byte array base"); + Asserts.assertEquals(unsafe.arrayBaseOffset(char[].class), INT_ARRAY_OFFSET, "Misplaced char array base"); + Asserts.assertEquals(unsafe.arrayBaseOffset(short[].class), INT_ARRAY_OFFSET, "Misplaced short array base"); + Asserts.assertEquals(unsafe.arrayBaseOffset(int[].class), INT_ARRAY_OFFSET, "Misplaced int array base"); + Asserts.assertEquals(unsafe.arrayBaseOffset(long[].class), LONG_ARRAY_OFFSET, "Misplaced long array base"); + Asserts.assertEquals(unsafe.arrayBaseOffset(float[].class), INT_ARRAY_OFFSET, "Misplaced float array base"); + Asserts.assertEquals(unsafe.arrayBaseOffset(double[].class), LONG_ARRAY_OFFSET, "Misplaced double array base"); + boolean narrowOops = System.getProperty("java.vm.compressedOopsMode") != null || + !Platform.is64bit(); + int expected_objary_offset = narrowOops ? INT_ARRAY_OFFSET : LONG_ARRAY_OFFSET; + Asserts.assertEquals(unsafe.arrayBaseOffset(Object[].class), expected_objary_offset, "Misplaced object array base"); + } +} diff --git a/test/hotspot/jtreg/runtime/cds/CdsDifferentCompactObjectHeaders.java b/test/hotspot/jtreg/runtime/cds/CdsDifferentCompactObjectHeaders.java new file mode 100644 index 00000000000..604bfb678ac --- /dev/null +++ b/test/hotspot/jtreg/runtime/cds/CdsDifferentCompactObjectHeaders.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2023, 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 CdsDifferentCompactObjectHeaders + * @summary Testing CDS (class data sharing) using opposite compact object header settings. + * Using different compact bject headers setting for each dump/load pair. + * This is a negative test; using compact header setting for loading that + * is different from compact headers for creating a CDS file + * should fail when loading. + * @requires vm.cds + * @requires vm.bits == 64 + * @library /test/lib + * @run driver CdsDifferentCompactObjectHeaders + */ + +import jdk.test.lib.cds.CDSTestUtils; +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.Platform; + +public class CdsDifferentCompactObjectHeaders { + + public static void main(String[] args) throws Exception { + createAndLoadSharedArchive(true, false); + createAndLoadSharedArchive(false, true); + } + + // Parameters are object alignment expressed in bytes + private static void + createAndLoadSharedArchive(boolean createCompactHeaders, boolean loadCompactHeaders) + throws Exception { + String createCompactHeadersArg = "-XX:" + (createCompactHeaders ? "+" : "-") + "UseCompactObjectHeaders"; + String loadCompactHeadersArg = "-XX:" + (loadCompactHeaders ? "+" : "-") + "UseCompactObjectHeaders"; + String expectedErrorMsg = + String.format( + "The shared archive file's UseCompactObjectHeaders setting (%s)" + + " does not equal the current UseCompactObjectHeaders setting (%s)", + createCompactHeaders ? "enabled" : "disabled", + loadCompactHeaders ? "enabled" : "disabled"); + + CDSTestUtils.createArchiveAndCheck("-XX:+UnlockExperimentalVMOptions", createCompactHeadersArg); + + OutputAnalyzer out = CDSTestUtils.runWithArchive("-Xlog:cds", "-XX:+UnlockExperimentalVMOptions", loadCompactHeadersArg); + CDSTestUtils.checkExecExpectError(out, 1, expectedErrorMsg); + } +}