From abff5f62037284024aaf469fc46a6e8de98fa1e3 Mon Sep 17 00:00:00 2001 From: Peter Zhu Date: Wed, 11 Jan 2023 09:23:03 -0500 Subject: Move classpath to rb_classext_t This commit moves the classpath (and tmp_classpath) from instance variables to the rb_classext_t. This improves performance as we no longer need to set an instance variable when assigning a classpath to a class. I benchmarked with the following script: ```ruby name = :MyClass puts(Benchmark.measure do 10_000_000.times do |i| Object.const_set(name, Class.new) Object.send(:remove_const, name) end end) ``` Before this patch: ``` 5.440119 0.025264 5.465383 ( 5.467105) ``` After this patch: ``` 4.889646 0.028325 4.917971 ( 4.942678) ``` --- internal/class.h | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'internal/class.h') diff --git a/internal/class.h b/internal/class.h index 2af1a52666..92e018f759 100644 --- a/internal/class.h +++ b/internal/class.h @@ -59,6 +59,8 @@ struct rb_classext_struct { #endif uint32_t max_iv_count; unsigned char variation_count; + bool permanent_classpath; + VALUE classpath; }; typedef struct rb_classext_struct rb_classext_t; @@ -73,8 +75,10 @@ struct RClass { #endif }; -typedef struct rb_subclass_entry rb_subclass_entry_t; -typedef struct rb_classext_struct rb_classext_t; +#if RCLASS_EXT_EMBEDDED +// Assert that classes can be embedded in size_pools[2] (which has 160B slot size) +STATIC_ASSERT(sizeof_rb_classext_t, sizeof(struct RClass) + sizeof(rb_classext_t) <= 4 * RVALUE_SIZE); +#endif #if RCLASS_EXT_EMBEDDED # define RCLASS_EXT(c) ((rb_classext_t *)((char *)(c) + sizeof(struct RClass))) @@ -184,4 +188,14 @@ RCLASS_SET_SUPER(VALUE klass, VALUE super) return super; } +static inline void +RCLASS_SET_CLASSPATH(VALUE klass, VALUE classpath, bool permanent) +{ + assert(BUILTIN_TYPE(klass) == T_CLASS || BUILTIN_TYPE(klass) == T_MODULE); + assert(classpath == 0 || BUILTIN_TYPE(classpath) == T_STRING); + + RB_OBJ_WRITE(klass, &(RCLASS_EXT(klass)->classpath), classpath); + RCLASS_EXT(klass)->permanent_classpath = permanent; +} + #endif /* INTERNAL_CLASS_H */ -- cgit v1.2.1