Skip to content

Instantly share code, notes, and snippets.

@alpaca-tc
Created March 31, 2025 04:25
Show Gist options
  • Save alpaca-tc/cc0939189c383b8481fd1ed1319437c9 to your computer and use it in GitHub Desktop.
Save alpaca-tc/cc0939189c383b8481fd1ed1319437c9 to your computer and use it in GitHub Desktop.
testing optimized_refine.patch for 3.3.7
diff --git a/vm.c b/vm.c
index a0fe0104b0..9e733f638d 100644
--- a/vm.c
+++ b/vm.c
@@ -2877,6 +2877,13 @@ rb_vm_each_stack_value(void *ptr, void (*cb)(VALUE, void*), void *ctx)
}
}
+static enum rb_id_table_iterator_result
+vm_mark_refined_cc(VALUE val, void *dmy)
+{
+ rb_gc_mark(val);
+ return ID_TABLE_CONTINUE;
+}
+
static enum rb_id_table_iterator_result
vm_mark_negative_cme(VALUE val, void *dmy)
{
@@ -2943,6 +2950,7 @@ rb_vm_mark(void *ptr)
rb_gc_mark_values(RUBY_NSIG, vm->trap_list.cmd);
rb_id_table_foreach_values(vm->negative_cme_table, vm_mark_negative_cme, NULL);
+ rb_id_table_foreach_values(vm->refined_cc_table, vm_mark_refined_cc, NULL);
rb_mark_tbl_no_pin(vm->overloaded_cme_table);
for (i=0; i<VM_GLOBAL_CC_CACHE_TABLE_SIZE; i++) {
const struct rb_callcache *cc = vm->global_cc_cache_table[i];
@@ -3017,6 +3025,7 @@ ruby_vm_destruct(rb_vm_t *vm)
rb_free_loaded_features_index(vm);
rb_id_table_free(vm->negative_cme_table);
+ rb_id_table_free(vm->refined_cc_table);
st_free_table(vm->overloaded_cme_table);
rb_id_table_free(RCLASS(rb_mRubyVMFrozenCore)->m_tbl);
@@ -3154,6 +3163,7 @@ vm_memsize(const void *ptr)
rb_st_memsize(vm->frozen_strings) +
vm_memsize_builtin_function_table(vm->builtin_function_table) +
rb_id_table_memsize(vm->negative_cme_table) +
+ rb_id_table_memsize(vm->refined_cc_table) +
rb_st_memsize(vm->overloaded_cme_table) +
vm_memsize_constant_cache() +
GET_SHAPE_TREE()->cache_size * sizeof(redblack_node_t)
@@ -4197,6 +4207,7 @@ Init_BareVM(void)
ruby_current_vm_ptr = vm;
vm->objspace = rb_objspace_alloc();
vm->negative_cme_table = rb_id_table_create(16);
+ vm->refined_cc_table = rb_id_table_create(16);
vm->overloaded_cme_table = st_init_numtable();
vm->constant_cache = rb_id_table_create(0);
diff --git a/vm_core.h b/vm_core.h
index 30bfb8404a..fc2e61ac29 100644
--- a/vm_core.h
+++ b/vm_core.h
@@ -752,6 +752,7 @@ typedef struct rb_vm_struct {
st_table *ci_table;
struct rb_id_table *negative_cme_table;
+ struct rb_id_table *refined_cc_table;
st_table *overloaded_cme_table; // cme -> overloaded_cme
// This id table contains a mapping from ID to ICs. It does this with ID
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index 7284769854..0427b05980 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -4241,6 +4241,15 @@ vm_call_refined(rb_execution_context_t *ec, rb_control_frame_t *cfp, struct rb_c
if (calling->cd->cc) {
const struct rb_callcache *cc = calling->cc = vm_cc_new(vm_cc_cme(calling->cc)->defined_class, ref_cme, vm_call_general, cc_type_refinement);
RB_OBJ_WRITE(cfp->iseq, &calling->cd->cc, cc);
+
+ rb_vm_t *vm = GET_VM();
+ VALUE cc_key = (VALUE)cc;
+ VALUE existing;
+
+ if (!rb_id_table_lookup(vm->refined_cc_table, cc_key, &existing)) {
+ rb_id_table_insert(vm->refined_cc_table, cc_key, (VALUE)cc);
+ }
+
return vm_call_method(ec, cfp, calling);
}
else {
diff --git a/vm_method.c b/vm_method.c
index 7b57b56cd6..5a785089f5 100644
--- a/vm_method.c
+++ b/vm_method.c
@@ -451,10 +451,36 @@ rb_vm_ci_free(const struct rb_callinfo *ci)
RB_VM_LOCK_LEAVE();
}
+static enum rb_id_table_iterator_result
+invalidate_refinement_cc(VALUE v, void *dmy)
+{
+ void *ptr = asan_poisoned_object_p(v);
+ asan_unpoison_object(v, false);
+
+ if (RBASIC(v)->flags) { // liveness check
+ const struct rb_callcache *cc = (const struct rb_callcache *)v;
+
+ VM_ASSERT(imemo_type_p(v, imemo_callcache));
+ VM_ASSERT(vm_cc_refinement_p(cc));
+
+ if (cc->klass) {
+ vm_cc_invalidate(cc);
+ }
+ }
+
+ if (ptr) {
+ asan_poison_object(v);
+ }
+
+ return ID_TABLE_CONTINUE;
+}
+
void
rb_clear_all_refinement_method_cache(void)
{
- rb_objspace_each_objects(invalidate_all_refinement_cc, NULL);
+ rb_vm_t *vm = GET_VM();
+ rb_id_table_foreach_values(vm->refined_cc_table, invalidate_refinement_cc, 0);
+ rb_id_table_clear(vm->refined_cc_table);
rb_yjit_invalidate_all_method_lookup_assumptions();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment