aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Python
diff options
context:
space:
mode:
Diffstat (limited to 'Python')
-rw-r--r--Python/bytecodes.c21
-rw-r--r--Python/crossinterp.c1
-rw-r--r--Python/executor_cases.c.h40
-rw-r--r--Python/optimizer_analysis.c2
-rw-r--r--Python/optimizer_bytecodes.c36
-rw-r--r--Python/optimizer_cases.c.h55
-rw-r--r--Python/optimizer_symbols.c3
-rw-r--r--Python/qsbr.c2
8 files changed, 146 insertions, 14 deletions
diff --git a/Python/bytecodes.c b/Python/bytecodes.c
index 307844d38cc..535e552e047 100644
--- a/Python/bytecodes.c
+++ b/Python/bytecodes.c
@@ -344,6 +344,27 @@ dummy_func(
PyStackRef_XCLOSE(value);
}
+ op(_POP_TOP_NOP, (value --)) {
+ assert(PyStackRef_IsNull(value) || (!PyStackRef_RefcountOnObject(value)) ||
+ _Py_IsImmortal((PyStackRef_AsPyObjectBorrow(value))));
+ DEAD(value);
+ }
+
+ op(_POP_TOP_INT, (value --)) {
+ assert(PyLong_CheckExact(PyStackRef_AsPyObjectBorrow(value)));
+ PyStackRef_CLOSE_SPECIALIZED(value, _PyLong_ExactDealloc);
+ }
+
+ op(_POP_TOP_FLOAT, (value --)) {
+ assert(PyFloat_CheckExact(PyStackRef_AsPyObjectBorrow(value)));
+ PyStackRef_CLOSE_SPECIALIZED(value, _PyFloat_ExactDealloc);
+ }
+
+ op(_POP_TOP_UNICODE, (value --)) {
+ assert(PyUnicode_CheckExact(PyStackRef_AsPyObjectBorrow(value)));
+ PyStackRef_CLOSE_SPECIALIZED(value, _PyUnicode_ExactDealloc);
+ }
+
tier2 op(_POP_TWO, (nos, tos --)) {
PyStackRef_CLOSE(tos);
PyStackRef_CLOSE(nos);
diff --git a/Python/crossinterp.c b/Python/crossinterp.c
index c44bcd55900..16a23f0351c 100644
--- a/Python/crossinterp.c
+++ b/Python/crossinterp.c
@@ -2617,6 +2617,7 @@ _PyXI_Enter(_PyXI_session *session,
// Convert the attrs for cross-interpreter use.
_PyXI_namespace *sharedns = NULL;
if (nsupdates != NULL) {
+ assert(PyDict_Check(nsupdates));
Py_ssize_t len = PyDict_Size(nsupdates);
if (len < 0) {
if (result != NULL) {
diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h
index 8f506172550..46fc164a5b3 100644
--- a/Python/executor_cases.c.h
+++ b/Python/executor_cases.c.h
@@ -539,6 +539,46 @@
break;
}
+ case _POP_TOP_NOP: {
+ _PyStackRef value;
+ value = stack_pointer[-1];
+ assert(PyStackRef_IsNull(value) || (!PyStackRef_RefcountOnObject(value)) ||
+ _Py_IsImmortal((PyStackRef_AsPyObjectBorrow(value))));
+ stack_pointer += -1;
+ assert(WITHIN_STACK_BOUNDS());
+ break;
+ }
+
+ case _POP_TOP_INT: {
+ _PyStackRef value;
+ value = stack_pointer[-1];
+ assert(PyLong_CheckExact(PyStackRef_AsPyObjectBorrow(value)));
+ PyStackRef_CLOSE_SPECIALIZED(value, _PyLong_ExactDealloc);
+ stack_pointer += -1;
+ assert(WITHIN_STACK_BOUNDS());
+ break;
+ }
+
+ case _POP_TOP_FLOAT: {
+ _PyStackRef value;
+ value = stack_pointer[-1];
+ assert(PyFloat_CheckExact(PyStackRef_AsPyObjectBorrow(value)));
+ PyStackRef_CLOSE_SPECIALIZED(value, _PyFloat_ExactDealloc);
+ stack_pointer += -1;
+ assert(WITHIN_STACK_BOUNDS());
+ break;
+ }
+
+ case _POP_TOP_UNICODE: {
+ _PyStackRef value;
+ value = stack_pointer[-1];
+ assert(PyUnicode_CheckExact(PyStackRef_AsPyObjectBorrow(value)));
+ PyStackRef_CLOSE_SPECIALIZED(value, _PyUnicode_ExactDealloc);
+ stack_pointer += -1;
+ assert(WITHIN_STACK_BOUNDS());
+ break;
+ }
+
case _POP_TWO: {
_PyStackRef tos;
_PyStackRef nos;
diff --git a/Python/optimizer_analysis.c b/Python/optimizer_analysis.c
index 8b1a63e3d29..145a8c118d3 100644
--- a/Python/optimizer_analysis.c
+++ b/Python/optimizer_analysis.c
@@ -345,7 +345,7 @@ remove_globals(_PyInterpreterFrame *frame, _PyUOpInstruction *buffer,
#define sym_new_tuple _Py_uop_sym_new_tuple
#define sym_tuple_getitem _Py_uop_sym_tuple_getitem
#define sym_tuple_length _Py_uop_sym_tuple_length
-#define sym_is_immortal _Py_uop_sym_is_immortal
+#define sym_is_immortal _Py_uop_symbol_is_immortal
#define sym_is_compact_int _Py_uop_sym_is_compact_int
#define sym_new_compact_int _Py_uop_sym_new_compact_int
#define sym_new_truthiness _Py_uop_sym_new_truthiness
diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c
index 3f2e2e0351e..f8a0484bdc2 100644
--- a/Python/optimizer_bytecodes.c
+++ b/Python/optimizer_bytecodes.c
@@ -34,7 +34,7 @@ typedef struct _Py_UOpsAbstractFrame _Py_UOpsAbstractFrame;
#define sym_new_tuple _Py_uop_sym_new_tuple
#define sym_tuple_getitem _Py_uop_sym_tuple_getitem
#define sym_tuple_length _Py_uop_sym_tuple_length
-#define sym_is_immortal _Py_uop_sym_is_immortal
+#define sym_is_immortal _Py_uop_symbol_is_immortal
#define sym_new_compact_int _Py_uop_sym_new_compact_int
#define sym_is_compact_int _Py_uop_sym_is_compact_int
#define sym_new_truthiness _Py_uop_sym_new_truthiness
@@ -452,7 +452,13 @@ dummy_func(void) {
res = sym_new_compact_int(ctx);
}
else {
- res = sym_new_not_null(ctx);
+ PyTypeObject *type = sym_get_type(value);
+ if (type == &PyLong_Type || type == &PyFloat_Type) {
+ res = sym_new_type(ctx, type);
+ }
+ else {
+ res = sym_new_not_null(ctx);
+ }
}
}
@@ -534,7 +540,7 @@ dummy_func(void) {
}
op(_LOAD_CONST_INLINE, (ptr/4 -- value)) {
- value = PyJitRef_Borrow(sym_new_const(ctx, ptr));
+ value = sym_new_const(ctx, ptr);
}
op(_LOAD_CONST_INLINE_BORROW, (ptr/4 -- value)) {
@@ -542,7 +548,7 @@ dummy_func(void) {
}
op(_POP_TOP_LOAD_CONST_INLINE, (ptr/4, pop -- value)) {
- value = PyJitRef_Borrow(sym_new_const(ctx, ptr));
+ value = sym_new_const(ctx, ptr);
}
op(_POP_TOP_LOAD_CONST_INLINE_BORROW, (ptr/4, pop -- value)) {
@@ -561,6 +567,24 @@ dummy_func(void) {
value = PyJitRef_Borrow(sym_new_const(ctx, ptr));
}
+ op(_POP_TOP, (value -- )) {
+ PyTypeObject *typ = sym_get_type(value);
+ if (PyJitRef_IsBorrowed(value) ||
+ sym_is_immortal(PyJitRef_Unwrap(value)) ||
+ sym_is_null(value)) {
+ REPLACE_OP(this_instr, _POP_TOP_NOP, 0, 0);
+ }
+ else if (typ == &PyLong_Type) {
+ REPLACE_OP(this_instr, _POP_TOP_INT, 0, 0);
+ }
+ else if (typ == &PyFloat_Type) {
+ REPLACE_OP(this_instr, _POP_TOP_FLOAT, 0, 0);
+ }
+ else if (typ == &PyUnicode_Type) {
+ REPLACE_OP(this_instr, _POP_TOP_UNICODE, 0, 0);
+ }
+ }
+
op(_COPY, (bottom, unused[oparg-1] -- bottom, unused[oparg-1], top)) {
assert(oparg > 0);
top = bottom;
@@ -803,7 +827,9 @@ dummy_func(void) {
}
op(_RETURN_VALUE, (retval -- res)) {
- JitOptRef temp = retval;
+ // We wrap and unwrap the value to mimic PyStackRef_MakeHeapSafe
+ // in bytecodes.c
+ JitOptRef temp = PyJitRef_Wrap(PyJitRef_Unwrap(retval));
DEAD(retval);
SAVE_STACK();
ctx->frame->stack_pointer = stack_pointer;
diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h
index 91927180b35..10767ccdbd5 100644
--- a/Python/optimizer_cases.c.h
+++ b/Python/optimizer_cases.c.h
@@ -100,6 +100,47 @@
}
case _POP_TOP: {
+ JitOptRef value;
+ value = stack_pointer[-1];
+ PyTypeObject *typ = sym_get_type(value);
+ if (PyJitRef_IsBorrowed(value) ||
+ sym_is_immortal(PyJitRef_Unwrap(value)) ||
+ sym_is_null(value)) {
+ REPLACE_OP(this_instr, _POP_TOP_NOP, 0, 0);
+ }
+ else if (typ == &PyLong_Type) {
+ REPLACE_OP(this_instr, _POP_TOP_INT, 0, 0);
+ }
+ else if (typ == &PyFloat_Type) {
+ REPLACE_OP(this_instr, _POP_TOP_FLOAT, 0, 0);
+ }
+ else if (typ == &PyUnicode_Type) {
+ REPLACE_OP(this_instr, _POP_TOP_UNICODE, 0, 0);
+ }
+ stack_pointer += -1;
+ assert(WITHIN_STACK_BOUNDS());
+ break;
+ }
+
+ case _POP_TOP_NOP: {
+ stack_pointer += -1;
+ assert(WITHIN_STACK_BOUNDS());
+ break;
+ }
+
+ case _POP_TOP_INT: {
+ stack_pointer += -1;
+ assert(WITHIN_STACK_BOUNDS());
+ break;
+ }
+
+ case _POP_TOP_FLOAT: {
+ stack_pointer += -1;
+ assert(WITHIN_STACK_BOUNDS());
+ break;
+ }
+
+ case _POP_TOP_UNICODE: {
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
break;
@@ -149,7 +190,13 @@
res = sym_new_compact_int(ctx);
}
else {
- res = sym_new_not_null(ctx);
+ PyTypeObject *type = sym_get_type(value);
+ if (type == &PyLong_Type || type == &PyFloat_Type) {
+ res = sym_new_type(ctx, type);
+ }
+ else {
+ res = sym_new_not_null(ctx);
+ }
}
stack_pointer[-1] = res;
break;
@@ -784,7 +831,7 @@
JitOptRef retval;
JitOptRef res;
retval = stack_pointer[-1];
- JitOptRef temp = retval;
+ JitOptRef temp = PyJitRef_Wrap(PyJitRef_Unwrap(retval));
stack_pointer += -1;
assert(WITHIN_STACK_BOUNDS());
ctx->frame->stack_pointer = stack_pointer;
@@ -2660,7 +2707,7 @@
case _LOAD_CONST_INLINE: {
JitOptRef value;
PyObject *ptr = (PyObject *)this_instr->operand0;
- value = PyJitRef_Borrow(sym_new_const(ctx, ptr));
+ value = sym_new_const(ctx, ptr);
stack_pointer[0] = value;
stack_pointer += 1;
assert(WITHIN_STACK_BOUNDS());
@@ -2670,7 +2717,7 @@
case _POP_TOP_LOAD_CONST_INLINE: {
JitOptRef value;
PyObject *ptr = (PyObject *)this_instr->operand0;
- value = PyJitRef_Borrow(sym_new_const(ctx, ptr));
+ value = sym_new_const(ctx, ptr);
stack_pointer[-1] = value;
break;
}
diff --git a/Python/optimizer_symbols.c b/Python/optimizer_symbols.c
index 64cc1b9074f..c3d9e0e778b 100644
--- a/Python/optimizer_symbols.c
+++ b/Python/optimizer_symbols.c
@@ -668,9 +668,6 @@ _Py_uop_symbol_is_immortal(JitOptSymbol *sym)
if (sym->tag == JIT_SYM_KNOWN_CLASS_TAG) {
return sym->cls.type == &PyBool_Type;
}
- if (sym->tag == JIT_SYM_TRUTHINESS_TAG) {
- return true;
- }
return false;
}
diff --git a/Python/qsbr.c b/Python/qsbr.c
index bf34fb2523d..afa03776c26 100644
--- a/Python/qsbr.c
+++ b/Python/qsbr.c
@@ -1,6 +1,6 @@
/*
* Implementation of safe memory reclamation scheme using
- * quiescent states.
+ * quiescent states. See InternalDocs/qsbr.md.
*
* This is derived from the "GUS" safe memory reclamation technique
* in FreeBSD written by Jeffrey Roberson. It is heavily modified. Any bugs