diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index 945eee571f2..40684eef481 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -97,6 +97,12 @@ static int max_stack_depth_bytes = 2048 * 1024; /* Do not make static so PL/Java can modifiy it */ 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 @@ -2288,6 +2294,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 * @@ -2335,6 +2370,27 @@ check_stack_depth(void) errmsg("stack depth limit exceeded"), errhint("Increase the configuration parameter \"max_stack_depth\"."))); } + + /* + * 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\"."))); + } +#endif /* IA64 */ } /* GUC assign hook to update max_stack_depth_bytes from max_stack_depth */ @@ -2491,6 +2547,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')