Skip to content

GH-95245: Store object values and dict pointers in single tagged pointer.#95278

Merged
markshannon merged 6 commits intopython:mainfrom
faster-cpython:merge-dict-and-values-pointers
Aug 1, 2022
Merged

GH-95245: Store object values and dict pointers in single tagged pointer.#95278
markshannon merged 6 commits intopython:mainfrom
faster-cpython:merge-dict-and-values-pointers

Conversation

@markshannon
Copy link
Copy Markdown
Member

@markshannon markshannon commented Jul 26, 2022

This is the first part of #95245. Part two will move the weakrefs pointer into the object pre-header.

I have chosen to tag the values pointer, rather than the dict pointer, because it allows _PyObject_GetDictPtr(PyObject *obj) to continue to return a valid pointer.

@markshannon
Copy link
Copy Markdown
Member Author

No change in performance

Comment thread Objects/dictobject.c Outdated
Comment thread Objects/object.c Outdated
Comment thread Objects/object.c
Comment thread Objects/object.c
@iritkatriel
Copy link
Copy Markdown
Member

Is there any documentation about this? It's pretty intricate.

@markshannon
Copy link
Copy Markdown
Member Author

I was going to document this once I'd done the second part of #95245
Something like this: https://github.com/faster-cpython/cpython/blob/document-object-layout/Objects/object_layout.md

Copy link
Copy Markdown
Member

@iritkatriel iritkatriel left a comment

Choose a reason for hiding this comment

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

I have no more comments.

static inline void
_PyDictOrValues_SetValues(PyDictOrValues *ptr, PyDictValues *values)
{
ptr->values = ((char *)values) - 1;
Copy link
Copy Markdown
Contributor

@matthiasgoergens matthiasgoergens Aug 26, 2022

Choose a reason for hiding this comment

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

I'm curious why this one is a -1? Naively, I would have expected something like (|1), ie setting the lowest bit. Which would be equivalent to +1.

I assume there's something that goes horribly wrong with that native approach that I am missing, though?

(As far as I can tell, subtracting one should also work. Not sure what C does with null pointers in this context, though.)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

_PyDictOrValues_SetValues mutates the pointer; _PyDictOrValues_GetValues restores the pointer. Think of it as $f(x) = y$ and $f^{-1}(y) = x$. Currently, $f(x) = x - 1$ and $f^{-1}(y) = y + 1$. If we'd used +1, as you suggest, we'd have to undo that using -1 iso. +1. AFAICS, either way is fine.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for explaining!

I am working on a prototype with a tagged pointer elsewhere in the code, I so I was looking for exiting examples to learn from.

Thanks for confirming that either way is fine.

I was just wrecking my brain about whether there's something more going on that I was missing. (And something that I would thus be bound to get horriby wrong in my code, where I want to store either a pointer directly, or an odd integer, in the same memory location.)

@markshannon markshannon deleted the merge-dict-and-values-pointers branch September 26, 2023 12:55
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.

6 participants