|
116 | 116 | import com.oracle.graal.python.nodes.expression.BinaryComparisonNode;
|
117 | 117 | import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
|
118 | 118 | import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
|
| 119 | +import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; |
119 | 120 | import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
|
120 | 121 | import com.oracle.graal.python.nodes.interop.PForeignToPTypeNode;
|
121 | 122 | import com.oracle.graal.python.nodes.object.GetClassNode;
|
|
149 | 150 | import com.oracle.truffle.api.interop.UnsupportedMessageException;
|
150 | 151 | import com.oracle.truffle.api.interop.UnsupportedTypeException;
|
151 | 152 | import com.oracle.truffle.api.nodes.DirectCallNode;
|
| 153 | +import com.oracle.truffle.api.nodes.ExplodeLoop; |
152 | 154 | import com.oracle.truffle.api.nodes.Node;
|
153 | 155 | import com.oracle.truffle.api.nodes.RootNode;
|
154 | 156 | import com.oracle.truffle.api.profiles.BranchProfile;
|
@@ -1841,4 +1843,88 @@ Object doIt(Object object,
|
1841 | 1843 | return wrapper;
|
1842 | 1844 | }
|
1843 | 1845 | }
|
| 1846 | + |
| 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 | + |
| 1881 | + @Builtin(name = "PyTruffle_HandleCache_Create", fixedNumOfPositionalArgs = 1) |
| 1882 | + @GenerateNodeFactory |
| 1883 | + abstract static class PyTruffleHandleCacheCreate extends PythonUnaryBuiltinNode { |
| 1884 | + @Specialization |
| 1885 | + Object createCache(TruffleObject ptrToResolveHandle) { |
| 1886 | + return new HandleCache(ptrToResolveHandle); |
| 1887 | + } |
| 1888 | + } |
| 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 | + } |
1844 | 1930 | }
|
0 commit comments