Feature #5767 » cache_expanded_load_path.patch
load.c | ||
---|---|---|
return load_path;
|
||
}
|
||
static void rb_check_expanded_cache();
|
||
static int cached_expanded_load_path = 1;
|
||
VALUE
|
||
rb_get_expanded_load_path(void)
|
||
{
|
||
VALUE load_path = rb_get_load_path();
|
||
VALUE ary;
|
||
long i;
|
||
rb_vm_t *vm = GET_VM();
|
||
ary = rb_ary_new2(RARRAY_LEN(load_path));
|
||
for (i = 0; i < RARRAY_LEN(load_path); ++i) {
|
||
VALUE path = rb_file_expand_path(RARRAY_PTR(load_path)[i], Qnil);
|
||
rb_str_freeze(path);
|
||
rb_ary_push(ary, path);
|
||
rb_check_expanded_cache();
|
||
ary = vm->load_path_expanded;
|
||
if ( !RTEST(ary) ) {
|
||
long i;
|
||
ary = rb_ary_new2(RARRAY_LEN(load_path));
|
||
for (i = 0; i < RARRAY_LEN(load_path); ++i) {
|
||
VALUE path = rb_file_expand_path(RARRAY_PTR(load_path)[i], Qnil);
|
||
rb_str_freeze(path);
|
||
rb_ary_push(ary, path);
|
||
}
|
||
if (cached_expanded_load_path) {
|
||
char *curwd = my_getcwd();
|
||
vm->load_path_curwd = rb_str_new_cstr(curwd);
|
||
xfree(curwd);
|
||
vm->load_path_expanded = ary;
|
||
}
|
||
}
|
||
rb_obj_freeze(ary);
|
||
return ary;
|
||
}
|
||
... | ... | |
return rb_mod_autoload_p(klass, sym);
|
||
}
|
||
static const char *load_path_reset_cache_methods[] = {
|
||
"[]=", "collect!", "compact!", "delete",
|
||
"delete_if", "fill", "flatten!", "insert", "keep_if",
|
||
"map!", "reject!", "replace", "select!", "shuffle!",
|
||
"sort!", "sort_by!", "uniq!", NULL
|
||
};
|
||
static const char *load_path_apply_to_cache_methods[] = {
|
||
"clear", "delete_at", "pop", "reverse!", "rotate!",
|
||
"shift", "slice!", NULL
|
||
};
|
||
static const char *load_path_apply_expanded_methods[] = {
|
||
"<<", "push", "unshift", NULL
|
||
};
|
||
static void
|
||
rb_reset_expanded_cache()
|
||
{
|
||
rb_vm_t *vm = GET_VM();
|
||
vm->load_path_curwd = 0;
|
||
vm->load_path_expanded = 0;
|
||
}
|
||
static void
|
||
rb_check_expanded_cache()
|
||
{
|
||
rb_vm_t *vm = GET_VM();
|
||
if (RTEST(vm->load_path_curwd)) {
|
||
char *cwd = my_getcwd();
|
||
if (strcmp(RSTRING_PTR(vm->load_path_curwd), cwd)) {
|
||
rb_reset_expanded_cache();
|
||
}
|
||
xfree(cwd);
|
||
}
|
||
}
|
||
static VALUE
|
||
rb_load_path_reset_cache_method(int argc, VALUE *argv, VALUE self)
|
||
{
|
||
rb_reset_expanded_cache();
|
||
return rb_call_super(argc, argv);
|
||
}
|
||
static VALUE
|
||
rb_load_path_apply_to_cache_method(int argc, VALUE *argv, VALUE self)
|
||
{
|
||
VALUE load_path_expanded;
|
||
RB_GC_GUARD(load_path_expanded) = GET_VM()->load_path_expanded;
|
||
if (RTEST(load_path_expanded)) {
|
||
ID func = rb_frame_this_func();
|
||
rb_funcall2(load_path_expanded, func, argc, argv);
|
||
}
|
||
return rb_call_super(argc, argv);
|
||
}
|
||
static VALUE
|
||
rb_load_path_apply_expanded_method(int argc, VALUE *argv, VALUE self)
|
||
{
|
||
VALUE load_path_expanded;
|
||
rb_check_expanded_cache();
|
||
RB_GC_GUARD(load_path_expanded) = GET_VM()->load_path_expanded;
|
||
if (RTEST(load_path_expanded)) {
|
||
int i;
|
||
ID func = rb_frame_this_func();
|
||
VALUE expanded = rb_ary_new2(argc);
|
||
for(i = 0; i < argc; i++) {
|
||
VALUE path = rb_file_expand_path(argv[i], Qnil);
|
||
rb_str_freeze(path);
|
||
rb_ary_push(expanded, path);
|
||
}
|
||
rb_funcall2(load_path_expanded, func, argc, RARRAY_PTR(expanded));
|
||
}
|
||
return rb_call_super(argc, argv);
|
||
}
|
||
// concat - special
|
||
static VALUE
|
||
rb_load_path_concat(VALUE self, VALUE ary)
|
||
{
|
||
ID push;
|
||
CONST_ID(push, "push");
|
||
RB_GC_GUARD(ary);
|
||
return rb_funcall2(self, push, RARRAY_LEN(ary), RARRAY_PTR(ary));
|
||
}
|
||
static VALUE
|
||
rb_load_path_init(void)
|
||
{
|
||
const char **name;
|
||
VALUE load_path = rb_ary_new();
|
||
char *cached_flag;
|
||
cached_flag = getenv("RUBY_CACHED_LOAD_PATH");
|
||
if (cached_flag != NULL) {
|
||
cached_expanded_load_path = atoi(cached_flag);
|
||
}
|
||
if (cached_expanded_load_path) {
|
||
VALUE load_path_c = rb_singleton_class(load_path);
|
||
for(name = load_path_reset_cache_methods; *name; name++ ) {
|
||
rb_define_method(load_path_c, *name, rb_load_path_reset_cache_method, -1);
|
||
}
|
||
for(name = load_path_apply_to_cache_methods; *name; name++ ) {
|
||
rb_define_method(load_path_c, *name, rb_load_path_apply_to_cache_method, -1);
|
||
}
|
||
for(name = load_path_apply_expanded_methods; *name; name++ ) {
|
||
rb_define_method(load_path_c, *name, rb_load_path_apply_expanded_method, -1);
|
||
}
|
||
rb_define_method(load_path_c, "concat", rb_load_path_concat, 1);
|
||
}
|
||
rb_reset_expanded_cache();
|
||
return load_path;
|
||
}
|
||
void
|
||
Init_load()
|
||
{
|
||
... | ... | |
rb_define_hooked_variable(var_load_path, (VALUE*)vm, load_path_getter, rb_gvar_readonly_setter);
|
||
rb_alias_variable(rb_intern("$-I"), id_load_path);
|
||
rb_alias_variable(rb_intern("$LOAD_PATH"), id_load_path);
|
||
vm->load_path = rb_ary_new();
|
||
vm->load_path = rb_load_path_init();
|
||
rb_define_virtual_variable("$\"", get_loaded_features, 0);
|
||
rb_define_virtual_variable("$LOADED_FEATURES", get_loaded_features, 0);
|
vm.c | ||
---|---|---|
RUBY_MARK_UNLESS_NULL(vm->thgroup_default);
|
||
RUBY_MARK_UNLESS_NULL(vm->mark_object_ary);
|
||
RUBY_MARK_UNLESS_NULL(vm->load_path);
|
||
RUBY_MARK_UNLESS_NULL(vm->load_path_expanded);
|
||
RUBY_MARK_UNLESS_NULL(vm->load_path_curwd);
|
||
RUBY_MARK_UNLESS_NULL(vm->loaded_features);
|
||
RUBY_MARK_UNLESS_NULL(vm->top_self);
|
||
RUBY_MARK_UNLESS_NULL(vm->coverages);
|
vm_core.h | ||
---|---|---|
/* load */
|
||
VALUE top_self;
|
||
VALUE load_path;
|
||
VALUE load_path_expanded;
|
||
VALUE load_path_curwd;
|
||
VALUE loaded_features;
|
||
struct st_table *loading_table;
|
||