Add Ruby 3.2.0 images

This will be used to see how much effort it would be to
jump to Ruby 3.2.0 and to see what performance improvements
we might see with YJIT.
This commit is contained in:
Stan Hu 2023-01-18 13:24:58 -08:00
parent 5cc90b8ba2
commit bc3223ac21
No known key found for this signature in database
GPG key ID: 8D3931AD39CC7A20
3 changed files with 190 additions and 0 deletions

View file

@ -0,0 +1,160 @@
diff --git a/gc.c b/gc.c
index 0fccc17a32..49a4cc21b6 100644
--- a/gc.c
+++ b/gc.c
@@ -2541,6 +2541,13 @@ newobj_init(VALUE klass, VALUE flags, int wb_protected, rb_objspace_t *objspace,
// TODO: make it atomic, or ractor local
objspace->total_allocated_objects++;
+#if THREAD_TRACE_MEMORY_ALLOCATIONS
+ rb_thread_t *th = ruby_threadptr_for_trace_memory_allocations();
+ if (th) {
+ ATOMIC_SIZE_INC(th->memory_allocations.total_allocated_objects);
+ }
+#endif
+
#if RGENGC_PROFILE
if (wb_protected) {
objspace->profile.total_generated_normal_object_count++;
@@ -12127,6 +12134,19 @@ objspace_malloc_increase_body(rb_objspace_t *objspace, void *mem, size_t new_siz
#endif
}
+#if THREAD_TRACE_MEMORY_ALLOCATIONS
+ rb_thread_t *th = ruby_threadptr_for_trace_memory_allocations();
+ if (th) {
+ if (new_size > old_size) {
+ ATOMIC_SIZE_ADD(th->memory_allocations.total_malloc_bytes, new_size - old_size);
+ }
+
+ if (type == MEMOP_TYPE_MALLOC) {
+ ATOMIC_SIZE_INC(th->memory_allocations.total_mallocs);
+ }
+ }
+#endif
+
if (type == MEMOP_TYPE_MALLOC) {
retry:
if (malloc_increase > malloc_limit && ruby_native_thread_p() && !dont_gc_val()) {
diff --git a/thread.c b/thread.c
index 56a5644552..176509e1be 100644
--- a/thread.c
+++ b/thread.c
@@ -5289,6 +5289,55 @@ Init_Thread_Mutex(void)
rb_native_mutex_initialize(&th->interrupt_lock);
}
+#if THREAD_TRACE_MEMORY_ALLOCATIONS
+rb_thread_t *
+ruby_threadptr_for_trace_memory_allocations(void)
+{
+ // The order of this checks is important due
+ // to how Ruby VM is initialized
+ if (GET_VM()->thread_trace_memory_allocations && GET_EC() != NULL) {
+ return GET_THREAD();
+ }
+
+ return NULL;
+}
+
+static VALUE
+rb_thread_s_trace_memory_allocations(VALUE _)
+{
+ return GET_THREAD()->vm->thread_trace_memory_allocations ? Qtrue : Qfalse;
+}
+
+static VALUE
+rb_thread_s_trace_memory_allocations_set(VALUE self, VALUE val)
+{
+ GET_THREAD()->vm->thread_trace_memory_allocations = RTEST(val);
+ return val;
+}
+
+static VALUE
+rb_thread_memory_allocations(VALUE self)
+{
+ rb_thread_t *th = rb_thread_ptr(self);
+
+ if (!th->vm->thread_trace_memory_allocations) {
+ return Qnil;
+ }
+
+ VALUE ret = rb_hash_new();
+
+ VALUE total_allocated_objects = ID2SYM(rb_intern_const("total_allocated_objects"));
+ VALUE total_malloc_bytes = ID2SYM(rb_intern_const("total_malloc_bytes"));
+ VALUE total_mallocs = ID2SYM(rb_intern_const("total_mallocs"));
+
+ rb_hash_aset(ret, total_allocated_objects, SIZET2NUM(th->memory_allocations.total_allocated_objects));
+ rb_hash_aset(ret, total_malloc_bytes, SIZET2NUM(th->memory_allocations.total_malloc_bytes));
+ rb_hash_aset(ret, total_mallocs, SIZET2NUM(th->memory_allocations.total_mallocs));
+
+ return ret;
+}
+#endif
+
/*
* Document-class: ThreadError
*
@@ -5371,6 +5420,12 @@ Init_Thread(void)
rb_define_method(rb_cThread, "to_s", rb_thread_to_s, 0);
rb_define_alias(rb_cThread, "inspect", "to_s");
+#if THREAD_TRACE_MEMORY_ALLOCATIONS
+ rb_define_singleton_method(rb_cThread, "trace_memory_allocations", rb_thread_s_trace_memory_allocations, 0);
+ rb_define_singleton_method(rb_cThread, "trace_memory_allocations=", rb_thread_s_trace_memory_allocations_set, 1);
+ rb_define_method(rb_cThread, "memory_allocations", rb_thread_memory_allocations, 0);
+#endif
+
rb_vm_register_special_exception(ruby_error_stream_closed, rb_eIOError,
"stream closed in another thread");
diff --git a/vm_core.h b/vm_core.h
index 4f6e07d818..893b578cc8 100644
--- a/vm_core.h
+++ b/vm_core.h
@@ -114,6 +114,13 @@ extern int ruby_assert_critical_section_entered;
# define VM_INSN_INFO_TABLE_IMPL 2
#endif
+/*
+ * track a per thread memory allocations
+ */
+#ifndef THREAD_TRACE_MEMORY_ALLOCATIONS
+# define THREAD_TRACE_MEMORY_ALLOCATIONS 1
+#endif
+
#if defined(NSIG_MAX) /* POSIX issue 8 */
# undef NSIG
# define NSIG NSIG_MAX
@@ -661,6 +668,7 @@ typedef struct rb_vm_struct {
unsigned int thread_abort_on_exception: 1;
unsigned int thread_report_on_exception: 1;
unsigned int thread_ignore_deadlock: 1;
+ unsigned int thread_trace_memory_allocations: 1;
/* object management */
VALUE mark_object_ary;
@@ -1040,6 +1048,14 @@ typedef struct rb_thread_struct {
struct rb_waiting_list *join_list;
+#if THREAD_TRACE_MEMORY_ALLOCATIONS
+ struct {
+ size_t total_allocated_objects;
+ size_t total_malloc_bytes;
+ size_t total_mallocs;
+ } memory_allocations;
+#endif
+
union {
struct {
VALUE proc;
@@ -1967,6 +1983,7 @@ void rb_threadptr_interrupt(rb_thread_t *th);
void rb_threadptr_unlock_all_locking_mutexes(rb_thread_t *th);
void rb_threadptr_pending_interrupt_clear(rb_thread_t *th);
void rb_threadptr_pending_interrupt_enque(rb_thread_t *th, VALUE v);
+rb_thread_t *ruby_threadptr_for_trace_memory_allocations(void);
VALUE rb_ec_get_errinfo(const rb_execution_context_t *ec);
void rb_ec_error_print(rb_execution_context_t * volatile ec, volatile VALUE errinfo);
void rb_execution_context_update(rb_execution_context_t *ec);