diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index 43e912f5cf..cf591ed5e3 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -111,6 +111,12 @@ static long max_stack_depth_bytes = 100 * 1024L; */ char *stack_base_ptr = NULL; +/* + * On IA64 we also have to remember the register stack base. + */ +#if defined(__ia64__) || defined(__ia64) +char *register_stack_base_ptr = NULL; +#endif /* * Flag to mark SIGHUP. Whenever the main loop comes around it @@ -2677,6 +2683,35 @@ ProcessInterrupts(void) } +/* + * IA64-specific code to fetch the AR.BSP register for stack depth checks. + * + * We currently support gcc and icc here. + */ +#if defined(__ia64__) || defined(__ia64) + +#include + +static __inline__ char * +ia64_get_bsp(void) +{ + char *ret; + +#ifndef __INTEL_COMPILER + /* the ;; is a "stop", seems to be required before fetching BSP */ + __asm__ __volatile__( + ";;\n" + " mov %0=ar.bsp \n" +: "=r"(ret)); +#else + ret = (char *) __getReg(_IA64_REG_AR_BSP); +#endif + return ret; +} + +#endif /* IA64 */ + + /* * check_stack_depth: check for excessively deep recursion * @@ -2719,6 +2754,28 @@ check_stack_depth(void) errhint("Increase the configuration parameter \"max_stack_depth\", " "after ensuring the platform's stack depth limit is adequate."))); } + + /* + * On IA64 there is a separate "register" stack that requires its own + * independent check. For this, we have to measure the change in the + * "BSP" pointer from PostgresMain to here. Logic is just as above, + * except that we know IA64's register stack grows up. + * + * Note we assume that the same max_stack_depth applies to both stacks. + */ +#if defined(__ia64__) || defined(__ia64) + stack_depth = (long) (ia64_get_bsp() - register_stack_base_ptr); + + if (stack_depth > max_stack_depth_bytes && + register_stack_base_ptr != NULL) + { + ereport(ERROR, + (errcode(ERRCODE_STATEMENT_TOO_COMPLEX), + errmsg("stack depth limit exceeded"), + errhint("Increase the configuration parameter \"max_stack_depth\", " + "after ensuring the platform's stack depth limit is adequate."))); + } +#endif /* IA64 */ } /* GUC assign hook for max_stack_depth */ @@ -2894,6 +2951,9 @@ PostgresMain(int argc, char *argv[], const char *username) /* Set up reference point for stack depth checking */ stack_base_ptr = &stack_base; +#if defined(__ia64__) || defined(__ia64) + register_stack_base_ptr = ia64_get_bsp(); +#endif /* Compute paths, if we didn't inherit them from postmaster */ if (my_exec_path[0] == '\0')