Skip to content

Commit 19dd21e

Browse files
committed
Make handle cache more lightweight.
1 parent 549661d commit 19dd21e

File tree

3 files changed

+115
-80
lines changed

3 files changed

+115
-80
lines changed

graalpython/com.oracle.graal.python.cext/src/capi.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,10 @@ uint64_t (*PY_TRUFFLE_CEXT_LANDING_L)(void* name, ...);
5353
double (*PY_TRUFFLE_CEXT_LANDING_D)(void* name, ...);
5454
void* (*PY_TRUFFLE_CEXT_LANDING_PTR)(void* name, ...);
5555

56-
static void* cache;
57-
void* (*resolve_handle)(void* cache, uint64_t handle);
56+
typedef void* (*cache_t)(uint64_t);
57+
static cache_t cache;
58+
59+
#define resolve_handle(__cache__, __addr__) (__cache__)(__addr__)
5860

5961
__attribute__((constructor (__COUNTER__)))
6062
static void initialize_upcall_functions() {
@@ -76,7 +78,6 @@ static void initialize_upcall_functions() {
7678
__attribute__((constructor (__COUNTER__)))
7779
static void initialize_handle_cache() {
7880
cache = polyglot_invoke(PY_TRUFFLE_CEXT, "PyTruffle_HandleCache_Create", truffle_managed_from_handle);
79-
resolve_handle = ((void* (*)(void* cache, uint64_t handle))polyglot_get_member(PY_TRUFFLE_CEXT, polyglot_from_string("PyTruffle_HandleCache_GetOrInsert", SRC_CS)));
8081
}
8182

8283
static void initialize_type_structure(PyTypeObject* structure, const char* typname, void* typeid) {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/TruffleCextBuiltins.java

Lines changed: 1 addition & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
import com.oracle.graal.python.builtins.objects.cext.CArrayWrappers.CByteArrayWrapper;
6969
import com.oracle.graal.python.builtins.objects.cext.CArrayWrappers.CStringWrapper;
7070
import com.oracle.graal.python.builtins.objects.cext.CExtNodes;
71+
import com.oracle.graal.python.builtins.objects.cext.HandleCache;
7172
import com.oracle.graal.python.builtins.objects.cext.NativeWrappers.PySequenceArrayWrapper;
7273
import com.oracle.graal.python.builtins.objects.cext.NativeWrappers.PythonClassInitNativeWrapper;
7374
import com.oracle.graal.python.builtins.objects.cext.NativeWrappers.PythonClassNativeWrapper;
@@ -116,7 +117,6 @@
116117
import com.oracle.graal.python.nodes.expression.BinaryComparisonNode;
117118
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
118119
import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
119-
import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
120120
import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
121121
import com.oracle.graal.python.nodes.interop.PForeignToPTypeNode;
122122
import com.oracle.graal.python.nodes.object.GetClassNode;
@@ -150,7 +150,6 @@
150150
import com.oracle.truffle.api.interop.UnsupportedMessageException;
151151
import com.oracle.truffle.api.interop.UnsupportedTypeException;
152152
import com.oracle.truffle.api.nodes.DirectCallNode;
153-
import com.oracle.truffle.api.nodes.ExplodeLoop;
154153
import com.oracle.truffle.api.nodes.Node;
155154
import com.oracle.truffle.api.nodes.RootNode;
156155
import com.oracle.truffle.api.profiles.BranchProfile;
@@ -1844,40 +1843,6 @@ Object doIt(Object object,
18441843
}
18451844
}
18461845

1847-
private static class HandleCacheEntry {
1848-
private long key;
1849-
private Object value;
1850-
}
1851-
1852-
static class HandleCache implements TruffleObject {
1853-
private static final int CACHE_SIZE = 10;
1854-
1855-
private final HandleCacheEntry[] entries;
1856-
private final TruffleObject ptrToResolveHandle;
1857-
1858-
private int pos = 0;
1859-
1860-
public HandleCache(TruffleObject ptrToResolveHandle) {
1861-
entries = new HandleCacheEntry[CACHE_SIZE];
1862-
for (int i = 0; i < entries.length; i++) {
1863-
entries[i] = new HandleCacheEntry();
1864-
}
1865-
this.ptrToResolveHandle = ptrToResolveHandle;
1866-
}
1867-
1868-
protected int len() {
1869-
return entries.length;
1870-
}
1871-
1872-
protected TruffleObject getPtrToResolveHandle() {
1873-
return ptrToResolveHandle;
1874-
}
1875-
1876-
public ForeignAccess getForeignAccess() {
1877-
return null;
1878-
}
1879-
}
1880-
18811846
@Builtin(name = "PyTruffle_HandleCache_Create", fixedNumOfPositionalArgs = 1)
18821847
@GenerateNodeFactory
18831848
abstract static class PyTruffleHandleCacheCreate extends PythonUnaryBuiltinNode {
@@ -1886,45 +1851,4 @@ Object createCache(TruffleObject ptrToResolveHandle) {
18861851
return new HandleCache(ptrToResolveHandle);
18871852
}
18881853
}
1889-
1890-
@Builtin(name = "PyTruffle_HandleCache_GetOrInsert", fixedNumOfPositionalArgs = 2)
1891-
@GenerateNodeFactory
1892-
abstract static class PyTruffleHandleCacheGetOrInsert extends PythonBinaryBuiltinNode {
1893-
@Child private Node executeNode;
1894-
1895-
private final BranchProfile errorProfile = BranchProfile.create();
1896-
1897-
@ExplodeLoop
1898-
@Specialization(limit = "1", guards = {"cache.len() == cachedLen", "cache.getPtrToResolveHandle() == ptrToResolveHandle"})
1899-
Object doIt(HandleCache cache, long handle,
1900-
@Cached("cache.len()") int cachedLen,
1901-
@Cached("cache.getPtrToResolveHandle()") TruffleObject ptrToResolveHandle) {
1902-
for (int i = 0; i < cachedLen; i++) {
1903-
if (cache.entries[i].key == handle) {
1904-
return cache.entries[i].value;
1905-
}
1906-
}
1907-
1908-
try {
1909-
Object resolved = ForeignAccess.sendExecute(getExecuteNode(), ptrToResolveHandle, handle);
1910-
1911-
cache.entries[cache.pos].key = handle;
1912-
cache.entries[cache.pos].value = resolved;
1913-
cache.pos = (cache.pos + 1) % cache.len();
1914-
1915-
return resolved;
1916-
} catch (UnsupportedTypeException | ArityException | UnsupportedMessageException e) {
1917-
errorProfile.enter();
1918-
throw e.raise();
1919-
}
1920-
}
1921-
1922-
private Node getExecuteNode() {
1923-
if (executeNode == null) {
1924-
CompilerDirectives.transferToInterpreterAndInvalidate();
1925-
executeNode = insert(Message.EXECUTE.createNode());
1926-
}
1927-
return executeNode;
1928-
}
1929-
}
19301854
}
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
package com.oracle.graal.python.builtins.objects.cext;
2+
3+
import com.oracle.graal.python.builtins.objects.cext.HandleCacheFactory.HandleCacheMRFactory.GetOrInsertNodeGen;
4+
import com.oracle.truffle.api.CompilerDirectives;
5+
import com.oracle.truffle.api.dsl.Cached;
6+
import com.oracle.truffle.api.dsl.Specialization;
7+
import com.oracle.truffle.api.interop.ArityException;
8+
import com.oracle.truffle.api.interop.ForeignAccess;
9+
import com.oracle.truffle.api.interop.Message;
10+
import com.oracle.truffle.api.interop.MessageResolution;
11+
import com.oracle.truffle.api.interop.Resolve;
12+
import com.oracle.truffle.api.interop.TruffleObject;
13+
import com.oracle.truffle.api.interop.UnsupportedMessageException;
14+
import com.oracle.truffle.api.interop.UnsupportedTypeException;
15+
import com.oracle.truffle.api.nodes.ExplodeLoop;
16+
import com.oracle.truffle.api.nodes.Node;
17+
import com.oracle.truffle.api.profiles.BranchProfile;
18+
19+
public final class HandleCache implements TruffleObject {
20+
private static final int CACHE_SIZE = 10;
21+
22+
final long[] keys;
23+
final Object[] values;
24+
private final TruffleObject ptrToResolveHandle;
25+
26+
int pos = 0;
27+
28+
public HandleCache(TruffleObject ptrToResolveHandle) {
29+
keys = new long[CACHE_SIZE];
30+
values = new Object[CACHE_SIZE];
31+
this.ptrToResolveHandle = ptrToResolveHandle;
32+
}
33+
34+
protected int len() {
35+
return keys.length;
36+
}
37+
38+
protected TruffleObject getPtrToResolveHandle() {
39+
return ptrToResolveHandle;
40+
}
41+
42+
public ForeignAccess getForeignAccess() {
43+
return HandleCacheMRForeign.ACCESS;
44+
}
45+
46+
public static boolean isInstance(TruffleObject obj) {
47+
return obj instanceof HandleCache;
48+
}
49+
50+
@MessageResolution(receiverType = HandleCache.class)
51+
static class HandleCacheMR {
52+
53+
@Resolve(message = "EXECUTE")
54+
abstract static class ExecuteNode extends Node {
55+
@Child private GetOrInsertNode getOrInsertNode = GetOrInsertNodeGen.create();
56+
57+
private final BranchProfile invalidArgCountProfile = BranchProfile.create();
58+
59+
Object access(HandleCache receiver, Object[] args) {
60+
if (args.length != 1) {
61+
invalidArgCountProfile.enter();
62+
throw ArityException.raise(1, args.length);
63+
}
64+
return getOrInsertNode.execute(receiver, (long) args[0]);
65+
}
66+
67+
}
68+
69+
abstract static class GetOrInsertNode extends Node {
70+
@Child private Node executeNode;
71+
72+
private final BranchProfile errorProfile = BranchProfile.create();
73+
74+
public abstract Object execute(HandleCache cache, long handle);
75+
76+
@ExplodeLoop
77+
@Specialization(guards = {"cache.len() == cachedLen", "cache.getPtrToResolveHandle() == ptrToResolveHandle"})
78+
Object doIt(HandleCache cache, long handle,
79+
@Cached("cache.len()") int cachedLen,
80+
@Cached("cache.getPtrToResolveHandle()") TruffleObject ptrToResolveHandle) {
81+
for (int i = 0; i < cachedLen; i++) {
82+
if (cache.keys[i] == handle) {
83+
return cache.values[i];
84+
}
85+
}
86+
87+
try {
88+
Object resolved = ForeignAccess.sendExecute(getExecuteNode(), ptrToResolveHandle, handle);
89+
90+
cache.keys[cache.pos] = handle;
91+
cache.values[cache.pos] = resolved;
92+
cache.pos = (cache.pos + 1) % cache.len();
93+
94+
return resolved;
95+
} catch (UnsupportedTypeException | ArityException | UnsupportedMessageException e) {
96+
errorProfile.enter();
97+
throw e.raise();
98+
}
99+
}
100+
101+
private Node getExecuteNode() {
102+
if (executeNode == null) {
103+
CompilerDirectives.transferToInterpreterAndInvalidate();
104+
executeNode = insert(Message.EXECUTE.createNode());
105+
}
106+
return executeNode;
107+
}
108+
}
109+
}
110+
}

0 commit comments

Comments
 (0)