From 86df08dac6fc4642a6bac7bab6ccd5f44b7a293c Mon Sep 17 00:00:00 2001 From: luislavena Date: Fri, 24 Aug 2012 03:44:56 +0000 Subject: Improve require/File.expand_path performance on Windows * configure.in (mingw): add shlwapi to the list of dependency libs for Windows. * win32/Makefile.sub (EXTSOLIBS): ditto. * internal.h: declare internal functions rb_w32_init_file, rb_file_expand_path_internal and rb_file_expand_path_fast. * file.c (Init_File): invoke Windows initialization rb_w32_init_file * win32/file.c (rb_file_load_path_internal): new function. Windows-specific implementation that replaces file_expand_path. [Bug #6836][ruby-core:46996] * win32/file.c (rb_w32_init_file): new function. Initialize codepage cache for faster conversion encodings lookup. * file.c (file_expand_path): rename to rb_file_expand_path_internal. Conditionally exclude from Windows. * file.c (rb_file_expand_path_fast): new function. delegates to rb_file_expand_path_internal without performing a hit to the filesystem. * file.c (file_expand_path_1): use rb_file_expand_path_internal without path expansion (used by require). * file.c (rb_find_file_ext_safe): ditto. * file.c (rb_find_file_safe): ditto. * load.c (rb_get_expanded_load_path): use rb_file_expand_path_fast. * load.c (rb_feature_provided): ditto. * file.c (rb_file_expand_path): use rb_file_expand_path_internal with path expansion. * file.c (rb_file_absolute_path): ditto. * test/ruby/test_file_exhaustive.rb: new tests to exercise rb_file_expand_path_internal implementation and compliance with existing behaviors. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36811 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- file.c | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) (limited to 'file.c') diff --git a/file.c b/file.c index 24aa1115fe..8c63f56d01 100644 --- a/file.c +++ b/file.c @@ -2882,8 +2882,9 @@ append_fspath(VALUE result, VALUE fname, char *dir, rb_encoding **enc, rb_encodi return buf + dirlen; } -static VALUE -file_expand_path(VALUE fname, VALUE dname, int abs_mode, VALUE result) +#ifndef _WIN32 +VALUE +rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_name, VALUE result) { const char *s, *b, *fend; char *buf, *p, *pend, *root; @@ -2945,7 +2946,7 @@ file_expand_path(VALUE fname, VALUE dname, int abs_mode, VALUE result) /* specified drive, but not full path */ int same = 0; if (!NIL_P(dname) && !not_same_drive(dname, s[0])) { - file_expand_path(dname, Qnil, abs_mode, result); + rb_file_expand_path_internal(dname, Qnil, abs_mode, long_name, result); BUFINIT(); if (has_drive_letter(p) && TOLOWER(p[0]) == TOLOWER(s[0])) { /* ok, same drive */ @@ -2969,7 +2970,7 @@ file_expand_path(VALUE fname, VALUE dname, int abs_mode, VALUE result) #endif else if (!rb_is_absolute_path(s)) { if (!NIL_P(dname)) { - file_expand_path(dname, Qnil, abs_mode, result); + rb_file_expand_path_internal(dname, Qnil, abs_mode, long_name, result); rb_enc_associate(result, rb_enc_check(result, fname)); BUFINIT(); p = pend; @@ -3222,6 +3223,7 @@ file_expand_path(VALUE fname, VALUE dname, int abs_mode, VALUE result) ENC_CODERANGE_CLEAR(result); return result; } +#endif /* _WIN32 */ #define EXPAND_PATH_BUFFER() rb_usascii_str_new(0, MAXPATHLEN + 2) @@ -3232,14 +3234,21 @@ file_expand_path(VALUE fname, VALUE dname, int abs_mode, VALUE result) static VALUE file_expand_path_1(VALUE fname) { - return file_expand_path(fname, Qnil, 0, EXPAND_PATH_BUFFER()); + return rb_file_expand_path_internal(fname, Qnil, 0, 0, EXPAND_PATH_BUFFER()); } VALUE rb_file_expand_path(VALUE fname, VALUE dname) { check_expand_path_args(fname, dname); - return file_expand_path(fname, dname, 0, EXPAND_PATH_BUFFER()); + return rb_file_expand_path_internal(fname, dname, 0, 1, EXPAND_PATH_BUFFER()); +} + +VALUE +rb_file_expand_path_fast(VALUE fname, VALUE dname) +{ + check_expand_path_args(fname, dname); + return rb_file_expand_path_internal(fname, dname, 0, 0, EXPAND_PATH_BUFFER()); } /* @@ -3276,7 +3285,7 @@ VALUE rb_file_absolute_path(VALUE fname, VALUE dname) { check_expand_path_args(fname, dname); - return file_expand_path(fname, dname, 1, EXPAND_PATH_BUFFER()); + return rb_file_expand_path_internal(fname, dname, 1, 1, EXPAND_PATH_BUFFER()); } /* @@ -5251,7 +5260,7 @@ rb_find_file_ext_safe(VALUE *filep, const char *const *ext, int safe_level) RB_GC_GUARD(str) = rb_get_path_check(str, safe_level); if (RSTRING_LEN(str) == 0) continue; - file_expand_path(fname, str, 0, tmp); + rb_file_expand_path_internal(fname, str, 0, 0, tmp); if (rb_file_load_ok(RSTRING_PTR(tmp))) { *filep = copy_path_class(tmp, *filep); return (int)(j+1); @@ -5311,7 +5320,7 @@ rb_find_file_safe(VALUE path, int safe_level) VALUE str = RARRAY_PTR(load_path)[i]; RB_GC_GUARD(str) = rb_get_path_check(str, safe_level); if (RSTRING_LEN(str) > 0) { - file_expand_path(path, str, 0, tmp); + rb_file_expand_path_internal(path, str, 0, 0, tmp); f = RSTRING_PTR(tmp); if (rb_file_load_ok(f)) goto found; } @@ -5546,4 +5555,8 @@ Init_File(void) rb_define_method(rb_cStat, "setuid?", rb_stat_suid, 0); rb_define_method(rb_cStat, "setgid?", rb_stat_sgid, 0); rb_define_method(rb_cStat, "sticky?", rb_stat_sticky, 0); + +#ifdef _WIN32 + rb_w32_init_file(); +#endif } -- cgit v1.2.3