Skip to content

Commit b63c4e4

Browse files
author
Anselm Kruis
committed
merge 3.4-slp (Stackless python#97)
2 parents 734a42a + 67701c1 commit b63c4e4

11 files changed

+165
-31
lines changed

Stackless/changelog.txt

+8
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,14 @@ What's New in Stackless 3.X.X?
99

1010
*Release date: 20XX-XX-XX*
1111

12+
- https://bitbucket.org/stackless-dev/stackless/issues/97
13+
Fix the stack switching for optimized builds for all Unix-like architectures
14+
except amd64, where it was already OK. This change removes the "static"
15+
declaration from the function slp_switch(). This forces the compiler
16+
to adhere to the ABI specification. On i386 and amd64 it is now save to
17+
configure stackless with --enable-stacklessfewerregisters, except if you
18+
compile for darwin.
19+
1220
- https://bitbucket.org/stackless-dev/stackless/issues/94
1321
Calls to __init__(self, ...) are now stackless, if
1422
soft-switching is enabled.

Stackless/platf/switch_amd64_unix.h

+16-1
Original file line numberDiff line numberDiff line change
@@ -104,12 +104,20 @@ int
104104
slp_switch(void)
105105
{
106106
register long *stackref, stsizediff;
107-
void * rbp; int mxcsr; short x87cw;
107+
int mxcsr; short x87cw;
108+
#if STACKLESS_FRHACK
109+
__asm__ volatile (
110+
"fstcw %0\n\t"
111+
"stmxcsr %1\n\t"
112+
: "=m" (x87cw), "=m" (mxcsr) : : REGS_CLOBBERED );
113+
#else
114+
void * rbp;
108115
__asm__ volatile (
109116
"fstcw %0\n\t"
110117
"stmxcsr %1\n\t"
111118
"movq %%rbp, %2\n\t"
112119
: "=m" (x87cw), "=m" (mxcsr), "=m" (rbp) : : REGS_CLOBBERED );
120+
#endif
113121
__asm__ ("movq %%rsp, %0" : "=g" (stackref));
114122
{
115123
SLP_SAVE_STATE(stackref, stsizediff);
@@ -120,11 +128,18 @@ slp_switch(void)
120128
: "r" (stsizediff)
121129
);
122130
SLP_RESTORE_STATE();
131+
#if STACKLESS_FRHACK
132+
__asm__ volatile (
133+
"ldmxcsr %1\n\t"
134+
"fldcw %0\n\t"
135+
: : "m" (x87cw), "m" (mxcsr));
136+
#else
123137
__asm__ volatile (
124138
"movq %2, %%rbp\n\t"
125139
"ldmxcsr %1\n\t"
126140
"fldcw %0\n\t"
127141
: : "m" (x87cw), "m" (mxcsr), "m" (rbp));
142+
#endif
128143
return 0;
129144
}
130145
}

Stackless/platf/switch_arm32_gcc.h

+9-2
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,15 @@
2727
#define STACK_MAGIC 0
2828
#define REGS_TO_SAVE /*"r1", "r2", "r3", "r4",*/ "r5", "r6", "fp", "ip", "lr"
2929

30-
static int
30+
/*
31+
* You may want to make the function static enable optimizations.
32+
* However, the ABI SPEC does not apply to static functions. Therefore
33+
* I make slp_switch a regular global function.
34+
*/
35+
#if 0
36+
static
37+
#endif
38+
int
3139
slp_switch(void)
3240
{
3341
register int *stackref, stsizediff;
@@ -44,7 +52,6 @@ slp_switch(void)
4452
SLP_RESTORE_STATE();
4553
return 0;
4654
}
47-
__asm__ volatile ("" : : : REGS_TO_SAVE);
4855
}
4956

5057
#endif

Stackless/platf/switch_mips_unix.h

+10-2
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,16 @@
1919
#define REGS_TO_SAVE "$16", "$17", "$18", "$19", "$20", "$21", "$22", \
2020
"$23", "$30"
2121
#endif
22-
static int
22+
__asm__ volatile ("" : : : REGS_TO_SAVE);
23+
/*
24+
* You may want to make the function static enable optimizations.
25+
* However, the ABI SPEC does not apply to static functions. Therefore
26+
* I make slp_switch a regular global function.
27+
*/
28+
#if 0
29+
static
30+
#endif
31+
int
2332
slp_switch(void)
2433
{
2534
register int *stackref, stsizediff;
@@ -38,7 +47,6 @@ slp_switch(void)
3847
);
3948
SLP_RESTORE_STATE();
4049
}
41-
/* __asm__ __volatile__ ("" : : : REGS_TO_SAVE); */
4250
return 0;
4351
}
4452

Stackless/platf/switch_ppc_macosx.h

+9-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,15 @@
4242
"cr2", "cr3", "cr4"
4343
#endif
4444

45-
static int
45+
/*
46+
* You may want to make the function static enable optimizations.
47+
* However, the ABI SPEC does not apply to static functions. Therefore
48+
* I make slp_switch a regular global function.
49+
*/
50+
#if 0
51+
static
52+
#endif
53+
int
4654
slp_switch(void)
4755
{
4856
static int x = 0;

Stackless/platf/switch_ppc_unix.h

+9-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,15 @@
3737
#define REGS_TO_SAVE "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20", \
3838
"r21", "r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29", "r31", \
3939
"cr2", "cr3", "cr4"
40-
static int
40+
/*
41+
* You may want to make the function static enable optimizations.
42+
* However, the ABI SPEC does not apply to static functions. Therefore
43+
* I make slp_switch a regular global function.
44+
*/
45+
#if 0
46+
static
47+
#endif
48+
int
4149
slp_switch(void)
4250
{
4351
register int *stackref, stsizediff;

Stackless/platf/switch_s390_unix.h

+9-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,15 @@
2121
"f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \
2222
"f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15"
2323

24-
static int
24+
/*
25+
* You may want to make the function static enable optimizations.
26+
* However, the ABI SPEC does not apply to static functions. Therefore
27+
* I make slp_switch a regular global function.
28+
*/
29+
#if 0
30+
static
31+
#endif
32+
int
2533
slp_switch(void)
2634
{
2735
register int *stackref, stsizediff;
@@ -37,7 +45,6 @@ slp_switch(void)
3745
SLP_RESTORE_STATE();
3846
return 0;
3947
}
40-
__asm__ volatile ("" : : : REGS_TO_SAVE);
4148
}
4249

4350
#endif

Stackless/platf/switch_sparc_sun_gcc.h

+9-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,15 @@
2323

2424
#define STACK_MAGIC 0
2525

26-
static int
26+
/*
27+
* You may want to make the function static enable optimizations.
28+
* However, the ABI SPEC does not apply to static functions. Therefore
29+
* I make slp_switch a regular global function.
30+
*/
31+
#if 0
32+
static
33+
#endif
34+
int
2735
slp_switch(void)
2836
{
2937
register int *stackref, stsizediff;

Stackless/platf/switch_x86_unix.h

+62-12
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
* this is the internal transfer function.
33
*
44
* HISTORY
5+
* 06-Nov-16 Anselm Kruis <a.kruis@atos.net>
6+
* Reworked based on the i386 ABI spec.
57
* 24-Nov-02 Christian Tismer <tismer@tismer.com>
68
* needed to add another magic constant to insure
79
* that f in slp_eval_frame(PyFrameObject *f)
@@ -23,36 +25,84 @@
2325

2426
#ifdef SLP_EVAL
2527

26-
/* #define STACK_MAGIC 3 */
27-
/* the above works fine with gcc 2.96, but 2.95.3 wants this */
2828
#define STACK_MAGIC 0
2929

30-
static int
30+
/*
31+
* In order to switch the stack, we use the fact, that the compiler
32+
* already knows how to preserve registers accross function calls.
33+
*
34+
* The relevant i386 ABI specifigation pecisely defines which registers
35+
* must be preserved and which registers may be modified.
36+
* We use a gcc inline assembly feature to pretend that the inline
37+
* assembly block modifies the registers to be preserved. As a result,
38+
* the compiler emits code to preserve those registers.
39+
*
40+
* The "System V Application Binary Interface Intel386 Architecture Processor Supplment, Fourth Edition"
41+
* Section 3 chapter "Function Calling Sequence" states:
42+
* All registers on the Intel386 are global and thus visible to both a calling and a
43+
* called function. Registers %ebp, %ebx, %edi, %esi, and %esp "belong" to the cal-
44+
* ling function. In other words, a called function must preserve these registers’
45+
* values for its caller. Remaining registers ‘‘belong’’ to the called function.
46+
*
47+
* The compiler always preserves the %esp register accros a function call.
48+
*
49+
* Depending on the usage of a frame pointer, which is optional
50+
* for the i386 ABI, the compiler already preserves the %ebp
51+
* register. Unfortunately, we must not add "ebp" to the clobber list, if
52+
* ebp is used as a frame pointer (won't compile). Therefore we save
53+
* ebp manually.
54+
*
55+
* For the other registers we tell the compiler,
56+
* that we are going to clobber the registers. The compiler will then save the registers
57+
* for us. (However the compiler gives no guarantee, when it will restore
58+
* the registers.) And the compiler only preserves those registers, that must
59+
* be preserved according to the calling convention. It does not preserve any other
60+
* register, that may be modified during a function call. Therefore specifying additional
61+
* registers has no effect at all. Take a look at the generated assembly code!
62+
*/
63+
64+
/* Registers marked as clobbered, minimum set according to the ABI spec. */
65+
#define REGS_CLOBBERED "ebx", "edi", "esi"
66+
67+
/*
68+
* You may want to make the function static enable optimizations.
69+
* However, the ABI SPEC does not apply to static functions. Therefore
70+
* I make slp_switch a regular global function.
71+
*/
72+
#if 0
73+
static
74+
#endif
75+
int
3176
slp_switch(void)
3277
{
3378
register int *stackref, stsizediff;
3479
#if STACKLESS_FRHACK
35-
__asm__ volatile ("" : : : "esi", "edi");
80+
__asm__ volatile (
81+
""
82+
: : : REGS_CLOBBERED );
3683
#else
37-
__asm__ volatile ("" : : : "ebx", "esi", "edi");
84+
void * ebp;
85+
__asm__ volatile (
86+
"movl %%ebp, %0\n\t"
87+
: "=m" (ebp) : : REGS_CLOBBERED );
3888
#endif
3989
__asm__ ("movl %%esp, %0" : "=g" (stackref));
4090
{
4191
SLP_SAVE_STATE(stackref, stsizediff);
4292
__asm__ volatile (
43-
"addl %0, %%esp\n"
44-
"addl %0, %%ebp\n"
93+
"addl %0, %%esp\n\t"
94+
"addl %0, %%ebp\n\t"
4595
:
4696
: "r" (stsizediff)
4797
);
4898
SLP_RESTORE_STATE();
99+
#if ! STACKLESS_FRHACK
100+
__asm__ volatile (
101+
"movl %0, %%ebp\n\t"
102+
: : "m" (ebp) );
103+
#endif
49104
return 0;
50105
}
51-
#if STACKLESS_FRHACK
52-
__asm__ volatile ("" : : : "esi", "edi");
53-
#else
54-
__asm__ volatile ("" : : : "ebx", "esi", "edi");
55-
#endif
56106
}
57107

58108

configure

+22
Original file line numberDiff line numberDiff line change
@@ -3163,6 +3163,16 @@ else
31633163

31643164
fi
31653165

3166+
3167+
# Check whether --enable-stacklessfewerregisters was given.
3168+
if test "${enable_stacklessfewerregisters+set}" = set; then :
3169+
enableval=$enable_stacklessfewerregisters; STACKLESS_FRHACK=1
3170+
else
3171+
STACKLESS_FRHACK=0
3172+
fi
3173+
3174+
3175+
31663176
# Check whether --enable-framework was given.
31673177
if test "${enable_framework+set}" = set; then :
31683178
enableval=$enable_framework;
@@ -3362,6 +3372,17 @@ if test "$cross_compiling" = yes; then
33623372
_PYTHON_HOST_PLATFORM="$MACHDEP${_host_cpu:+-$_host_cpu}"
33633373
fi
33643374

3375+
# Stackless flags for compiling the hard switching code
3376+
case $MACHDEP in
3377+
darwin)
3378+
SLPFLAGS="-fomit-frame-pointer -fno-inline-functions"
3379+
;;
3380+
*)
3381+
SLPFLAGS="-fno-omit-frame-pointer -fno-inline-functions"
3382+
;;
3383+
esac
3384+
3385+
33653386
# Some systems cannot stand _XOPEN_SOURCE being defined at all; they
33663387
# disable features if it is defined, without any means to access these
33673388
# features as extensions. For these systems, we skip the definition of
@@ -6631,6 +6652,7 @@ $as_echo "$ac_cv_enable_unreachable_code_warning" >&6; }
66316652
;;
66326653
esac
66336654

6655+
BASECFLAGS="${BASECFLAGS} -DSTACKLESS_FRHACK=${STACKLESS_FRHACK}"
66346656
case $ac_sys_system in
66356657
SCO_SV*)
66366658
BASECFLAGS="$BASECFLAGS -m486 -DSCO5"

configure.ac

+2-9
Original file line numberDiff line numberDiff line change
@@ -435,10 +435,10 @@ fi
435435
# Stackless flags for compiling the hard switching code
436436
case $MACHDEP in
437437
darwin)
438-
SLPFLAGS="-fomit-frame-pointer -O2"
438+
SLPFLAGS="-fomit-frame-pointer -fno-inline-functions"
439439
;;
440440
*)
441-
SLPFLAGS="-fno-omit-frame-pointer -O2"
441+
SLPFLAGS="-fno-omit-frame-pointer -fno-inline-functions"
442442
;;
443443
esac
444444
AC_SUBST(SLPFLAGS)
@@ -4905,13 +4905,6 @@ if test "$have_gcc_asm_for_x87" = yes; then
49054905
;;
49064906
esac
49074907
fi
4908-
AC_SUBST(SLPFLAGS)
4909-
SLPFLAGS="-fno-omit-frame-pointer -O2"
4910-
case $MACHDEP in
4911-
darwin) SLPFLAGS="-fomit-frame-pointer -O2";;
4912-
'') SLPFLAGS="-fno-omit-frame-pointer -O2";;
4913-
esac
4914-
49154908

49164909
# Check for stdatomic.h
49174910
AC_MSG_CHECKING(for stdatomic.h)

0 commit comments

Comments
 (0)