cache_expanded_load_path.patch

Yura Sokolov, 12/15/2011 06:18 PM

Download (5.67 KB)

View differences:

load.c
34 34
    return load_path;
35 35
}
36 36

  
37
static void rb_check_expanded_cache();
38
static int cached_expanded_load_path = 1;
39

  
37 40
VALUE
38 41
rb_get_expanded_load_path(void)
39 42
{
40 43
    VALUE load_path = rb_get_load_path();
41 44
    VALUE ary;
42
    long i;
45
    rb_vm_t *vm = GET_VM();
43 46

  
44
    ary = rb_ary_new2(RARRAY_LEN(load_path));
45
    for (i = 0; i < RARRAY_LEN(load_path); ++i) {
46
	VALUE path = rb_file_expand_path(RARRAY_PTR(load_path)[i], Qnil);
47
	rb_str_freeze(path);
48
	rb_ary_push(ary, path);
47
    rb_check_expanded_cache();
48
    ary = vm->load_path_expanded;
49

  
50
    if ( !RTEST(ary) ) {
51
	long i;
52

  
53
	ary = rb_ary_new2(RARRAY_LEN(load_path));
54
	for (i = 0; i < RARRAY_LEN(load_path); ++i) {
55
	    VALUE path = rb_file_expand_path(RARRAY_PTR(load_path)[i], Qnil);
56
	    rb_str_freeze(path);
57
	    rb_ary_push(ary, path);
58
	}
59
	if (cached_expanded_load_path) {
60
	    char *curwd = my_getcwd();
61
	    vm->load_path_curwd = rb_str_new_cstr(curwd);
62
	    xfree(curwd);
63
	    vm->load_path_expanded = ary;
64
	}
49 65
    }
50
    rb_obj_freeze(ary);
51 66
    return ary;
52 67
}
53 68

  
......
772 787
    return rb_mod_autoload_p(klass, sym);
773 788
}
774 789

  
790
static const char *load_path_reset_cache_methods[] = {
791
    "[]=", "collect!", "compact!", "delete",
792
    "delete_if", "fill", "flatten!", "insert", "keep_if",
793
    "map!", "reject!", "replace", "select!", "shuffle!",
794
    "sort!", "sort_by!", "uniq!", NULL
795
};
796

  
797
static const char *load_path_apply_to_cache_methods[] = {
798
    "clear", "delete_at", "pop", "reverse!", "rotate!",
799
    "shift", "slice!", NULL
800
};
801

  
802
static const char *load_path_apply_expanded_methods[] = {
803
    "<<", "push", "unshift", NULL
804
};
805

  
806
static void
807
rb_reset_expanded_cache()
808
{
809
    rb_vm_t *vm = GET_VM();
810
    vm->load_path_curwd = 0;
811
    vm->load_path_expanded = 0;
812
}
813

  
814
static void
815
rb_check_expanded_cache()
816
{
817
    rb_vm_t *vm = GET_VM();
818
    if (RTEST(vm->load_path_curwd)) {
819
	char *cwd = my_getcwd();
820
	if (strcmp(RSTRING_PTR(vm->load_path_curwd), cwd)) {
821
	    rb_reset_expanded_cache();
822
	}
823
	xfree(cwd);
824
    }
825
}
826

  
827
static VALUE
828
rb_load_path_reset_cache_method(int argc, VALUE *argv, VALUE self)
829
{
830
    rb_reset_expanded_cache();
831
    return rb_call_super(argc, argv);
832
}
833

  
834
static VALUE
835
rb_load_path_apply_to_cache_method(int argc, VALUE *argv, VALUE self)
836
{
837
    VALUE load_path_expanded;
838
    RB_GC_GUARD(load_path_expanded) = GET_VM()->load_path_expanded;
839
    if (RTEST(load_path_expanded)) {
840
	ID func = rb_frame_this_func();
841
	rb_funcall2(load_path_expanded, func, argc, argv);
842
    }
843
    return rb_call_super(argc, argv);
844
}
845

  
846
static VALUE
847
rb_load_path_apply_expanded_method(int argc, VALUE *argv, VALUE self)
848
{
849
    VALUE load_path_expanded;
850
    rb_check_expanded_cache();
851
    RB_GC_GUARD(load_path_expanded) = GET_VM()->load_path_expanded;
852
    if (RTEST(load_path_expanded)) {
853
	int i;
854
	ID func = rb_frame_this_func();
855
	VALUE expanded = rb_ary_new2(argc);
856
	for(i = 0; i < argc; i++) {
857
	    VALUE path = rb_file_expand_path(argv[i], Qnil);
858
	    rb_str_freeze(path);
859
	    rb_ary_push(expanded, path);
860
	}
861
	rb_funcall2(load_path_expanded, func, argc, RARRAY_PTR(expanded));
862
    }
863
    return rb_call_super(argc, argv);
864
}
865
// concat - special
866
static VALUE
867
rb_load_path_concat(VALUE self, VALUE ary)
868
{
869
    ID push;
870
    CONST_ID(push, "push");
871
    RB_GC_GUARD(ary);
872
    return rb_funcall2(self, push, RARRAY_LEN(ary), RARRAY_PTR(ary));
873
}
874

  
875
static VALUE
876
rb_load_path_init(void)
877
{
878
    const char **name;
879
    VALUE load_path = rb_ary_new();
880
    char *cached_flag;
881

  
882
    cached_flag = getenv("RUBY_CACHED_LOAD_PATH");
883
    if (cached_flag != NULL) {
884
	cached_expanded_load_path = atoi(cached_flag);
885
    }
886

  
887

  
888
    if (cached_expanded_load_path) {
889
	VALUE load_path_c = rb_singleton_class(load_path);
890

  
891
	for(name = load_path_reset_cache_methods; *name; name++ ) {
892
	    rb_define_method(load_path_c, *name, rb_load_path_reset_cache_method, -1);
893
	}
894

  
895
	for(name = load_path_apply_to_cache_methods; *name; name++ ) {
896
	    rb_define_method(load_path_c, *name, rb_load_path_apply_to_cache_method, -1);
897
	}
898

  
899
	for(name = load_path_apply_expanded_methods; *name; name++ ) {
900
	    rb_define_method(load_path_c, *name, rb_load_path_apply_expanded_method, -1);
901
	}
902

  
903
	rb_define_method(load_path_c, "concat", rb_load_path_concat, 1);
904
    }
905

  
906
    rb_reset_expanded_cache();
907

  
908
    return load_path;
909
}
910

  
775 911
void
776 912
Init_load()
777 913
{
......
784 920
    rb_define_hooked_variable(var_load_path, (VALUE*)vm, load_path_getter, rb_gvar_readonly_setter);
785 921
    rb_alias_variable(rb_intern("$-I"), id_load_path);
786 922
    rb_alias_variable(rb_intern("$LOAD_PATH"), id_load_path);
787
    vm->load_path = rb_ary_new();
923
    vm->load_path = rb_load_path_init();
788 924

  
789 925
    rb_define_virtual_variable("$\"", get_loaded_features, 0);
790 926
    rb_define_virtual_variable("$LOADED_FEATURES", get_loaded_features, 0);
vm.c
1570 1570
	RUBY_MARK_UNLESS_NULL(vm->thgroup_default);
1571 1571
	RUBY_MARK_UNLESS_NULL(vm->mark_object_ary);
1572 1572
	RUBY_MARK_UNLESS_NULL(vm->load_path);
1573
	RUBY_MARK_UNLESS_NULL(vm->load_path_expanded);
1574
	RUBY_MARK_UNLESS_NULL(vm->load_path_curwd);
1573 1575
	RUBY_MARK_UNLESS_NULL(vm->loaded_features);
1574 1576
	RUBY_MARK_UNLESS_NULL(vm->top_self);
1575 1577
	RUBY_MARK_UNLESS_NULL(vm->coverages);
vm_core.h
298 298
    /* load */
299 299
    VALUE top_self;
300 300
    VALUE load_path;
301
    VALUE load_path_expanded;
302
    VALUE load_path_curwd;
303

  
301 304
    VALUE loaded_features;
302 305
    struct st_table *loading_table;
303 306