diff options
author | John Hawthorn <[email protected]> | 2021-07-12 13:35:09 -0700 |
---|---|---|
committer | Alan Wu <[email protected]> | 2021-10-20 18:19:37 -0400 |
commit | cb5571eece818b33d2f6a33b892e7cda31231e69 (patch) | |
tree | e320cfb64a30f1c5b3b1ca6adb038aee5b3ca197 /yjit_core.c | |
parent | d5f18f7845f0f0fb3024ada63a552deac9c11ad7 (diff) |
Flatten mappings when clearing locals
We clear locals when we know their values might change (ex. when
performing a method call). However previously values on the stack which
were originally pushed from a local would still point back to that
local.
With this commit, when clearing locals, we'll now iterate over the
mappings of the stack and copy the known type from the local to the
stack mapping, removing the association to the local.
This should mean both that we'll retain any information we already know
about the local type, and that if a local is modified we won't
incorrectly infer it's new type from the existing value on the stack.
Diffstat (limited to 'yjit_core.c')
-rw-r--r-- | yjit_core.c | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/yjit_core.c b/yjit_core.c index c4f18e872f..ae771fb7c4 100644 --- a/yjit_core.c +++ b/yjit_core.c @@ -201,6 +201,16 @@ void ctx_set_local_type(ctx_t* ctx, size_t idx, val_type_t type) // eg: because of a call we can't track void ctx_clear_local_types(ctx_t* ctx) { + // When clearing local types we must detach any stack mappings to those + // locals. Even if local values may have changed, stack values will not. + for (int i = 0; i < ctx->stack_size && i < MAX_LOCAL_TYPES; i++) { + temp_mapping_t *mapping = &ctx->temp_mapping[i]; + if (mapping->kind == TEMP_LOCAL) { + RUBY_ASSERT(mapping->idx < MAX_LOCAL_TYPES); + ctx->temp_types[i] = ctx->local_types[mapping->idx]; + *mapping = MAP_STACK; + } + } memset(&ctx->local_types, 0, sizeof(ctx->local_types)); } |