Skip to content

Commit

Permalink
some performance fixes in new deref handle code
Browse files Browse the repository at this point in the history
  • Loading branch information
lukasstadler committed Nov 29, 2019
1 parent 249476a commit 7a3f559
Show file tree
Hide file tree
Showing 12 changed files with 98 additions and 90 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -183,8 +183,8 @@ synchronized LLVMFunctionDescriptor create(String name, FunctionType type, LLVMF
this.sigIgn = LLVMNativePointer.create(1);
this.sigErr = LLVMNativePointer.create(-1);
LLVMMemory memory = language.getCapability(LLVMMemory.class);
this.handleContainer = memory.createHandleContainer(false);
this.derefHandleContainer = memory.createHandleContainer(true);
this.handleContainer = memory.createHandleContainer(false, language.getNoHandleAssumption(false));
this.derefHandleContainer = memory.createHandleContainer(true, language.getNoHandleAssumption(true));
this.functionPointerRegistry = new LLVMFunctionPointerRegistry();
this.interopTypeRegistry = new LLVMInteropType.InteropTypeRegistry();
this.sourceContext = new LLVMSourceContext();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,12 @@

import org.graalvm.options.OptionDescriptors;

import com.oracle.truffle.api.Assumption;
import com.oracle.truffle.api.CallTarget;
import com.oracle.truffle.api.CompilerAsserts;
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
import com.oracle.truffle.api.Scope;
import com.oracle.truffle.api.Truffle;
import com.oracle.truffle.api.TruffleLanguage;
import com.oracle.truffle.api.debug.DebuggerTags;
import com.oracle.truffle.api.frame.Frame;
Expand Down Expand Up @@ -100,6 +102,11 @@ static class GlobalObjectType extends ObjectType {
static final String NAME = "LLVM";

@CompilationFinal private List<ContextExtension> contextExtensions;
@CompilationFinal private Configuration activeConfiguration = null;

private final LLDBSupport lldbSupport = new LLDBSupport(this);
private final Assumption noCommonHandleAssumption = Truffle.getRuntime().createAssumption("no common handle");
private final Assumption noDerefHandleAssumption = Truffle.getRuntime().createAssumption("no deref handle");

public abstract static class Loader implements LLVMCapability {
public abstract void loadDefaults(LLVMContext context, Path internalLibraryPath);
Expand Down Expand Up @@ -158,17 +165,23 @@ public static LLDBSupport getLLDBSupport() {
return getLanguage().lldbSupport;
}

private @CompilationFinal Configuration activeConfiguration = null;

private final LLDBSupport lldbSupport = new LLDBSupport(this);

public <C extends LLVMCapability> C getCapability(Class<C> type) {
CompilerAsserts.partialEvaluationConstant(type);
C ret = activeConfiguration.getCapability(type);
CompilerAsserts.partialEvaluationConstant(ret);
return ret;
}

/**
* Get assumptions used to globally enable/disable checks for handles. This function will return
* an assumption that is valid as long as no handles of the selected type (deref or normal
* handles) have been created.
*/
public Assumption getNoHandleAssumption(boolean deref) {
CompilerAsserts.partialEvaluationConstant(deref);
return deref ? noDerefHandleAssumption : noCommonHandleAssumption;
}

public final String getLLVMLanguageHome() {
return getLanguageHome();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import java.util.function.IntBinaryOperator;
import java.util.function.LongBinaryOperator;

import com.oracle.truffle.api.Assumption;
import com.oracle.truffle.api.CompilerDirectives.ValueType;
import com.oracle.truffle.llvm.runtime.LLVMIVarBit;
import com.oracle.truffle.llvm.runtime.config.LLVMCapability;
Expand Down Expand Up @@ -235,10 +236,6 @@ public interface BooleanBinaryOperator {

public abstract void fullFence();

public abstract boolean isCommonHandleMemory(long addr);

public abstract boolean isDerefHandleMemory(long addr);

public abstract static class HandleContainer {

public abstract LLVMNativePointer allocate(Object value);
Expand All @@ -251,7 +248,7 @@ public abstract static class HandleContainer {

}

public abstract HandleContainer createHandleContainer(boolean deref);
public abstract HandleContainer createHandleContainer(boolean deref, Assumption noHandleAssumption);

@ValueType
public static final class CMPXCHGI8 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@
import com.oracle.truffle.api.CompilerAsserts;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.Truffle;
import com.oracle.truffle.llvm.runtime.LLVMIVarBit;
import com.oracle.truffle.llvm.runtime.LLVMLanguage;
import com.oracle.truffle.llvm.runtime.floating.LLVM80BitFloat;
Expand All @@ -60,7 +59,7 @@ public final class LLVMNativeMemory extends LLVMMemory {
private static final long HANDLE_SPACE_START = 0x8000000000000000L;
private static final long HANDLE_SPACE_END = 0xC000000000000000L;
private static final long DEREF_HANDLE_SPACE_START = HANDLE_SPACE_END;
public static final long DEREF_HANDLE_SPACE_END = 0x0000000000000000L;
private static final long DEREF_HANDLE_SPACE_END = 0x0000000000000000L;

static {
assert (DEREF_HANDLE_SPACE_START & HANDLE_HEADER_MASK) != (DEREF_HANDLE_SPACE_END & HANDLE_HEADER_MASK);
Expand All @@ -79,9 +78,6 @@ public final class LLVMNativeMemory extends LLVMMemory {

private static final Unsafe unsafe = getUnsafe();

private final Assumption noCommonHandleAssumption = Truffle.getRuntime().createAssumption("no common handle assumption");
private final Assumption noDerefHandleAssumption = Truffle.getRuntime().createAssumption("no deref handle assumption");

private static Unsafe getUnsafe() {
CompilerAsserts.neverPartOfCompilation();
try {
Expand Down Expand Up @@ -533,31 +529,29 @@ public void fullFence() {
}

/**
* A fast check if the provided address is within the handle space.
* A fast bit-check if the provided address is within the handle space.
*/
public static boolean isHandleMemory(long address) {
return (address & HANDLE_SPACE_START) != 0;
}

/**
* A fast check if the provided address is within the normal handle space.
* A fast bit-check if the provided address is within the normal handle space.
*/
@Override
public boolean isCommonHandleMemory(long address) {
return !noCommonHandleAssumption.isValid() && ((address & HANDLE_HEADER_MASK) == HANDLE_SPACE_START);
public static boolean isCommonHandleMemory(long address) {
return ((address & HANDLE_HEADER_MASK) == HANDLE_SPACE_START);
}

/**
* A fast check if the provided address is within the auto-deref handle space.
* A fast bit-check if the provided address is within the auto-deref handle space.
*/
@Override
public boolean isDerefHandleMemory(long address) {
return !noDerefHandleAssumption.isValid() && ((address & HANDLE_HEADER_MASK) == DEREF_HANDLE_SPACE_START);
public static boolean isDerefHandleMemory(long address) {
return ((address & HANDLE_HEADER_MASK) == DEREF_HANDLE_SPACE_START);
}

@Override
public HandleContainer createHandleContainer(boolean deref) {
return deref ? new DerefHandleContainer(noDerefHandleAssumption) : new CommonHandleContainer(noCommonHandleAssumption);
public HandleContainer createHandleContainer(boolean deref, Assumption noHandleAssumption) {
return deref ? new DerefHandleContainer(noHandleAssumption) : new CommonHandleContainer(noHandleAssumption);
}

private abstract static class AbstractHandleContainer extends HandleContainer {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,18 @@
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
import com.oracle.truffle.api.TruffleLanguage.ContextReference;
import com.oracle.truffle.api.TruffleLanguage.LanguageReference;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.CachedContext;
import com.oracle.truffle.api.dsl.NodeChild;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.llvm.runtime.nodes.memory.load.LLVMDerefHandleGetReceiverNode;
import com.oracle.truffle.llvm.runtime.LLVMContext;
import com.oracle.truffle.llvm.runtime.LLVMFunctionDescriptor;
import com.oracle.truffle.llvm.runtime.LLVMLanguage;
import com.oracle.truffle.llvm.runtime.interop.LLVMTypedForeignObject;
import com.oracle.truffle.llvm.runtime.memory.LLVMMemory;
import com.oracle.truffle.llvm.runtime.memory.LLVMNativeMemory;
import com.oracle.truffle.llvm.runtime.nodes.api.LLVMExpressionNode;
import com.oracle.truffle.llvm.runtime.nodes.memory.load.LLVMDerefHandleGetReceiverNode;
import com.oracle.truffle.llvm.runtime.pointer.LLVMManagedPointer;
import com.oracle.truffle.llvm.runtime.pointer.LLVMNativePointer;

Expand All @@ -51,7 +52,7 @@ public abstract class LLVMLookupDispatchTargetNode extends LLVMExpressionNode {

protected static final int INLINE_CACHE_SIZE = 5;

@CompilationFinal private LLVMMemory llvmMemory;
@CompilationFinal private LanguageReference<LLVMLanguage> languageRef;

@Child private LLVMDerefHandleGetReceiverNode derefHandleGetReceiverNode;

Expand Down Expand Up @@ -114,16 +115,16 @@ protected static boolean isForeignFunction(Object object) {
return object instanceof LLVMTypedForeignObject;
}

protected final LLVMMemory getLLVMMemoryCached() {
if (llvmMemory == null) {
protected boolean isAutoDerefHandle(long addr) {
if (languageRef == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
llvmMemory = getLLVMMemory();
languageRef = lookupLanguageReference(LLVMLanguage.class);
}
return llvmMemory;
}

protected boolean isAutoDerefHandle(long addr) {
return getLLVMMemoryCached().isDerefHandleMemory(addr);
// checking the bit is cheaper than getting the assumption in interpreted mode
if (CompilerDirectives.inCompiledCode() && languageRef.get().getNoHandleAssumption(true).isValid()) {
return false;
}
return LLVMNativeMemory.isDerefHandleMemory(addr);
}

protected LLVMDerefHandleGetReceiverNode getDerefHandleGetReceiverNode() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import com.oracle.truffle.api.Truffle;
import com.oracle.truffle.api.TruffleLanguage;
import com.oracle.truffle.api.TruffleLanguage.ContextReference;
import com.oracle.truffle.api.TruffleLanguage.LanguageReference;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Fallback;
import com.oracle.truffle.api.dsl.NodeChild;
Expand All @@ -44,20 +45,20 @@
import com.oracle.truffle.api.nodes.DirectCallNode;
import com.oracle.truffle.api.nodes.RootNode;
import com.oracle.truffle.api.profiles.ConditionProfile;
import com.oracle.truffle.llvm.runtime.nodes.func.LLVMDispatchNode;
import com.oracle.truffle.llvm.runtime.nodes.intrinsics.llvm.LLVMIntrinsic;
import com.oracle.truffle.llvm.runtime.nodes.memory.load.LLVMDerefHandleGetReceiverNode;
import com.oracle.truffle.llvm.runtime.LLVMContext;
import com.oracle.truffle.llvm.runtime.LLVMContext.ExternalLibrary;
import com.oracle.truffle.llvm.runtime.LLVMFunctionDescriptor;
import com.oracle.truffle.llvm.runtime.LLVMFunctionDescriptor.LLVMIRFunction;
import com.oracle.truffle.llvm.runtime.LLVMLanguage;
import com.oracle.truffle.llvm.runtime.except.LLVMPolyglotException;
import com.oracle.truffle.llvm.runtime.interop.LLVMTypedForeignObject;
import com.oracle.truffle.llvm.runtime.memory.LLVMMemory;
import com.oracle.truffle.llvm.runtime.memory.LLVMNativeMemory;
import com.oracle.truffle.llvm.runtime.memory.LLVMStack.StackPointer;
import com.oracle.truffle.llvm.runtime.nodes.api.LLVMExpressionNode;
import com.oracle.truffle.llvm.runtime.nodes.func.LLVMDispatchNode;
import com.oracle.truffle.llvm.runtime.nodes.func.LLVMDispatchNodeGen;
import com.oracle.truffle.llvm.runtime.nodes.intrinsics.llvm.LLVMIntrinsic;
import com.oracle.truffle.llvm.runtime.nodes.memory.load.LLVMDerefHandleGetReceiverNode;
import com.oracle.truffle.llvm.runtime.pointer.LLVMManagedPointer;
import com.oracle.truffle.llvm.runtime.pointer.LLVMNativePointer;
import com.oracle.truffle.llvm.runtime.types.FunctionType;
Expand All @@ -70,6 +71,8 @@ public abstract class LLVMTruffleDecorateFunction extends LLVMIntrinsic {

@CompilationFinal private ContextReference<LLVMContext> contextRef;

@CompilationFinal private LanguageReference<LLVMLanguage> languageRef;

protected LLVMDerefHandleGetReceiverNode getDerefHandleGetReceiverNode() {
if (derefHandleGetReceiverNode == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
Expand All @@ -78,18 +81,16 @@ protected LLVMDerefHandleGetReceiverNode getDerefHandleGetReceiverNode() {
return derefHandleGetReceiverNode;
}

@CompilationFinal private LLVMMemory cachedMemory;

private LLVMMemory getLLVMMemoryCached() {
if (cachedMemory == null) {
protected boolean isAutoDerefHandle(LLVMNativePointer addr) {
if (languageRef == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
cachedMemory = getLLVMMemory();
languageRef = lookupLanguageReference(LLVMLanguage.class);
}
return cachedMemory;
}

protected boolean isAutoDerefHandle(LLVMNativePointer addr) {
return getLLVMMemoryCached().isDerefHandleMemory(addr.asNative());
// checking the bit is cheaper than getting the assumption in interpreted mode
if (CompilerDirectives.inCompiledCode() && languageRef.get().getNoHandleAssumption(true).isValid()) {
return false;
}
return LLVMNativeMemory.isDerefHandleMemory(addr.asNative());
}

protected abstract static class DecoratedRoot extends RootNode {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
import com.oracle.truffle.api.profiles.ConditionProfile;
import com.oracle.truffle.llvm.runtime.LLVMContext;
import com.oracle.truffle.llvm.runtime.LLVMLanguage;
import com.oracle.truffle.llvm.runtime.memory.LLVMMemory;
import com.oracle.truffle.llvm.runtime.memory.LLVMNativeMemory;
import com.oracle.truffle.llvm.runtime.nodes.api.LLVMExpressionNode;
import com.oracle.truffle.llvm.runtime.nodes.api.LLVMToNativeNode;
import com.oracle.truffle.llvm.runtime.nodes.intrinsics.llvm.LLVMIntrinsic;
Expand All @@ -53,7 +53,7 @@ protected LLVMManagedPointer doIntrinsic(Object rawHandle,
@CachedLanguage LLVMLanguage language,
@Cached("createBinaryProfile()") ConditionProfile isDerefProfile) {
long address = forceAddressNode.executeWithTarget(rawHandle).asNative();
if (isDerefProfile.profile(language.getCapability(LLVMMemory.class).isDerefHandleMemory(address))) {
if (!language.getNoHandleAssumption(true).isValid() && isDerefProfile.profile(LLVMNativeMemory.isDerefHandleMemory(address))) {
return context.getDerefHandleContainer().getValue(address).copy();
} else {
return context.getHandleContainer().getValue(address).copy();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,44 +29,39 @@
*/
package com.oracle.truffle.llvm.runtime.nodes.intrinsics.interop;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
import com.oracle.truffle.api.TruffleLanguage.ContextReference;
import com.oracle.truffle.api.dsl.CachedContext;
import com.oracle.truffle.api.dsl.CachedLanguage;
import com.oracle.truffle.api.dsl.Fallback;
import com.oracle.truffle.api.dsl.NodeChild;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.llvm.runtime.LLVMContext;
import com.oracle.truffle.llvm.runtime.LLVMLanguage;
import com.oracle.truffle.llvm.runtime.memory.LLVMMemory;
import com.oracle.truffle.llvm.runtime.memory.LLVMNativeMemory;
import com.oracle.truffle.llvm.runtime.nodes.api.LLVMExpressionNode;
import com.oracle.truffle.llvm.runtime.nodes.intrinsics.llvm.LLVMIntrinsic;
import com.oracle.truffle.llvm.runtime.pointer.LLVMNativePointer;

@NodeChild(type = LLVMExpressionNode.class)
public abstract class LLVMTruffleIsHandleToManaged extends LLVMIntrinsic {

@CompilationFinal private LLVMMemory memory;

@Specialization
protected boolean doLongCase(long address,
@CachedLanguage LLVMLanguage language,
@CachedContext(LLVMLanguage.class) ContextReference<LLVMContext> context) {
if (memory == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
memory = getLLVMMemory();
}
if (memory.isDerefHandleMemory(address)) {
if (!language.getNoHandleAssumption(true).isValid() && LLVMNativeMemory.isDerefHandleMemory(address)) {
return context.get().getDerefHandleContainer().isHandle(address);
} else if (memory.isCommonHandleMemory(address)) {
} else if (!language.getNoHandleAssumption(false).isValid() && LLVMNativeMemory.isCommonHandleMemory(address)) {
return context.get().getHandleContainer().isHandle(address);
}
return false;
}

@Specialization
protected boolean doPointerCase(LLVMNativePointer a,
@CachedLanguage LLVMLanguage language,
@CachedContext(LLVMLanguage.class) ContextReference<LLVMContext> context) {
return doLongCase(a.asNative(), context);
return doLongCase(a.asNative(), language, context);
}

@Fallback
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.llvm.runtime.LLVMContext;
import com.oracle.truffle.llvm.runtime.LLVMLanguage;
import com.oracle.truffle.llvm.runtime.memory.LLVMMemory;
import com.oracle.truffle.llvm.runtime.memory.LLVMNativeMemory;
import com.oracle.truffle.llvm.runtime.nodes.api.LLVMExpressionNode;
import com.oracle.truffle.llvm.runtime.nodes.intrinsics.llvm.LLVMIntrinsic;
import com.oracle.truffle.llvm.runtime.pointer.LLVMNativePointer;
Expand All @@ -52,7 +52,7 @@ protected Object doIntrinsic(LLVMNativePointer handle,
@CachedContext(LLVMLanguage.class) LLVMContext context,
@CachedLanguage LLVMLanguage language) {
long address = handle.asNative();
if (language.getCapability(LLVMMemory.class).isDerefHandleMemory(address)) {
if (!language.getNoHandleAssumption(true).isValid() && LLVMNativeMemory.isDerefHandleMemory(address)) {
context.getDerefHandleContainer().free(address);
} else {
context.getHandleContainer().free(address);
Expand Down
Loading

0 comments on commit 7a3f559

Please sign in to comment.