Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
34e6b9f
Fix a few wrong steals in bytecodes.c
Fidget-Spinner Jun 28, 2024
b3b6851
Deferred refcount GC
Fidget-Spinner Jun 28, 2024
a90a074
add a steal
Fidget-Spinner Jun 29, 2024
e82c2dc
Conversion function should have steal variant
Fidget-Spinner Jun 29, 2024
5df23bf
remove a steal
Fidget-Spinner Jun 29, 2024
6b63066
Fix double decref in error path
Fidget-Spinner Jun 30, 2024
634adcc
Revert "Fix double decref in error path"
Fidget-Spinner Jun 30, 2024
5b55760
Merge remote-tracking branch 'upstream/main' into deferred_gc
Fidget-Spinner Jul 3, 2024
8cb139f
Remove immortalize visitor
Fidget-Spinner Jul 3, 2024
c260fc9
fix the JIT builds
Fidget-Spinner Jul 3, 2024
700c2fd
fix buildbot bug
Fidget-Spinner Jul 3, 2024
cde931d
don't deref NULL
Fidget-Spinner Jul 3, 2024
4e59420
Remove steal conversion, add list_fromstackrefsteal
Fidget-Spinner Jul 3, 2024
98f9c0f
Silence warnings
Fidget-Spinner Jul 3, 2024
32aaf2b
Fix error case in CALL
Fidget-Spinner Jul 3, 2024
41c6218
remove all temporary immortalization
Fidget-Spinner Jul 3, 2024
dca2ec3
Revert "remove all temporary immortalization"
Fidget-Spinner Jul 3, 2024
39e8a56
Apply suggestions
Fidget-Spinner Jul 4, 2024
3e14b1c
fix non-free-threaded
Fidget-Spinner Jul 4, 2024
2bfe017
Merge remote-tracking branch 'upstream/main' into deferred_gc
Fidget-Spinner Jul 9, 2024
07f78ce
fix bytecodes.c to use arrays instead of pointers
Fidget-Spinner Jul 9, 2024
34b047e
Merge remote-tracking branch 'upstream/main' into deferred_gc
Fidget-Spinner Jul 18, 2024
f4b4022
Automatically flush to stack new
Fidget-Spinner Jul 18, 2024
4c0afa1
lint
Fidget-Spinner Jul 18, 2024
71aed5c
Simpler implementation
Fidget-Spinner Jul 18, 2024
1d19a97
reduce diff
Fidget-Spinner Jul 18, 2024
2b383b1
reduce diff
Fidget-Spinner Jul 18, 2024
2d2cd7c
reduce diff again (sorry)
Fidget-Spinner Jul 18, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Automatically flush to stack new
  • Loading branch information
Fidget-Spinner committed Jul 18, 2024
commit f4b40223bbaa764da44e9e326bf5d9e4475d997f
2 changes: 1 addition & 1 deletion Include/internal/pycore_frame.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ static inline void _PyFrame_Copy(_PyInterpreterFrame *src, _PyInterpreterFrame *

#ifdef Py_GIL_DISABLED
PyCodeObject *co = (PyCodeObject *)dest->f_executable;
for (int i = src->stacktop; i < co->co_nlocalsplus + co->co_stacksize; i++) {
for (int i = stacktop; i < co->co_nlocalsplus + co->co_stacksize; i++) {
dest->localsplus[i] = PyStackRef_NULL;
}
#endif
Expand Down
42 changes: 42 additions & 0 deletions Python/executor_cases.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 3 additions & 5 deletions Python/gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -537,12 +537,10 @@ visit_decref(PyObject *op, void *parent)
int
_PyGC_VisitFrameStack(_PyInterpreterFrame *frame, visitproc visit, void *arg)
{
/* locals */
_PyStackRef *locals = _PyFrame_GetLocalsArray(frame);
int i = 0;
_PyStackRef *i = frame->localsplus;
/* locals and stack */
for (; i <frame->stacktop; i++) {
Py_VISIT(PyStackRef_AsPyObjectBorrow(locals[i]));
for (; i < frame->stackpointer; i++) {
Py_VISIT(PyStackRef_AsPyObjectBorrow(*i));
}
return 0;
}
Expand Down
14 changes: 6 additions & 8 deletions Python/gc_free_threading.c
Original file line number Diff line number Diff line change
Expand Up @@ -703,8 +703,8 @@ clear_weakrefs(struct collection_state *state)
// freed after its function object.
PyGenObject *gen = (PyGenObject *)op;
struct _PyInterpreterFrame *frame = &(gen->gi_iframe);
for (int i = 0; i < frame->stacktop; i++) {
gc_visit_stackref(frame->localsplus[i]);
for (_PyStackRef *i = frame->localsplus; i < frame->stackpointer; i++) {
gc_visit_stackref(*i);
}
}
if (PyWeakref_Check(op)) {
Expand Down Expand Up @@ -939,16 +939,14 @@ visit_decref_unreachable(PyObject *op, void *data)
int
_PyGC_VisitFrameStack(_PyInterpreterFrame *frame, visitproc visit, void *arg)
{
/* locals */
_PyStackRef *locals = _PyFrame_GetLocalsArray(frame);
int i = 0;
_PyStackRef *i = frame->localsplus;
/* locals and stack */
for (; i <frame->stacktop; i++) {
if (PyStackRef_IsDeferred(locals[i]) &&
for (; i < frame->stackpointer; i++) {
if (PyStackRef_IsDeferred(*i) &&
(visit == visit_decref || visit == visit_decref_unreachable)) {
continue;
}
Py_VISIT(PyStackRef_AsPyObjectBorrow(locals[i]));
Py_VISIT(PyStackRef_AsPyObjectBorrow(*i));
}
return 0;
}
Expand Down
41 changes: 40 additions & 1 deletion Python/generated_cases.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

31 changes: 28 additions & 3 deletions Tools/cases_generator/analyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ class Uop:
stack: StackEffect
caches: list[CacheEntry]
body: list[lexer.Token]
token_requires_flush: list[bool] # bitmap to body
properties: Properties
_size: int = -1
implicitly_created: bool = False
Expand Down Expand Up @@ -345,6 +346,24 @@ def analyze_caches(inputs: list[parser.InputEffect]) -> list[CacheEntry]:
return [CacheEntry(i.name, int(i.size)) for i in caches]


def analyze_specials_requiring_flush(name: str, op: list[lexer.Token], outputs: list[StackItem]) -> list[bool]:
res = []
for idx, token in enumerate(op):
if token.kind == "IDENTIFIER" and token.text == "PyStackRef_FromPyObjectNew":
should_flush = True
assert op[idx-1].kind == "EQUALS", (f"{name} Result of a specials that is flushed"
" must be written to a stack variable directly")
# Scan to look for the first thing it's assigned to
for assgn_target in reversed(op[:idx-1]):
out_names = [out.name for out in outputs]
if assgn_target.kind == "IDENTIFIER":
should_flush = assgn_target.text in out_names
break
res.append(should_flush)
else:
res.append(False)
return res

def variable_used(node: parser.InstDef, name: str) -> bool:
"""Determine whether a variable with a given name is used in a node."""
return any(
Expand Down Expand Up @@ -619,13 +638,15 @@ def compute_properties(op: parser.InstDef) -> Properties:


def make_uop(name: str, op: parser.InstDef, inputs: list[parser.InputEffect], uops: dict[str, Uop]) -> Uop:
stack = analyze_stack(op)
result = Uop(
name=name,
context=op.context,
annotations=op.annotations,
stack=analyze_stack(op),
stack=stack,
caches=analyze_caches(inputs),
body=op.block.tokens,
token_requires_flush=analyze_specials_requiring_flush(name, op.block.tokens, stack.outputs),
properties=compute_properties(op),
)
if effect_depends_on_oparg_1(op) and "split" in op.annotations:
Expand All @@ -636,13 +657,15 @@ def make_uop(name: str, op: parser.InstDef, inputs: list[parser.InputEffect], uo
if properties.oparg:
# May not need oparg anymore
properties.oparg = any(token.text == "oparg" for token in op.block.tokens)
stack = analyze_stack(op, bit)
rep = Uop(
name=name_x,
context=op.context,
annotations=op.annotations,
stack=analyze_stack(op, bit),
stack=stack,
caches=analyze_caches(inputs),
body=op.block.tokens,
token_requires_flush=analyze_specials_requiring_flush(name, op.block.tokens, stack.outputs),
properties=properties,
)
rep.replicates = result
Expand All @@ -658,13 +681,15 @@ def make_uop(name: str, op: parser.InstDef, inputs: list[parser.InputEffect], uo
properties = compute_properties(op)
properties.oparg = False
properties.const_oparg = oparg
stack = analyze_stack(op)
rep = Uop(
name=name_x,
context=op.context,
annotations=op.annotations,
stack=analyze_stack(op),
stack=stack,
caches=analyze_caches(inputs),
body=op.block.tokens,
token_requires_flush=analyze_specials_requiring_flush(name, op.block.tokens, stack.outputs),
properties=properties,
)
rep.replicates = result
Expand Down
Loading