]> granicus.if.org Git - php/commitdiff
Cache negative defined() results
authorDmitry Stogov <dmitry@zend.com>
Fri, 30 Mar 2018 13:41:02 +0000 (16:41 +0300)
committerDmitry Stogov <dmitry@zend.com>
Fri, 30 Mar 2018 13:41:02 +0000 (16:41 +0300)
Zend/zend_execute.h
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

index 5da2e2d9b12fe4900495d63a3e90c4bc03a02934..67bac91dd7ba0231eaf485ef512757f7fcbb2b43 100644 (file)
@@ -371,6 +371,23 @@ ZEND_API int ZEND_FASTCALL zend_do_fcall_overloaded(zend_execute_data *call, zva
                (slot)[1] = (ptr); \
        } while (0)
 
+#define CACHE_SPECIAL (1<<0)
+
+#define IS_SPECIAL_CACHE_VAL(ptr) \
+       (((uintptr_t)(ptr)) & CACHE_SPECIAL)
+
+#define ENCODE_SPECIAL_CACHE_NUM(num) \
+       ((void*)((((uintptr_t)(num)) << 1) | CACHE_SPECIAL))
+
+#define DECODE_SPECIAL_CACHE_NUM(ptr) \
+       (((uintptr_t)(ptr)) >> 1)
+
+#define ENCODE_SPECIAL_CACHE_PTR(ptr) \
+       ((void*)(((uintptr_t)(ptr)) | CACHE_SPECIAL))
+
+#define DECODE_SPECIAL_CACHE_PTR(ptr) \
+       ((void*)(((uintptr_t)(ptr)) & ~CACHE_SPECIAL))
+
 #define SKIP_EXT_OPLINE(opline) do { \
                while (UNEXPECTED((opline)->opcode >= ZEND_EXT_STMT \
                        && (opline)->opcode <= ZEND_TICKS)) {     \
index 206452c0a63d6b07aa8226a5ff0720dfc09d4469..72e197e9edd3f74add805368cb7bd8462de039e2 100644 (file)
@@ -5024,8 +5024,9 @@ ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, UNUSED|CONST_FETCH, CONST, CACHE_SLOT)
        USE_OPLINE
        zend_constant *c;
 
-       if (EXPECTED(CACHED_PTR(opline->extended_value))) {
-               c = CACHED_PTR(opline->extended_value);
+       c = CACHED_PTR(opline->extended_value);
+       if (EXPECTED(c != NULL) && EXPECTED(!IS_SPECIAL_CACHE_VAL(c))) {
+               /* pass */
        } else if (UNEXPECTED((c = zend_quick_get_constant(RT_CONSTANT(opline, opline->op2) + 1, opline->op1.num)) == NULL)) {
                SAVE_OPLINE();
 
@@ -7640,14 +7641,25 @@ ZEND_VM_HANDLER(122, ZEND_DEFINED, CONST, ANY, CACHE_SLOT)
        zend_constant *c;
        int result;
 
-       if (EXPECTED(CACHED_PTR(opline->extended_value))) {
-               result = 1;
-       } else if ((c = zend_quick_get_constant(RT_CONSTANT(opline, opline->op1), 0)) == NULL) {
-               result = 0;
-       } else {
-               CACHE_PTR(opline->extended_value, c);
-               result = 1;
-       }
+       c = CACHED_PTR(opline->extended_value);
+       do {
+               if (EXPECTED(c != NULL)) {
+                       if (!IS_SPECIAL_CACHE_VAL(c)) {
+                               result = 1;
+                               break;
+                       } else if (EXPECTED(zend_hash_num_elements(EG(zend_constants)) == DECODE_SPECIAL_CACHE_NUM(c))) {
+                               result = 0;
+                               break;
+                       }
+               }
+               if ((c = zend_quick_get_constant(RT_CONSTANT(opline, opline->op1), 0)) == NULL) {
+                       CACHE_PTR(opline->extended_value, ENCODE_SPECIAL_CACHE_NUM(zend_hash_num_elements(EG(zend_constants))));
+                       result = 0;
+               } else {
+                       CACHE_PTR(opline->extended_value, c);
+                       result = 1;
+               }
+       } while (0);
        ZEND_VM_SMART_BRANCH(result, 0);
        ZVAL_BOOL(EX_VAR(opline->result.var), result);
        ZEND_VM_NEXT_OPCODE();
index 9ddae524c26a7c4a6af920519d99b955c07a2bc9..b6a6e9753cbca99314aaf254c29a5ad3fff8d8d5 100644 (file)
@@ -3946,14 +3946,25 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DEFINED_SPEC_CONST_HANDLER(ZEN
        zend_constant *c;
        int result;
 
-       if (EXPECTED(CACHED_PTR(opline->extended_value))) {
-               result = 1;
-       } else if ((c = zend_quick_get_constant(RT_CONSTANT(opline, opline->op1), 0)) == NULL) {
-               result = 0;
-       } else {
-               CACHE_PTR(opline->extended_value, c);
-               result = 1;
-       }
+       c = CACHED_PTR(opline->extended_value);
+       do {
+               if (EXPECTED(c != NULL)) {
+                       if (!IS_SPECIAL_CACHE_VAL(c)) {
+                               result = 1;
+                               break;
+                       } else if (EXPECTED(zend_hash_num_elements(EG(zend_constants)) == DECODE_SPECIAL_CACHE_NUM(c))) {
+                               result = 0;
+                               break;
+                       }
+               }
+               if ((c = zend_quick_get_constant(RT_CONSTANT(opline, opline->op1), 0)) == NULL) {
+                       CACHE_PTR(opline->extended_value, ENCODE_SPECIAL_CACHE_NUM(zend_hash_num_elements(EG(zend_constants))));
+                       result = 0;
+               } else {
+                       CACHE_PTR(opline->extended_value, c);
+                       result = 1;
+               }
+       } while (0);
        ZEND_VM_SMART_BRANCH(result, 0);
        ZVAL_BOOL(EX_VAR(opline->result.var), result);
        ZEND_VM_NEXT_OPCODE();
@@ -32040,8 +32051,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_UNUSED_CON
        USE_OPLINE
        zend_constant *c;
 
-       if (EXPECTED(CACHED_PTR(opline->extended_value))) {
-               c = CACHED_PTR(opline->extended_value);
+       c = CACHED_PTR(opline->extended_value);
+       if (EXPECTED(c != NULL) && EXPECTED(!IS_SPECIAL_CACHE_VAL(c))) {
+               /* pass */
        } else if (UNEXPECTED((c = zend_quick_get_constant(RT_CONSTANT(opline, opline->op2) + 1, opline->op1.num)) == NULL)) {
                SAVE_OPLINE();