Skip to content

Commit

Permalink
8318485: Narrow klass shift should be zero if encoding range extends …
Browse files Browse the repository at this point in the history
…to 0x1_0000_0000

Reviewed-by: ccheung, iklam
  • Loading branch information
tstuefe committed Oct 23, 2023
1 parent 8d9a4b4 commit 5ba9705
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 3 deletions.
1 change: 0 additions & 1 deletion src/hotspot/os/linux/os_linux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5300,7 +5300,6 @@ void os::print_memory_mappings(char* addr, size_t bytes, outputStream* st) {
if (num_found == 0) {
st->print_cr("nothing.");
}
st->cr();
}
}

Expand Down
5 changes: 5 additions & 0 deletions src/hotspot/share/memory/metaspace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -778,6 +778,11 @@ void Metaspace::global_initialize() {
if (rs.is_reserved()) {
log_info(metaspace)("Successfully forced class space address to " PTR_FORMAT, p2i(base));
} else {
LogTarget(Debug, metaspace) lt;
if (lt.is_enabled()) {
LogStream ls(lt);
os::print_memory_mappings((char*)base, size, &ls);
}
vm_exit_during_initialization(
err_msg("CompressedClassSpaceBaseAddress=" PTR_FORMAT " given, but reserving class space failed.",
CompressedClassSpaceBaseAddress));
Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/share/oops/compressedKlass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ void CompressedKlassPointers::initialize(address addr, size_t len) {

// We may not even need a shift if the range fits into 32bit:
const uint64_t UnscaledClassSpaceMax = (uint64_t(max_juint) + 1);
if (range < UnscaledClassSpaceMax) {
if (range <= UnscaledClassSpaceMax) {
shift = 0;
} else {
shift = LogKlassAlignmentInBytes;
Expand Down
2 changes: 1 addition & 1 deletion test/hotspot/gtest/runtime/test_os.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ static inline bool can_reserve_executable_memory(void) {
#endif

// Test that os::release_memory() can deal with areas containing multiple mappings.
#define PRINT_MAPPINGS(s) { tty->print_cr("%s", s); os::print_memory_mappings((char*)p, total_range_len, tty); }
#define PRINT_MAPPINGS(s) { tty->print_cr("%s", s); os::print_memory_mappings((char*)p, total_range_len, tty); tty->cr(); }
//#define PRINT_MAPPINGS

// Release a range allocated with reserve_multiple carefully, to not trip mapping
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* Copyright (c) 2013, 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
* @summary Testing that, faced with a given (possibly odd) mapping address of class space, the encoding
* scheme fits the address
* @requires vm.bits == 64 & !vm.graal.enabled
* @requires vm.flagless
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.management
* @run driver CompressedClassPointersEncodingScheme
*/

import jdk.test.lib.Platform;
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.process.ProcessTools;
import jtreg.SkippedException;

import java.io.IOException;

public class CompressedClassPointersEncodingScheme {

private static void test(long forceAddress, long classSpaceSize, long expectedEncodingBase, int expectedEncodingShift) throws IOException {
String forceAddressString = String.format("0x%016X", forceAddress).toLowerCase();
String expectedEncodingBaseString = String.format("0x%016X", expectedEncodingBase).toLowerCase();
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
"-Xshare:off", // to make CompressedClassSpaceBaseAddress work
"-XX:+UnlockDiagnosticVMOptions",
"-XX:-UseCompressedOops", // keep VM from optimizing heap location
"-XX:CompressedClassSpaceBaseAddress=" + forceAddress,
"-XX:CompressedClassSpaceSize=" + classSpaceSize,
"-Xmx128m",
"-Xlog:metaspace*",
"-version");
OutputAnalyzer output = new OutputAnalyzer(pb.start());

output.reportDiagnosticSummary();

// We ignore cases where we were not able to map at the force address
if (output.contains("reserving class space failed")) {
throw new SkippedException("Skipping because we cannot force ccs to " + forceAddressString);
}

output.shouldHaveExitValue(0);
output.shouldContain("Narrow klass base: " + expectedEncodingBaseString + ", Narrow klass shift: " + expectedEncodingShift);
}

final static long K = 1024;
final static long M = K * 1024;
final static long G = M * 1024;
public static void main(String[] args) throws Exception {
// Test ccs nestling right at the end of the 4G range
// Expecting base=0, shift=0
test(4 * G - 128 * M, 128 * M, 0, 0);

// add more...

}
}
21 changes: 21 additions & 0 deletions test/lib/jdk/test/lib/process/OutputAnalyzer.java
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,27 @@ public OutputAnalyzer stderrShouldNotBeEmpty() {
return this;
}

/**
* Returns true if stdout contains the given string
*/
public boolean stdoutContains(String expectedString) {
return getStdout().contains(expectedString);
}

/**
* Returns true if stderr contains the given string
*/
public boolean stderrContains(String expectedString) {
return getStderr().contains(expectedString);
}

/**
* Returns true if either stdout or stderr contains the given string
*/
public boolean contains(String expectedString) {
return stdoutContains(expectedString) || stderrContains(expectedString);
}

/**
* Verify that the stdout and stderr contents of output buffer contains the string
*
Expand Down

1 comment on commit 5ba9705

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.