Skip to content

gh-91117: Ensure integer mod and pow operations use cached small ints #31843

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 11, 2022

Conversation

sweeneyde
Copy link
Member

@sweeneyde sweeneyde commented Mar 13, 2022

@sweeneyde
Copy link
Member Author

I found the call graph of function names a lot to juggle, but the relevant call graphs are like this:

long_divmod:
    l_divmod:
        fast_floor_div
        fast_mod
        long_divrem (doesn't check for small remainders):
            divrem1 (returns fresh longs)
            x_divrem (returns fresh longs)

long_mod:
    l_mod:
        fast_mod
        long_rem (doesn't check for small remainders):
            rem1
            x_divrem (returns fresh longs)

long_pow:
    l_mod:
        (same as above)
 

As I noted in the issue, x_divrem always returns new freshly-allocated ints. Its callers are like this:

    - long_divrem
        - uses maybe_small_long on quotient
        - doesn't check if remainder is small <---- oops
    - long_rem
        - throws away quotient
        - doesn't check if remainder is small <---- oops
    - long_true_divide
        - modifies the quotient (!!!)
        - throws away remainder

@sweeneyde sweeneyde marked this pull request as ready for review March 13, 2022 08:41
@mdickinson
Copy link
Member

@sweeneyde Sorry Dennis. This is on my list of things to review, but I'm not likely to get to it for a few days.

Copy link
Member

@mdickinson mdickinson left a comment

Choose a reason for hiding this comment

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

LGTM!

@@ -2732,6 +2733,7 @@ long_rem(PyLongObject *a, PyLongObject *b, PyLongObject **prem)
else {
/* Slow path using divrem. */
Py_XDECREF(x_divrem(a, b, prem));
*prem = maybe_small_long(*prem);
Copy link
Member

Choose a reason for hiding this comment

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

It surprised me initially that it was okay to call maybe_small_long on a value that might be NULL, but I see that other parts of Objects/longobject.c also do that (and it makes sense from a convenience perspective).

@sweeneyde sweeneyde changed the title bpo-46961: Ensure integer mod and pow operations use cached small ints gh-91117: Ensure integer mod and pow operations use cached small ints Apr 11, 2022
@sweeneyde sweeneyde closed this Apr 11, 2022
@sweeneyde sweeneyde reopened this Apr 11, 2022
@ghost
Copy link

ghost commented Apr 11, 2022

Commit authors are required to sign the Contributor License Agreement.
CLA not signed

@sweeneyde
Copy link
Member Author

Thanks for the review! Looks like we should wait for Blurb-It to sign its CLA ;)

@mdickinson
Copy link
Member

Looks like we should wait for Blurb-It to sign its CLA ;)

I think we can reasonably bypass that. Feel free to merge!

@sweeneyde sweeneyde merged commit 8be8949 into python:main Apr 11, 2022
@sweeneyde sweeneyde deleted the small_ints branch April 22, 2022 16:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants