diff options
author | Jean Boussier <jean.boussier@gmail.com> | 2022-02-23 16:51:28 +0100 |
---|---|---|
committer | Jean Boussier <jean.boussier@gmail.com> | 2022-02-23 16:58:48 +0100 |
commit | b8f0dc59d52266d9fbfc039e2f4b0f727c62baa0 (patch) | |
tree | b0e58ad641ebdb7d7bd8984d9ae7e2014a998210 /load.c | |
parent | 651b2e59598427edd0ec3ceb3a0a49b5e106a145 (diff) |
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 <peter.zhu@shopify.com>
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/5593
Diffstat (limited to 'load.c')
-rw-r--r-- | load.c | 4 |
1 files changed, 4 insertions, 0 deletions
@@ -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); |