From 78f6b66c7223146f772b0f048c8f0f22180f5555 Mon Sep 17 00:00:00 2001 From: Anselm Kruis Date: Tue, 13 Nov 2018 00:18:43 +0100 Subject: [PATCH] Stackless issue #183: use a volatile pointer to call slp_switch() Prevent inlining slp_switch() more reliably. C standard guarantees to read the value of a volatile variable from memory on each access. Therefore the compiler does not know the called function and can't inline. --- Stackless/core/slp_transfer.c | 6 +++++- Stackless/platf/switch_amd64_unix.h | 10 +--------- Stackless/platf/switch_arm32_gcc.h | 10 +--------- Stackless/platf/switch_mips_unix.h | 10 +--------- Stackless/platf/switch_ppc_macosx.h | 10 +--------- Stackless/platf/switch_ppc_unix.h | 10 +--------- Stackless/platf/switch_s390_unix.h | 10 +--------- Stackless/platf/switch_sparc_sun_gcc.h | 10 +--------- Stackless/platf/switch_x86_unix.h | 10 +--------- 9 files changed, 13 insertions(+), 73 deletions(-) diff --git a/Stackless/core/slp_transfer.c b/Stackless/core/slp_transfer.c index 64f9c761ae19f9..7a18c1a71e2a35 100644 --- a/Stackless/core/slp_transfer.c +++ b/Stackless/core/slp_transfer.c @@ -122,6 +122,10 @@ slp_transfer(PyCStackObject **cstprev, PyCStackObject *cst, { PyThreadState *ts = PyThreadState_GET(); int result; + /* Use a volatile pointer to prevent inlining of slp_switch(). + * See Stackless issue 183 + */ + static int (*volatile slp_switch_ptr)(void) = slp_switch; /* since we change the stack we must assure that the protocol was met */ STACKLESS_ASSERT(); @@ -153,7 +157,7 @@ slp_transfer(PyCStackObject **cstprev, PyCStackObject *cst, _cstprev = cstprev; _cst = cst; _prev = prev; - result = slp_switch(); + result = slp_switch_ptr(); SLP_ASSERT_FRAME_IN_TRANSFER(ts); if (!result) { if (_cst) { diff --git a/Stackless/platf/switch_amd64_unix.h b/Stackless/platf/switch_amd64_unix.h index 370b0b429ded12..8ae7ba78652395 100644 --- a/Stackless/platf/switch_amd64_unix.h +++ b/Stackless/platf/switch_amd64_unix.h @@ -94,15 +94,7 @@ "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15" #endif -/* - * You may want to make the function static enable optimizations. - * However, the ABI SPEC does not apply to static functions. Therefore - * I make slp_switch a regular global function. - */ -#if 0 -static -#endif -int +static int slp_switch(void) { register long *stackref, stsizediff; diff --git a/Stackless/platf/switch_arm32_gcc.h b/Stackless/platf/switch_arm32_gcc.h index 640b7344fd0629..d0c05d68e0a9b5 100644 --- a/Stackless/platf/switch_arm32_gcc.h +++ b/Stackless/platf/switch_arm32_gcc.h @@ -27,15 +27,7 @@ #define STACK_MAGIC 0 #define REGS_TO_SAVE /*"r1", "r2", "r3", "r4",*/ "r5", "r6", "fp", "ip", "lr" -/* - * You may want to make the function static enable optimizations. - * However, the ABI SPEC does not apply to static functions. Therefore - * I make slp_switch a regular global function. - */ -#if 0 -static -#endif -int +static int slp_switch(void) { register int *stackref, stsizediff; diff --git a/Stackless/platf/switch_mips_unix.h b/Stackless/platf/switch_mips_unix.h index 1b99ef9206a4e4..7d6d51c579861a 100644 --- a/Stackless/platf/switch_mips_unix.h +++ b/Stackless/platf/switch_mips_unix.h @@ -20,15 +20,7 @@ "$23", "$30" #endif __asm__ volatile ("" : : : REGS_TO_SAVE); -/* - * You may want to make the function static enable optimizations. - * However, the ABI SPEC does not apply to static functions. Therefore - * I make slp_switch a regular global function. - */ -#if 0 -static -#endif -int +static int slp_switch(void) { register int *stackref, stsizediff; diff --git a/Stackless/platf/switch_ppc_macosx.h b/Stackless/platf/switch_ppc_macosx.h index b8c50f89bba8f6..d582d3125f43bf 100644 --- a/Stackless/platf/switch_ppc_macosx.h +++ b/Stackless/platf/switch_ppc_macosx.h @@ -42,15 +42,7 @@ "cr2", "cr3", "cr4" #endif -/* - * You may want to make the function static enable optimizations. - * However, the ABI SPEC does not apply to static functions. Therefore - * I make slp_switch a regular global function. - */ -#if 0 -static -#endif -int +static int slp_switch(void) { static int x = 0; diff --git a/Stackless/platf/switch_ppc_unix.h b/Stackless/platf/switch_ppc_unix.h index 924d6efbdb0162..f0bf07845f1dcf 100644 --- a/Stackless/platf/switch_ppc_unix.h +++ b/Stackless/platf/switch_ppc_unix.h @@ -37,15 +37,7 @@ #define REGS_TO_SAVE "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20", \ "r21", "r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29", "r31", \ "cr2", "cr3", "cr4" -/* - * You may want to make the function static enable optimizations. - * However, the ABI SPEC does not apply to static functions. Therefore - * I make slp_switch a regular global function. - */ -#if 0 -static -#endif -int +static int slp_switch(void) { register int *stackref, stsizediff; diff --git a/Stackless/platf/switch_s390_unix.h b/Stackless/platf/switch_s390_unix.h index f335d5da8c8501..1e08c604998548 100644 --- a/Stackless/platf/switch_s390_unix.h +++ b/Stackless/platf/switch_s390_unix.h @@ -21,15 +21,7 @@ "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \ "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15" -/* - * You may want to make the function static enable optimizations. - * However, the ABI SPEC does not apply to static functions. Therefore - * I make slp_switch a regular global function. - */ -#if 0 -static -#endif -int +static int slp_switch(void) { register int *stackref, stsizediff; diff --git a/Stackless/platf/switch_sparc_sun_gcc.h b/Stackless/platf/switch_sparc_sun_gcc.h index 8f67602e751cd6..449e49faebfc9d 100644 --- a/Stackless/platf/switch_sparc_sun_gcc.h +++ b/Stackless/platf/switch_sparc_sun_gcc.h @@ -23,15 +23,7 @@ #define STACK_MAGIC 0 -/* - * You may want to make the function static enable optimizations. - * However, the ABI SPEC does not apply to static functions. Therefore - * I make slp_switch a regular global function. - */ -#if 0 -static -#endif -int +static int slp_switch(void) { register int *stackref, stsizediff; diff --git a/Stackless/platf/switch_x86_unix.h b/Stackless/platf/switch_x86_unix.h index e4bada209148fa..1610d04fa688e6 100644 --- a/Stackless/platf/switch_x86_unix.h +++ b/Stackless/platf/switch_x86_unix.h @@ -66,15 +66,7 @@ /* Registers marked as clobbered, minimum set according to the ABI spec. */ #define REGS_CLOBBERED "ebx", "edi", "esi" -/* - * You may want to make the function static enable optimizations. - * However, the ABI SPEC does not apply to static functions. Therefore - * I make slp_switch a regular global function. - */ -#if 0 -static -#endif -int +static int slp_switch(void) { register int *stackref, stsizediff;