-
Notifications
You must be signed in to change notification settings - Fork 52
Description
Optimized superblocks will depend on two types of assumptions.
- Local ones that are checked by inline guards.
- Global assumptions that are not checked locally.
For example, we might assume that the class of an object has version 212
. We would insert an inline guard to check that.
We might also assume the builtin len
has not be reassigned. It is expensive to check this all the time, so we don't want to have to put a guard in the optimized code. In which case we need a mechanism to invalidate the optimized dynamic superblock should len
actually get changed.
We can use the mechanism of watchers to install a watcher, but then we need find all the superblocks to deoptimize.
Designing an efficient and compact data structure that can perform this task will be important.
One possibility is to use bloom filters to avoid having to store all possible deoptimization events on the superblock.
Deoptimizing a superblocks unnecessarily will impact performance, but not correctness. So, a few false positives should be fine.
The actual deoptimization is simple enough: just replace the start of the code with code that returns to the base interpreter.
Here's an initial list of possible deoptimization events:
We won't need to worry about events until we have optimizations that assume those event won't happen.
Local events (will only deopt a few superblocks)
- Instrumentation of a single code object
- Function version change
- Type version change (including cached keys)
- Watched dict value changes
__class__
of object changes (We might be able to merge this with type version change)
Global events (will deopt all superblocks)
- Global instrumentation
- Changes to the builtins dict.
@carljm Anything I've missed here?