summaryrefslogtreecommitdiff
path: root/internal/class.h
diff options
context:
space:
mode:
authorPeter Zhu <peter@peterzhu.ca>2023-01-11 09:23:03 -0500
committerPeter Zhu <peter@peterzhu.ca>2023-01-11 11:06:58 -0500
commitabff5f62037284024aaf469fc46a6e8de98fa1e3 (patch)
tree47347d74b361020233615449e9c508b82afaccdc /internal/class.h
parentd86833e717104b477c32e135a15fcbf380c6abb2 (diff)
downloadruby-abff5f62037284024aaf469fc46a6e8de98fa1e3.tar.gz
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) ```
Diffstat (limited to 'internal/class.h')
-rw-r--r--internal/class.h18
1 files changed, 16 insertions, 2 deletions
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 */