@@ -894,8 +894,8 @@ static void* dasm_labels[zend_lb_MAX];
894
894
|| }
895
895
| .if X64
896
896
|| } else if (!IS_32BIT(zv)) {
897
- | mov64 tmp_reg, ((uintptr_t)zv)
898
- | SSE_AVX_INS movsd, vmovsd, xmm(dst_reg-ZREG_XMM0), qword [tmp_reg]
897
+ | mov64 Ra( tmp_reg) , ((uintptr_t)zv)
898
+ | SSE_AVX_INS movsd, vmovsd, xmm(dst_reg-ZREG_XMM0), qword [Ra( tmp_reg) ]
899
899
| .endif
900
900
|| } else {
901
901
| SSE_AVX_INS movsd, vmovsd, xmm(dst_reg-ZREG_XMM0), qword [((uint32_t)(uintptr_t)zv)]
@@ -913,8 +913,8 @@ static void* dasm_labels[zend_lb_MAX];
913
913
|| if (Z_MODE(dst_addr) == IS_REG) {
914
914
| mov64 Ra(Z_REG(dst_addr)), ((uintptr_t)Z_LVAL_P(zv))
915
915
|| } else {
916
- | mov64 tmp_reg, ((uintptr_t)Z_LVAL_P(zv))
917
- | SET_ZVAL_LVAL dst_addr, tmp_reg
916
+ | mov64 Ra( tmp_reg) , ((uintptr_t)Z_LVAL_P(zv))
917
+ | SET_ZVAL_LVAL dst_addr, Ra( tmp_reg)
918
918
|| }
919
919
|| } else {
920
920
| SET_ZVAL_LVAL dst_addr, Z_LVAL_P(zv)
@@ -948,8 +948,8 @@ static void* dasm_labels[zend_lb_MAX];
948
948
|| }
949
949
| .if X64
950
950
|| } else if (!IS_32BIT(zv)) {
951
- | mov64 tmp_reg, ((uintptr_t)zv)
952
- | SSE_AVX_INS movsd, vmovsd, xmm(dst_reg-ZREG_XMM0), qword [tmp_reg]
951
+ | mov64 Ra( tmp_reg) , ((uintptr_t)zv)
952
+ | SSE_AVX_INS movsd, vmovsd, xmm(dst_reg-ZREG_XMM0), qword [Ra( tmp_reg) ]
953
953
| .endif
954
954
|| } else {
955
955
| SSE_AVX_INS movsd, vmovsd, xmm(dst_reg-ZREG_XMM0), qword [((uint32_t)(uintptr_t)zv)]
@@ -986,9 +986,9 @@ static void* dasm_labels[zend_lb_MAX];
986
986
| mov64 Ra(Z_REG(res_addr)), ((uintptr_t)Z_LVAL_P(zv))
987
987
| SET_ZVAL_LVAL dst_addr, Ra(Z_REG(res_addr))
988
988
|| } else {
989
- | mov64 tmp_reg, ((uintptr_t)Z_LVAL_P(zv))
990
- | SET_ZVAL_LVAL dst_addr, tmp_reg
991
- | SET_ZVAL_LVAL res_addr, tmp_reg
989
+ | mov64 Ra( tmp_reg) , ((uintptr_t)Z_LVAL_P(zv))
990
+ | SET_ZVAL_LVAL dst_addr, Ra( tmp_reg)
991
+ | SET_ZVAL_LVAL res_addr, Ra( tmp_reg)
992
992
|| }
993
993
|| } else if (Z_MODE(dst_addr) == IS_REG) {
994
994
| SET_ZVAL_LVAL dst_addr, Z_LVAL_P(zv)
@@ -5367,20 +5367,28 @@ static int zend_jit_simple_assign(dasm_State **Dst,
5367
5367
int save_r1)
5368
5368
/* Labels: 1,2,3 */
5369
5369
{
5370
- ZEND_ASSERT(Z_MODE(var_addr) == IS_REG || Z_REG(var_addr) != ZREG_R0);
5370
+ zend_reg tmp_reg;
5371
+
5372
+ if (Z_MODE(var_addr) == IS_REG || Z_REG(var_addr) != ZREG_R0) {
5373
+ tmp_reg = ZREG_R0;
5374
+ } else {
5375
+ /* ASSIGN_DIM */
5376
+ tmp_reg = ZREG_FCARG1a;
5377
+ }
5378
+
5371
5379
if (Z_MODE(val_addr) == IS_CONST_ZVAL) {
5372
5380
zval *zv = Z_ZV(val_addr);
5373
5381
5374
5382
if (!res_addr) {
5375
- | ZVAL_COPY_CONST var_addr, var_info, var_def_info, zv, r0
5383
+ | ZVAL_COPY_CONST var_addr, var_info, var_def_info, zv, tmp_reg
5376
5384
} else {
5377
- | ZVAL_COPY_CONST_2 var_addr, res_addr, var_info, var_def_info, zv, r0
5385
+ | ZVAL_COPY_CONST_2 var_addr, res_addr, var_info, var_def_info, zv, tmp_reg
5378
5386
}
5379
5387
if (Z_REFCOUNTED_P(zv)) {
5380
5388
if (!res_addr) {
5381
- | ADDREF_CONST zv, r0
5389
+ | ADDREF_CONST zv, Ra(tmp_reg)
5382
5390
} else {
5383
- | ADDREF_CONST_2 zv, r0
5391
+ | ADDREF_CONST_2 zv, Ra(tmp_reg)
5384
5392
}
5385
5393
}
5386
5394
} else {
@@ -5400,7 +5408,7 @@ static int zend_jit_simple_assign(dasm_State **Dst,
5400
5408
if (res_addr) {
5401
5409
| SET_ZVAL_TYPE_INFO res_addr, IS_NULL
5402
5410
}
5403
- | SAVE_VALID_OPLINE opline, r0
5411
+ | SAVE_VALID_OPLINE opline, Ra(tmp_reg)
5404
5412
| mov FCARG1d, val.var
5405
5413
| EXT_CALL zend_jit_undefined_op_helper, r0
5406
5414
if (save_r1) {
@@ -5435,22 +5443,22 @@ static int zend_jit_simple_assign(dasm_State **Dst,
5435
5443
| // ZVAL_COPY_VALUE(return_value, &ref->value);
5436
5444
ref_addr = ZEND_ADDR_MEM_ZVAL(ZREG_R2, 8);
5437
5445
if (!res_addr) {
5438
- | ZVAL_COPY_VALUE var_addr, var_info, ref_addr, val_info, ZREG_R2, ZREG_R0
5446
+ | ZVAL_COPY_VALUE var_addr, var_info, ref_addr, val_info, ZREG_R2, tmp_reg
5439
5447
} else {
5440
- | ZVAL_COPY_VALUE_2 var_addr, var_info, res_addr, ref_addr, val_info, ZREG_R2, ZREG_R0
5448
+ | ZVAL_COPY_VALUE_2 var_addr, var_info, res_addr, ref_addr, val_info, ZREG_R2, tmp_reg
5441
5449
}
5442
5450
| je >2
5443
5451
| IF_NOT_REFCOUNTED dh, >3
5444
5452
if (!res_addr) {
5445
- | GC_ADDREF r0
5453
+ | GC_ADDREF Ra(tmp_reg)
5446
5454
} else {
5447
- | add dword [r0 ], 2
5455
+ | add dword [Ra(tmp_reg) ], 2
5448
5456
}
5449
5457
| jmp >3
5450
5458
|2:
5451
5459
if (res_addr) {
5452
5460
| IF_NOT_REFCOUNTED dh, >2
5453
- | GC_ADDREF r0
5461
+ | GC_ADDREF Ra(tmp_reg)
5454
5462
|2:
5455
5463
}
5456
5464
if (save_r1) {
@@ -5470,20 +5478,20 @@ static int zend_jit_simple_assign(dasm_State **Dst,
5470
5478
}
5471
5479
5472
5480
if (!res_addr) {
5473
- | ZVAL_COPY_VALUE var_addr, var_info, val_addr, val_info, ZREG_R2, ZREG_R0
5481
+ | ZVAL_COPY_VALUE var_addr, var_info, val_addr, val_info, ZREG_R2, tmp_reg
5474
5482
} else {
5475
- | ZVAL_COPY_VALUE_2 var_addr, var_info, res_addr, val_addr, val_info, ZREG_R2, ZREG_R0
5483
+ | ZVAL_COPY_VALUE_2 var_addr, var_info, res_addr, val_addr, val_info, ZREG_R2, tmp_reg
5476
5484
}
5477
5485
5478
5486
if (val_type == IS_CV) {
5479
5487
if (!res_addr) {
5480
- | TRY_ADDREF val_info, dh, r0
5488
+ | TRY_ADDREF val_info, dh, Ra(tmp_reg)
5481
5489
} else {
5482
- | TRY_ADDREF_2 val_info, dh, r0
5490
+ | TRY_ADDREF_2 val_info, dh, Ra(tmp_reg)
5483
5491
}
5484
5492
} else {
5485
5493
if (res_addr) {
5486
- | TRY_ADDREF val_info, dh, r0
5494
+ | TRY_ADDREF val_info, dh, Ra(tmp_reg)
5487
5495
}
5488
5496
}
5489
5497
|3:
@@ -5543,24 +5551,33 @@ static int zend_jit_assign_to_variable(dasm_State **Dst,
5543
5551
/* Labels: 1,2,3,4,5,8 */
5544
5552
{
5545
5553
int done = 0;
5554
+ zend_reg ref_reg, tmp_reg;
5555
+
5556
+ if (Z_MODE(var_addr) == IS_REG || Z_REG(var_use_addr) != ZREG_R0) {
5557
+ ref_reg = ZREG_FCARG1a;
5558
+ tmp_reg = ZREG_R0;
5559
+ } else {
5560
+ /* ASSIGN_DIM */
5561
+ ref_reg = ZREG_R0;
5562
+ tmp_reg = ZREG_FCARG1a;
5563
+ }
5546
5564
5547
5565
if (var_info & MAY_BE_REF) {
5548
- if (Z_MODE(var_use_addr) != IS_MEM_ZVAL || Z_REG(var_use_addr) != ZREG_FCARG1a || Z_OFFSET(var_use_addr) != 0) {
5549
- | LOAD_ZVAL_ADDR FCARG1a , var_use_addr
5550
- var_addr = var_use_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1a , 0);
5566
+ if (Z_MODE(var_use_addr) != IS_MEM_ZVAL || Z_REG(var_use_addr) != ref_reg || Z_OFFSET(var_use_addr) != 0) {
5567
+ | LOAD_ZVAL_ADDR Ra(ref_reg) , var_use_addr
5568
+ var_addr = var_use_addr = ZEND_ADDR_MEM_ZVAL(ref_reg , 0);
5551
5569
}
5552
5570
| // if (Z_ISREF_P(variable_ptr)) {
5553
- | IF_NOT_Z_TYPE, FCARG1a , IS_REFERENCE, >1
5571
+ | IF_NOT_Z_TYPE, Ra(ref_reg) , IS_REFERENCE, >1
5554
5572
| // if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(variable_ptr)))) {
5555
- | GET_Z_PTR FCARG1a, FCARG1a
5573
+ | GET_Z_PTR FCARG1a, Ra(ref_reg)
5556
5574
if (!zend_jit_assign_to_typed_ref(Dst, opline, val_type, val_addr, check_exception)) {
5557
5575
return 0;
5558
5576
}
5559
- | add FCARG1a, offsetof(zend_reference, val)
5577
+ | lea Ra(ref_reg), [FCARG1a + offsetof(zend_reference, val)]
5560
5578
|1:
5561
5579
}
5562
5580
if (var_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE)) {
5563
- ZEND_ASSERT(Z_REG(var_use_addr) != ZREG_R0);
5564
5581
if (RC_MAY_BE_1(var_info)) {
5565
5582
int in_cold = 0;
5566
5583
@@ -5570,13 +5587,42 @@ static int zend_jit_assign_to_variable(dasm_State **Dst,
5570
5587
|1:
5571
5588
in_cold = 1;
5572
5589
}
5573
- if (Z_REG(var_use_addr) == ZREG_FCARG1a) {
5574
- | GET_ZVAL_PTR r0, var_use_addr
5575
- | mov aword T1, r0 // save
5590
+ if (Z_REG(var_use_addr) == ZREG_FCARG1a || Z_REG(var_use_addr) == ZREG_R0) {
5591
+ zend_bool keep_gc = 0;
5592
+
5593
+ | GET_ZVAL_PTR Ra(tmp_reg), var_use_addr
5594
+ if (tmp_reg == ZREG_FCARG1a) {
5595
+ if (Z_MODE(val_addr) == IS_REG) {
5596
+ keep_gc = 1;
5597
+ } else if ((val_info & ((MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_GUARD)-(MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE))) == 0) {
5598
+ keep_gc = 1;
5599
+ } else if (Z_MODE(val_addr) == IS_CONST_ZVAL) {
5600
+ if (sizeof(void*) == 4) {
5601
+ keep_gc = 1;
5602
+ } else {
5603
+ zval *zv = Z_ZV(val_addr);
5604
+
5605
+ if (Z_TYPE_P(zv) == IS_DOUBLE) {
5606
+ if (Z_DVAL_P(zv) == 0 || IS_32BIT(zv)) {
5607
+ keep_gc = 1;
5608
+ }
5609
+ } else if (IS_SIGNED_32BIT(Z_LVAL_P(zv))) {
5610
+ keep_gc = 1;
5611
+ }
5612
+ }
5613
+ } else if (Z_MODE(val_addr) == IS_MEM_ZVAL) {
5614
+ if ((val_info & (MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_GUARD)) == MAY_BE_DOUBLE) {
5615
+ keep_gc = 1;
5616
+ }
5617
+ }
5618
+ }
5619
+ if (!keep_gc) {
5620
+ | mov aword T1, Ra(tmp_reg) // save
5621
+ }
5576
5622
if (!zend_jit_simple_assign(Dst, opline, var_addr, var_info, var_def_info, val_type, val, val_addr, val_info, res_addr, in_cold, 0)) {
5577
5623
return 0;
5578
5624
}
5579
- if (Z_REG(var_use_addr) == ZREG_FCARG1a ) {
5625
+ if (!keep_gc ) {
5580
5626
| mov FCARG1a, aword T1 // restore
5581
5627
}
5582
5628
} else {
@@ -5618,26 +5664,20 @@ static int zend_jit_assign_to_variable(dasm_State **Dst,
5618
5664
if (var_info & ((MAY_BE_ANY|MAY_BE_UNDEF)-(MAY_BE_OBJECT|MAY_BE_RESOURCE))) {
5619
5665
| IF_NOT_ZVAL_REFCOUNTED var_use_addr, >5
5620
5666
}
5621
- | GET_ZVAL_PTR r0, var_use_addr
5622
- | GC_DELREF r0
5623
5667
if (var_info & (MAY_BE_ARRAY|MAY_BE_OBJECT)) {
5624
5668
if (Z_REG(var_use_addr) == ZREG_FP) {
5625
- | GET_ZVAL_PTR FCARG1a, var_use_addr
5626
- | IF_GC_MAY_NOT_LEAK FCARG1a, >5
5627
- } else if (Z_REG(var_use_addr) != ZREG_FCARG1a) {
5628
- | GET_ZVAL_PTR FCARG1a, var_use_addr
5629
- | IF_GC_MAY_NOT_LEAK FCARG1a, >5
5630
- | mov T1, Ra(Z_REG(var_use_addr)) // save
5631
- } else {
5632
- | GET_ZVAL_PTR r0, var_use_addr
5633
- | IF_GC_MAY_NOT_LEAK r0, >5
5634
5669
| mov T1, Ra(Z_REG(var_use_addr)) // save
5635
- | GET_ZVAL_PTR FCARG1a, var_use_addr
5636
5670
}
5671
+ | GET_ZVAL_PTR FCARG1a, var_use_addr
5672
+ | GC_DELREF FCARG1a
5673
+ | IF_GC_MAY_NOT_LEAK FCARG1a, >5
5637
5674
| EXT_CALL gc_possible_root, r0
5638
5675
if (Z_REG(var_use_addr) != ZREG_FP) {
5639
5676
| mov Ra(Z_REG(var_use_addr)), T1 // restore
5640
5677
}
5678
+ } else {
5679
+ | GET_ZVAL_PTR Ra(tmp_reg), var_use_addr
5680
+ | GC_DELREF Ra(tmp_reg)
5641
5681
}
5642
5682
|5:
5643
5683
}
@@ -5714,7 +5754,7 @@ static int zend_jit_assign_dim(dasm_State **Dst, const zend_op *opline, uint32_t
5714
5754
|6:
5715
5755
if (opline->op2_type == IS_UNUSED) {
5716
5756
uint32_t var_info = MAY_BE_NULL;
5717
- zend_jit_addr var_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1a , 0);
5757
+ zend_jit_addr var_addr = ZEND_ADDR_MEM_ZVAL(ZREG_R0 , 0);
5718
5758
5719
5759
| // var_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(container), &EG(uninitialized_zval));
5720
5760
| LOAD_ADDR_ZTS FCARG2a, executor_globals, uninitialized_zval
@@ -5729,28 +5769,26 @@ static int zend_jit_assign_dim(dasm_State **Dst, const zend_op *opline, uint32_t
5729
5769
| //ZEND_VM_C_GOTO(assign_dim_op_ret_null);
5730
5770
| jmp >9
5731
5771
|.code
5732
- | mov FCARG1a, r0
5733
5772
5734
5773
if (!zend_jit_simple_assign(Dst, opline, var_addr, var_info, -1, (opline+1)->op1_type, (opline+1)->op1, op3_addr, val_info, res_addr, 0, 0)) {
5735
5774
return 0;
5736
5775
}
5737
5776
} else {
5738
5777
uint32_t var_info = zend_array_element_type(op1_info, opline->op1_type, 0, 0);
5739
- zend_jit_addr var_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1a , 0);
5778
+ zend_jit_addr var_addr = ZEND_ADDR_MEM_ZVAL(ZREG_R0 , 0);
5740
5779
5741
5780
if (!zend_jit_fetch_dimension_address_inner(Dst, opline, BP_VAR_W, op1_info, op2_info, NULL, NULL, NULL)) {
5742
5781
return 0;
5743
5782
}
5744
5783
5745
- |8:
5746
- | mov FCARG1a, r0
5747
-
5748
5784
if (op1_info & (MAY_BE_ARRAY_OF_REF|MAY_BE_OBJECT)) {
5749
5785
var_info |= MAY_BE_REF;
5750
5786
}
5751
5787
if (var_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE)) {
5752
5788
var_info |= MAY_BE_RC1;
5753
5789
}
5790
+
5791
+ |8:
5754
5792
| // value = zend_assign_to_variable(variable_ptr, value, OP_DATA_TYPE);
5755
5793
if (!zend_jit_assign_to_variable(Dst, opline, var_addr, var_addr, var_info, -1, (opline+1)->op1_type, (opline+1)->op1, op3_addr, val_info, res_addr, 0)) {
5756
5794
return 0;
@@ -9191,7 +9229,7 @@ static int zend_jit_send_val(dasm_State **Dst, const zend_op *opline, uint32_t o
9191
9229
if (opline->op1_type == IS_CONST) {
9192
9230
zval *zv = RT_CONSTANT(opline, opline->op1);
9193
9231
9194
- | ZVAL_COPY_CONST arg_addr, MAY_BE_ANY, MAY_BE_ANY, zv, r0
9232
+ | ZVAL_COPY_CONST arg_addr, MAY_BE_ANY, MAY_BE_ANY, zv, ZREG_R0
9195
9233
if (Z_REFCOUNTED_P(zv)) {
9196
9234
| ADDREF_CONST zv, r0
9197
9235
}
@@ -10297,7 +10335,7 @@ static int zend_jit_return(dasm_State **Dst, const zend_op *opline, const zend_o
10297
10335
10298
10336
if (opline->op1_type == IS_CONST) {
10299
10337
zval *zv = RT_CONSTANT(opline, opline->op1);
10300
- | ZVAL_COPY_CONST ret_addr, MAY_BE_ANY, MAY_BE_ANY, zv, r0
10338
+ | ZVAL_COPY_CONST ret_addr, MAY_BE_ANY, MAY_BE_ANY, zv, ZREG_R0
10301
10339
if (Z_REFCOUNTED_P(zv)) {
10302
10340
| ADDREF_CONST zv, r0
10303
10341
}
@@ -11102,7 +11140,7 @@ static int zend_jit_recv_init(dasm_State **Dst, const zend_op *opline, const zen
11102
11140
| cmp dword EX->This.u2.num_args, arg_num
11103
11141
| jae >5
11104
11142
}
11105
- | ZVAL_COPY_CONST res_addr, -1, -1, zv, r0
11143
+ | ZVAL_COPY_CONST res_addr, -1, -1, zv, ZREG_R0
11106
11144
if (Z_REFCOUNTED_P(zv)) {
11107
11145
| ADDREF_CONST zv, r0
11108
11146
}
0 commit comments