diff options
| author | Dmitry Antipov | 2014-09-01 20:05:43 +0400 |
|---|---|---|
| committer | Dmitry Antipov | 2014-09-01 20:05:43 +0400 |
| commit | 50e9e580077869b2f2ced5916299bade6b4f4efd (patch) | |
| tree | 911756b76f580c119c080770ff895e6955f0be95 /src | |
| parent | 203fb3639ace0e05284d9be5aa5c3d63701f33a4 (diff) | |
| download | emacs-50e9e580077869b2f2ced5916299bade6b4f4efd.tar.gz emacs-50e9e580077869b2f2ced5916299bade6b4f4efd.zip | |
Avoid extra calls to strlen in filesystem I/O routines.
* fileio.c (Fexpand_file_name): Avoid calls to strlen if
the length of 'newdir' is known or may be precalculated.
(file_accessible_directory_p): Prefer to pass Lisp_Object,
not 'char *', and so use precalculated length.
(Ffile_accessible_directory_p):
* callproc.c (encode_current_directory, init_callproc):
* charset.c (init_charset):
* lread.c (load_path_check, load_path_default): Adjust users.
* lisp.h (file_accessible_directory_p): Tweak prototype.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 13 | ||||
| -rw-r--r-- | src/callproc.c | 6 | ||||
| -rw-r--r-- | src/charset.c | 2 | ||||
| -rw-r--r-- | src/fileio.c | 48 | ||||
| -rw-r--r-- | src/lisp.h | 2 | ||||
| -rw-r--r-- | src/lread.c | 2 |
6 files changed, 51 insertions, 22 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 02435801d69..a5ec9c35efa 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,16 @@ | |||
| 1 | 2014-09-01 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 2 | |||
| 3 | Avoid extra calls to strlen in filesystem I/O routines. | ||
| 4 | * fileio.c (Fexpand_file_name): Avoid calls to strlen if | ||
| 5 | the length of 'newdir' is known or may be precalculated. | ||
| 6 | (file_accessible_directory_p): Prefer to pass Lisp_Object, | ||
| 7 | not 'char *', and so use precalculated length. | ||
| 8 | (Ffile_accessible_directory_p): | ||
| 9 | * callproc.c (encode_current_directory, init_callproc): | ||
| 10 | * charset.c (init_charset): | ||
| 11 | * lread.c (load_path_check, load_path_default): Adjust users. | ||
| 12 | * lisp.h (file_accessible_directory_p): Tweak prototype. | ||
| 13 | |||
| 1 | 2014-09-01 Eli Zaretskii <eliz@gnu.org> | 14 | 2014-09-01 Eli Zaretskii <eliz@gnu.org> |
| 2 | 15 | ||
| 3 | * w32proc.c (w32_compare_strings): Support "C" and "POSIX" | 16 | * w32proc.c (w32_compare_strings): Support "C" and "POSIX" |
diff --git a/src/callproc.c b/src/callproc.c index 2f68ea6f328..01008312155 100644 --- a/src/callproc.c +++ b/src/callproc.c | |||
| @@ -129,7 +129,7 @@ encode_current_directory (void) | |||
| 129 | 129 | ||
| 130 | if (STRING_MULTIBYTE (dir)) | 130 | if (STRING_MULTIBYTE (dir)) |
| 131 | dir = ENCODE_FILE (dir); | 131 | dir = ENCODE_FILE (dir); |
| 132 | if (! file_accessible_directory_p (SSDATA (dir))) | 132 | if (! file_accessible_directory_p (dir)) |
| 133 | report_file_error ("Setting current directory", | 133 | report_file_error ("Setting current directory", |
| 134 | BVAR (current_buffer, directory)); | 134 | BVAR (current_buffer, directory)); |
| 135 | 135 | ||
| @@ -1625,12 +1625,12 @@ init_callproc (void) | |||
| 1625 | #endif | 1625 | #endif |
| 1626 | { | 1626 | { |
| 1627 | tempdir = Fdirectory_file_name (Vexec_directory); | 1627 | tempdir = Fdirectory_file_name (Vexec_directory); |
| 1628 | if (! file_accessible_directory_p (SSDATA (tempdir))) | 1628 | if (! file_accessible_directory_p (tempdir)) |
| 1629 | dir_warning ("arch-dependent data dir", Vexec_directory); | 1629 | dir_warning ("arch-dependent data dir", Vexec_directory); |
| 1630 | } | 1630 | } |
| 1631 | 1631 | ||
| 1632 | tempdir = Fdirectory_file_name (Vdata_directory); | 1632 | tempdir = Fdirectory_file_name (Vdata_directory); |
| 1633 | if (! file_accessible_directory_p (SSDATA (tempdir))) | 1633 | if (! file_accessible_directory_p (tempdir)) |
| 1634 | dir_warning ("arch-independent data dir", Vdata_directory); | 1634 | dir_warning ("arch-independent data dir", Vdata_directory); |
| 1635 | 1635 | ||
| 1636 | sh = getenv ("SHELL"); | 1636 | sh = getenv ("SHELL"); |
diff --git a/src/charset.c b/src/charset.c index 341ac356aff..6964208137b 100644 --- a/src/charset.c +++ b/src/charset.c | |||
| @@ -2298,7 +2298,7 @@ init_charset (void) | |||
| 2298 | { | 2298 | { |
| 2299 | Lisp_Object tempdir; | 2299 | Lisp_Object tempdir; |
| 2300 | tempdir = Fexpand_file_name (build_string ("charsets"), Vdata_directory); | 2300 | tempdir = Fexpand_file_name (build_string ("charsets"), Vdata_directory); |
| 2301 | if (! file_accessible_directory_p (SSDATA (tempdir))) | 2301 | if (! file_accessible_directory_p (tempdir)) |
| 2302 | { | 2302 | { |
| 2303 | /* This used to be non-fatal (dir_warning), but it should not | 2303 | /* This used to be non-fatal (dir_warning), but it should not |
| 2304 | happen, and if it does sooner or later it will cause some | 2304 | happen, and if it does sooner or later it will cause some |
diff --git a/src/fileio.c b/src/fileio.c index d9c7397c2de..d4929184cee 100644 --- a/src/fileio.c +++ b/src/fileio.c | |||
| @@ -889,7 +889,7 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 889 | bool collapse_newdir = 1; | 889 | bool collapse_newdir = 1; |
| 890 | bool is_escaped = 0; | 890 | bool is_escaped = 0; |
| 891 | #endif /* DOS_NT */ | 891 | #endif /* DOS_NT */ |
| 892 | ptrdiff_t length; | 892 | ptrdiff_t length, newdirlen; |
| 893 | Lisp_Object handler, result, handled_name; | 893 | Lisp_Object handler, result, handled_name; |
| 894 | bool multibyte; | 894 | bool multibyte; |
| 895 | Lisp_Object hdir; | 895 | Lisp_Object hdir; |
| @@ -1147,6 +1147,7 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 1147 | append it to the current working directory. */ | 1147 | append it to the current working directory. */ |
| 1148 | 1148 | ||
| 1149 | newdir = 0; | 1149 | newdir = 0; |
| 1150 | newdirlen = -1; | ||
| 1150 | 1151 | ||
| 1151 | if (nm[0] == '~') /* prefix ~ */ | 1152 | if (nm[0] == '~') /* prefix ~ */ |
| 1152 | { | 1153 | { |
| @@ -1171,10 +1172,12 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 1171 | else | 1172 | else |
| 1172 | #endif | 1173 | #endif |
| 1173 | tem = build_string (newdir); | 1174 | tem = build_string (newdir); |
| 1175 | newdirlen = SBYTES (tem); | ||
| 1174 | if (multibyte && !STRING_MULTIBYTE (tem)) | 1176 | if (multibyte && !STRING_MULTIBYTE (tem)) |
| 1175 | { | 1177 | { |
| 1176 | hdir = DECODE_FILE (tem); | 1178 | hdir = DECODE_FILE (tem); |
| 1177 | newdir = SSDATA (hdir); | 1179 | newdir = SSDATA (hdir); |
| 1180 | newdirlen = SBYTES (hdir); | ||
| 1178 | } | 1181 | } |
| 1179 | #ifdef DOS_NT | 1182 | #ifdef DOS_NT |
| 1180 | collapse_newdir = 0; | 1183 | collapse_newdir = 0; |
| @@ -1201,10 +1204,12 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 1201 | bite us since we expect the directory to be | 1204 | bite us since we expect the directory to be |
| 1202 | multibyte. */ | 1205 | multibyte. */ |
| 1203 | tem = build_string (newdir); | 1206 | tem = build_string (newdir); |
| 1207 | newdirlen = SBYTES (tem); | ||
| 1204 | if (multibyte && !STRING_MULTIBYTE (tem)) | 1208 | if (multibyte && !STRING_MULTIBYTE (tem)) |
| 1205 | { | 1209 | { |
| 1206 | hdir = DECODE_FILE (tem); | 1210 | hdir = DECODE_FILE (tem); |
| 1207 | newdir = SSDATA (hdir); | 1211 | newdir = SSDATA (hdir); |
| 1212 | newdirlen = SBYTES (hdir); | ||
| 1208 | } | 1213 | } |
| 1209 | nm = p; | 1214 | nm = p; |
| 1210 | #ifdef DOS_NT | 1215 | #ifdef DOS_NT |
| @@ -1234,7 +1239,8 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 1234 | Lisp_Object tem = build_string (adir); | 1239 | Lisp_Object tem = build_string (adir); |
| 1235 | 1240 | ||
| 1236 | tem = DECODE_FILE (tem); | 1241 | tem = DECODE_FILE (tem); |
| 1237 | memcpy (adir, SSDATA (tem), SBYTES (tem) + 1); | 1242 | newdirlen = SBYTES (tem); |
| 1243 | memcpy (adir, SSDATA (tem), newdirlen + 1); | ||
| 1238 | } | 1244 | } |
| 1239 | } | 1245 | } |
| 1240 | if (!adir) | 1246 | if (!adir) |
| @@ -1245,6 +1251,7 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 1245 | adir[1] = ':'; | 1251 | adir[1] = ':'; |
| 1246 | adir[2] = '/'; | 1252 | adir[2] = '/'; |
| 1247 | adir[3] = 0; | 1253 | adir[3] = 0; |
| 1254 | newdirlen = 3; | ||
| 1248 | } | 1255 | } |
| 1249 | newdir = adir; | 1256 | newdir = adir; |
| 1250 | } | 1257 | } |
| @@ -1265,11 +1272,13 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 1265 | && !newdir) | 1272 | && !newdir) |
| 1266 | { | 1273 | { |
| 1267 | newdir = SSDATA (default_directory); | 1274 | newdir = SSDATA (default_directory); |
| 1275 | newdirlen = SBYTES (default_directory); | ||
| 1268 | #ifdef DOS_NT | 1276 | #ifdef DOS_NT |
| 1269 | /* Note if special escape prefix is present, but remove for now. */ | 1277 | /* Note if special escape prefix is present, but remove for now. */ |
| 1270 | if (newdir[0] == '/' && newdir[1] == ':') | 1278 | if (newdir[0] == '/' && newdir[1] == ':') |
| 1271 | { | 1279 | { |
| 1272 | is_escaped = 1; | 1280 | is_escaped = 1; |
| 1281 | newdirlen -= 2; | ||
| 1273 | newdir += 2; | 1282 | newdir += 2; |
| 1274 | } | 1283 | } |
| 1275 | #endif | 1284 | #endif |
| @@ -1305,14 +1314,14 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 1305 | if (IS_DRIVE (newdir[0]) && IS_DEVICE_SEP (newdir[1])) | 1314 | if (IS_DRIVE (newdir[0]) && IS_DEVICE_SEP (newdir[1])) |
| 1306 | { | 1315 | { |
| 1307 | drive = (unsigned char) newdir[0]; | 1316 | drive = (unsigned char) newdir[0]; |
| 1317 | newdirlen -= 2; | ||
| 1308 | newdir += 2; | 1318 | newdir += 2; |
| 1309 | } | 1319 | } |
| 1310 | if (!IS_DIRECTORY_SEP (nm[0])) | 1320 | if (!IS_DIRECTORY_SEP (nm[0])) |
| 1311 | { | 1321 | { |
| 1312 | ptrdiff_t newlen = strlen (newdir); | 1322 | char *tmp = alloca (newdirlen + file_name_as_directory_slop |
| 1313 | char *tmp = alloca (newlen + file_name_as_directory_slop | ||
| 1314 | + strlen (nm) + 1); | 1323 | + strlen (nm) + 1); |
| 1315 | file_name_as_directory (tmp, newdir, newlen, multibyte); | 1324 | file_name_as_directory (tmp, newdir, newdirlen, multibyte); |
| 1316 | strcat (tmp, nm); | 1325 | strcat (tmp, nm); |
| 1317 | nm = tmp; | 1326 | nm = tmp; |
| 1318 | } | 1327 | } |
| @@ -1329,8 +1338,11 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 1329 | Lisp_Object tem = build_string (adir); | 1338 | Lisp_Object tem = build_string (adir); |
| 1330 | 1339 | ||
| 1331 | tem = DECODE_FILE (tem); | 1340 | tem = DECODE_FILE (tem); |
| 1332 | memcpy (adir, SSDATA (tem), SBYTES (tem) + 1); | 1341 | newdirlen = SBYTES (tem); |
| 1342 | memcpy (adir, SSDATA (tem), newdirlen + 1); | ||
| 1333 | } | 1343 | } |
| 1344 | else | ||
| 1345 | newdirlen = strlen (aidr); | ||
| 1334 | newdir = adir; | 1346 | newdir = adir; |
| 1335 | } | 1347 | } |
| 1336 | 1348 | ||
| @@ -1338,6 +1350,7 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 1338 | if (IS_DRIVE (newdir[0]) && IS_DEVICE_SEP (newdir[1])) | 1350 | if (IS_DRIVE (newdir[0]) && IS_DEVICE_SEP (newdir[1])) |
| 1339 | { | 1351 | { |
| 1340 | drive = newdir[0]; | 1352 | drive = newdir[0]; |
| 1353 | newdirlen -= 2; | ||
| 1341 | newdir += 2; | 1354 | newdir += 2; |
| 1342 | } | 1355 | } |
| 1343 | 1356 | ||
| @@ -1349,17 +1362,18 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 1349 | if (IS_DIRECTORY_SEP (newdir[0]) && IS_DIRECTORY_SEP (newdir[1]) | 1362 | if (IS_DIRECTORY_SEP (newdir[0]) && IS_DIRECTORY_SEP (newdir[1]) |
| 1350 | && !IS_DIRECTORY_SEP (newdir[2])) | 1363 | && !IS_DIRECTORY_SEP (newdir[2])) |
| 1351 | { | 1364 | { |
| 1352 | char *adir = strcpy (alloca (strlen (newdir) + 1), newdir); | 1365 | char *adir = strcpy (alloca (newdirlen + 1), newdir); |
| 1353 | char *p = adir + 2; | 1366 | char *p = adir + 2; |
| 1354 | while (*p && !IS_DIRECTORY_SEP (*p)) p++; | 1367 | while (*p && !IS_DIRECTORY_SEP (*p)) p++; |
| 1355 | p++; | 1368 | p++; |
| 1356 | while (*p && !IS_DIRECTORY_SEP (*p)) p++; | 1369 | while (*p && !IS_DIRECTORY_SEP (*p)) p++; |
| 1357 | *p = 0; | 1370 | *p = 0; |
| 1358 | newdir = adir; | 1371 | newdir = adir; |
| 1372 | newdirlen = strlen (adir); | ||
| 1359 | } | 1373 | } |
| 1360 | else | 1374 | else |
| 1361 | #endif | 1375 | #endif |
| 1362 | newdir = ""; | 1376 | newdirlen = 0, newdir = ""; |
| 1363 | } | 1377 | } |
| 1364 | } | 1378 | } |
| 1365 | #endif /* DOS_NT */ | 1379 | #endif /* DOS_NT */ |
| @@ -1368,7 +1382,8 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 1368 | { | 1382 | { |
| 1369 | /* Ignore any slash at the end of newdir, unless newdir is | 1383 | /* Ignore any slash at the end of newdir, unless newdir is |
| 1370 | just "/" or "//". */ | 1384 | just "/" or "//". */ |
| 1371 | length = strlen (newdir); | 1385 | length = newdirlen; |
| 1386 | eassert (length == strlen (newdir)); | ||
| 1372 | while (length > 1 && IS_DIRECTORY_SEP (newdir[length - 1]) | 1387 | while (length > 1 && IS_DIRECTORY_SEP (newdir[length - 1]) |
| 1373 | && ! (length == 2 && IS_DIRECTORY_SEP (newdir[0]))) | 1388 | && ! (length == 2 && IS_DIRECTORY_SEP (newdir[0]))) |
| 1374 | length--; | 1389 | length--; |
| @@ -2765,23 +2780,24 @@ searchable directory. */) | |||
| 2765 | } | 2780 | } |
| 2766 | 2781 | ||
| 2767 | absname = ENCODE_FILE (absname); | 2782 | absname = ENCODE_FILE (absname); |
| 2768 | return file_accessible_directory_p (SSDATA (absname)) ? Qt : Qnil; | 2783 | return file_accessible_directory_p (absname) ? Qt : Qnil; |
| 2769 | } | 2784 | } |
| 2770 | 2785 | ||
| 2771 | /* If FILE is a searchable directory or a symlink to a | 2786 | /* If FILE is a searchable directory or a symlink to a |
| 2772 | searchable directory, return true. Otherwise return | 2787 | searchable directory, return true. Otherwise return |
| 2773 | false and set errno to an error number. */ | 2788 | false and set errno to an error number. */ |
| 2774 | bool | 2789 | bool |
| 2775 | file_accessible_directory_p (char const *file) | 2790 | file_accessible_directory_p (Lisp_Object file) |
| 2776 | { | 2791 | { |
| 2777 | #ifdef DOS_NT | 2792 | #ifdef DOS_NT |
| 2778 | /* There's no need to test whether FILE is searchable, as the | 2793 | /* There's no need to test whether FILE is searchable, as the |
| 2779 | searchable/executable bit is invented on DOS_NT platforms. */ | 2794 | searchable/executable bit is invented on DOS_NT platforms. */ |
| 2780 | return file_directory_p (file); | 2795 | return file_directory_p (SSDATA (file)); |
| 2781 | #else | 2796 | #else |
| 2782 | /* On POSIXish platforms, use just one system call; this avoids a | 2797 | /* On POSIXish platforms, use just one system call; this avoids a |
| 2783 | race and is typically faster. */ | 2798 | race and is typically faster. */ |
| 2784 | ptrdiff_t len = strlen (file); | 2799 | const char *data = SSDATA (file); |
| 2800 | ptrdiff_t len = SBYTES (file); | ||
| 2785 | char const *dir; | 2801 | char const *dir; |
| 2786 | bool ok; | 2802 | bool ok; |
| 2787 | int saved_errno; | 2803 | int saved_errno; |
| @@ -2793,15 +2809,15 @@ file_accessible_directory_p (char const *file) | |||
| 2793 | "/" and "//" are distinct on some platforms, whereas "/", "///", | 2809 | "/" and "//" are distinct on some platforms, whereas "/", "///", |
| 2794 | "////", etc. are all equivalent. */ | 2810 | "////", etc. are all equivalent. */ |
| 2795 | if (! len) | 2811 | if (! len) |
| 2796 | dir = file; | 2812 | dir = data; |
| 2797 | else | 2813 | else |
| 2798 | { | 2814 | { |
| 2799 | /* Just check for trailing '/' when deciding whether to append '/'. | 2815 | /* Just check for trailing '/' when deciding whether to append '/'. |
| 2800 | That's simpler than testing the two special cases "/" and "//", | 2816 | That's simpler than testing the two special cases "/" and "//", |
| 2801 | and it's a safe optimization here. */ | 2817 | and it's a safe optimization here. */ |
| 2802 | char *buf = SAFE_ALLOCA (len + 3); | 2818 | char *buf = SAFE_ALLOCA (len + 3); |
| 2803 | memcpy (buf, file, len); | 2819 | memcpy (buf, data, len); |
| 2804 | strcpy (buf + len, &"/."[file[len - 1] == '/']); | 2820 | strcpy (buf + len, &"/."[data[len - 1] == '/']); |
| 2805 | dir = buf; | 2821 | dir = buf; |
| 2806 | } | 2822 | } |
| 2807 | 2823 | ||
diff --git a/src/lisp.h b/src/lisp.h index 53d6cf8009e..05b27ab9f00 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -4029,7 +4029,7 @@ extern _Noreturn void report_file_error (const char *, Lisp_Object); | |||
| 4029 | extern bool internal_delete_file (Lisp_Object); | 4029 | extern bool internal_delete_file (Lisp_Object); |
| 4030 | extern Lisp_Object emacs_readlinkat (int, const char *); | 4030 | extern Lisp_Object emacs_readlinkat (int, const char *); |
| 4031 | extern bool file_directory_p (const char *); | 4031 | extern bool file_directory_p (const char *); |
| 4032 | extern bool file_accessible_directory_p (const char *); | 4032 | extern bool file_accessible_directory_p (Lisp_Object); |
| 4033 | extern void init_fileio (void); | 4033 | extern void init_fileio (void); |
| 4034 | extern void syms_of_fileio (void); | 4034 | extern void syms_of_fileio (void); |
| 4035 | extern Lisp_Object make_temp_name (Lisp_Object, bool); | 4035 | extern Lisp_Object make_temp_name (Lisp_Object, bool); |
diff --git a/src/lread.c b/src/lread.c index 639d574ac6b..7626e16e818 100644 --- a/src/lread.c +++ b/src/lread.c | |||
| @@ -4213,7 +4213,7 @@ load_path_check (Lisp_Object lpath) | |||
| 4213 | if (STRINGP (dirfile)) | 4213 | if (STRINGP (dirfile)) |
| 4214 | { | 4214 | { |
| 4215 | dirfile = Fdirectory_file_name (dirfile); | 4215 | dirfile = Fdirectory_file_name (dirfile); |
| 4216 | if (! file_accessible_directory_p (SSDATA (dirfile))) | 4216 | if (! file_accessible_directory_p (dirfile)) |
| 4217 | dir_warning ("Lisp directory", XCAR (path_tail)); | 4217 | dir_warning ("Lisp directory", XCAR (path_tail)); |
| 4218 | } | 4218 | } |
| 4219 | } | 4219 | } |