Skip to content

Commit d286eab

Browse files
committed
Raise MemoryError if resizing of handle table fails
1 parent 80410a9 commit d286eab

File tree

1 file changed

+23
-3
lines changed
  • graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/transitions

1 file changed

+23
-3
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/transitions/CApiTransitions.java

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
import java.util.concurrent.ConcurrentHashMap;
5353
import java.util.logging.Level;
5454

55+
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
5556
import com.oracle.graal.python.builtins.objects.PNone;
5657
import com.oracle.graal.python.builtins.objects.PythonAbstractObject;
5758
import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject;
@@ -85,12 +86,14 @@
8586
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
8687
import com.oracle.graal.python.nodes.PGuards;
8788
import com.oracle.graal.python.nodes.PNodeWithContext;
89+
import com.oracle.graal.python.nodes.PRaiseNode;
8890
import com.oracle.graal.python.nodes.object.GetClassNode;
8991
import com.oracle.graal.python.runtime.GilNode;
9092
import com.oracle.graal.python.runtime.PythonContext;
9193
import com.oracle.graal.python.runtime.sequence.storage.NativeSequenceStorage;
9294
import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage;
9395
import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage.ListStorageType;
96+
import com.oracle.graal.python.util.OverflowException;
9497
import com.oracle.graal.python.util.PythonUtils;
9598
import com.oracle.truffle.api.CompilerAsserts;
9699
import com.oracle.truffle.api.CompilerDirectives;
@@ -526,7 +529,16 @@ public static PythonObjectReference nativeStubLookupGet(HandleContext context, l
526529
return result;
527530
}
528531

529-
private static int nativeStubLookupReserve(HandleContext context) {
532+
/**
533+
* Reserves a free slot in the handle table that can later be used to store a
534+
* {@link PythonObjectReference} using
535+
* {@link #nativeStubLookupPut(HandleContext, PythonObjectReference)}. If the handle table is
536+
* currently too small, it will be enlarged.
537+
*
538+
* @throws OverflowException Indicates that we cannot resize the handle table anymore. This
539+
* essentially indicates a Python-level MemoryError.
540+
*/
541+
private static int nativeStubLookupReserve(HandleContext context) throws OverflowException {
530542
int idx = context.nativeStubLookupFreeStack.pop();
531543
if (idx == -1) {
532544
idx = resizeNativeStubLookupTable(context);
@@ -536,10 +548,10 @@ private static int nativeStubLookupReserve(HandleContext context) {
536548
}
537549

538550
@TruffleBoundary
539-
private static int resizeNativeStubLookupTable(HandleContext context) {
551+
private static int resizeNativeStubLookupTable(HandleContext context) throws OverflowException {
540552
int oldSize = context.nativeStubLookup.length;
541553
// exponentially grow until 1 MB; then linearly grow by 1 MB
542-
int newSize = oldSize >= HandleContext.LINEAR_THRESHOLD ? oldSize + HandleContext.LINEAR_THRESHOLD : oldSize * 2;
554+
int newSize = oldSize >= HandleContext.LINEAR_THRESHOLD ? PythonUtils.addExact(oldSize, HandleContext.LINEAR_THRESHOLD) : PythonUtils.multiplyExact(oldSize, 2);
543555
assert newSize != oldSize;
544556
if (LOGGER.isLoggable(Level.FINE)) {
545557
LOGGER.fine(String.format("Resizing native stub lookup table: %d -> %d", oldSize, newSize));
@@ -663,6 +675,14 @@ static long doGeneric(Node inliningTarget, PythonAbstractObjectNativeWrapper wra
663675
nativeStubLookupPut(handleContext, ref);
664676

665677
return logResult(taggedPointer);
678+
} catch (OverflowException e) {
679+
/*
680+
* The OverflowException may be thrown by 'nativeStubLookupReserve' and indicates
681+
* that we cannot resize the handle table anymore. This essentially indicates a
682+
* Python-level MemoryError.
683+
*/
684+
CompilerDirectives.transferToInterpreterAndInvalidate();
685+
throw PRaiseNode.raiseUncached(inliningTarget, PythonBuiltinClassType.MemoryError);
666686
} finally {
667687
gil.release(acquired);
668688
}

0 commit comments

Comments
 (0)