Skip to content

Commit

Permalink
Revert "Revert "Ruby 3.2 - Speed up rebuilding the loaded feature ind…
Browse files Browse the repository at this point in the history
…ex and realpath cache (ruby#8023)""

This reverts commit 1c76244.
  • Loading branch information
MSP-Greg committed Aug 19, 2023
1 parent 0c908fa commit 5e8d31f
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 6 deletions.
47 changes: 41 additions & 6 deletions load.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,12 @@ get_loaded_features_realpaths(rb_vm_t *vm)
return vm->loaded_features_realpaths;
}

static VALUE
get_loaded_features_realpath_map(rb_vm_t *vm)
{
return vm->loaded_features_realpath_map;
}

static VALUE
get_LOADED_FEATURES(ID _x, VALUE *_y)
{
Expand Down Expand Up @@ -361,7 +367,10 @@ get_loaded_features_index(rb_vm_t *vm)
st_foreach(vm->loaded_features_index, loaded_features_index_clear_i, 0);

VALUE realpaths = vm->loaded_features_realpaths;
VALUE realpath_map = vm->loaded_features_realpath_map;
VALUE previous_realpath_map = rb_hash_dup(realpath_map);
rb_hash_clear(realpaths);
rb_hash_clear(realpath_map);
features = vm->loaded_features;
for (i = 0; i < RARRAY_LEN(features); i++) {
VALUE entry, as_str;
Expand All @@ -378,9 +387,14 @@ get_loaded_features_index(rb_vm_t *vm)
long j = RARRAY_LEN(features);
for (i = 0; i < j; i++) {
VALUE as_str = rb_ary_entry(features, i);
VALUE realpath = rb_check_realpath(Qnil, as_str, NULL);
if (NIL_P(realpath)) realpath = as_str;
rb_hash_aset(realpaths, rb_fstring(realpath), Qtrue);
VALUE realpath = rb_hash_aref(previous_realpath_map, as_str);
if (NIL_P(realpath)) {
realpath = rb_check_realpath(Qnil, as_str, NULL);
if (NIL_P(realpath)) realpath = as_str;
realpath = rb_fstring(realpath);
}
rb_hash_aset(realpaths, realpath, Qtrue);
rb_hash_aset(realpath_map, as_str, realpath);
}
}
return vm->loaded_features_index;
Expand Down Expand Up @@ -675,6 +689,19 @@ rb_provide(const char *feature)

NORETURN(static void load_failed(VALUE));

static inline VALUE
realpath_internal_cached(VALUE hash, VALUE path)
{
VALUE ret = rb_hash_aref(hash, path);
if(RTEST(ret)) {
return ret;
}

VALUE realpath = rb_realpath_internal(Qnil, path, 1);
rb_hash_aset(hash, rb_fstring(path), rb_fstring(realpath));
return realpath;
}

static inline void
load_iseq_eval(rb_execution_context_t *ec, VALUE fname)
{
Expand All @@ -687,8 +714,12 @@ load_iseq_eval(rb_execution_context_t *ec, VALUE fname)
VALUE parser = rb_parser_new();
rb_parser_set_context(parser, NULL, FALSE);
ast = (rb_ast_t *)rb_parser_load_file(parser, fname);

rb_thread_t *th = rb_ec_thread_ptr(ec);
VALUE realpath_map = get_loaded_features_realpath_map(th->vm);

iseq = rb_iseq_new_top(&ast->body, rb_fstring_lit("<top (required)>"),
fname, rb_realpath_internal(Qnil, fname, 1), NULL);
fname, realpath_internal_cached(realpath_map, fname), NULL);
rb_ast_dispose(ast);
rb_vm_pop_frame(ec);
RB_GC_GUARD(v);
Expand Down Expand Up @@ -1161,6 +1192,7 @@ require_internal(rb_execution_context_t *ec, VALUE fname, int exception, bool wa
volatile VALUE saved_path;
volatile VALUE realpath = 0;
VALUE realpaths = get_loaded_features_realpaths(th->vm);
VALUE realpath_map = get_loaded_features_realpath_map(th->vm);
volatile bool reset_ext_config = false;
struct rb_ext_config prev_ext_config;

Expand Down Expand Up @@ -1194,7 +1226,7 @@ require_internal(rb_execution_context_t *ec, VALUE fname, int exception, bool wa
}
#endif
else if (RTEST(rb_hash_aref(realpaths,
realpath = rb_realpath_internal(Qnil, path, 1)))) {
realpath = realpath_internal_cached(realpath_map, path)))) {
result = 0;
}
else {
Expand Down Expand Up @@ -1252,7 +1284,8 @@ require_internal(rb_execution_context_t *ec, VALUE fname, int exception, bool wa
rb_provide_feature(th2->vm, path);
VALUE real = realpath;
if (real) {
rb_hash_aset(realpaths, rb_fstring(real), Qtrue);
real = rb_fstring(real);
rb_hash_aset(realpaths, real, Qtrue);
}
}
ec->errinfo = saved.errinfo;
Expand Down Expand Up @@ -1473,6 +1506,8 @@ Init_load(void)
vm->loaded_features_index = st_init_numtable();
vm->loaded_features_realpaths = rb_hash_new();
rb_obj_hide(vm->loaded_features_realpaths);
vm->loaded_features_realpath_map = rb_hash_new();
rb_obj_hide(vm->loaded_features_realpath_map);

rb_define_global_function("load", rb_f_load, -1);
rb_define_global_function("require", rb_f_require, 1);
Expand Down
2 changes: 2 additions & 0 deletions vm.c
Original file line number Diff line number Diff line change
Expand Up @@ -2703,6 +2703,7 @@ rb_vm_update_references(void *ptr)
vm->loaded_features = rb_gc_location(vm->loaded_features);
vm->loaded_features_snapshot = rb_gc_location(vm->loaded_features_snapshot);
vm->loaded_features_realpaths = rb_gc_location(vm->loaded_features_realpaths);
vm->loaded_features_realpath_map = rb_gc_location(vm->loaded_features_realpath_map);
vm->top_self = rb_gc_location(vm->top_self);
vm->orig_progname = rb_gc_location(vm->orig_progname);

Expand Down Expand Up @@ -2794,6 +2795,7 @@ rb_vm_mark(void *ptr)
rb_gc_mark_movable(vm->loaded_features);
rb_gc_mark_movable(vm->loaded_features_snapshot);
rb_gc_mark_movable(vm->loaded_features_realpaths);
rb_gc_mark_movable(vm->loaded_features_realpath_map);
rb_gc_mark_movable(vm->top_self);
rb_gc_mark_movable(vm->orig_progname);
RUBY_MARK_MOVABLE_UNLESS_NULL(vm->coverages);
Expand Down
1 change: 1 addition & 0 deletions vm_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -680,6 +680,7 @@ typedef struct rb_vm_struct {
VALUE loaded_features;
VALUE loaded_features_snapshot;
VALUE loaded_features_realpaths;
VALUE loaded_features_realpath_map;
struct st_table *loaded_features_index;
struct st_table *loading_table;
#if EXTSTATIC
Expand Down

0 comments on commit 5e8d31f

Please sign in to comment.