Skip to content

Commit

Permalink
[GR-39476] Fix a few compilation bailouts
Browse files Browse the repository at this point in the history
PullRequest: graalpython/2320
  • Loading branch information
timfel committed Jun 27, 2022
2 parents 13acfa3 + 752df81 commit 77b957f
Show file tree
Hide file tree
Showing 8 changed files with 69 additions and 115 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -208,10 +208,12 @@ long start(VirtualFrame frame, Object cls, Object callable, Object args, Object
// TODO: python thread stack size != java thread stack size
// ignore setting the stack size for the moment
Thread thread = env.createThread(() -> {
Object[] arguments = getArgsNode.executeWith(frame, args);
PKeyword[] keywords = getKwArgsNode.execute(kwargs);

try (GilNode.UncachedAcquire gil = GilNode.uncachedAcquire()) {
// if args is an arbitrary iterable, converting it to an Object[] may run
// Python code
Object[] arguments = getArgsNode.executeWith(null, args);
PKeyword[] keywords = getKwArgsNode.execute(kwargs);

// the increment is protected by the gil
DynamicObjectLibrary lib = DynamicObjectLibrary.getUncached();
int curCount = 0;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
Expand Down Expand Up @@ -47,7 +47,7 @@
import com.oracle.graal.python.builtins.objects.cext.capi.DynamicObjectNativeWrapper.ToPyObjectNode;
import com.oracle.graal.python.builtins.objects.function.PKeyword;
import com.oracle.graal.python.nodes.argument.keywords.ExpandKeywordStarargsNode;
import com.oracle.graal.python.nodes.argument.positional.ExecutePositionalStarargsNode.ExecutePositionalStarargsInteropNode;
import com.oracle.graal.python.nodes.argument.positional.ExecutePositionalStarargsNode;
import com.oracle.graal.python.nodes.argument.positional.PositionalArgumentsNode;
import com.oracle.graal.python.nodes.call.CallNode;
import com.oracle.graal.python.runtime.GilNode;
Expand Down Expand Up @@ -128,7 +128,7 @@ public Object execute(Object[] arguments,
@Exclusive @Cached ToJavaNode toJavaNode,
@Exclusive @Cached CExtNodes.ToNewRefNode toSulongNode,
@Exclusive @Cached CallNode callNode,
@Exclusive @Cached ExecutePositionalStarargsInteropNode posStarargsNode,
@Exclusive @Cached ExecutePositionalStarargsNode posStarargsNode,
@Exclusive @Cached ExpandKeywordStarargsNode expandKwargsNode,
@Exclusive @Cached GilNode gil) throws ArityException {
boolean mustRelease = gil.acquire();
Expand All @@ -143,7 +143,7 @@ public Object execute(Object[] arguments,
Object starArgs = toJavaNode.execute(arguments[1]);
Object kwArgs = toJavaNode.execute(arguments[2]);

Object[] starArgsArray = posStarargsNode.executeWithGlobalState(starArgs);
Object[] starArgsArray = posStarargsNode.executeWith(null, starArgs);
Object[] pArgs = PositionalArgumentsNode.prependArgument(receiver, starArgsArray);
PKeyword[] kwArgsArray = expandKwargsNode.execute(kwArgs);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@
import static com.oracle.graal.python.util.PythonUtils.tsLiteral;

import com.oracle.graal.python.builtins.PythonBuiltinClassType;
import com.oracle.graal.python.builtins.modules.cext.PythonCextAbstractBuiltins.PyMappingKeysNode;
import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes.AllToJavaNode;
import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes.IsPointerNode;
import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes.PCallCapiFunction;
Expand All @@ -64,12 +63,11 @@
import com.oracle.graal.python.builtins.objects.cext.capi.DynamicObjectNativeWrapper.ToPyObjectNode;
import com.oracle.graal.python.builtins.objects.function.PKeyword;
import com.oracle.graal.python.lib.PyObjectGetAttr;
import com.oracle.graal.python.lib.PyObjectGetItem;
import com.oracle.graal.python.lib.PyObjectLookupAttr;
import com.oracle.graal.python.lib.PyObjectSetAttr;
import com.oracle.graal.python.nodes.ErrorMessages;
import com.oracle.graal.python.nodes.argument.keywords.ExpandKeywordStarargsNodeGen;
import com.oracle.graal.python.nodes.argument.positional.ExecutePositionalStarargsNodeGen.ExecutePositionalStarargsInteropNodeGen;
import com.oracle.graal.python.nodes.argument.positional.ExecutePositionalStarargsNodeGen;
import com.oracle.graal.python.nodes.call.special.CallVarargsMethodNode;
import com.oracle.graal.python.nodes.statement.AbstractImportNode;
import com.oracle.graal.python.runtime.GilNode;
Expand Down Expand Up @@ -547,18 +545,16 @@ protected Object execute(Object[] args,
@Cached ToSulongNode toSulongNode,
@Cached CallVarargsMethodNode callNode,
@Cached AllToJavaNode allToJavaNode,
@Cached PyObjectGetItem getItemNode,
@Cached(allowUncached = true) PyMappingKeysNode keysNode,
@Cached PyObjectLookupAttr lookupNode,
@Cached CExtNodes.AddRefCntNode incRefNode,
@Cached TransformExceptionToNativeNode transformExceptionToNativeNode,
@Exclusive @Cached GilNode gil) throws ArityException {
@Exclusive @Cached GilNode gil) {
boolean mustRelease = gil.acquire();
try {
Object[] convertedArgs = allToJavaNode.execute(args);
Object type = convertedArgs[0];

Object[] callArgs = ExecutePositionalStarargsInteropNodeGen.getUncached().executeWithGlobalState(convertedArgs[1]);
Object[] callArgs = ExecutePositionalStarargsNodeGen.getUncached().executeWith(null, convertedArgs[1]);
PKeyword[] kwds;
if (convertedArgs.length > 2) {
kwds = ExpandKeywordStarargsNodeGen.getUncached().execute(convertedArgs[2]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ static class Execute {
@Specialization(guards = "arguments.length == 3")
static int init(InitWrapper self, Object[] arguments,
@CachedLibrary("self") PythonNativeWrapperLibrary lib,
@Cached ExecutePositionalStarargsNode.ExecutePositionalStarargsInteropNode posStarargsNode,
@Cached ExecutePositionalStarargsNode posStarargsNode,
@Cached ExpandKeywordStarargsNode expandKwargsNode,
@Cached CallVarargsMethodNode callNode,
@Cached ToJavaNode toJavaNode,
Expand All @@ -231,7 +231,7 @@ static int init(InitWrapper self, Object[] arguments,
Object starArgs = toJavaNode.execute(arguments[1]);
Object kwArgs = toJavaNode.execute(arguments[2]);

Object[] starArgsArray = posStarargsNode.executeWithGlobalState(starArgs);
Object[] starArgsArray = posStarargsNode.executeWith(null, starArgs);
Object[] pArgs = PositionalArgumentsNode.prependArgument(receiver, starArgsArray);
PKeyword[] kwArgsArray = expandKwargsNode.execute(kwArgs);
callNode.execute(null, lib.getDelegate(self), pArgs, kwArgsArray);
Expand Down Expand Up @@ -266,7 +266,7 @@ static class Execute {
@Specialization(guards = "arguments.length == 3")
static Object call(TernaryFunctionWrapper self, Object[] arguments,
@CachedLibrary("self") PythonNativeWrapperLibrary lib,
@Cached ExecutePositionalStarargsNode.ExecutePositionalStarargsInteropNode posStarargsNode,
@Cached ExecutePositionalStarargsNode posStarargsNode,
@Cached ExpandKeywordStarargsNode expandKwargsNode,
@Cached CallVarargsMethodNode callNode,
@Cached ToJavaNode toJavaNode,
Expand All @@ -281,7 +281,7 @@ static Object call(TernaryFunctionWrapper self, Object[] arguments,
Object starArgs = toJavaNode.execute(arguments[1]);
Object kwArgs = toJavaNode.execute(arguments[2]);

Object[] starArgsArray = posStarargsNode.executeWithGlobalState(starArgs);
Object[] starArgsArray = posStarargsNode.executeWith(null, starArgs);
Object[] pArgs = PositionalArgumentsNode.prependArgument(receiver, starArgsArray);
PKeyword[] kwArgsArray = expandKwargsNode.execute(kwArgs);
Object result = callNode.execute(null, lib.getDelegate(self), pArgs, kwArgsArray);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@
import com.oracle.graal.python.nodes.SpecialMethodNames;
import com.oracle.graal.python.nodes.WriteUnraisableNode;
import com.oracle.graal.python.nodes.argument.keywords.ExpandKeywordStarargsNode;
import com.oracle.graal.python.nodes.argument.positional.ExecutePositionalStarargsNode.ExecutePositionalStarargsInteropNode;
import com.oracle.graal.python.nodes.argument.positional.ExecutePositionalStarargsNode;
import com.oracle.graal.python.nodes.attributes.LookupCallableSlotInMRONode;
import com.oracle.graal.python.nodes.attributes.LookupInheritedAttributeNode;
import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode;
Expand Down Expand Up @@ -2736,7 +2736,7 @@ public static final class GraalHPyCallTupleDict extends GraalHPyContextFunction
Object execute(Object[] arguments,
@Cached HPyAsContextNode asContextNode,
@Cached HPyAsPythonObjectNode asPythonObjectNode,
@Cached ExecutePositionalStarargsInteropNode expandArgsNode,
@Cached ExecutePositionalStarargsNode expandArgsNode,
@Cached HashingCollectionNodes.LenNode lenNode,
@Cached ExpandKeywordStarargsNode expandKwargsNode,
@Cached HPyAsHandleNode asHandleNode,
Expand Down Expand Up @@ -2764,14 +2764,14 @@ Object execute(Object[] arguments,
}

private static Object[] castArgs(Object args,
ExecutePositionalStarargsInteropNode expandArgsNode,
ExecutePositionalStarargsNode expandArgsNode,
PRaiseNode raiseNode) {
// this indicates that a NULL handle was passed (which is valid)
if (args == PNone.NO_VALUE) {
return PythonUtils.EMPTY_OBJECT_ARRAY;
}
if (PGuards.isPTuple(args)) {
return expandArgsNode.executeWithGlobalState(args);
return expandArgsNode.executeWith(null, args);
}
throw raiseNode.raise(TypeError, ErrorMessages.HPY_CALLTUPLEDICT_REQUIRES_ARGS_TUPLE_OR_NULL);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,12 @@
import com.oracle.graal.python.runtime.PosixSupportLibrary;
import com.oracle.graal.python.runtime.PosixSupportLibrary.PosixException;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.dsl.Bind;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.GenerateNodeFactory;
import com.oracle.truffle.api.dsl.NodeFactory;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.dsl.Cached.Shared;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.library.CachedLibrary;
import com.oracle.truffle.api.profiles.ConditionProfile;
Expand Down Expand Up @@ -237,7 +239,7 @@ static Object stat(VirtualFrame frame, PDirEntry self, boolean followSymlinks,
}
}

abstract static class StatHelperNode extends PythonBuiltinBaseNode {
abstract static class StatHelperSimpleNode extends PythonBuiltinBaseNode {

abstract PTuple execute(VirtualFrame frame, PDirEntry self, boolean followSymlinks, boolean catchNoent);

Expand All @@ -253,44 +255,60 @@ static PTuple cachedLStat(PDirEntry self, boolean followSymlinks, boolean catchN
return self.lstatCache;
}

@Specialization(guards = "self.getStatCache(followSymlinks) == null")
PTuple stat(VirtualFrame frame, PDirEntry self, boolean followSymlinks, boolean catchNoent,
@Specialization(guards = {"followSymlinks", "self.statCache == null", "isSymlink"}, limit = "1")
PTuple uncachedStatWithSymlink(VirtualFrame frame, PDirEntry self, boolean followSymlinks, boolean catchNoent,
@SuppressWarnings("unused") @Cached IsSymlinkNode isSymlinkNode,
@SuppressWarnings("unused") @Bind("isSymlinkNode.executeBoolean(frame, self)") boolean isSymlink,
@CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib,
@Cached IsSymlinkNode isSymlinkNode,
@Cached StatHelperNode recursiveNode,
@Cached CachedPosixPathNode cachedPosixPathNode,
@Cached ConditionProfile positiveLongProfile,
@Cached ConditionProfile noSymlinkProfile) {
PTuple res;
@Shared("cachedPosixPathNode") @Cached CachedPosixPathNode cachedPosixPathNode,
@Shared("positiveLongProfile") @Cached ConditionProfile positiveLongProfile) {
// There are two caches - one for `follow_symlinks=True` and the other for
// 'follow_symlinks=False`. They are different only when the dir entry is a symlink.
// If it is not, they need to be the same, so we must make sure that fstatat() gets
// called only once.
if (noSymlinkProfile.profile(followSymlinks && !isSymlinkNode.execute(frame, self))) {
// The entry is not a symlink, so both stat caches need to have the
// same value. Also, the `follow_symlinks=False` cache might already be filled
// in. (In fact, the call to isSymlinkNode in the condition may fill it.)
// So we call ourselves recursively to either use or fill that cache first, and
// the `follow_symlinks=True` cache will be filled below.
res = recursiveNode.execute(frame, self, false, catchNoent);
} else {
int dirFd = self.scandirPath instanceof PosixFd ? ((PosixFd) self.scandirPath).fd : AT_FDCWD.value;
PosixPath posixPath = cachedPosixPathNode.execute(frame, self);
try {
long[] rawStat = posixLib.fstatat(getPosixSupport(), dirFd, posixPath.value, followSymlinks);
res = PosixModuleBuiltins.createStatResult(factory(), positiveLongProfile, rawStat);
} catch (PosixException e) {
if (catchNoent && e.getErrorCode() == OSErrorEnum.ENOENT.getNumber()) {
return null;
}
throw raiseOSErrorFromPosixException(frame, e, posixPath.originalObject);
return uncachedLStatWithSymlink(frame, self, followSymlinks, catchNoent, posixLib, cachedPosixPathNode, positiveLongProfile);
}

@Specialization(guards = {"!followSymlinks", "self.lstatCache == null"})
PTuple uncachedLStatWithSymlink(VirtualFrame frame, PDirEntry self, boolean followSymlinks, boolean catchNoent,
@CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib,
@Shared("cachedPosixPathNode") @Cached CachedPosixPathNode cachedPosixPathNode,
@Shared("positiveLongProfile") @Cached ConditionProfile positiveLongProfile) {
PTuple res;
int dirFd = self.scandirPath instanceof PosixFd ? ((PosixFd) self.scandirPath).fd : AT_FDCWD.value;
PosixPath posixPath = cachedPosixPathNode.execute(frame, self);
try {
long[] rawStat = posixLib.fstatat(getPosixSupport(), dirFd, posixPath.value, followSymlinks);
res = PosixModuleBuiltins.createStatResult(factory(), positiveLongProfile, rawStat);
} catch (PosixException e) {
if (catchNoent && e.getErrorCode() == OSErrorEnum.ENOENT.getNumber()) {
return null;
}
throw raiseOSErrorFromPosixException(frame, e, posixPath.originalObject);
}
self.setStatCache(followSymlinks, res);
return res;
}
}

abstract static class StatHelperNode extends StatHelperSimpleNode {
@Specialization(guards = {"followSymlinks", "self.statCache == null", "!isSymlink"})
static PTuple uncachedStatWithSymlink(VirtualFrame frame, PDirEntry self, boolean followSymlinks, boolean catchNoent,
@SuppressWarnings("unused") @Cached IsSymlinkNode isSymlinkNode,
@SuppressWarnings("unused") @Bind("isSymlinkNode.executeBoolean(frame, self)") boolean isSymlink,
@Cached StatHelperSimpleNode recursiveNode) {
// There are two caches - one for `follow_symlinks=True` and the other for
// 'follow_symlinks=False`. They are different only when the dir entry is a symlink.
// If it is not, they need to be the same, so we must make sure that fstatat() gets
// called only once. The entry is not a symlink, so both stat caches need to have the
// same value. Also, the `follow_symlinks=False` cache might already be filled
// in. (In fact, the call to isSymlinkNode in the condition may fill it.)
// So we call ourselves recursively to either use or fill that cache first, and
// the `follow_symlinks=True` cache will be filled below.
PTuple res = recursiveNode.execute(frame, self, false, catchNoent);
self.setStatCache(followSymlinks, res);
return res;
}
}

abstract static class TestModeNode extends PythonBuiltinBaseNode {

private final long expectedMode;
Expand Down Expand Up @@ -355,7 +373,7 @@ static TestModeNode createDir() {
@GenerateNodeFactory
abstract static class IsSymlinkNode extends PythonUnaryBuiltinNode {

abstract boolean execute(VirtualFrame frame, PDirEntry self);
abstract boolean executeBoolean(VirtualFrame frame, PDirEntry self);

@Specialization
static boolean isSymlink(VirtualFrame frame, PDirEntry self,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,7 @@ public static Object[] toCharacterArray(TruffleString arg, TruffleString.CodePoi
return values;
}

@TruffleBoundary
public static boolean isPrintable(int codepoint) {
if (ImageInfo.inImageBuildtimeCode()) {
// Executing ICU4J at image build time causes issues with runtime/build time
Expand Down
Loading

0 comments on commit 77b957f

Please sign in to comment.