@@ -97,7 +97,7 @@ Fast, but limited size. */
9797
9898/* Growth rate for stack allocated by the OS. Should be the multiply
9999of page size. */
100- #define STACK_GROWTH_RATE 8192
100+ #define STACK_GROWTH_RATE (sljit_sw) 8192
101101
102102/* Enable to check that the allocation could destroy temporaries. */
103103#if defined SLJIT_DEBUG && SLJIT_DEBUG
@@ -438,6 +438,8 @@ typedef struct compiler_common {
438438 BOOL local_quit_available ;
439439 /* Currently in a positive assertion. */
440440 BOOL in_positive_assertion ;
441+ /* More than STACK_GROWTH_RATE / 2 stack memory is allocated. */
442+ BOOL large_stack_allocation ;
441443 /* Newline control. */
442444 int nltype ;
443445 sljit_u32 nlmax ;
@@ -3144,6 +3146,8 @@ static SLJIT_INLINE void allocate_stack(compiler_common *common, int size)
31443146DEFINE_COMPILER ;
31453147
31463148SLJIT_ASSERT (size > 0 );
3149+ if (size > (STACK_GROWTH_RATE / ((sljit_s32 )sizeof (sljit_sw ) * 2 )))
3150+ common -> large_stack_allocation = TRUE;
31473151OP2 (SLJIT_SUB , STACK_TOP , 0 , STACK_TOP , 0 , SLJIT_IMM , size * sizeof (sljit_sw ));
31483152#ifdef DESTROY_REGISTERS
31493153OP1 (SLJIT_MOV , TMP1 , 0 , SLJIT_IMM , 12345 );
@@ -14193,7 +14197,20 @@ SLJIT_ASSERT(TMP1 == SLJIT_R0 && STR_PTR == SLJIT_R1);
1419314197
1419414198OP1 (SLJIT_MOV , SLJIT_MEM1 (SLJIT_SP ), LOCALS1 , STR_PTR , 0 );
1419514199OP1 (SLJIT_MOV , SLJIT_R0 , 0 , ARGUMENTS , 0 );
14196- OP2 (SLJIT_SUB , SLJIT_R1 , 0 , STACK_LIMIT , 0 , SLJIT_IMM , STACK_GROWTH_RATE );
14200+ if (common -> large_stack_allocation )
14201+ {
14202+ SLJIT_COMPILE_ASSERT ((STACK_GROWTH_RATE & (STACK_GROWTH_RATE - 1 )) == 0 , stack_growth_must_be_power_of_2 );
14203+ // Negative difference. The positive difference would also use the same amount
14204+ // of operations, but the last subtraction emits several instructions on x86.
14205+ OP2 (SLJIT_SUB , SLJIT_R1 , 0 , STACK_TOP , 0 , STACK_LIMIT , 0 );
14206+ // Minimum extra space after allocation.
14207+ OP2 (SLJIT_SUB , SLJIT_R1 , 0 , SLJIT_R1 , 0 , SLJIT_IMM , (STACK_GROWTH_RATE / 2 ));
14208+ // Rounds down negative numbers.
14209+ OP2 (SLJIT_AND , SLJIT_R1 , 0 , SLJIT_R1 , 0 , SLJIT_IMM , ~(STACK_GROWTH_RATE - 1 ));
14210+ OP2 (SLJIT_ADD , SLJIT_R1 , 0 , SLJIT_R1 , 0 , STACK_LIMIT , 0 );
14211+ }
14212+ else
14213+ OP2 (SLJIT_SUB , SLJIT_R1 , 0 , STACK_LIMIT , 0 , SLJIT_IMM , STACK_GROWTH_RATE );
1419714214OP1 (SLJIT_MOV , SLJIT_R0 , 0 , SLJIT_MEM1 (SLJIT_R0 ), SLJIT_OFFSETOF (jit_arguments , stack ));
1419814215OP1 (SLJIT_MOV , STACK_LIMIT , 0 , TMP2 , 0 );
1419914216
0 commit comments