Some questions about reference count in php extension

function test($arr) {
    return $arr;
}

$arr = [1111];
test($arr);
debug_zval_dump($arr);

c implementation code of test:

PHP_FUNCTION(test)
{
    zval *arr;
    ZEND_PARSE_PARAMETERS_START(1, 1)
        Z_PARAM_ARRAY(arr)
    ZEND_PARSE_PARAMETERS_END();

    Z_TRY_ADDREF_P(arr);
    RETURN_ARR(Z_ARR_P(arr));
}

the final reference count of $arr in this code is 1 when test is defined. The kernel adds 1 through the macro Z _ TRY_ADDREF_P when the test method is called, and 1 when it is used as a parameter to debug_zval_dump. The question is why add 1 when calling the test method, rather than wait until the return value of test is needed?

$c = [33333];

$t = [
    "a" => 111,
    "c" => $c
];

$t["c"] = 222;
// test_set($t, "c", 2111);

directly manipulate the array or call test_set to modify the value of the key "c". The reference count of the variable $c is subtracted by 1. The c implementation code of
test_set:

PHP_FUNCTION(test_set)
{
    zval *arr, *val;
    zend_string *key;
    ZEND_PARSE_PARAMETERS_START(3, 3)
        Z_PARAM_ARRAY_EX(arr, 0, 1)
        Z_PARAM_STR(key)
        Z_PARAM_ZVAL(val)
    ZEND_PARSE_PARAMETERS_END();

    Z_TRY_ADDREF_P(val);
    zend_symtable_update(Z_ARRVAL_P(arr), key, val);

    RETURN_TRUE;
}

the reference is not subtracted by 1 in test_set. Where does the subtract 1 operation take place here?

Php
Apr.19,2021
Menu