diff options
author | Maxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com> | 2021-01-22 14:57:44 -0500 |
---|---|---|
committer | Alan Wu <XrXr@users.noreply.github.com> | 2021-10-20 18:19:27 -0400 |
commit | 738160db0a7fb32d609133fb68fbdff02ff315f2 (patch) | |
tree | 93011f83550ddd21559cf1b9c7fc4c8ed2cb2105 | |
parent | 7efde1bfb486aa7bb57f5f355a13be040a6973ff (diff) |
Write ctx_diff() function to compate ctx_t objects
-rw-r--r-- | ujit_core.c | 48 | ||||
-rw-r--r-- | ujit_core.h | 1 |
2 files changed, 44 insertions, 5 deletions
diff --git a/ujit_core.c b/ujit_core.c index 2143ab3923..8e7ce31330 100644 --- a/ujit_core.c +++ b/ujit_core.c @@ -103,6 +103,42 @@ ctx_get_top_type(ctx_t* ctx) return ctx->temp_types[ctx->stack_size - 1]; } +/** +Compute a difference score for two context objects +Returns 0 if the two contexts are the same +Returns -1 if incompatible +Returns > 0 if different but compatible +*/ +int ctx_diff(const ctx_t* src, const ctx_t* dst) +{ + if (dst->stack_size != src->stack_size) + return -1; + + if (dst->self_is_object != src->self_is_object) + return -1; + + // Difference sum + int diff = 0; + + // For each temporary variable + for (size_t i = 0; i < MAX_TEMP_TYPES; ++i) + { + int t_src = src->temp_types[i]; + int t_dst = dst->temp_types[i]; + + if (t_dst != t_src) + { + // It's OK to lose some type information + if (t_dst == T_NONE) + diff += 1; + else + return -1; + } + } + + return diff; +} + // Add an incoming branch for a given block version static void add_incoming(block_t* p_block, uint32_t branch_idx) { @@ -118,16 +154,18 @@ static void add_incoming(block_t* p_block, uint32_t branch_idx) block_t* find_block_version(blockid_t blockid, const ctx_t* ctx) { // If there exists a version for this block id - st_data_t st_version; - if (rb_st_lookup(version_tbl, (st_data_t)&blockid, &st_version)) { - return (block_t*)st_version; - } + block_t* first_version; + if (!rb_st_lookup(version_tbl, (st_data_t)&blockid, (st_data_t*)&first_version)) + return NULL; // // TODO: use the ctx parameter to search existing versions for a match // - return NULL; + // Check that the version found is actually compatible + RUBY_ASSERT(ctx_diff(ctx, &first_version->ctx) >= 0); + + return first_version; } // Compile a new block version immediately block_t* gen_block_version(blockid_t blockid, const ctx_t* start_ctx) diff --git a/ujit_core.h b/ujit_core.h index ff73890e4d..7b230d779d 100644 --- a/ujit_core.h +++ b/ujit_core.h @@ -130,6 +130,7 @@ x86opnd_t ctx_stack_push(ctx_t* ctx, int type); x86opnd_t ctx_stack_pop(ctx_t* ctx, size_t n); x86opnd_t ctx_stack_opnd(ctx_t* ctx, int32_t idx); int ctx_get_top_type(ctx_t* ctx); +int ctx_diff(const ctx_t* src, const ctx_t* dst); block_t* find_block_version(blockid_t blockid, const ctx_t* ctx); block_t* gen_block_version(blockid_t blockid, const ctx_t* ctx); |