@@ -462,10 +462,28 @@ static int zend_jit_trace_record_fake_init_call(zend_execute_data *call, zend_ji
462
462
zend_jit_trace_stop stop ZEND_ATTRIBUTE_UNUSED = ZEND_JIT_TRACE_STOP_ERROR ;
463
463
464
464
do {
465
+ zend_function * func ;
466
+ zend_jit_op_array_trace_extension * jit_extension ;
467
+
465
468
if (call -> prev_execute_data ) {
466
469
idx = zend_jit_trace_record_fake_init_call (call -> prev_execute_data , trace_buffer , idx );
467
470
}
468
- TRACE_RECORD (ZEND_JIT_TRACE_INIT_CALL , ZEND_JIT_TRACE_FAKE_INIT_CALL , call -> func );
471
+
472
+ func = call -> func ;
473
+ if (func -> common .fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE ) {
474
+ /* TODO: Can we continue recording ??? */
475
+ return -1 ;
476
+ }
477
+ if (func -> type == ZEND_USER_FUNCTION
478
+ && (func -> op_array .fn_flags & ZEND_ACC_CLOSURE )) {
479
+ jit_extension =
480
+ (zend_jit_op_array_trace_extension * )ZEND_FUNC_INFO (& func -> op_array );
481
+ if (UNEXPECTED (!jit_extension )) {
482
+ return -1 ;
483
+ }
484
+ func = (zend_function * )jit_extension -> op_array ;
485
+ }
486
+ TRACE_RECORD (ZEND_JIT_TRACE_INIT_CALL , ZEND_JIT_TRACE_FAKE_INIT_CALL , func );
469
487
} while (0 );
470
488
return idx ;
471
489
}
@@ -511,6 +529,7 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
511
529
int level = 0 ;
512
530
int ret_level = 0 ;
513
531
zend_vm_opcode_handler_t handler ;
532
+ const zend_op_array * op_array ;
514
533
zend_jit_op_array_trace_extension * jit_extension ;
515
534
size_t offset ;
516
535
int idx , count ;
@@ -521,7 +540,6 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
521
540
int backtrack_ret_recursion_level = 0 ;
522
541
int loop_unroll_limit = 0 ;
523
542
const zend_op_array * unrolled_calls [ZEND_JIT_TRACE_MAX_CALL_DEPTH + ZEND_JIT_TRACE_MAX_RET_DEPTH ];
524
- zend_bool is_toplevel ;
525
543
#ifdef HAVE_GCC_GLOBAL_REGS
526
544
zend_execute_data * prev_execute_data = ex ;
527
545
@@ -541,15 +559,23 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
541
559
542
560
orig_opline = opline ;
543
561
562
+ op_array = & EX (func )-> op_array ;
544
563
jit_extension =
545
- (zend_jit_op_array_trace_extension * )ZEND_FUNC_INFO (& EX ( func ) -> op_array );
564
+ (zend_jit_op_array_trace_extension * )ZEND_FUNC_INFO (op_array );
546
565
offset = jit_extension -> offset ;
566
+ if (!op_array -> function_name
567
+ || (op_array -> fn_flags & ZEND_ACC_CLOSURE )) {
568
+ op_array = jit_extension -> op_array ;
569
+ }
547
570
548
- TRACE_START (ZEND_JIT_TRACE_START , start , & EX (func )-> op_array , opline );
549
- is_toplevel = EX (func )-> op_array .function_name == NULL ;
571
+ TRACE_START (ZEND_JIT_TRACE_START , start , op_array , opline );
550
572
551
573
if (prev_call ) {
552
- idx = zend_jit_trace_record_fake_init_call (prev_call , trace_buffer , idx );
574
+ int ret = zend_jit_trace_record_fake_init_call (prev_call , trace_buffer , idx );
575
+ if (ret < 0 ) {
576
+ return ZEND_JIT_TRACE_STOP_BAD_FUNC ;
577
+ }
578
+ idx = ret ;
553
579
}
554
580
555
581
while (1 ) {
@@ -660,7 +686,6 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
660
686
break ;
661
687
}
662
688
if (UNEXPECTED (execute_data != prev_execute_data )) {
663
- if (execute_data -> prev_execute_data == prev_execute_data ) {
664
689
#else
665
690
rc = handler (ZEND_OPCODE_HANDLER_ARGS_PASSTHRU );
666
691
if (rc != 0 ) {
@@ -670,6 +695,24 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
670
695
}
671
696
execute_data = EG (current_execute_data );
672
697
opline = EX (opline );
698
+ #endif
699
+
700
+ op_array = & EX (func )-> op_array ;
701
+ jit_extension =
702
+ (zend_jit_op_array_trace_extension * )ZEND_FUNC_INFO (op_array );
703
+ if (UNEXPECTED (!jit_extension )) {
704
+ stop = ZEND_JIT_TRACE_STOP_BAD_FUNC ;
705
+ break ;
706
+ }
707
+ offset = jit_extension -> offset ;
708
+ if (!op_array -> function_name
709
+ || (op_array -> fn_flags & ZEND_ACC_CLOSURE )) {
710
+ op_array = jit_extension -> op_array ;
711
+ }
712
+
713
+ #ifdef HAVE_GCC_GLOBAL_REGS
714
+ if (execute_data -> prev_execute_data == prev_execute_data ) {
715
+ #else
673
716
if (rc == 1 ) {
674
717
#endif
675
718
/* Enter into function */
@@ -687,7 +730,7 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
687
730
688
731
TRACE_RECORD (ZEND_JIT_TRACE_ENTER ,
689
732
EX (return_value ) != NULL ? ZEND_JIT_TRACE_RETRUN_VALUE_USED : 0 ,
690
- & EX ( func ) -> op_array );
733
+ op_array );
691
734
692
735
count = zend_jit_trace_recursive_call_count (& EX (func )-> op_array , unrolled_calls , ret_level , level );
693
736
@@ -708,10 +751,7 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
708
751
/* Return from function */
709
752
prev_call = EX (call );
710
753
if (level == 0 ) {
711
- if (is_toplevel ) {
712
- stop = ZEND_JIT_TRACE_STOP_TOPLEVEL ;
713
- break ;
714
- } else if (start == ZEND_JIT_TRACE_START_RETURN
754
+ if (start == ZEND_JIT_TRACE_START_RETURN
715
755
&& JIT_G (max_recursive_returns ) > 0
716
756
&& execute_data -> prev_execute_data
717
757
&& execute_data -> prev_execute_data -> func
@@ -721,7 +761,7 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
721
761
stop = ZEND_JIT_TRACE_STOP_TOO_DEEP_RET ;
722
762
break ;
723
763
}
724
- TRACE_RECORD (ZEND_JIT_TRACE_BACK , 0 , & EX ( func ) -> op_array );
764
+ TRACE_RECORD (ZEND_JIT_TRACE_BACK , 0 , op_array );
725
765
count = zend_jit_trace_recursive_ret_count (& EX (func )-> op_array , unrolled_calls , ret_level );
726
766
if (opline == orig_opline ) {
727
767
if (count + 1 >= JIT_G (max_recursive_returns )) {
@@ -737,10 +777,14 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
737
777
738
778
unrolled_calls [ret_level ] = & EX (func )-> op_array ;
739
779
ret_level ++ ;
740
- is_toplevel = EX (func )-> op_array .function_name == NULL ;
741
780
742
781
if (prev_call ) {
743
- idx = zend_jit_trace_record_fake_init_call (prev_call , trace_buffer , idx );
782
+ int ret = zend_jit_trace_record_fake_init_call (prev_call , trace_buffer , idx );
783
+ if (ret < 0 ) {
784
+ stop = ZEND_JIT_TRACE_STOP_BAD_FUNC ;
785
+ break ;
786
+ }
787
+ idx = ret ;
744
788
}
745
789
} else if (start & ZEND_JIT_TRACE_START_LOOP
746
790
&& !zend_jit_trace_bad_loop_exit (orig_opline )) {
@@ -754,29 +798,36 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
754
798
}
755
799
} else {
756
800
level -- ;
757
- TRACE_RECORD (ZEND_JIT_TRACE_BACK , 0 , & EX ( func ) -> op_array );
801
+ TRACE_RECORD (ZEND_JIT_TRACE_BACK , 0 , op_array );
758
802
}
759
803
}
760
804
#ifdef HAVE_GCC_GLOBAL_REGS
761
805
prev_execute_data = execute_data ;
762
806
#endif
763
- jit_extension =
764
- (zend_jit_op_array_trace_extension * )ZEND_FUNC_INFO (& EX (func )-> op_array );
765
- if (UNEXPECTED (!jit_extension )) {
766
- stop = ZEND_JIT_TRACE_STOP_BAD_FUNC ;
767
- break ;
768
- }
769
- offset = jit_extension -> offset ;
770
807
}
771
808
if (EX (call ) != prev_call ) {
772
809
if (EX (call )
773
810
&& EX (call )-> prev_execute_data == prev_call ) {
811
+ zend_function * func ;
812
+ zend_jit_op_array_trace_extension * jit_extension ;
813
+
774
814
if (EX (call )-> func -> common .fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE ) {
775
815
/* TODO: Can we continue recording ??? */
776
816
stop = ZEND_JIT_TRACE_STOP_TRAMPOLINE ;
777
817
break ;
778
818
}
779
- TRACE_RECORD (ZEND_JIT_TRACE_INIT_CALL , 0 , EX (call )-> func );
819
+ func = EX (call )-> func ;
820
+ if (func -> type == ZEND_USER_FUNCTION
821
+ && (func -> op_array .fn_flags & ZEND_ACC_CLOSURE )) {
822
+ jit_extension =
823
+ (zend_jit_op_array_trace_extension * )ZEND_FUNC_INFO (& func -> op_array );
824
+ if (UNEXPECTED (!jit_extension )) {
825
+ stop = ZEND_JIT_TRACE_STOP_BAD_FUNC ;
826
+ break ;
827
+ }
828
+ func = (zend_function * )jit_extension -> op_array ;
829
+ }
830
+ TRACE_RECORD (ZEND_JIT_TRACE_INIT_CALL , 0 , func );
780
831
}
781
832
prev_call = EX (call );
782
833
}
0 commit comments