10000 bpo-44337: Port LOAD_ATTR to PEP 659 adaptive interpreter by markshannon · Pull Request #26595 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

bpo-44337: Port LOAD_ATTR to PEP 659 adaptive interpreter #26595

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 17 commits into from
Jun 10, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
Next Next commit
Specialize LOAD_ATTR with LOAD_ATTR_SLOT and LOAD_ATTR_SPLIT_KEYS
  • Loading branch information
markshannon committed Jun 8, 2021
commit 8db0653950309a2b911972acd4f025c0d5e90a78
65 changes: 65 additions & 0 deletions Include/internal/pycore_code.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ typedef struct {
uint16_t index;
} _PyAdaptiveEntry;


typedef struct {
uint32_t tp_version;
uint32_t dk_version;
} _PyLoadAttrCache;

/* Add specialized versions of entries to this union.
*
* Do not break the invariant: sizeof(SpecializedCacheEntry) == 8
Expand All @@ -55,6 +61,7 @@ typedef struct {
typedef union {
_PyEntryZero zero;
_PyAdaptiveEntry adaptive;
_PyLoadAttrCache load_attr;
} SpecializedCacheEntry;

#define INSTRUCTIONS_PER_ENTRY (sizeof(SpecializedCacheEntry)/sizeof(_Py_CODEUNIT))
Expand Down Expand Up @@ -255,6 +262,64 @@ PyAPI_FUNC(PyObject *) _PyCode_GetCellvars(PyCodeObject *);
PyAPI_FUNC(PyObject *) _PyCode_GetFreevars(PyCodeObject *);


/* Cache hits and misses */

static inline uint8_t
saturating_increment(uint8_t c)
{
return c<<1;
}

static inline uint8_t
saturating_decrement(uint8_t c)
{
return (c>>1) + 128;
}

static inline uint8_t
saturating_zero(void)
{
return 255;
}

/* Starting value for saturating counter.
* Technically this should be 1, but that is likely to
* cause a bit of thrashing when we optimize then get an immediate miss.
* We want to give the counter a change to stabilize, so we start at 3.
*/
static inline uint8_t
saturating_start(void)
{
return saturating_zero()<<3;
}

static inline void
record_cache_hit(_PyAdaptiveEntry *entry) {
entry->counter = saturating_increment(entry->counter);
}

static inline void
record_cache_miss(_PyAdaptiveEntry *entry) {
entry->counter = saturating_decrement(entry->counter);
}

static inline int
too_many_cache_misses(_PyAdaptiveEntry *entry) {
return entry->counter == saturating_zero();
}

#define BACKOFF 64

static inline void
cache_backoff(_PyAdaptiveEntry *entry) {
entry->counter = BACKOFF;
}

/* Specialization functions */

int _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name, SpecializedCacheEntry *cache);


#ifdef __cplusplus
}
#endif
Expand Down
3 changes: 3 additions & 0 deletions Include/opcode.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions Lib/opcode.py
Original file line number Diff line number Diff line change
Expand Up @@ -218,3 +218,9 @@ def jabs_op(name, op):
def_op('CALL_METHOD_KW', 166)

del def_op, name_op, jrel_op, jabs_op

_specialized_instructions = [
"LOAD_ATTR_ADAPTIVE",
"LOAD_ATTR_SPLIT_KEYS",
"LOAD_ATTR_SLOT",
]
Loading
0