@@ -290,9 +290,13 @@ static inline uint16_t uop_get_error_target(const _PyUOpInstruction *inst)
290290
291291
292292#define REF_IS_BORROWED 1
293- #define REF_IS_INVALID 2
293+ #define REF_IS_UNIQUE 2
294+ #define REF_IS_INVALID 3
294295#define REF_TAG_BITS 3
295296
297+ #define REF_GET_TAG (x ) ((uintptr_t)(x) & (REF_TAG_BITS))
298+ #define REF_CLEAR_TAG (x ) ((uintptr_t)(x) & (~REF_TAG_BITS))
299+
296300#define JIT_BITS_TO_PTR_MASKED (REF ) ((JitOptSymbol *)(((REF).bits) & (~REF_TAG_BITS)))
297301
298302static inline JitOptSymbol *
@@ -313,13 +317,34 @@ PyJitRef_Wrap(JitOptSymbol *sym)
313317static inline JitOptRef
314318PyJitRef_WrapInvalid (void * ptr )
315319{
316- return (JitOptRef ){.bits = ( uintptr_t )ptr | REF_IS_INVALID };
320+ return (JitOptRef ){.bits = REF_CLEAR_TAG (( uintptr_t )ptr ) | REF_IS_INVALID };
317321}
318322
319323static inline bool
320324PyJitRef_IsInvalid (JitOptRef ref )
321325{
322- return (ref .bits & REF_IS_INVALID ) == REF_IS_INVALID ;
326+ return REF_GET_TAG (ref .bits ) == REF_IS_INVALID ;
327+ }
328+
329+ static inline JitOptRef
330+ PyJitRef_MakeUnique (JitOptRef ref )
331+ {
332+ return (JitOptRef ){ REF_CLEAR_TAG (ref .bits ) | REF_IS_UNIQUE };
333+ }
334+
335+ static inline bool
336+ PyJitRef_IsUnique (JitOptRef ref )
337+ {
338+ return REF_GET_TAG (ref .bits ) == REF_IS_UNIQUE ;
339+ }
340+
341+ static inline JitOptRef
342+ PyJitRef_StripBorrowInfo (JitOptRef ref )
343+ {
344+ if (PyJitRef_IsUnique (ref )) {
345+ return ref ;
346+ }
347+ return (JitOptRef ){ .bits = REF_CLEAR_TAG (ref .bits ) };
323348}
324349
325350static inline JitOptRef
@@ -328,10 +353,19 @@ PyJitRef_StripReferenceInfo(JitOptRef ref)
328353 return PyJitRef_Wrap (PyJitRef_Unwrap (ref ));
329354}
330355
356+ static inline JitOptRef
357+ PyJitRef_RemoveUnique (JitOptRef ref )
358+ {
359+ if (PyJitRef_IsUnique (ref )) {
360+ ref = PyJitRef_StripReferenceInfo (ref );
361+ }
362+ return ref ;
363+ }
364+
331365static inline JitOptRef
332366PyJitRef_Borrow (JitOptRef ref )
333367{
334- return (JitOptRef ){ .bits = ref .bits | REF_IS_BORROWED };
368+ return (JitOptRef ){ .bits = REF_CLEAR_TAG ( ref .bits ) | REF_IS_BORROWED };
335369}
336370
337371static const JitOptRef PyJitRef_NULL = {.bits = REF_IS_BORROWED };
@@ -345,7 +379,7 @@ PyJitRef_IsNull(JitOptRef ref)
345379static inline int
346380PyJitRef_IsBorrowed (JitOptRef ref )
347381{
348- return (ref .bits & REF_IS_BORROWED ) == REF_IS_BORROWED ;
382+ return REF_GET_TAG (ref .bits ) == REF_IS_BORROWED ;
349383}
350384
351385extern bool _Py_uop_sym_is_null (JitOptRef sym );
0 commit comments