Skip to content

Basic block invalidation mechanism #21

@maximecb

Description

@maximecb

There are a few situations in which it might be useful to invalidate basic block versions:

  • Primitive op (eg: plus/minus) redefined
  • Method redefined on class, throw away code calling that method
  • A method uses binding to modify local types in a caller

In the case of primitive op redefinitions, we might be better off throwing away all the compiled code, but class method redefinitions might happen too often for that to be practical. We could instead implement a strategy that allows invalidating generated code for one specific basic block version. I think it makes sense to figure out a solution for this early on, to avoid tedious refactorings later down the road.

To invalidate an individual basic block:

  • All branches jumping to the block should be atomically patched with jumps going to a stub instead.
  • There can also be other blocks falling through to the invalidated block because they immediately precede it.
    • If an incoming fall-through branch is too short to be patched, we may need to invalidate its block
      • This may not be an issue in practice, because the block we go to could have space
      • We can force any block that may need to be invalidated to have sufficient space to contain a jump to a stub
  • If the block is an entry point, it needs to be unmapped from its iseq
    • Unmap/remap anything at this iseq/idx
    • Optional: may want to recompile a new deoptimized entry point
  • Call continuation addresses on the stack can also be atomically replaced by jumps going to the stub.

Need:

  • list of blocks making cc/cme assumptions
    • Alan already created a hash table
    • Should contain blockid (iseq/idx) to invalidate
  • For a given block version, list of incoming branch entries (branch idxs)
    • This could be stored in a hash map or on some block version object
    • We only care about the branches that are actually patched, already executed
      • Jump to stubs can stay as-is

Question: would it be useful to have block version objects?

  • It looks like a blockid_t is not sufficient, we need a specific version
  • For invalidation, we need per-block metadata such as incoming branches
  • Branches may need a pointer to their parent block

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions