diff options
author | YU Jincheng <shana@zju.edu.cn> | 2021-09-29 17:37:26 +0800 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2021-10-07 15:22:35 +0200 |
commit | 1f925038ab9c6bd8f6b3cd40ed7aab0ef10d898e (patch) | |
tree | a625455a60081738812f469de6a02010f0c5b252 | |
parent | 17e6fb06b3d36eae11575b226858e8474e2b46d3 (diff) | |
download | busybox-w32-1f925038ab9c6bd8f6b3cd40ed7aab0ef10d898e.tar.gz busybox-w32-1f925038ab9c6bd8f6b3cd40ed7aab0ef10d898e.tar.bz2 busybox-w32-1f925038ab9c6bd8f6b3cd40ed7aab0ef10d898e.zip |
*: generalize "const trick"
While at it, change all "__asm__" to "asm"
Co-authored-by: canyie <31466456+canyie@users.noreply.github.com>
Signed-off-by: YU Jincheng <shana@zju.edu.cn>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | coreutils/test.c | 5 | ||||
-rw-r--r-- | include/libbb.h | 34 | ||||
-rw-r--r-- | libbb/appletlib.c | 3 | ||||
-rw-r--r-- | libbb/lineedit.c | 5 | ||||
-rw-r--r-- | procps/powertop.c | 2 | ||||
-rw-r--r-- | shell/ash.c | 23 |
6 files changed, 34 insertions, 38 deletions
diff --git a/coreutils/test.c b/coreutils/test.c index 7c6574334..fc956724b 100644 --- a/coreutils/test.c +++ b/coreutils/test.c | |||
@@ -435,7 +435,7 @@ struct test_statics { | |||
435 | }; | 435 | }; |
436 | 436 | ||
437 | /* See test_ptr_hack.c */ | 437 | /* See test_ptr_hack.c */ |
438 | extern struct test_statics *const test_ptr_to_statics; | 438 | extern struct test_statics *BB_GLOBAL_CONST test_ptr_to_statics; |
439 | 439 | ||
440 | #define S (*test_ptr_to_statics) | 440 | #define S (*test_ptr_to_statics) |
441 | #define args (S.args ) | 441 | #define args (S.args ) |
@@ -446,8 +446,7 @@ extern struct test_statics *const test_ptr_to_statics; | |||
446 | #define leaving (S.leaving ) | 446 | #define leaving (S.leaving ) |
447 | 447 | ||
448 | #define INIT_S() do { \ | 448 | #define INIT_S() do { \ |
449 | (*(struct test_statics**)not_const_pp(&test_ptr_to_statics)) = xzalloc(sizeof(S)); \ | 449 | ASSIGN_CONST_PTR(test_ptr_to_statics, xzalloc(sizeof(S))); \ |
450 | barrier(); \ | ||
451 | } while (0) | 450 | } while (0) |
452 | #define DEINIT_S() do { \ | 451 | #define DEINIT_S() do { \ |
453 | free(group_array); \ | 452 | free(group_array); \ |
diff --git a/include/libbb.h b/include/libbb.h index dfcaa05ec..02cc008f0 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
@@ -365,13 +365,27 @@ struct BUG_off_t_size_is_misdetected { | |||
365 | #endif | 365 | #endif |
366 | #endif | 366 | #endif |
367 | 367 | ||
368 | /* We use a trick to have more optimized code (fewer pointer reloads | ||
369 | * and reduced binary size by a few kilobytes) like: | ||
370 | * ash.c: extern struct globals *const ash_ptr_to_globals; | ||
371 | * ash_ptr_hack.c: struct globals *ash_ptr_to_globals; | ||
372 | * This way, compiler in ash.c knows the pointer can not change. | ||
373 | * | ||
374 | * However, this may break on weird arches or toolchains. In this case, | ||
375 | * set "-DBB_GLOBAL_CONST=''" in CONFIG_EXTRA_CFLAGS to disable | ||
376 | * this optimization. | ||
377 | */ | ||
378 | #ifndef BB_GLOBAL_CONST | ||
379 | # define BB_GLOBAL_CONST const | ||
380 | #endif | ||
381 | |||
368 | #if defined(errno) | 382 | #if defined(errno) |
369 | /* If errno is a define, assume it's "define errno (*__errno_location())" | 383 | /* If errno is a define, assume it's "define errno (*__errno_location())" |
370 | * and we will cache it's result in this variable */ | 384 | * and we will cache it's result in this variable */ |
371 | extern int *const bb_errno; | 385 | extern int *BB_GLOBAL_CONST bb_errno; |
372 | #undef errno | 386 | # undef errno |
373 | #define errno (*bb_errno) | 387 | # define errno (*bb_errno) |
374 | #define bb_cached_errno_ptr 1 | 388 | # define bb_cached_errno_ptr 1 |
375 | #endif | 389 | #endif |
376 | 390 | ||
377 | #if !(ULONG_MAX > 0xffffffff) | 391 | #if !(ULONG_MAX > 0xffffffff) |
@@ -2270,6 +2284,8 @@ struct globals; | |||
2270 | * If you want to assign a value, use SET_PTR_TO_GLOBALS(x) */ | 2284 | * If you want to assign a value, use SET_PTR_TO_GLOBALS(x) */ |
2271 | extern struct globals *const ptr_to_globals; | 2285 | extern struct globals *const ptr_to_globals; |
2272 | 2286 | ||
2287 | #define barrier() asm volatile ("":::"memory") | ||
2288 | |||
2273 | #if defined(__clang_major__) && __clang_major__ >= 9 | 2289 | #if defined(__clang_major__) && __clang_major__ >= 9 |
2274 | /* Clang/llvm drops assignment to "constant" storage. Silently. | 2290 | /* Clang/llvm drops assignment to "constant" storage. Silently. |
2275 | * Needs serious convincing to not eliminate the store. | 2291 | * Needs serious convincing to not eliminate the store. |
@@ -2277,7 +2293,7 @@ extern struct globals *const ptr_to_globals; | |||
2277 | static ALWAYS_INLINE void* not_const_pp(const void *p) | 2293 | static ALWAYS_INLINE void* not_const_pp(const void *p) |
2278 | { | 2294 | { |
2279 | void *pp; | 2295 | void *pp; |
2280 | __asm__ __volatile__( | 2296 | asm volatile ( |
2281 | "# forget that p points to const" | 2297 | "# forget that p points to const" |
2282 | : /*outputs*/ "=r" (pp) | 2298 | : /*outputs*/ "=r" (pp) |
2283 | : /*inputs*/ "0" (p) | 2299 | : /*inputs*/ "0" (p) |
@@ -2288,13 +2304,13 @@ static ALWAYS_INLINE void* not_const_pp(const void *p) | |||
2288 | static ALWAYS_INLINE void* not_const_pp(const void *p) { return (void*)p; } | 2304 | static ALWAYS_INLINE void* not_const_pp(const void *p) { return (void*)p; } |
2289 | #endif | 2305 | #endif |
2290 | 2306 | ||
2291 | /* At least gcc 3.4.6 on mipsel system needs optimization barrier */ | 2307 | #define ASSIGN_CONST_PTR(p, v) do { \ |
2292 | #define barrier() __asm__ __volatile__("":::"memory") | 2308 | *(void**)not_const_pp(&p) = (void*)(v); \ |
2293 | #define SET_PTR_TO_GLOBALS(x) do { \ | 2309 | /* At least gcc 3.4.6 on mipsel needs optimization barrier */ \ |
2294 | (*(struct globals**)not_const_pp(&ptr_to_globals)) = (void*)(x); \ | ||
2295 | barrier(); \ | 2310 | barrier(); \ |
2296 | } while (0) | 2311 | } while (0) |
2297 | 2312 | ||
2313 | #define SET_PTR_TO_GLOBALS(x) ASSIGN_CONST_PTR(ptr_to_globals, x) | ||
2298 | #define FREE_PTR_TO_GLOBALS() do { \ | 2314 | #define FREE_PTR_TO_GLOBALS() do { \ |
2299 | if (ENABLE_FEATURE_CLEAN_UP) { \ | 2315 | if (ENABLE_FEATURE_CLEAN_UP) { \ |
2300 | free(ptr_to_globals); \ | 2316 | free(ptr_to_globals); \ |
diff --git a/libbb/appletlib.c b/libbb/appletlib.c index 5c5d7eb95..bf26c99e9 100644 --- a/libbb/appletlib.c +++ b/libbb/appletlib.c | |||
@@ -247,8 +247,7 @@ void lbb_prepare(const char *applet | |||
247 | IF_FEATURE_INDIVIDUAL(, char **argv)) | 247 | IF_FEATURE_INDIVIDUAL(, char **argv)) |
248 | { | 248 | { |
249 | #ifdef bb_cached_errno_ptr | 249 | #ifdef bb_cached_errno_ptr |
250 | (*(int **)not_const_pp(&bb_errno)) = get_perrno(); | 250 | ASSIGN_CONST_PTR(bb_errno, get_perrno()); |
251 | barrier(); | ||
252 | #endif | 251 | #endif |
253 | applet_name = applet; | 252 | applet_name = applet; |
254 | 253 | ||
diff --git a/libbb/lineedit.c b/libbb/lineedit.c index a7a3ee103..3c87abcf9 100644 --- a/libbb/lineedit.c +++ b/libbb/lineedit.c | |||
@@ -192,7 +192,7 @@ struct lineedit_statics { | |||
192 | }; | 192 | }; |
193 | 193 | ||
194 | /* See lineedit_ptr_hack.c */ | 194 | /* See lineedit_ptr_hack.c */ |
195 | extern struct lineedit_statics *const lineedit_ptr_to_statics; | 195 | extern struct lineedit_statics *BB_GLOBAL_CONST lineedit_ptr_to_statics; |
196 | 196 | ||
197 | #define S (*lineedit_ptr_to_statics) | 197 | #define S (*lineedit_ptr_to_statics) |
198 | #define state (S.state ) | 198 | #define state (S.state ) |
@@ -214,8 +214,7 @@ extern struct lineedit_statics *const lineedit_ptr_to_statics; | |||
214 | #define delbuf (S.delbuf ) | 214 | #define delbuf (S.delbuf ) |
215 | 215 | ||
216 | #define INIT_S() do { \ | 216 | #define INIT_S() do { \ |
217 | (*(struct lineedit_statics**)not_const_pp(&lineedit_ptr_to_statics)) = xzalloc(sizeof(S)); \ | 217 | ASSIGN_CONST_PTR(lineedit_ptr_to_statics, xzalloc(sizeof(S))); \ |
218 | barrier(); \ | ||
219 | } while (0) | 218 | } while (0) |
220 | 219 | ||
221 | static void deinit_S(void) | 220 | static void deinit_S(void) |
diff --git a/procps/powertop.c b/procps/powertop.c index fc6018b7a..24c2b320f 100644 --- a/procps/powertop.c +++ b/procps/powertop.c | |||
@@ -505,7 +505,7 @@ static void cpuid(unsigned int *eax, unsigned int *ebx, unsigned int *ecx, | |||
505 | unsigned int *edx) | 505 | unsigned int *edx) |
506 | { | 506 | { |
507 | /* EAX value specifies what information to return */ | 507 | /* EAX value specifies what information to return */ |
508 | __asm__( | 508 | asm ( |
509 | " pushl %%ebx\n" /* Save EBX */ | 509 | " pushl %%ebx\n" /* Save EBX */ |
510 | " cpuid\n" | 510 | " cpuid\n" |
511 | " movl %%ebx, %1\n" /* Save content of EBX */ | 511 | " movl %%ebx, %1\n" /* Save content of EBX */ |
diff --git a/shell/ash.c b/shell/ash.c index 4bf0615ea..7b85981ec 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -303,20 +303,6 @@ typedef long arith_t; | |||
303 | # error "Do not even bother, ash will not run on NOMMU machine" | 303 | # error "Do not even bother, ash will not run on NOMMU machine" |
304 | #endif | 304 | #endif |
305 | 305 | ||
306 | /* We use a trick to have more optimized code (fewer pointer reloads): | ||
307 | * ash.c: extern struct globals *const ash_ptr_to_globals; | ||
308 | * ash_ptr_hack.c: struct globals *ash_ptr_to_globals; | ||
309 | * This way, compiler in ash.c knows the pointer can not change. | ||
310 | * | ||
311 | * However, this may break on weird arches or toolchains. In this case, | ||
312 | * set "-DBB_GLOBAL_CONST=''" in CONFIG_EXTRA_CFLAGS to disable | ||
313 | * this optimization. | ||
314 | */ | ||
315 | #ifndef BB_GLOBAL_CONST | ||
316 | # define BB_GLOBAL_CONST const | ||
317 | #endif | ||
318 | |||
319 | |||
320 | /* ============ Hash table sizes. Configurable. */ | 306 | /* ============ Hash table sizes. Configurable. */ |
321 | 307 | ||
322 | #define VTABSIZE 39 | 308 | #define VTABSIZE 39 |
@@ -518,8 +504,7 @@ extern struct globals_misc *BB_GLOBAL_CONST ash_ptr_to_globals_misc; | |||
518 | #define random_gen (G_misc.random_gen ) | 504 | #define random_gen (G_misc.random_gen ) |
519 | #define backgndpid (G_misc.backgndpid ) | 505 | #define backgndpid (G_misc.backgndpid ) |
520 | #define INIT_G_misc() do { \ | 506 | #define INIT_G_misc() do { \ |
521 | (*(struct globals_misc**)not_const_pp(&ash_ptr_to_globals_misc)) = xzalloc(sizeof(G_misc)); \ | 507 | ASSIGN_CONST_PTR(ash_ptr_to_globals_misc, xzalloc(sizeof(G_misc))); \ |
522 | barrier(); \ | ||
523 | savestatus = -1; \ | 508 | savestatus = -1; \ |
524 | curdir = nullstr; \ | 509 | curdir = nullstr; \ |
525 | physdir = nullstr; \ | 510 | physdir = nullstr; \ |
@@ -1597,8 +1582,7 @@ extern struct globals_memstack *BB_GLOBAL_CONST ash_ptr_to_globals_memstack; | |||
1597 | #define g_stacknleft (G_memstack.g_stacknleft) | 1582 | #define g_stacknleft (G_memstack.g_stacknleft) |
1598 | #define stackbase (G_memstack.stackbase ) | 1583 | #define stackbase (G_memstack.stackbase ) |
1599 | #define INIT_G_memstack() do { \ | 1584 | #define INIT_G_memstack() do { \ |
1600 | (*(struct globals_memstack**)not_const_pp(&ash_ptr_to_globals_memstack)) = xzalloc(sizeof(G_memstack)); \ | 1585 | ASSIGN_CONST_PTR(ash_ptr_to_globals_memstack, xzalloc(sizeof(G_memstack))); \ |
1601 | barrier(); \ | ||
1602 | g_stackp = &stackbase; \ | 1586 | g_stackp = &stackbase; \ |
1603 | g_stacknxt = stackbase.space; \ | 1587 | g_stacknxt = stackbase.space; \ |
1604 | g_stacknleft = MINSIZE; \ | 1588 | g_stacknleft = MINSIZE; \ |
@@ -2229,8 +2213,7 @@ extern struct globals_var *BB_GLOBAL_CONST ash_ptr_to_globals_var; | |||
2229 | #endif | 2213 | #endif |
2230 | #define INIT_G_var() do { \ | 2214 | #define INIT_G_var() do { \ |
2231 | unsigned i; \ | 2215 | unsigned i; \ |
2232 | (*(struct globals_var**)not_const_pp(&ash_ptr_to_globals_var)) = xzalloc(sizeof(G_var)); \ | 2216 | ASSIGN_CONST_PTR(ash_ptr_to_globals_var, xzalloc(sizeof(G_var))); \ |
2233 | barrier(); \ | ||
2234 | for (i = 0; i < ARRAY_SIZE(varinit_data); i++) { \ | 2217 | for (i = 0; i < ARRAY_SIZE(varinit_data); i++) { \ |
2235 | varinit[i].flags = varinit_data[i].flags; \ | 2218 | varinit[i].flags = varinit_data[i].flags; \ |
2236 | varinit[i].var_text = varinit_data[i].var_text; \ | 2219 | varinit[i].var_text = varinit_data[i].var_text; \ |