Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[GR-46257] ProfilingSampler does not need local variable values. #6763

Merged
merged 4 commits into from
Jun 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -481,8 +481,8 @@ public static long getTearDownFailureNanos() {
@Option(help = "Define the maximum number of stores for which the loop that zeroes out objects is unrolled.")//
public static final HostedOptionKey<Integer> MaxUnrolledObjectZeroingStores = new HostedOptionKey<>(8);

@Option(help = "Provide method names for stack traces.")//
public static final HostedOptionKey<Boolean> StackTrace = new HostedOptionKey<>(true);
@Option(help = "Deprecated, has no effect.", deprecated = true)//
static final HostedOptionKey<Boolean> StackTrace = new HostedOptionKey<>(true);

@Option(help = "Parse and consume standard options and system properties from the command line arguments when the VM is created.")//
public static final HostedOptionKey<Boolean> ParseRuntimeOptions = new HostedOptionKey<>(true);
Expand Down Expand Up @@ -517,9 +517,6 @@ public static long getTearDownFailureNanos() {
@Option(help = "Use callee saved registers to reduce spilling for low-frequency calls to stubs (if callee saved registers are supported by the architecture)")//
public static final HostedOptionKey<Boolean> UseCalleeSavedRegisters = new HostedOptionKey<>(true);

@Option(help = "Use compressed frame encoding for frames without local values.", type = OptionType.Expert)//
public static final HostedOptionKey<Boolean> UseCompressedFrameEncodings = new HostedOptionKey<>(true);

@Option(help = "Report error if <typename>[:<UsageKind>{,<UsageKind>}] is discovered during analysis (valid values for UsageKind: InHeap, Allocated, Reachable).", type = OptionType.Debug)//
public static final HostedOptionKey<LocatableMultiOptionValue.Strings> ReportAnalysisForbiddenType = new HostedOptionKey<>(LocatableMultiOptionValue.Strings.build());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,21 +117,13 @@ public Encoders() {
this.objectConstants = FrequencyEncoder.createEqualityEncoder();
this.sourceClasses = FrequencyEncoder.createEqualityEncoder();
this.sourceMethodNames = FrequencyEncoder.createEqualityEncoder();
if (FrameInfoDecoder.encodeSourceReferences()) {
this.names = FrequencyEncoder.createEqualityEncoder();
} else {
this.names = null;
}
this.names = FrequencyEncoder.createEqualityEncoder();
}

private void encodeAllAndInstall(CodeInfo target, ReferenceAdjuster adjuster) {
JavaConstant[] encodedJavaConstants = objectConstants.encodeAll(new JavaConstant[objectConstants.getLength()]);
Class<?>[] sourceClassesArray = null;
String[] sourceMethodNamesArray = null;
if (FrameInfoDecoder.encodeSourceReferences()) {
sourceClassesArray = sourceClasses.encodeAll(new Class<?>[sourceClasses.getLength()]);
sourceMethodNamesArray = sourceMethodNames.encodeAll(new String[sourceMethodNames.getLength()]);
}
Class<?>[] sourceClassesArray = sourceClasses.encodeAll(new Class<?>[sourceClasses.getLength()]);
String[] sourceMethodNamesArray = sourceMethodNames.encodeAll(new String[sourceMethodNames.getLength()]);
install(target, encodedJavaConstants, sourceClassesArray, sourceMethodNamesArray, adjuster);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,9 @@

import java.util.Arrays;

import org.graalvm.compiler.api.replacements.Fold;
import org.graalvm.compiler.core.common.util.TypeConversion;
import org.graalvm.compiler.nodes.FrameState;

import com.oracle.svm.core.SubstrateOptions;
import com.oracle.svm.core.Uninterruptible;
import com.oracle.svm.core.c.NonmovableArray;
import com.oracle.svm.core.c.NonmovableArrays;
Expand All @@ -47,17 +46,38 @@
import com.oracle.svm.core.util.NonmovableByteArrayTypeReader;
import com.oracle.svm.core.util.VMError;

import jdk.vm.ci.code.BytecodeFrame;
import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.JavaKind;

public class FrameInfoDecoder {

protected static final int BCI_SHIFT = 2;
protected static final int DURING_CALL_MASK = 2;
protected static final int RETHROW_EXCEPTION_MASK = 1;
/**
* Shift of raw bci values to make room for the {@link #ENCODED_BCI_DURING_CALL_MASK} and
* {@link #ENCODED_BCI_RETHROW_EXCEPTION_MASK} flags.
*/
protected static final int ENCODED_BCI_SHIFT = 2;
/**
* Added to raw bci values to make them non-negative. Some of the negative marker values defined
* in {@link BytecodeFrame} can show up as bci values. The encoded bci is stored as an unsigned
* value to avoid wasting one bit on the sign.
*/
protected static final int ENCODED_BCI_ADDEND = 4;
/**
* Flag in the encoded bci to preserve {@link FrameState#duringCall()} information.
*/
protected static final int ENCODED_BCI_DURING_CALL_MASK = 2;
/**
* Flag in the encoded bci to preserve {@link FrameState#rethrowException()} information.
*/
protected static final int ENCODED_BCI_RETHROW_EXCEPTION_MASK = 1;

protected static final int NO_CALLER_BCI = -1;
protected static final int NO_LOCAL_INFO_BCI = -2;
/**
* There cannot be any frame state with both the {@link #ENCODED_BCI_DURING_CALL_MASK} and
* {@link #ENCODED_BCI_RETHROW_EXCEPTION_MASK} flag set, so we can use that combination as a
* marker value.
*/
protected static final int ENCODED_BCI_NO_CALLER = ENCODED_BCI_DURING_CALL_MASK | ENCODED_BCI_RETHROW_EXCEPTION_MASK;

/**
* Differentiates between compressed and uncompressed frame slices. See
Expand Down Expand Up @@ -87,8 +107,8 @@ protected static boolean isFrameInfoMatch(long frameInfoIndex, NonmovableArray<B
}

/* Read encoded bci from uncompressed frame slice. */
long actualEncodedBci = readBuffer.getSV();
assert actualEncodedBci != NO_CALLER_BCI;
long actualEncodedBci = readBuffer.getUV();
assert actualEncodedBci != ENCODED_BCI_NO_CALLER;

return actualEncodedBci == searchEncodedBci;
}
Expand Down Expand Up @@ -281,8 +301,6 @@ private static FrameInfoQueryResult decodeCompressedFrameInfo(boolean isDeoptEnt
return result;
}

assert encodeSourceReferences();
cur.encodedBci = NO_LOCAL_INFO_BCI;
cur.isDeoptEntry = isDeoptEntry;

long bufferIndexToRestore = -1;
Expand Down Expand Up @@ -349,6 +367,7 @@ private static void decodeCompressedFrameData(ReusableTypeReader readBuffer, Cod
int sourceMethodNameIndex = CompressedFrameDecoderHelper.decodeMethodIndex(encodedSourceMethodNameIndex);
int encodedSourceLineNumber = readBuffer.getSVInt();
int sourceLineNumber = CompressedFrameDecoderHelper.decodeSourceLineNumber(encodedSourceLineNumber);
long encodedBci = readBuffer.getUV();
int methodId = readBuffer.getSVInt();

queryResult.sourceClassIndex = sourceClassIndex;
Expand All @@ -357,6 +376,7 @@ private static void decodeCompressedFrameData(ReusableTypeReader readBuffer, Cod
queryResult.sourceClass = NonmovableArrays.getObject(CodeInfoAccess.getFrameInfoSourceClasses(info), sourceClassIndex);
queryResult.sourceMethodName = NonmovableArrays.getObject(CodeInfoAccess.getFrameInfoSourceMethodNames(info), sourceMethodNameIndex);
queryResult.sourceLineNumber = sourceLineNumber;
queryResult.encodedBci = encodedBci;
queryResult.methodId = methodId;

if (CompressedFrameDecoderHelper.hasEncodedUniqueSharedFrameSuccessor(encodedSourceMethodNameIndex)) {
Expand All @@ -379,8 +399,8 @@ private static FrameInfoQueryResult decodeUncompressedFrameInfo(boolean isDeoptE

while (!state.isDone) {
long start = readBuffer.getByteIndex();
int encodedBci = readBuffer.getSVInt();
if (encodedBci == NO_CALLER_BCI) {
long encodedBci = readBuffer.getUV();
if (encodedBci == ENCODED_BCI_NO_CALLER) {
state.isDone = true;
return result;
}
Expand All @@ -396,60 +416,54 @@ private static FrameInfoQueryResult decodeUncompressedFrameInfo(boolean isDeoptE
cur.encodedBci = encodedBci;
cur.isDeoptEntry = isDeoptEntry;

boolean needLocalValues = encodedBci != NO_LOCAL_INFO_BCI;

if (needLocalValues) {
cur.numLocks = readBuffer.getUVInt();
cur.numLocals = readBuffer.getUVInt();
cur.numStack = readBuffer.getUVInt();

/*
* We either encode a reference to the target method (for runtime compilations) or
* just the start offset of the target method (for native image methods, because we
* do not want to include unnecessary method metadata in the native image.
*/
int deoptMethodIndex = readBuffer.getSVInt();
if (deoptMethodIndex < 0) {
/* Negative number is a reference to the target method. */
cur.deoptMethod = (SharedMethod) NonmovableArrays.getObject(CodeInfoAccess.getFrameInfoObjectConstants(info), -1 - deoptMethodIndex);
cur.deoptMethodOffset = cur.deoptMethod.getDeoptOffsetInImage();
} else {
/* Positive number is a directly encoded method offset. */
cur.deoptMethodOffset = deoptMethodIndex;
}
cur.numLocks = readBuffer.getUVInt();
cur.numLocals = readBuffer.getUVInt();
cur.numStack = readBuffer.getUVInt();

/*
* We either encode a reference to the target method (for runtime compilations) or just
* the start offset of the target method (for native image methods, because we do not
* want to include unnecessary method metadata in the native image.
*/
int deoptMethodIndex = readBuffer.getSVInt();
if (deoptMethodIndex < 0) {
/* Negative number is a reference to the target method. */
cur.deoptMethod = (SharedMethod) NonmovableArrays.getObject(CodeInfoAccess.getFrameInfoObjectConstants(info), -1 - deoptMethodIndex);
cur.deoptMethodOffset = cur.deoptMethod.getDeoptOffsetInImage();
} else {
/* Positive number is a directly encoded method offset. */
cur.deoptMethodOffset = deoptMethodIndex;
}

int curValueInfosLength = readBuffer.getUVInt();
cur.valueInfos = decodeValues(valueInfoAllocator, curValueInfosLength, readBuffer, CodeInfoAccess.getFrameInfoObjectConstants(info));

if (state.isFirstFrame) {
/* This is the first frame, i.e., the top frame that will be returned. */
int numVirtualObjects = readBuffer.getUVInt();
virtualObjects = newValueInfoArrayArray(valueInfoAllocator, numVirtualObjects);
for (int i = 0; i < numVirtualObjects; i++) {
int numValues = readBuffer.getUVInt();
ValueInfo[] decodedValues = decodeValues(valueInfoAllocator, numValues, readBuffer, CodeInfoAccess.getFrameInfoObjectConstants(info));
if (virtualObjects != null) {
virtualObjects[i] = decodedValues;
}
int curValueInfosLength = readBuffer.getUVInt();
cur.valueInfos = decodeValues(valueInfoAllocator, curValueInfosLength, readBuffer, CodeInfoAccess.getFrameInfoObjectConstants(info));

if (state.isFirstFrame) {
/* This is the first frame, i.e., the top frame that will be returned. */
int numVirtualObjects = readBuffer.getUVInt();
virtualObjects = newValueInfoArrayArray(valueInfoAllocator, numVirtualObjects);
for (int i = 0; i < numVirtualObjects; i++) {
int numValues = readBuffer.getUVInt();
ValueInfo[] decodedValues = decodeValues(valueInfoAllocator, numValues, readBuffer, CodeInfoAccess.getFrameInfoObjectConstants(info));
if (virtualObjects != null) {
virtualObjects[i] = decodedValues;
}
}
}
cur.virtualObjects = virtualObjects;

if (encodeSourceReferences()) {
int sourceClassIndex = readBuffer.getSVInt();
int sourceMethodNameIndex = readBuffer.getSVInt();
int sourceLineNumber = readBuffer.getSVInt();
int sourceMethodId = readBuffer.getUVInt();
int sourceClassIndex = readBuffer.getSVInt();
int sourceMethodNameIndex = readBuffer.getSVInt();
int sourceLineNumber = readBuffer.getSVInt();
int sourceMethodId = readBuffer.getUVInt();

cur.sourceClassIndex = sourceClassIndex;
cur.sourceMethodNameIndex = sourceMethodNameIndex;
cur.sourceClassIndex = sourceClassIndex;
cur.sourceMethodNameIndex = sourceMethodNameIndex;

cur.sourceClass = NonmovableArrays.getObject(CodeInfoAccess.getFrameInfoSourceClasses(info), sourceClassIndex);
cur.sourceMethodName = NonmovableArrays.getObject(CodeInfoAccess.getFrameInfoSourceMethodNames(info), sourceMethodNameIndex);
cur.sourceLineNumber = sourceLineNumber;
cur.methodId = sourceMethodId;
}
cur.sourceClass = NonmovableArrays.getObject(CodeInfoAccess.getFrameInfoSourceClasses(info), sourceClassIndex);
cur.sourceMethodName = NonmovableArrays.getObject(CodeInfoAccess.getFrameInfoSourceMethodNames(info), sourceMethodNameIndex);
cur.sourceLineNumber = sourceLineNumber;
cur.methodId = sourceMethodId;

if (prev == null) {
// first frame read during this invocation
Expand Down Expand Up @@ -514,38 +528,36 @@ private static ValueInfo newValueInfo(ValueInfoAllocator valueInfoAllocator) {
return valueInfoAllocator.newValueInfo();
}

@Fold
protected static boolean encodeSourceReferences() {
return SubstrateOptions.StackTrace.getValue();
}

@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
protected static int decodeBci(long encodedBci) {
long value = encodedBci >> BCI_SHIFT;
assert value >= Integer.MIN_VALUE && value <= Integer.MAX_VALUE;
return (int) value;
assert encodedBci > 0 && encodedBci != FrameInfoDecoder.ENCODED_BCI_NO_CALLER;
long result = (encodedBci >> ENCODED_BCI_SHIFT) - ENCODED_BCI_ADDEND;
assert result >= Integer.MIN_VALUE && result <= Integer.MAX_VALUE;
return (int) result;
}

protected static boolean decodeDuringCall(long encodedBci) {
return (encodedBci & DURING_CALL_MASK) != 0;
assert encodedBci > 0 && encodedBci != FrameInfoDecoder.ENCODED_BCI_NO_CALLER;
return (encodedBci & ENCODED_BCI_DURING_CALL_MASK) != 0;
}

protected static boolean decodeRethrowException(long encodedBci) {
return (encodedBci & RETHROW_EXCEPTION_MASK) != 0;
assert encodedBci > 0 && encodedBci != FrameInfoDecoder.ENCODED_BCI_NO_CALLER;
return (encodedBci & ENCODED_BCI_RETHROW_EXCEPTION_MASK) != 0;
}

public static String readableBci(long encodedBci) {
return decodeBci(encodedBci) +
((encodedBci & DURING_CALL_MASK) != 0 ? " duringCall" : "") +
((encodedBci & RETHROW_EXCEPTION_MASK) != 0 ? " rethrowException" : "");
(decodeDuringCall(encodedBci) ? " duringCall" : "") +
(decodeRethrowException(encodedBci) ? " rethrowException" : "");
}

public static void logReadableBci(Log log, long encodedBci) {
log.signed(decodeBci(encodedBci));
if ((encodedBci & DURING_CALL_MASK) != 0) {
if (decodeDuringCall(encodedBci)) {
log.string(" duringCall");
}
if ((encodedBci & RETHROW_EXCEPTION_MASK) != 0) {
if (decodeRethrowException(encodedBci)) {
log.string(" rethrowException");
}
}
Expand Down
Loading