Skip to content

Commit 9918000

Browse files
committed
[GR-36885] Refactorings around HPy
PullRequest: graalpython/2260
2 parents 80a1060 + f02242f commit 9918000

File tree

14 files changed

+867
-743
lines changed

14 files changed

+867
-743
lines changed

docs/contributor/DEV_TASKS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,5 @@ Follow these steps to update HPy.
5353
- Adding `GraalHPyContextFunction` implementations for the new APIs
5454
- Updating the `createMembers` method to assign the appropriate
5555
implementations to the context members
56+
- Updating hpy.c to assign new context members to their native locations
5657

graalpython/com.oracle.graal.python.jni/src/ctx_tracker.c

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* MIT License
22
*
3-
* Copyright (c) 2021, Oracle and/or its affiliates.
3+
* Copyright (c) 2021, 2022, Oracle and/or its affiliates.
44
* Copyright (c) 2019 pyhandle
55
*
66
* Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -81,7 +81,7 @@
8181
* return HPy_NULL;
8282
*/
8383

84-
#include "hpy.h"
84+
#include "hpy_jni.h"
8585

8686
static const HPy_ssize_t HPYTRACKER_INITIAL_CAPACITY = 5;
8787

@@ -155,13 +155,20 @@ tracker_resize(HPyContext *ctx, _HPyTracker_s *hp, HPy_ssize_t capacity)
155155
_HPy_HIDDEN int
156156
ctx_Tracker_Add(HPyContext *ctx, HPyTracker ht, HPy h)
157157
{
158-
_HPyTracker_s *hp = _ht2hp(ht);
159-
hp->handles[hp->length++] = h;
160-
if (hp->capacity <= hp->length) {
161-
if (tracker_resize(ctx, hp, hp->capacity * 2 - 1) < 0)
162-
return -1;
158+
uint64_t bits = toBits(h);
159+
if (!isBoxedHandle(bits)) {
160+
return 0;
161+
} else if (bits < IMMUTABLE_HANDLES) {
162+
return 0;
163+
} else {
164+
_HPyTracker_s *hp = _ht2hp(ht);
165+
hp->handles[hp->length++] = h;
166+
if (hp->capacity <= hp->length) {
167+
if (tracker_resize(ctx, hp, hp->capacity * 2 - 1) < 0)
168+
return -1;
169+
}
170+
return 0;
163171
}
164-
return 0;
165172
}
166173

167174
_HPy_HIDDEN void
@@ -176,9 +183,7 @@ ctx_Tracker_Close(HPyContext *ctx, HPyTracker ht)
176183
{
177184
_HPyTracker_s *hp = _ht2hp(ht);
178185
HPy_ssize_t i;
179-
for (i=0; i<hp->length; i++) {
180-
HPy_Close(ctx, hp->handles[i]);
181-
}
186+
upcallBulkClose(ctx, hp->handles, hp->length);
182187
free(hp->handles);
183188
free(hp);
184189
}

graalpython/com.oracle.graal.python.jni/src/hpy_jni.c

Lines changed: 36 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ static JNIEnv* jniEnv;
7171
UPCALL(TypeGenericNew, SIG_HPY, SIG_HPY) \
7272
UPCALL(AsStruct, SIG_HPY, SIG_PTR) \
7373
UPCALL(Close, SIG_HPY, SIG_VOID) \
74+
UPCALL(BulkClose, SIG_PTR SIG_INT, SIG_VOID) \
7475
UPCALL(FloatFromDouble, SIG_DOUBLE, SIG_HPY) \
7576
UPCALL(FloatAsDouble, SIG_HPY, SIG_DOUBLE) \
7677
UPCALL(LongAsLong, SIG_HPY, SIG_LONG) \
@@ -197,25 +198,6 @@ static HPy ctx_ListNew_jni(HPyContext *ctx, HPy_ssize_t len) {
197198
//*************************
198199
// BOXING
199200

200-
#define NAN_BOXING_BASE (0x0007000000000000llu)
201-
#define NAN_BOXING_MASK (0xFFFF000000000000llu)
202-
#define NAN_BOXING_INT (0x0001000000000000llu)
203-
#define NAN_BOXING_INT_MASK (0x00000000FFFFFFFFllu)
204-
#define NAN_BOXING_MAX_HANDLE (0x000000007FFFFFFFllu)
205-
#define IMMUTABLE_HANDLES (0x0000000000000100llu)
206-
207-
static bool isBoxedDouble(uint64_t value) {
208-
return value >= NAN_BOXING_BASE;
209-
}
210-
211-
static bool isBoxedHandle(uint64_t value) {
212-
return value <= NAN_BOXING_MAX_HANDLE;
213-
}
214-
215-
static bool isBoxedInt(uint64_t value) {
216-
return (value & NAN_BOXING_MASK) == NAN_BOXING_INT;
217-
}
218-
219201
static double unboxDouble(uint64_t value) {
220202
uint64_t doubleBits = value - NAN_BOXING_BASE;
221203
return * ((double*) &doubleBits);
@@ -227,32 +209,6 @@ static uint64_t boxDouble(double value) {
227209
return doubleBits + NAN_BOXING_BASE;
228210
}
229211

230-
static uint64_t unboxHandle(uint64_t value) {
231-
return value;
232-
}
233-
234-
static uint64_t boxHandle(uint64_t handle) {
235-
return handle;
236-
}
237-
238-
static int32_t unboxInt(uint64_t value) {
239-
return (int32_t) (value - NAN_BOXING_INT);
240-
}
241-
242-
static uint64_t boxInt(int32_t value) {
243-
return (value & NAN_BOXING_INT_MASK) + NAN_BOXING_INT;
244-
}
245-
246-
static inline uint64_t toBits(HPy ptr) {
247-
/* return * ((uint64_t*) &ptr._i); */
248-
return (uint64_t) (ptr._i);
249-
}
250-
251-
static inline HPy toPtr(uint64_t ptr) {
252-
/* return * ((void**) &ptr); */
253-
return (HPy) { (HPy_ssize_t) ptr };
254-
}
255-
256212
//*************************
257213
// direct fast paths that handle certain calls on the native side:
258214

@@ -269,6 +225,19 @@ static int (*original_TypeCheck)(HPyContext *ctx, HPy h, HPy type);
269225
static void (*original_Close)(HPyContext *ctx, HPy h);
270226
static HPy (*original_UnicodeFromWideChar)(HPyContext *ctx, const wchar_t *arr, HPy_ssize_t size);
271227
static HPy (*original_TupleFromArray)(HPyContext *ctx, HPy *items, HPy_ssize_t nitems);
228+
static int (*original_Is)(HPyContext *ctx, HPy a, HPy b);
229+
230+
static int augment_Is(HPyContext *ctx, HPy a, HPy b) {
231+
long bitsA = toBits(a);
232+
long bitsB = toBits(b);
233+
if (bitsA == bitsB) {
234+
return 1;
235+
} else if (isBoxedHandle(bitsA) && isBoxedHandle(bitsB)) {
236+
return original_Is(ctx, a, b);
237+
} else {
238+
return 0;
239+
}
240+
}
272241

273242
static void *augment_AsStruct(HPyContext *ctx, HPy h) {
274243
uint64_t bits = toBits(h);
@@ -322,12 +291,25 @@ static HPy augment_LongFromLong(HPyContext *ctx, long l) {
322291
}
323292
}
324293

294+
#define MAX_UNCLOSED_HANDLES 32
295+
static int32_t unclosedHandleTop = 0;
296+
static HPy unclosedHandles[MAX_UNCLOSED_HANDLES];
297+
325298
static void augment_Close(HPyContext *ctx, HPy h) {
326299
uint64_t bits = toBits(h);
327300
if (!bits) {
328301
return;
329302
} else if (isBoxedHandle(bits)) {
330-
return original_Close(ctx, h);
303+
if (bits < IMMUTABLE_HANDLES) {
304+
return;
305+
}
306+
if (unclosedHandleTop < MAX_UNCLOSED_HANDLES) {
307+
unclosedHandles[unclosedHandleTop++] = h;
308+
} else {
309+
upcallBulkClose(ctx, unclosedHandles, unclosedHandleTop);
310+
memset(unclosedHandles, 0, sizeof(uint64_t) * unclosedHandleTop);
311+
unclosedHandleTop = 0;
312+
}
331313
}
332314
}
333315

@@ -440,6 +422,9 @@ static HPy augment_TupleFromArray(HPyContext *ctx, HPy *items, HPy_ssize_t nitem
440422
return upcallTupleFromArray(ctx, items, nitems, JNI_FALSE);
441423
}
442424

425+
_HPy_HIDDEN void upcallBulkClose(HPyContext *ctx, HPy *items, HPy_ssize_t nitems) {
426+
DO_UPCALL_VOID(CONTEXT_INSTANCE(ctx), BulkClose, items, nitems);
427+
}
443428

444429
void initDirectFastPaths(HPyContext *context) {
445430
LOG("%p", context);
@@ -466,6 +451,8 @@ void initDirectFastPaths(HPyContext *context) {
466451
original_AsStruct = context->ctx_AsStruct;
467452
context->ctx_AsStruct = augment_AsStruct;
468453

454+
context->ctx_AsStructLegacy = augment_AsStruct;
455+
469456
original_Dup = context->ctx_Dup;
470457
context->ctx_Dup = augment_Dup;
471458

@@ -483,6 +470,9 @@ void initDirectFastPaths(HPyContext *context) {
483470

484471
original_TupleFromArray = context->ctx_Tuple_FromArray;
485472
context->ctx_Tuple_FromArray = augment_TupleFromArray;
473+
474+
original_Is = context->ctx_Is;
475+
context->ctx_Is = augment_Is;
486476
}
487477

488478
void setHPyContextNativeSpace(HPyContext *context, void** nativeSpace) {

graalpython/com.oracle.graal.python.jni/src/hpy_jni.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,29 @@
4848
#include <hpy.h>
4949
#include <jni.h>
5050

51+
//*************************
52+
// BOXING
53+
54+
#define NAN_BOXING_BASE (0x0007000000000000llu)
55+
#define NAN_BOXING_MASK (0xFFFF000000000000llu)
56+
#define NAN_BOXING_INT (0x0001000000000000llu)
57+
#define NAN_BOXING_INT_MASK (0x00000000FFFFFFFFllu)
58+
#define NAN_BOXING_MAX_HANDLE (0x000000007FFFFFFFllu)
59+
#define IMMUTABLE_HANDLES (0x0000000000000100llu)
60+
61+
#define isBoxedDouble(value) ((value) >= NAN_BOXING_BASE)
62+
#define isBoxedHandle(value) ((value) <= NAN_BOXING_MAX_HANDLE)
63+
#define isBoxedInt(value) (((value) & NAN_BOXING_MASK) == NAN_BOXING_INT)
64+
65+
#define unboxHandle(value) (value)
66+
#define boxHandle(handle) (handle)
67+
68+
#define unboxInt(value) ((int32_t) ((value) - NAN_BOXING_INT))
69+
#define boxInt(value) ((((uint64_t) (value)) & NAN_BOXING_INT_MASK) + NAN_BOXING_INT)
70+
71+
#define toBits(ptr) ((uint64_t) ((ptr)._i))
72+
#define toPtr(ptr) ((HPy) { (HPy_ssize_t) (ptr) })
73+
5174
_HPy_HIDDEN HPy upcallTupleFromArray(HPyContext *ctx, HPy *items, HPy_ssize_t nitems, jboolean steal);
75+
76+
_HPy_HIDDEN void upcallBulkClose(HPyContext *ctx, HPy *items, HPy_ssize_t nitems);

0 commit comments

Comments
 (0)