summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Patterson <tenderlove@ruby-lang.org>2023-10-26 13:28:25 -0700
committerAaron Patterson <aaron.patterson@gmail.com>2023-10-26 14:49:42 -0700
commitbbf1d621ba05b345a695df554773a6dee6106d50 (patch)
tree3025e60b5192f7443d3e293a1517d5842dadfd7d
parent8e62596e38fc4a9247f306fb81c95ee85a42acbe (diff)
Decrease redblack cache / shape size in debug
When running tests in debug mode, we have tests that try to exhaust the space used for shapes and the redblack cache. However, this can cause Out of Memory issues on some machines, so this commit decreases the cache sizes when RUBY_DEBUG is enabled
-rw-r--r--shape.c16
1 files changed, 15 insertions, 1 deletions
diff --git a/shape.c b/shape.c
index 6e35ea55ee..718d7462a5 100644
--- a/shape.c
+++ b/shape.c
@@ -20,11 +20,17 @@
#endif
#if SIZEOF_SHAPE_T == 4
+#if RUBY_DEBUG
+#define SHAPE_BUFFER_SIZE 0x8000
+#else
#define SHAPE_BUFFER_SIZE 0x80000
+#endif
#else
#define SHAPE_BUFFER_SIZE 0x8000
#endif
+#define REDBLACK_CACHE_SIZE (SHAPE_BUFFER_SIZE * 32)
+
#define SINGLE_CHILD_TAG 0x1
#define TAG_SINGLE_CHILD(x) (struct rb_id_table *)((uintptr_t)x | SINGLE_CHILD_TAG)
#define SINGLE_CHILD_MASK (~((uintptr_t)SINGLE_CHILD_TAG))
@@ -125,6 +131,10 @@ redblack_id_for(redblack_node_t * node)
static redblack_node_t *
redblack_new(char color, ID key, rb_shape_t * value, redblack_node_t * left, redblack_node_t * right)
{
+ if (GET_SHAPE_TREE()->cache_size + 1 >= REDBLACK_CACHE_SIZE) {
+ // We're out of cache, just quit
+ return LEAF;
+ }
redblack_node_t * redblack_nodes = GET_SHAPE_TREE()->shape_cache;
redblack_node_t * node = &redblack_nodes[(GET_SHAPE_TREE()->cache_size)++];
node->key = key;
@@ -1106,7 +1116,7 @@ Init_default_shapes(void)
id_t_object = rb_make_internal_id();
#ifdef HAVE_MMAP
- rb_shape_tree_ptr->shape_cache = (redblack_node_t *)mmap(NULL, rb_size_mul_or_raise(SHAPE_BUFFER_SIZE * 32, sizeof(redblack_node_t), rb_eRuntimeError),
+ rb_shape_tree_ptr->shape_cache = (redblack_node_t *)mmap(NULL, rb_size_mul_or_raise(REDBLACK_CACHE_SIZE, sizeof(redblack_node_t), rb_eRuntimeError),
PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
rb_shape_tree_ptr->cache_size = 0;
#endif
@@ -1189,6 +1199,10 @@ Init_shape(void)
rb_define_const(rb_cShape, "SPECIAL_CONST_SHAPE_ID", INT2NUM(SPECIAL_CONST_SHAPE_ID));
rb_define_const(rb_cShape, "OBJ_TOO_COMPLEX_SHAPE_ID", INT2NUM(OBJ_TOO_COMPLEX_SHAPE_ID));
rb_define_const(rb_cShape, "SHAPE_MAX_VARIATIONS", INT2NUM(SHAPE_MAX_VARIATIONS));
+ rb_define_const(rb_cShape, "SIZEOF_RB_SHAPE_T", INT2NUM(sizeof(rb_shape_t)));
+ rb_define_const(rb_cShape, "SIZEOF_REDBLACK_NODE_T", INT2NUM(sizeof(redblack_node_t)));
+ rb_define_const(rb_cShape, "SHAPE_BUFFER_SIZE", INT2NUM(sizeof(rb_shape_t) * SHAPE_BUFFER_SIZE));
+ rb_define_const(rb_cShape, "REDBLACK_CACHE_SIZE", INT2NUM(sizeof(redblack_node_t) * REDBLACK_CACHE_SIZE));
rb_define_singleton_method(rb_cShape, "transition_tree", shape_transition_tree, 0);
rb_define_singleton_method(rb_cShape, "find_by_id", rb_shape_find_by_id, 1);