diff options
| author | Dmitry Stogov <dmitry@zend.com> | 2020-07-28 19:03:05 +0300 | 
|---|---|---|
| committer | Dmitry Stogov <dmitry@zend.com> | 2020-07-28 19:03:05 +0300 | 
| commit | 2a72778e2dc4f8dd9d3843e87138e0d33d928066 (patch) | |
| tree | 5dd272f5609ad1e587bb86c6d833ff1d04aad0ed | |
| parent | 251e667488fffa39f900c686a7df862aeade176b (diff) | |
| download | php-git-2a72778e2dc4f8dd9d3843e87138e0d33d928066.tar.gz | |
Check for EG(exception) after leaving function frame
| -rw-r--r-- | ext/opcache/jit/zend_jit.c | 2 | ||||
| -rw-r--r-- | ext/opcache/jit/zend_jit_trace.c | 8 | ||||
| -rw-r--r-- | ext/opcache/jit/zend_jit_x86.dasc | 13 | 
3 files changed, 18 insertions, 5 deletions
| diff --git a/ext/opcache/jit/zend_jit.c b/ext/opcache/jit/zend_jit.c index 1968eff8d5..7b7534fff6 100644 --- a/ext/opcache/jit/zend_jit.c +++ b/ext/opcache/jit/zend_jit.c @@ -2727,7 +2727,7 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op  									}  								}  							} -						    if (!zend_jit_leave_func(&dasm_state, opline, op_array, NULL, NULL)) { +						    if (!zend_jit_leave_func(&dasm_state, opline, op_array, NULL, NULL, 1)) {  								goto jit_failure;  						    }  						} diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index a018c31c2e..d894b50f18 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -3724,6 +3724,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par  							}  						} else {  							int j; +							int may_throw = 0;  							if (!zend_jit_return(&dasm_state, opline, op_array,  									op1_info, OP1_REG_ADDR())) { @@ -3750,9 +3751,14 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par  									if (!zend_jit_free_cv(&dasm_state, opline, op_array, info, j)) {  										goto jit_failure;  									} +									if (info & (MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_ARRAY_OF_OBJECT|MAY_BE_ARRAY_OF_ARRAY|MAY_BE_ARRAY_OF_RESOURCE)) { +										if (info & MAY_BE_RC1) { +											may_throw = 1; +										} +									}  								}  							} -							if (!zend_jit_leave_func(&dasm_state, opline, op_array, p + 1, &zend_jit_traces[ZEND_JIT_TRACE_NUM])) { +							if (!zend_jit_leave_func(&dasm_state, opline, op_array, p + 1, &zend_jit_traces[ZEND_JIT_TRACE_NUM], may_throw)) {  								goto jit_failure;  							}  						} diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index 0c8d847dec..a63db2ad9a 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -9986,7 +9986,7 @@ static int zend_jit_free_op(dasm_State **Dst, const zend_op *opline, /*const zen  	return 1;  } -static int zend_jit_leave_func(dasm_State **Dst, const zend_op *opline, const zend_op_array *op_array, zend_jit_trace_rec *trace, zend_jit_trace_info *trace_info) +static int zend_jit_leave_func(dasm_State **Dst, const zend_op *opline, const zend_op_array *op_array, zend_jit_trace_rec *trace, zend_jit_trace_info *trace_info, int may_throw)  {  	/* ZEND_CALL_FAKE_CLOSURE handled on slow path to eliminate check for ZEND_CALL_CLOSURE on fast path */  	|	mov FCARG1d, dword [FP + offsetof(zend_execute_data, This.u1.type_info)] @@ -10055,13 +10055,20 @@ static int zend_jit_leave_func(dasm_State **Dst, const zend_op *opline, const ze  		 && (JIT_G(current_frame) && !TRACE_FRAME_IS_UNKNOWN_RETURN(JIT_G(current_frame)))) {  			zend_jit_reset_opline(Dst, NULL);  		} else { -			// TODO: exception handling for tracing JIT ???  			|	LOAD_OPLINE  			|	ADD_IP sizeof(zend_op)  		}  		|8: +		if ((trace->op != ZEND_JIT_TRACE_END || +				trace->stop != ZEND_JIT_TRACE_STOP_RECURSIVE_RET) && +					may_throw) { +			|	// if (EG(exception)) +			|	MEM_OP2_1_ZTS cmp, aword, executor_globals, exception, 0, r0 +			|	jne ->leave_throw_handler +		} +  		if (trace->op == ZEND_JIT_TRACE_BACK  		 && (!JIT_G(current_frame) || TRACE_FRAME_IS_UNKNOWN_RETURN(JIT_G(current_frame)))) {  			const zend_op *next_opline = trace->opline; @@ -10074,6 +10081,7 @@ static int zend_jit_leave_func(dasm_State **Dst, const zend_op *opline, const ze  			} while (trace->op == ZEND_JIT_TRACE_INIT_CALL);  			ZEND_ASSERT(trace->op == ZEND_JIT_TRACE_VM || trace->op == ZEND_JIT_TRACE_END);  			next_opline = trace->opline; +			ZEND_ASSERT(next_opline != NULL);  			current_frame = JIT_G(current_frame);  			JIT_G(current_frame) = NULL;  			exit_point = zend_jit_trace_get_exit_point(opline, NULL, trace, 0); @@ -10082,7 +10090,6 @@ static int zend_jit_leave_func(dasm_State **Dst, const zend_op *opline, const ze  			if (!exit_addr) {  				return 0;  			} -			|	// TODO: exception handling ???  			if (trace->op == ZEND_JIT_TRACE_END  			 && trace->stop == ZEND_JIT_TRACE_STOP_RECURSIVE_RET) {  				trace_info->flags |= ZEND_JIT_TRACE_LOOP; | 
