8000 GH-115776: Embed the values array into the object, for "normal" Python objects. by markshannon · Pull Request #116115 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

GH-115776: Embed the values array into the object, for "normal" Python objects. #116115

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 35 commits into from
Apr 2, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
d5085db
Inline values work in progress
markshannon Feb 3, 2024
0d88de4
Change layout of PyDictValue to make is suitable for appending to end…
markshannon Feb 4, 2024
d922903
Add copy_values function
markshannon Feb 21, 2024
c03e6cb
Tidy up _PyObject_Init
markshannon Feb 21, 2024
621ea3b
Inline values -- Work in progress
markshannon Feb 21, 2024
67daab5
Get inline values closer to working
markshannon Feb 23, 2024
34c7171
Further fixing
markshannon Feb 23, 2024
c237e79
Remove debug field
markshannon Feb 23, 2024
f80befa
Remove unused function
markshannon Feb 23, 2024
a0c11e4
Merge branch 'main' into inline-values
markshannon Feb 24, 2024
bc1ebc8
Two tweaks
markshannon Feb 24, 2024
0dc68a4
Rename dict-or-values to managed-dict
markshannon Feb 24, 2024
084519c
Update object layout doc
markshannon Feb 24, 2024
3744f32
Add news
markshannon Feb 24, 2024
75ee5a0
Fix a couple of compilation errors on Windows
markshannon Feb 24, 2024
162 8000 764c
Update gdb support
markshannon Feb 24, 2024
82ece1b
Specialize LOAD_ATTR for (uninitialized) managed dicts
markshannon Feb 24, 2024
6a762ed
Allow extra allocation in JIT for tests.
markshannon Feb 24, 2024
9dbc8dd
Fix error from merge
markshannon Feb 24, 2024
4a1f7b7
Fix another mis-merge and update generated files
markshannon Feb 24, 2024
09121f9
Fix formatting
markshannon Feb 24, 2024
c384b05
Fix up free threading
markshannon Feb 24, 2024
ee5cf2a
Merge branch 'main' into inline-values
markshannon Feb 24, 2024
005b42b
Remove incorrect assertion
markshannon Feb 24, 2024
48d849e
Merge branch 'main' into inline-values
markshannon Feb 24, 2024
682217c
Remove some debug code
markshannon Feb 24, 2024
0ff1709
Fix off by one error.
markshannon Feb 24, 2024
895a944
Simplify PyObject_ClearManagedDict
markshannon Feb 25, 2024
1b4302a
Merge branch 'main' into inline-values
markshannon Mar 5, 2024
ecd4204
Merge branch 'main' into inline-values
markshannon Mar 26, 2024
c05d01d
Get tests passing for free-threaded build
markshannon Mar 26, 2024
d441d7b
Review comment and compiler warnings
markshannon Mar 27, 2024
3395bc2
Update stats gathering.
markshannon Mar 27, 2024
ccceffb
Better type safety. Fewer downcasts, some more upcasts
markshannon Mar 28, 2024
7700177
Merge branch 'main' into inline-values
markshannon Apr 2, 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
Add copy_values function
  • Loading branch information
markshannon committed Feb 21, 2024
commit d9229033c55b295629187bcfc9cb4c575621d455
2 changes: 1 addition & 1 deletion Include/internal/pycore_dict.h
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ struct _dictkeysobject {
struct _dictvalues {
uint8_t capacity;
uint8_t size;
uint8_t refcount;
uint8_t embedded;
PyObject *values[1];
};

Expand Down
43 changes: 31 additions & 12 deletions Objects/dictobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -709,6 +709,7 @@ new_values(size_t size)
if (res == NULL) {
return NULL;
}
res->embedded = 0;
res->size = 0;
res->capacity = size;
return res;
Expand All @@ -717,7 +718,9 @@ new_values(size_t size)
static inline void
free_values(PyDictValues *values)
{
PyMem_Free(values);
if (!values->embedded) {
PyMem_Free(values);
}
}

/* Consumes a reference to the keys object */
Expand Down Expand Up @@ -3104,6 +3107,27 @@ dict_copy_impl(PyDictObject *self)
return PyDict_Copy((PyObject *)self);
}

/* Copies the values, but does not change the reference
* counts of the objects in the array. */
static PyDictValues *
copy_values(PyDictValues *values)
{
PyDictValues *newvalues = new_values(values->capacity);
if (newvalues == NULL) {
PyErr_NoMemory();
return NULL;
}
newvalues->embedded = 0;
newvalues->size = values->size;
uint8_t *values_order = get_insertion_order_array(values);
uint8_t *new_values_order = get_insertion_order_array(newvalues);
memcpy(new_values_order, values_order, values->capacity);
for (int i = 0; i < values->capacity; i++) {
newvalues->values[i] = values->values[i];
}
return newvalues;
}

A123 PyObject *
PyDict_Copy(PyObject *o)
{
Expand All @@ -3124,28 +3148,23 @@ PyDict_Copy(PyObject *o)

if (_PyDict_HasSplitTable(mp)) {
PyDictObject *split_copy;
size_t size = shared_keys_usable_size(mp->ma_keys);
PyDictValues *newvalues = new_values(size);
if (newvalues == NULL)
PyDictValues *newvalues = copy_values(mp->ma_values);
if (newvalues == NULL) {
return PyErr_NoMemory();
}
split_copy = PyObject_GC_New(PyDictObject, &PyDict_Type);
if (split_copy == NULL) {
free_values(newvalues);
return NULL;
}
newvalues->size = mp->ma_values->size;
uint8_t *values_order = get_insertion_order_array(mp->ma_values);
uint8_t *new_values_order = get_insertion_order_array(newvalues);
memcpy(new_values_order, values_order, size);
for (size_t i = 0; i < newvalues->capacity; i++) {
Py_XINCREF(newvalues->values[i]);
}
split_copy->ma_values = newvalues;
split_copy->ma_keys = mp->ma_keys;
split_copy->ma_used = mp->ma_used;
split_copy->ma_version_tag = DICT_NEXT_VERSION(interp);
dictkeys_incref(mp->ma_keys);
for (size_t i = 0; i < size; i++) {
PyObject *value = mp->ma_values->values[i];
split_copy->ma_values->values[i] = Py_XNewRef(value);
}
if (_PyObject_GC_IS_TRACKED(mp))
_PyObject_GC_TRACK(split_copy);
return (PyObject *)split_copy;
Expand Down
0