From b8f0dc59d52266d9fbfc039e2f4b0f727c62baa0 Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Wed, 23 Feb 2022 16:51:28 +0100 Subject: [PATCH] rb_provide_feature: Prevent $LOADED_FEATURES from being copied [Bug #18599] `vm->loaded_features` and `vm->loaded_features_snapshot` both share the same root. When a feature is pushed into `loaded_features`, the sharing is broken and `loaded_features` is copied. So an application requiring 1000 files, will allocate 1000 arrays of increasing size, which is very wasteful. To avoid this, we first clear the snapshot, so that `loaded_features` can directly be pushed into. Co-Authored-By: Peter Zhu --- load.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/load.c b/load.c index d171e1d92b..c29c32f2dc 100644 --- a/load.c +++ b/load.c @@ -657,6 +657,10 @@ rb_provide_feature(rb_vm_t *vm, VALUE feature) rb_str_freeze(feature); get_loaded_features_index(vm); + // If loaded_features and loaded_features_snapshot share the same backing + // array, pushing into it would cause the whole array to be copied. + // To avoid this we first clear loaded_features_snapshot. + rb_ary_clear(vm->loaded_features_snapshot); rb_ary_push(features, rb_fstring(feature)); features_index_add(vm, feature, INT2FIX(RARRAY_LEN(features)-1)); reset_loaded_features_snapshot(vm);