forked from python/cpython
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
pythongh-108216: Add pycore_dict_struct.h internal header file
Add a new internal pycore_dict_struct.h header file. It can be used by debuggers and profilers to inspect a Python dictionary without having to call Python functions. It should be usable in C++. pycore_dict.h includes pycore_dict_struct.h (no API change).
- Loading branch information
Showing
7 changed files
with
136 additions
and
105 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
// Internal header which can be used by debuggers and profilers | ||
// to inspect a Python dictionary by reading memory, without executing | ||
// Python functions. Only define static inline functions to inspect a | ||
// dictionary. Sub-set of pycore_dict.h which should be usable in C++ | ||
// (gh-108216). | ||
|
||
#ifndef Py_INTERNAL_DICT_STRUCT_H | ||
#define Py_INTERNAL_DICT_STRUCT_H | ||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
#ifndef Py_BUILD_CORE | ||
# error "this header requires Py_BUILD_CORE define" | ||
#endif | ||
|
||
typedef struct { | ||
/* Cached hash code of me_key. */ | ||
Py_hash_t me_hash; | ||
PyObject *me_key; | ||
PyObject *me_value; /* This field is only meaningful for combined tables */ | ||
} PyDictKeyEntry; | ||
|
||
typedef struct { | ||
PyObject *me_key; /* The key must be Unicode and have hash. */ | ||
PyObject *me_value; /* This field is only meaningful for combined tables */ | ||
} PyDictUnicodeEntry; | ||
|
||
#define DKIX_EMPTY (-1) | ||
#define DKIX_DUMMY (-2) /* Used internally */ | ||
#define DKIX_ERROR (-3) | ||
#define DKIX_KEY_CHANGED (-4) /* Used internally */ | ||
|
||
typedef enum { | ||
DICT_KEYS_GENERAL = 0, | ||
DICT_KEYS_UNICODE = 1, | ||
DICT_KEYS_SPLIT = 2 | ||
} DictKeysKind; | ||
|
||
/* See dictobject.c for actual layout of DictKeysObject */ | ||
struct _dictkeysobject { | ||
Py_ssize_t dk_refcnt; | ||
|
||
/* Size of the hash table (dk_indices). It must be a power of 2. */ | ||
uint8_t dk_log2_size; | ||
|
||
/* Size of the hash table (dk_indices) by bytes. */ | ||
uint8_t dk_log2_index_bytes; | ||
|
||
/* Kind of keys */ | ||
uint8_t dk_kind; | ||
|
||
/* Version number -- Reset to 0 by any modification to keys */ | ||
uint32_t dk_version; | ||
|
||
/* Number of usable entries in dk_entries. */ | ||
Py_ssize_t dk_usable; | ||
|
||
/* Number of used entries in dk_entries. */ | ||
Py_ssize_t dk_nentries; | ||
|
||
/* Actual hash table of dk_size entries. It holds indices in dk_entries, | ||
or DKIX_EMPTY(-1) or DKIX_DUMMY(-2). | ||
Indices must be: 0 <= indice < USABLE_FRACTION(dk_size). | ||
The size in bytes of an indice depends on dk_size: | ||
- 1 byte if dk_size <= 0xff (char*) | ||
- 2 bytes if dk_size <= 0xffff (int16_t*) | ||
- 4 bytes if dk_size <= 0xffffffff (int32_t*) | ||
- 8 bytes otherwise (int64_t*) | ||
Dynamically sized, SIZEOF_VOID_P is minimum. */ | ||
char dk_indices[]; /* char is required to avoid strict aliasing. */ | ||
|
||
/* "PyDictKeyEntry or PyDictUnicodeEntry dk_entries[USABLE_FRACTION(DK_SIZE(dk))];" array follows: | ||
see the DK_ENTRIES() macro */ | ||
}; | ||
|
||
/* Layout of dict values: | ||
* | ||
* The PyObject *values are preceded by an array of bytes holding | ||
* the insertion order and size. | ||
* [-1] = prefix size. [-2] = used size. size[-2-n...] = insertion order. | ||
*/ | ||
struct _dictvalues { | ||
PyObject *values[1]; | ||
}; | ||
|
||
#define DK_LOG_SIZE(dk) _Py_RVALUE((dk)->dk_log2_size) | ||
#if SIZEOF_VOID_P > 4 | ||
#define DK_SIZE(dk) (((int64_t)1)<<DK_LOG_SIZE(dk)) | ||
#else | ||
#define DK_SIZE(dk) (1<<DK_LOG_SIZE(dk)) | ||
#endif | ||
|
||
static inline void* _DK_ENTRIES(PyDictKeysObject *dk) { | ||
int8_t *indices = (int8_t*)(dk->dk_indices); | ||
size_t index = (size_t)1 << dk->dk_log2_index_bytes; | ||
return (&indices[index]); | ||
} | ||
static inline PyDictKeyEntry* DK_ENTRIES(PyDictKeysObject *dk) { | ||
assert(dk->dk_kind == DICT_KEYS_GENERAL); | ||
return (PyDictKeyEntry*)_DK_ENTRIES(dk); | ||
} | ||
static inline PyDictUnicodeEntry* DK_UNICODE_ENTRIES(PyDictKeysObject *dk) { | ||
assert(dk->dk_kind != DICT_KEYS_GENERAL); | ||
return (PyDictUnicodeEntry*)_DK_ENTRIES(dk); | ||
} | ||
|
||
#define DK_IS_UNICODE(dk) ((dk)->dk_kind != DICT_KEYS_GENERAL) | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
#endif // !Py_INTERNAL_DICT_STRUCT_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
3 changes: 3 additions & 0 deletions
3
Misc/NEWS.d/next/C API/2023-08-21-20-41-47.gh-issue-108216.lzQ6Uq.rst
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
Add a new internal pycore_dict_struct.h header file. It can be used by | ||
debuggers and profilers to inspect a Python dictionary without having to | ||
call Python functions. It should be usable in C++. Patch by Victor Stinner. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters