GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — gh-127119: Remove check on accidental deallocation of immortal objects for free-threaded build by eendebakpt · Pull Request #127120 · python/cpython

Conversation

@eendebakpt

@eendebakpt eendebakpt commented Nov 21, 2024 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

(Description was updated) The python small ints are immortal with a fixed reference count (also some other types). However, old extension modules can still modify the reference count and end up deallocating these objects.

This should not be an issue on 64-bit builds (even when accidentically changing the reference count it will take a very long time for an object to reach refcount zero) or the free-threaded build (which used a different reference counts, so has no legacy extensions modules)

In this PR we remove the check on accidental deallocation for the free-threading build. This has performance impact for the long type (where the tp_dealloc is actually called often). For the other types we remove it to be consistent, but it should have no performance impact.

Also see:

  • PEP 683, section Accidental De-Immortalizing for details.
  • GH-101291: Rearrange the size bits in PyLongObject #102464 (comment)
  • gh-84436: Add static flag in PyLongObject's lv_tag #103403 (comment)
  • Issue: Remove redundant small int check in long_dealloc #127119

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@eendebakpt
Remove check on small ints in long_dealloc
19d64f0
@bedevere-app bedevere-app Bot mentioned this pull request Nov 21, 2024
Remove redundant small int check in long_dealloc #127119
Closed
@bedevere-app bedevere-app Bot added the awaiting review label Nov 21, 2024
@skirpichev

skirpichev commented Nov 22, 2024

Copy link
Copy Markdown
Member

Apparently, assertion is broken in tests.

nineteendo reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

eendebakpt and others added 3 commits November 22, 2024 08:56
@eendebakpt
rewrite assert
4117c54
@blurb-it
📜🤖 Added by blurb_it.
38862e3
@eendebakpt
Merge branch 'main' into small_int_immortal
a82a6ab
@eendebakpt

eendebakpt commented Nov 22, 2024

Copy link
Copy Markdown
Contributor Author

Apparently, assertion is broken in tests.

Yes, my mistake. Should be fixed now

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

Fidget-Spinner
Fidget-Spinner reviewed Nov 22, 2024
View reviewed changes
Comment thread Objects/longobject.c Resolved

Uh oh!

There was an error while loading. Please reload this page.

ZeroIntensity
ZeroIntensity reviewed Nov 22, 2024
View reviewed changes
Comment thread Misc/NEWS.d/next/Core_and_Builtins/2024-11-22-07-58-00.gh-issue-127119.p9Yv4U.rst Resolved

Uh oh!

There was an error while loading. Please reload this page.

eendebakpt and others added 3 commits November 22, 2024 16:03
@eendebakpt
avoid warnings in release builds by using Py_DEBUG
d8c318d
@eendebakpt @ZeroIntensity
Update Misc/NEWS.d/next/Core_and_Builtins/2024-11-22-07-58-00.gh-issu…
0cd1eba
…e-127119.p9Yv4U.rst

Co-authored-by: Peter Bierma <[email protected]>
@eendebakpt
Merge branch 'main' into small_int_immortal
4dc97c9
ZeroIntensity
ZeroIntensity previously approved these changes Nov 22, 2024
View reviewed changes

@ZeroIntensity ZeroIntensity left a comment

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@bedevere-app bedevere-app Bot added awaiting core review and removed awaiting review labels Nov 22, 2024
@ZeroIntensity ZeroIntensity added the 🔨 test-with-refleak-buildbots Test PR w/ refleak buildbots; report in status section label Nov 22, 2024
@bedevere-bot

bedevere-bot commented Nov 22, 2024

Copy link
Copy Markdown

🤖 New build scheduled with the buildbot fleet by @ZeroIntensity for commit 4dc97c9 🤖

If you want to schedule another build, you need to add the 🔨 test-with-refleak-buildbots label again.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@bedevere-bot bedevere-bot removed the 🔨 test-with-refleak-buildbots Test PR w/ refleak buildbots; report in status section label Nov 22, 2024
@ZeroIntensity
ZeroIntensity dismissed their stale review November 22, 2024 15:12

CI is failing, because apparently you can build with assertions but not with debug enabled (that's what I get for prematurely approving, ha).

@bedevere-app bedevere-app Bot added awaiting review and removed awaiting core review labels Nov 22, 2024
ZeroIntensity
ZeroIntensity reviewed Nov 22, 2024
View reviewed changes
Comment thread Objects/longobject.c Resolved

Uh oh!

There was an error while loading. Please reload this page.

eendebakpt added 6 commits November 22, 2024 16:51
@eendebakpt
use NDEBUG
2c23541
@eendebakpt
Merge branch 'main' into small_int_immortal
7d3a012
@eendebakpt
Merge branch 'small_int_immortal' of github.com:eendebakpt/cpython in…
00b735f
…to small_int_immortal
@eendebakpt
whitespace
ea17aee
@eendebakpt
Merge branch 'main' into small_int_immortal
312c790
@eendebakpt
Merge branch 'main' into small_int_immortal
fe0076c
ZeroIntensity
ZeroIntensity previously approved these changes Nov 22, 2024
View reviewed changes

@ZeroIntensity ZeroIntensity left a comment

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM (again)!

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@bedevere-app bedevere-app Bot added awaiting core review and removed awaiting review labels Nov 22, 2024
gpshead
gpshead reviewed Nov 24, 2024
View reviewed changes

@gpshead gpshead left a comment •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this changes from silently re-immortalizing the small ints to actually letting them be deallocated in non-debug builds. in theory this is supposed to be fine, but how confident are we of (buggy) reference counting code not relying in the former behavior?

(I'm not blocking this PR, I think the change is acceptable, just want that pondered...)

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@ZeroIntensity

ZeroIntensity commented Nov 24, 2024

Copy link
Copy Markdown
Member

in theory this is supposed to be fine, but how confident are we of (buggy) reference counting code not relying in the former behavior?

I thought about that too, but I think issues around immortal objects being buggy was fixed by GH-125251 (at least, I thought that was implied by the removal of _Py_IsImmortalLoose). Someone should double check though (I guess maybe it's possible for stable ABI extensions to break things).

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

eendebakpt added 2 commits November 24, 2024 21:10
@eendebakpt
keep check in stable ABI build
0837699
@eendebakpt
typo
0764241
@eendebakpt

eendebakpt commented Nov 24, 2024

Copy link
Copy Markdown
Contributor Author

The possibility of de-allocating immortal objects is described in [PEP 683, section Accidental De-Immortalizing](https://peps.python.org/pep-0683/#accidental-de-immortalizing). Also see
[Python-Dev] Re: PEP 683: "Immortal Objects, Using a Fixed Refcount" round 3. Even with the changes from #125251 this is still possible. The check in long_dealloc is therefore not redundant (although it is unlikely). The condiderations from PEP 683 are only 2 years old, so I do not think enough time has passed to reconsider the tradeoffs. I will update the comments in the PR with a pointer to the PEP.

But if I understand the correctly the accidental-de-immortalizing cannot happen on: 64-bit systems, or with the free-threading build, or when Py_LIMITED_API is not defined. I removed the check for these cases. I will benchmark this as well to see wether this makes a difference.

And yes, this should be double checked!

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@eendebakpt eendebakpt mentioned this pull request Nov 24, 2024
gh-126868: Add freelist for compact int objects #126865
Merged
@eendebakpt

eendebakpt commented Nov 24, 2024

Copy link
Copy Markdown
Contributor Author

Results on a microbenchmark:

bench_long: Mean +- std dev: [main] 194 ns +- 3 ns -> [pr_small_int_check] 188 ns +- 2 ns: 1.03x faster
bench_alloc: Mean +- std dev: [main] 407 us +- 14 us -> [pr_small_int_check] 393 us +- 21 us: 1.03x faster

Benchmark hidden because not significant (1): bench_collatz

Geometric mean: 1.02x faster

I expect no overall improvement on the pyperformance benchmark.

Benchmark script
# Quick benchmark for cpython long objects

import pyperf


def collatz(a):
    while a > 1:
        if a % 2 == 0:
            a = a // 2
        else:
            a = 3 * a + 1


def bench_collatz(loops):
    range_it = range(loops)
    t0 = pyperf.perf_counter()
    for ii in range_it:
        collatz(ii)
    return pyperf.perf_counter() - t0


def bench_long(loops):
    range_it = range(loops)
    t0 = pyperf.perf_counter()
    x = 10
    for ii in range_it:
        x = x * x
        y = x // 2
        x = y + ii + x
        if x > 10**10:
            x = x % 1000
    return pyperf.perf_counter() - t0


def bench_alloc(loops):
    range_it = range(loops)
    t0 = pyperf.perf_counter()
    for ii in range_it:
        for kk in range(20_000):
            del kk
    return pyperf.perf_counter() - t0


# %timeit bench_long(1000)

if __name__ == "__main__":
    runner = pyperf.Runner()
    runner.bench_time_func("bench_collatz", bench_collatz)
    runner.bench_time_func("bench_long", bench_long)
    runner.bench_time_func("bench_alloc", bench_alloc)
All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@skirpichev
skirpichev requested a review from ZeroIntensity November 25, 2024 04:08
@ZeroIntensity
ZeroIntensity dismissed their stale review November 25, 2024 04:11

The implementation changed.

@bedevere-app bedevere-app Bot added awaiting review and removed awaiting core review labels Nov 25, 2024
ZeroIntensity
ZeroIntensity requested changes Nov 25, 2024
View reviewed changes

@ZeroIntensity ZeroIntensity left a comment

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is now incorrect :(

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread Objects/longobject.c Outdated
Comment on lines +3617 to +3618
#ifdef Py_LIMITED_API
#ifndef Py_GIL_DISABLED

@ZeroIntensity ZeroIntensity Nov 25, 2024

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure it's possible for us to know when we're using the limited API. Py_LIMITED_API is something that affects Python.h at the compile-time of an extension module, but this happens during the compilation of CPython, so it will never be true.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@bedevere-app bedevere-app Bot added awaiting core review and removed awaiting review labels Nov 25, 2024
@eendebakpt
review comments
56f4133
@markshannon

markshannon commented Dec 4, 2024

Copy link
Copy Markdown
Member

As an alternative to removing the check altogether we could make it cheaper by using the reserved bit https://github.com/python/cpython/blob/main/Include/cpython/longintrepr.h#L79 as a marker for immortal/small ints.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@eendebakpt eendebakpt mentioned this pull request Dec 4, 2024
gh-127119: Faster check for small ints in long_dealloc #127620
Merged
@eendebakpt

eendebakpt commented Dec 4, 2024

Copy link
Copy Markdown
Contributor Author

@markshannon Thanks for the idea! I think it works and would not be hard to implement, but I am a bit hesitant to use a reserved bit for a small optimization like this. I created an alternative PR with a faster check based on your idea though

gpshead reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@markshannon

markshannon commented Dec 5, 2024

Copy link
Copy Markdown
Member

That bit is reserved for exactly this use case, so it is fine to use it.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@eendebakpt
apply same rule to all cases
8f6bf27
@eendebakpt
eendebakpt requested a review from markshannon as a code owner December 7, 2024 20:37
@eendebakpt eendebakpt changed the title gh-127119: Remove check on small ints in long_dealloc gh-127119: Remove check on accidental deallocation of immortal objects for free-threaded build Dec 7, 2024
@eendebakpt

eendebakpt commented Jan 28, 2025

Copy link
Copy Markdown
Contributor Author

Closing in favor of #127620

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@eendebakpt eendebakpt closed this Jan 28, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@gpshead gpshead gpshead left review comments
@Fidget-Spinner Fidget-Spinner Fidget-Spinner left review comments
@ZeroIntensity ZeroIntensity ZeroIntensity requested changes
@markshannon markshannon Awaiting requested review from markshannon

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

awaiting core review

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

7 participants

@eendebakpt @skirpichev @bedevere-bot @ZeroIntensity @markshannon @gpshead @Fidget-Spinner
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.