Skip to content

Commit a0fd9e2

Browse files
committed
Change JIT reference tags to 2 bit scheme
1 parent acfa737 commit a0fd9e2

File tree

3 files changed

+34
-27
lines changed

3 files changed

+34
-27
lines changed

Include/internal/pycore_optimizer.h

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -210,9 +210,12 @@ static inline uint16_t uop_get_error_target(const _PyUOpInstruction *inst)
210210

211211

212212
#define REF_IS_BORROWED 1
213-
#define REF_IS_INVALID 2
214-
#define REF_IS_UNIQUE 4
215-
#define REF_TAG_BITS 7
213+
#define REF_IS_UNIQUE 2
214+
#define REF_IS_INVALID 3
215+
#define REF_TAG_BITS 3
216+
217+
#define REF_GET_TAG(x) ((uintptr_t)(x) & (REF_TAG_BITS))
218+
#define REF_CLEAR_TAG(x) ((uintptr_t)(x) & (~REF_TAG_BITS))
216219

217220
#define JIT_BITS_TO_PTR_MASKED(REF) ((JitOptSymbol *)(((REF).bits) & (~REF_TAG_BITS)))
218221

@@ -234,38 +237,32 @@ PyJitRef_Wrap(JitOptSymbol *sym)
234237
static inline JitOptRef
235238
PyJitRef_WrapInvalid(void *ptr)
236239
{
237-
return (JitOptRef){.bits=(uintptr_t)ptr | REF_IS_INVALID};
240+
return (JitOptRef){.bits = REF_CLEAR_TAG((uintptr_t)ptr) | REF_IS_INVALID};
238241
}
239242

240243
static inline bool
241244
PyJitRef_IsInvalid(JitOptRef ref)
242245
{
243-
return (ref.bits & REF_IS_INVALID) == REF_IS_INVALID;
246+
return REF_GET_TAG(ref.bits) == REF_IS_INVALID;
244247
}
245248

246249
static inline JitOptRef
247250
PyJitRef_MakeUnique(JitOptRef ref)
248251
{
249-
assert((ref.bits & REF_IS_UNIQUE) == 0);
250-
return (JitOptRef){ ref.bits | REF_IS_UNIQUE };
251-
}
252-
253-
static inline JitOptRef
254-
PyJitRef_RemoveUnique(JitOptRef ref)
255-
{
256-
return (JitOptRef){ ref.bits & (~REF_IS_UNIQUE) };
252+
return (JitOptRef){ REF_CLEAR_TAG(ref.bits) | REF_IS_UNIQUE };
257253
}
258254

259255
static inline bool
260256
PyJitRef_IsUnique(JitOptRef ref)
261257
{
262-
return (ref.bits & REF_IS_UNIQUE) == REF_IS_UNIQUE;
258+
return REF_GET_TAG(ref.bits) == REF_IS_UNIQUE;
263259
}
264260

265261
static inline JitOptRef
266262
PyJitRef_StripBorrowInfo(JitOptRef ref)
267263
{
268-
return (JitOptRef){ .bits = ref.bits & ~(REF_IS_BORROWED | REF_IS_INVALID) };
264+
if (PyJitRef_IsUnique(ref)) return ref;
265+
return (JitOptRef){ .bits = REF_CLEAR_TAG(ref.bits) };
269266
}
270267

271268
static inline JitOptRef
@@ -277,7 +274,7 @@ PyJitRef_StripReferenceInfo(JitOptRef ref)
277274
static inline JitOptRef
278275
PyJitRef_Borrow(JitOptRef ref)
279276
{
280-
return (JitOptRef){ .bits = ref.bits | REF_IS_BORROWED };
277+
return (JitOptRef){ .bits = REF_CLEAR_TAG(ref.bits) | REF_IS_BORROWED };
281278
}
282279

283280
static const JitOptRef PyJitRef_NULL = {.bits = REF_IS_BORROWED};
@@ -291,7 +288,7 @@ PyJitRef_IsNull(JitOptRef ref)
291288
static inline int
292289
PyJitRef_IsBorrowed(JitOptRef ref)
293290
{
294-
return (ref.bits & REF_IS_BORROWED) == REF_IS_BORROWED;
291+
return REF_GET_TAG(ref.bits) == REF_IS_BORROWED;
295292
}
296293

297294
extern bool _Py_uop_sym_is_null(JitOptRef sym);

Python/optimizer_bytecodes.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -89,24 +89,29 @@ dummy_func(void) {
8989
if (sym_is_null(value)) {
9090
ctx->done = true;
9191
}
92-
value = PyJitRef_RemoveUnique(value);
92+
if (PyJitRef_IsUnique(value)) {
93+
value = PyJitRef_StripReferenceInfo(value);
94+
}
9395
}
9496

9597
op(_LOAD_FAST, (-- value)) {
9698
value = GETLOCAL(oparg);
97-
value = PyJitRef_RemoveUnique(value);
99+
if (PyJitRef_IsUnique(value)) {
100+
value = PyJitRef_StripReferenceInfo(value);
101+
}
98102
}
99103

100104
op(_LOAD_FAST_BORROW, (-- value)) {
101105
value = PyJitRef_Borrow(GETLOCAL(oparg));
102-
value = PyJitRef_RemoveUnique(value);
103106
}
104107

105108
op(_LOAD_FAST_AND_CLEAR, (-- value)) {
106109
value = GETLOCAL(oparg);
107110
JitOptRef temp = sym_new_null(ctx);
108111
GETLOCAL(oparg) = temp;
109-
value = PyJitRef_RemoveUnique(value);
112+
if (PyJitRef_IsUnique(value)) {
113+
value = PyJitRef_StripReferenceInfo(value);
114+
}
110115
}
111116

112117
op(_STORE_ATTR_INSTANCE_VALUE, (offset/1, value, owner -- o)) {
@@ -700,7 +705,7 @@ dummy_func(void) {
700705

701706
op(_COPY, (bottom, unused[oparg-1] -- bottom, unused[oparg-1], top)) {
702707
assert(oparg > 0);
703-
bottom = PyJitRef_RemoveUnique(bottom);
708+
bottom = PyJitRef_IsUnique(bottom) ? PyJitRef_StripReferenceInfo(bottom) : bottom;
704709
top = bottom;
705710
}
706711

Python/optimizer_cases.c.h

Lines changed: 10 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)