]> granicus.if.org Git - php/commitdiff
Inlined fast path
authorDmitry Stogov <dmitry@zend.com>
Wed, 4 May 2016 14:33:35 +0000 (17:33 +0300)
committerDmitry Stogov <dmitry@zend.com>
Wed, 4 May 2016 14:33:35 +0000 (17:33 +0300)
Zend/zend_execute.c
Zend/zend_hash.c
Zend/zend_hash.h

index eb685e81041ce1a7e6fc4ef03ba4498c02658e74..53f2362e19b05c30d3c79acf31964868af6b0dd3 100644 (file)
@@ -1559,24 +1559,24 @@ try_again:
        if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) {
                hval = Z_LVAL_P(dim);
 num_index:
-               retval = zend_hash_index_find(ht, hval);
-               if (retval == NULL) {
-                       switch (type) {
-                               case BP_VAR_R:
-                                       zend_error(E_NOTICE,"Undefined offset: " ZEND_LONG_FMT, hval);
-                                       /* break missing intentionally */
-                               case BP_VAR_UNSET:
-                               case BP_VAR_IS:
-                                       retval = &EG(uninitialized_zval);
-                                       break;
-                               case BP_VAR_RW:
-                                       zend_error(E_NOTICE,"Undefined offset: " ZEND_LONG_FMT, hval);
-                                       retval = zend_hash_index_update(ht, hval, &EG(uninitialized_zval));
-                                       break;
-                               case BP_VAR_W:
-                                       retval = zend_hash_index_add_new(ht, hval, &EG(uninitialized_zval));
-                                       break;
-                       }
+               ZEND_HASH_INDEX_FIND(ht, hval, retval, num_undef);
+               return retval;
+num_undef:
+               switch (type) {
+                       case BP_VAR_R:
+                               zend_error(E_NOTICE,"Undefined offset: " ZEND_LONG_FMT, hval);
+                               /* break missing intentionally */
+                       case BP_VAR_UNSET:
+                       case BP_VAR_IS:
+                               retval = &EG(uninitialized_zval);
+                               break;
+                       case BP_VAR_RW:
+                               zend_error(E_NOTICE,"Undefined offset: " ZEND_LONG_FMT, hval);
+                               retval = zend_hash_index_update(ht, hval, &EG(uninitialized_zval));
+                               break;
+                       case BP_VAR_W:
+                               retval = zend_hash_index_add_new(ht, hval, &EG(uninitialized_zval));
+                               break;
                }
        } else if (EXPECTED(Z_TYPE_P(dim) == IS_STRING)) {
                offset_key = Z_STR_P(dim);
index e116ffe55e27cda5dd15c582dfee548d9ab4bb84..1e3a9aa69a87d77f85487058aeb282fcbf6d90da 100644 (file)
@@ -2038,6 +2038,15 @@ ZEND_API zval* ZEND_FASTCALL zend_hash_index_find(const HashTable *ht, zend_ulon
        return p ? &p->val : NULL;
 }
 
+ZEND_API zval* ZEND_FASTCALL _zend_hash_index_find(const HashTable *ht, zend_ulong h)
+{
+       Bucket *p;
+
+       IS_CONSISTENT(ht);
+
+       p = zend_hash_index_find_bucket(ht, h);
+       return p ? &p->val : NULL;
+}
 
 ZEND_API zend_bool ZEND_FASTCALL zend_hash_index_exists(const HashTable *ht, zend_ulong h)
 {
index f18ce5c058fddaac9e5e7172cb88a134152b6d37..aa5dc24fd254096c653b0c603ee22317138932c6 100644 (file)
@@ -154,6 +154,26 @@ ZEND_API void ZEND_FASTCALL zend_hash_del_bucket(HashTable *ht, Bucket *p);
 ZEND_API zval* ZEND_FASTCALL zend_hash_find(const HashTable *ht, zend_string *key);
 ZEND_API zval* ZEND_FASTCALL zend_hash_str_find(const HashTable *ht, const char *key, size_t len);
 ZEND_API zval* ZEND_FASTCALL zend_hash_index_find(const HashTable *ht, zend_ulong h);
+ZEND_API zval* ZEND_FASTCALL _zend_hash_index_find(const HashTable *ht, zend_ulong h);
+
+#define ZEND_HASH_INDEX_FIND(_ht, _h, _ret, _not_found) do { \
+               if (EXPECTED((_ht)->u.flags & HASH_FLAG_PACKED)) { \
+                       if (EXPECTED((_h) < (_ht)->nNumUsed)) { \
+                               _ret = &ht->arData[_h].val; \
+                               if (UNEXPECTED(Z_TYPE_P(_ret) == IS_UNDEF)) { \
+                                       goto _not_found; \
+                               } \
+                       } else { \
+                               goto _not_found; \
+                       } \
+               } else { \
+                       _ret = _zend_hash_index_find(_ht, _h); \
+                       if (UNEXPECTED(_ret == NULL)) { \
+                               goto _not_found; \
+                       } \
+               } \
+       } while (0)
+
 
 /* Misc */
 ZEND_API zend_bool ZEND_FASTCALL zend_hash_exists(const HashTable *ht, zend_string *key);