[pypy-commit] pypy default: Improve test_set_length_fraction. Fix it and simplify the code
arigo
noreply at buildbot.pypy.org
Fri May 27 14:23:43 CEST 2011
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r44546:4424a9909ba1
Date: 2011-05-27 13:35 +0200
http://bitbucket.org/pypy/pypy/changeset/4424a9909ba1/
Log: Improve test_set_length_fraction. Fix it and simplify the code to
assume that the stack grows downward, which is the case for almost
all architectures nowadays.
diff --git a/pypy/jit/backend/llsupport/llmodel.py b/pypy/jit/backend/llsupport/llmodel.py
--- a/pypy/jit/backend/llsupport/llmodel.py
+++ b/pypy/jit/backend/llsupport/llmodel.py
@@ -143,11 +143,11 @@
STACK_CHECK_SLOWPATH = lltype.Ptr(lltype.FuncType([lltype.Signed],
lltype.Void))
def insert_stack_check():
- startaddr = rstack._stack_get_start_adr()
+ endaddr = rstack._stack_get_end_adr()
lengthaddr = rstack._stack_get_length_adr()
f = llhelper(STACK_CHECK_SLOWPATH, rstack.stack_check_slowpath)
slowpathaddr = rffi.cast(lltype.Signed, f)
- return startaddr, lengthaddr, slowpathaddr
+ return endaddr, lengthaddr, slowpathaddr
self.pos_exception = pos_exception
self.pos_exc_value = pos_exc_value
diff --git a/pypy/jit/backend/x86/assembler.py b/pypy/jit/backend/x86/assembler.py
--- a/pypy/jit/backend/x86/assembler.py
+++ b/pypy/jit/backend/x86/assembler.py
@@ -621,11 +621,11 @@
if self.stack_check_slowpath == 0:
pass # no stack check (e.g. not translated)
else:
- startaddr, lengthaddr, _ = self.cpu.insert_stack_check()
- self.mc.MOV(eax, esp) # MOV eax, current
- self.mc.SUB(eax, heap(startaddr)) # SUB eax, [start]
+ endaddr, lengthaddr, _ = self.cpu.insert_stack_check()
+ self.mc.MOV(eax, heap(endaddr)) # MOV eax, [start]
+ self.mc.SUB(eax, esp) # SUB eax, current
self.mc.CMP(eax, heap(lengthaddr)) # CMP eax, [length]
- self.mc.J_il8(rx86.Conditions['B'], 0) # JB .skip
+ self.mc.J_il8(rx86.Conditions['BE'], 0) # JBE .skip
jb_location = self.mc.get_relative_pos()
self.mc.CALL(imm(self.stack_check_slowpath))# CALL slowpath
# patch the JB above # .skip:
diff --git a/pypy/rlib/rstack.py b/pypy/rlib/rstack.py
--- a/pypy/rlib/rstack.py
+++ b/pypy/rlib/rstack.py
@@ -42,8 +42,8 @@
sandboxsafe=True, _nowrapper=True,
_callable=_callable)
-_stack_get_start = llexternal('LL_stack_get_start', [], lltype.Signed,
- lambda: 0)
+_stack_get_end = llexternal('LL_stack_get_end', [], lltype.Signed,
+ lambda: 0)
_stack_get_length = llexternal('LL_stack_get_length', [], lltype.Signed,
lambda: 1)
_stack_set_length_fraction = llexternal('LL_stack_set_length_fraction',
@@ -53,7 +53,7 @@
[lltype.Signed], lltype.Char,
lambda cur: '\x00')
# the following is used by the JIT
-_stack_get_start_adr = llexternal('LL_stack_get_start_adr', [], lltype.Signed)
+_stack_get_end_adr = llexternal('LL_stack_get_end_adr', [], lltype.Signed)
_stack_get_length_adr= llexternal('LL_stack_get_length_adr',[], lltype.Signed)
@@ -66,13 +66,13 @@
current = llop.stack_current(lltype.Signed)
#
# Load these variables from C code
- start = _stack_get_start()
+ end = _stack_get_end()
length = _stack_get_length()
#
- # Common case: if 'current' is within [start:start+length], everything
+ # Common case: if 'current' is within [end-length:end], everything
# is fine
- ofs = r_uint(current - start)
- if ofs < r_uint(length):
+ ofs = r_uint(end - current)
+ if ofs <= r_uint(length):
return
#
# Else call the slow path
diff --git a/pypy/translator/c/src/stack.h b/pypy/translator/c/src/stack.h
--- a/pypy/translator/c/src/stack.h
+++ b/pypy/translator/c/src/stack.h
@@ -11,7 +11,7 @@
* It is needed to have RPyThreadStaticTLS, too. */
#include "thread.h"
-extern char *_LLstacktoobig_stack_start;
+extern char *_LLstacktoobig_stack_end;
extern long _LLstacktoobig_stack_length;
void LL_stack_unwind(void);
@@ -19,9 +19,9 @@
void LL_stack_set_length_fraction(double);
/* some macros referenced from pypy.rlib.rstack */
-#define LL_stack_get_start() ((long)_LLstacktoobig_stack_start)
+#define LL_stack_get_end() ((long)_LLstacktoobig_stack_end)
#define LL_stack_get_length() _LLstacktoobig_stack_length
-#define LL_stack_get_start_adr() ((long)&_LLstacktoobig_stack_start) /* JIT */
+#define LL_stack_get_end_adr() ((long)&_LLstacktoobig_stack_end) /* JIT */
#define LL_stack_get_length_adr() ((long)&_LLstacktoobig_stack_length)/* JIT */
@@ -35,28 +35,11 @@
#ifndef PYPY_NOT_MAIN_FILE
#include <stdio.h>
-#ifndef PYPY_NOINLINE
-# if defined __GNUC__
-# define PYPY_NOINLINE __attribute__((noinline))
-# else
-// add hints for other compilers here ...
-# define PYPY_NOINLINE
-# endif
-#endif
-
-long PYPY_NOINLINE _LL_stack_growing_direction(char *parent)
-{
- char local;
- if (parent == NULL)
- return _LL_stack_growing_direction(&local);
- else
- return &local - parent;
-}
-
-char *_LLstacktoobig_stack_start = NULL;
+/* the current stack is in the interval [end-length:end]. We assume a
+ stack that grows downward here. */
+char *_LLstacktoobig_stack_end = NULL;
long _LLstacktoobig_stack_length = MAX_STACK_SIZE;
-int stack_direction = 0;
-RPyThreadStaticTLS start_tls_key;
+static RPyThreadStaticTLS end_tls_key;
void LL_stack_set_length_fraction(double fraction)
{
@@ -68,67 +51,49 @@
long diff, max_stack_size;
char *baseptr, *curptr = (char*)current;
- /* The stack_start variable is updated to match the current value
+ /* The stack_end variable is updated to match the current value
if it is still 0 or if we later find a 'curptr' position
- that is below it. The real stack_start pointer is stored in
+ that is above it. The real stack_end pointer is stored in
thread-local storage, but we try to minimize its overhead by
- keeping a local copy in _LLstacktoobig_stack_start. */
+ keeping a local copy in _LLstacktoobig_stack_end. */
- if (stack_direction == 0) {
+ if (_LLstacktoobig_stack_end == NULL) {
/* not initialized */
/* XXX We assume that initialization is performed early,
when there is still only one thread running. This
allows us to ignore race conditions here */
- char *errmsg = RPyThreadStaticTLS_Create(&start_tls_key);
+ char *errmsg = RPyThreadStaticTLS_Create(&end_tls_key);
if (errmsg) {
/* XXX should we exit the process? */
fprintf(stderr, "Internal PyPy error: %s\n", errmsg);
return 1;
}
- if (_LL_stack_growing_direction(NULL) > 0)
- stack_direction = +1;
- else
- stack_direction = -1;
}
- baseptr = (char *) RPyThreadStaticTLS_Get(start_tls_key);
+ baseptr = (char *) RPyThreadStaticTLS_Get(end_tls_key);
max_stack_size = _LLstacktoobig_stack_length;
- if (baseptr != NULL) {
- diff = curptr - baseptr;
- if (((unsigned long)diff) < (unsigned long)max_stack_size) {
+ if (baseptr == NULL) {
+ /* first time we see this thread */
+ }
+ else {
+ diff = baseptr - curptr;
+ if (((unsigned long)diff) <= (unsigned long)max_stack_size) {
/* within bounds, probably just had a thread switch */
- _LLstacktoobig_stack_start = baseptr;
+ _LLstacktoobig_stack_end = baseptr;
return 0;
}
-
- if (stack_direction > 0) {
- if (diff < 0 && diff > -max_stack_size)
- ; /* stack underflow */
- else
- return 1; /* stack overflow (probably) */
+ if (((unsigned long)-diff) <= (unsigned long)max_stack_size) {
+ /* stack underflowed: the initial estimation of
+ the stack base must be revised */
}
- else {
- if (diff >= max_stack_size && diff < 2*max_stack_size)
- ; /* stack underflow */
- else
- return 1; /* stack overflow (probably) */
- }
- /* else we underflowed the stack, which means that
- the initial estimation of the stack base must
- be revised */
+ else
+ return 1; /* stack overflow (probably) */
}
/* update the stack base pointer to the current value */
- if (stack_direction > 0) {
- /* the valid range is [curptr:curptr+MAX_STACK_SIZE] */
- baseptr = curptr;
- }
- else {
- /* the valid range is [curptr-MAX_STACK_SIZE+1:curptr+1] */
- baseptr = curptr - max_stack_size + 1;
- }
- RPyThreadStaticTLS_Set(start_tls_key, baseptr);
- _LLstacktoobig_stack_start = baseptr;
+ baseptr = curptr;
+ RPyThreadStaticTLS_Set(end_tls_key, baseptr);
+ _LLstacktoobig_stack_end = baseptr;
return 0;
}
diff --git a/pypy/translator/c/test/test_standalone.py b/pypy/translator/c/test/test_standalone.py
--- a/pypy/translator/c/test/test_standalone.py
+++ b/pypy/translator/c/test/test_standalone.py
@@ -702,6 +702,11 @@
return 42
return f(n+1)
def entry_point(argv):
+ _stack_set_length_fraction(0.1)
+ try:
+ return f(1)
+ except StackOverflow:
+ glob.n = 0
_stack_set_length_fraction(float(argv[1]))
try:
return f(1)
More information about the pypy-commit
mailing list