Skip to content
Permalink
Browse files
8260296: SA's dumpreplaydata fails
Reviewed-by: kvn, cjplummer, iignatyev
  • Loading branch information
rwestrel committed Feb 5, 2021
1 parent 0791899 commit 3495febf51d91236b1795e1088181ad91a3d9b9f
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2021, 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
@@ -27,6 +27,9 @@
#include "ci/ciUtilities.inline.hpp"
#include "gc/shared/collectedHeap.inline.hpp"

// Not inlined to preserve visibility of ciMetaData vtable symbol. Required by SA.
bool ciMetadata::is_classless() const { return false; }

// ------------------------------------------------------------------
// ciMetadata::print
//
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2021, 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
@@ -43,7 +43,7 @@ class ciMetadata: public ciBaseObject {
ciMetadata(): _metadata(NULL) {}
ciMetadata(Metadata* o): _metadata(o) {}

virtual bool is_classless() const { return false; }
virtual bool is_classless() const;
public:
bool is_loaded() const { return _metadata != NULL || is_classless(); }

@@ -1256,7 +1256,7 @@ void MethodData::initialize() {
object_size += extra_size + arg_data_size;

int parms_cell = ParametersTypeData::compute_cell_count(method());
// If we are profiling parameters, we reserver an area near the end
// If we are profiling parameters, we reserved an area near the end
// of the MDO after the slots for bytecodes (because there's no bci
// for method entry so they don't fit with the framework for the
// profiling of bytecodes). We store the offset within the MDO of
@@ -261,7 +261,7 @@ typedef HashtableEntry<InstanceKlass*, mtClass> KlassHashtableEntry;
nonstatic_field(Klass, _java_mirror, OopHandle) \
nonstatic_field(Klass, _modifier_flags, jint) \
nonstatic_field(Klass, _super, Klass*) \
volatile_nonstatic_field(Klass, _subklass, Klass*) \
volatile_nonstatic_field(Klass, _subklass, Klass*) \
nonstatic_field(Klass, _layout_helper, jint) \
nonstatic_field(Klass, _name, Symbol*) \
nonstatic_field(Klass, _access_flags, AccessFlags) \
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2021, 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
@@ -30,6 +30,7 @@
import sun.jvm.hotspot.runtime.*;
import sun.jvm.hotspot.oops.*;
import sun.jvm.hotspot.types.*;
import sun.jvm.hotspot.types.Field;
import sun.jvm.hotspot.utilities.Observable;
import sun.jvm.hotspot.utilities.Observer;

@@ -44,7 +45,7 @@ public void update(Observable o, Object data) {

private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
Type type = db.lookupType("ciMethodData");
origField = type.getAddressField("_orig");
origField = type.getField("_orig");
currentMileageField = new CIntField(type.getCIntegerField("_current_mileage"), 0);
argReturnedField = new CIntField(type.getCIntegerField("_arg_returned"), 0);
argStackField = new CIntField(type.getCIntegerField("_arg_stack"), 0);
@@ -61,7 +62,7 @@ private static synchronized void initialize(TypeDataBase db) throws WrongTypeExc
parametersTypeDataDi = new CIntField(typeMethodData.getCIntegerField("_parameters_type_data_di"), 0);
}

private static AddressField origField;
private static Field origField;
private static CIntField currentMileageField;
private static CIntField argReturnedField;
private static CIntField argStackField;
@@ -106,8 +107,8 @@ public void printMethodValueOn(ciMethod method, PrintStream st) {
public byte[] orig() {
// fetch the orig MethodData data between header and dataSize
Address base = getAddress().addOffsetTo(origField.getOffset());
byte[] result = new byte[MethodData.sizeofMethodDataOopDesc];
for (int i = 0; i < MethodData.sizeofMethodDataOopDesc; i++) {
byte[] result = new byte[(int)origField.getType().getSize()];
for (int i = 0; i < result.length; i++) {
result[i] = base.getJByteAt(i);
}
return result;
@@ -116,7 +117,7 @@ public void printMethodValueOn(ciMethod method, PrintStream st) {
public long[] data() {
// Read the data as an array of intptr_t elements
Address base = dataField.getValue(getAddress());
int elements = dataSize() / MethodData.cellSize;
int elements = (dataSize() + extraDataSize()) / MethodData.cellSize;
long[] result = new long[elements];
for (int i = 0; i < elements; i++) {
Address value = base.getAddressAt(i * MethodData.cellSize);
@@ -148,8 +149,7 @@ boolean outOfBounds(int dataIndex) {
}

ParametersTypeData<ciKlass,ciMethod> parametersTypeData() {
Address base = getAddress().addOffsetTo(origField.getOffset());
int di = (int)parametersTypeDataDi.getValue(base);
int di = (int)parametersTypeDataDi.getValue(getMetadata().getAddress());
if (di == -1 || di == -2) {
return null;
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2021, 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
@@ -81,9 +81,8 @@ private int getU22(int at) {
return data.getJShortAt(offset + at) & 0xffff;
}

int cellAt(int index) {
// Cells are intptr_t sized but only contain ints as raw values
return (int)data.getCIntegerAt(offset + cellOffset(index), MethodData.cellSize, false);
long cellAt(int index) {
return data.getCIntegerAt(offset + cellOffset(index), MethodData.cellSize, false);
}

public Address addressAt(int index) {
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2021, 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
@@ -234,8 +234,8 @@ public void printValueOn(PrintStream tty) {
public void iterateFields(MetadataVisitor visitor) {
super.iterateFields(visitor);
visitor.doMetadata(method, true);
visitor.doCInt(size, true);
}
visitor.doCInt(size, true);
}

int dataSize() {
if (dataSize == null) {
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2021, 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
@@ -51,7 +51,7 @@ public int dp() {
}

// Low-level accessors for underlying data
int intptrAt(int index) {
long intptrAt(int index) {
//assert(0 <= index && index < cellCount(), "oob");
return data().cellAt(index);
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2021, 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
@@ -48,17 +48,17 @@
final MethodDataInterface<K,M> methodData;

boolean wasNullSeen(int index) {
int v = pd.intptrAt(index);
long v = pd.intptrAt(index);
return (v & nullSeen) != 0;
}

boolean isTypeUnknown(int index) {
int v = pd.intptrAt(index);
long v = pd.intptrAt(index);
return (v & typeUnknown) != 0;
}

boolean isTypeNone(int index) {
int v = pd.intptrAt(index);
long v = pd.intptrAt(index);
return (v & typeMask) == 0;
}

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2021, 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
@@ -43,6 +43,7 @@
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.Asserts;
import jdk.test.lib.Utils;
import jdk.test.lib.util.CoreUtils;

public abstract class CiReplayBase {
public static final String REPLAY_FILE_NAME = "test_replay.txt";
@@ -65,17 +66,27 @@
"-XX:MetaspaceSize=4m", "-XX:MaxMetaspaceSize=16m", "-XX:InitialCodeCacheSize=512k",
"-XX:ReservedCodeCacheSize=4m", "-XX:ThreadStackSize=512", "-XX:VMThreadStackSize=512",
"-XX:CompilerThreadStackSize=512", "-XX:ParallelGCThreads=1", "-XX:CICompilerCount=2",
"-Xcomp", "-XX:CICrashAt=1", "-XX:+DumpReplayDataOnError",
"-XX:+PreferInterpreterNativeStubs", "-XX:+PrintCompilation", REPLAY_FILE_OPTION};
"-XX:-BackgroundCompilation", "-XX:CompileCommand=inline,java.io.PrintStream::*",
"-XX:+IgnoreUnrecognizedVMOptions", "-XX:TypeProfileLevel=222", // extra profile data as a stress test
"-XX:CICrashAt=1", "-XX:+DumpReplayDataOnError",
"-XX:+PreferInterpreterNativeStubs", REPLAY_FILE_OPTION};
private static final String[] REPLAY_OPTIONS = new String[]{DISABLE_COREDUMP_ON_CRASH,
"-XX:+IgnoreUnrecognizedVMOptions", "-XX:TypeProfileLevel=222",
"-XX:+ReplayCompiles", REPLAY_FILE_OPTION};
protected final Optional<Boolean> runServer;
private static int dummy;

public static class TestMain {
public static void main(String[] args) {
// Do something because empty methods might not be called/compiled.
dummy = 42;
for (int i = 0; i < 20_000; i++) {
test(i);
}
}

static void test(int i) {
if ((i % 1000) == 0) {
System.out.println("Hello World!");
}
}
}

@@ -103,7 +114,7 @@ public CiReplayBase(String args[]) {

public void runTest(boolean needCoreDump, String... args) {
cleanup();
if (generateReplay(needCoreDump)) {
if (generateReplay(needCoreDump, args)) {
testAction();
cleanup();
} else {
@@ -143,11 +154,16 @@ public boolean generateReplay(boolean needCoreDump, String... vmopts) {
options.addAll(Arrays.asList(REPLAY_GENERATION_OPTIONS));
options.addAll(Arrays.asList(vmopts));
options.add(needCoreDump ? ENABLE_COREDUMP_ON_CRASH : DISABLE_COREDUMP_ON_CRASH);
options.add(TestMain.class.getName());
if (needCoreDump) {
crashOut = ProcessTools.executeProcess(getTestJvmCommandlineWithPrefix(
RUN_SHELL_NO_LIMIT, options.toArray(new String[0])));
// CiReplayBase$TestMain needs to be quoted because of shell eval
options.add("-XX:CompileOnly='" + TestMain.class.getName() + "::test'");
options.add("'" + TestMain.class.getName() + "'");
crashOut = ProcessTools.executeProcess(
CoreUtils.addCoreUlimitCommand(
ProcessTools.createTestJvm(options.toArray(new String[0]))));
} else {
options.add("-XX:CompileOnly=" + TestMain.class.getName() + "::test");
options.add(TestMain.class.getName());
crashOut = ProcessTools.executeProcess(ProcessTools.createTestJvm(options));
}
crashOutputString = crashOut.getOutput();
@@ -159,18 +175,8 @@ public boolean generateReplay(boolean needCoreDump, String... vmopts) {
throw new Error("Can't create replay: " + t, t);
}
if (needCoreDump) {
String coreFileLocation = getCoreFileLocation(crashOutputString);
if (coreFileLocation == null) {
if (Platform.isOSX()) {
File coresDir = new File("/cores");
if (!coresDir.isDirectory() || !coresDir.canWrite()) {
return false;
}
}
throw new Error("Couldn't find core file location in: '" + crashOutputString + "'");
}
try {
Asserts.assertGT(new File(coreFileLocation).length(), 0L, "Unexpected core size");
String coreFileLocation = CoreUtils.getCoreFileLocation(crashOutputString, crashOut.pid());
Files.move(Paths.get(coreFileLocation), Paths.get(TEST_CORE_FILE_NAME));
} catch (IOException ioe) {
throw new Error("Can't move core file: " + ioe, ioe);
@@ -250,48 +256,6 @@ public void nonTieredTests(int compLevel) {
}
}

// lets search few possible locations using process output and return existing location
private String getCoreFileLocation(String crashOutputString) {
Asserts.assertTrue(crashOutputString.contains(LOCATIONS_STRING),
"Output doesn't contain the location of core file, see crash.out");
String stringWithLocation = Arrays.stream(crashOutputString.split("\\r?\\n"))
.filter(str -> str.contains(LOCATIONS_STRING))
.findFirst()
.get();
stringWithLocation = stringWithLocation.substring(stringWithLocation
.indexOf(LOCATIONS_STRING) + LOCATIONS_STRING.length());
String coreWithPid;
if (stringWithLocation.contains("or ") && !Platform.isWindows()) {
Matcher m = Pattern.compile("or.* ([^ ]+[^\\)])\\)?").matcher(stringWithLocation);
if (!m.find()) {
throw new Error("Couldn't find path to core inside location string");
}
coreWithPid = m.group(1);
} else {
coreWithPid = stringWithLocation.trim();
}
if (new File(coreWithPid).exists()) {
return coreWithPid;
}
String justCore = Paths.get("core").toString();
if (new File(justCore).exists()) {
return justCore;
}
Path coreWithPidPath = Paths.get(coreWithPid);
String justFile = coreWithPidPath.getFileName().toString();
if (new File(justFile).exists()) {
return justFile;
}
Path parent = coreWithPidPath.getParent();
if (parent != null) {
String coreWithoutPid = parent.resolve("core").toString();
if (new File(coreWithoutPid).exists()) {
return coreWithoutPid;
}
}
return null;
}

private String[] getTestJvmCommandlineWithPrefix(String prefix, String... args) {
try {
String cmd = ProcessTools.getCommandLine(ProcessTools.createTestJvm(args));
Loading

0 comments on commit 3495feb

Please sign in to comment.