Skip to content

Commit 5e6555b

Browse files
committed
Implement primitive caching
1 parent 87202b7 commit 5e6555b

File tree

4 files changed

+46
-1
lines changed

4 files changed

+46
-1
lines changed

Zend/zend.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -593,6 +593,11 @@ static void executor_globals_dtor(zend_executor_globals *executor_globals TSRMLS
593593
zend_hash_destroy(executor_globals->zend_constants);
594594
free(executor_globals->zend_constants);
595595
}
596+
if (executor_globals->protocol_cache) {
597+
zend_hash_destroy(executor_globals->protocol_cache);
598+
free(executor_globals->protocol_cache);
599+
}
600+
596601
}
597602
/* }}} */
598603

Zend/zend.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,7 @@ struct _zend_class_entry {
481481
int refcount;
482482
zend_uint ce_flags;
483483

484+
HashTable *protocol_cache;
484485
HashTable function_table;
485486
HashTable properties_info;
486487
zval **default_properties_table;

Zend/zend_globals.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,8 @@ struct _zend_executor_globals {
187187

188188
zend_op_array *active_op_array;
189189

190+
HashTable *protocol_cache; /* protocol cache hash table */
191+
190192
HashTable *function_table; /* function symbol table */
191193
HashTable *class_table; /* class table */
192194
HashTable *zend_constants; /* constants table */

Zend/zend_operators.c

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1804,11 +1804,48 @@ ZEND_API int is_smaller_or_equal_function(zval *result, zval *op1, zval *op2 TSR
18041804

18051805
static int protocol_check_function_implementation(void *function_entry TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key);
18061806

1807+
static void protocol_cache_dtor(void *data) /* {{{ */
1808+
{
1809+
zend_hash_destroy((HashTable *) data);
1810+
}
1811+
/* }}} */
1812+
18071813
ZEND_API zend_bool protocol_check_function(zend_class_entry *instance_ce, zend_class_entry *ce TSRMLS_DC) /* {{{ */
18081814
{
18091815
zend_bool result = 1;
1816+
HashTable *cache_bucket = NULL;
1817+
zend_bool *cache_result = NULL;
1818+
1819+
if (!instance_ce->protocol_cache) {
1820+
HashTable **cache_bucket_ext = NULL;
1821+
1822+
if (!EG(protocol_cache)) {
1823+
EG(protocol_cache) = (HashTable*) malloc(sizeof(HashTable));
1824+
zend_hash_init(EG(protocol_cache), 16, NULL, protocol_cache_dtor, 1);
1825+
}
1826+
1827+
if (zend_hash_find(EG(protocol_cache), instance_ce->name, instance_ce->name_length, (void **) &cache_bucket_ext) == FAILURE) {
1828+
cache_bucket = (HashTable*) malloc(sizeof(HashTable));
1829+
zend_hash_init(cache_bucket, 16, NULL, NULL, 1);
1830+
zend_hash_add(EG(protocol_cache), instance_ce->name, instance_ce->name_length, (void *) &cache_bucket, sizeof(void *), NULL);
1831+
} else {
1832+
cache_bucket = *cache_bucket_ext;
1833+
}
1834+
instance_ce->protocol_cache = cache_bucket;
1835+
} else {
1836+
cache_bucket = instance_ce->protocol_cache;
1837+
}
1838+
1839+
if (zend_hash_find(cache_bucket, ce->name, ce->name_length, (void **) &cache_result) != FAILURE) {
1840+
return *cache_result;
1841+
}
1842+
1843+
if (0 == instanceof_function(instance_ce, ce)) {
1844+
/* Short-circuit if types match */
1845+
zend_hash_apply_with_arguments(&(ce->function_table), protocol_check_function_implementation, 2, instance_ce, &result);
1846+
}
18101847

1811-
zend_hash_apply_with_arguments(&(ce->function_table), protocol_check_function_implementation, 2, instance_ce, &result);
1848+
zend_hash_add(cache_bucket, ce->name, ce->name_length, (void *) &result, sizeof(zend_bool), NULL);
18121849

18131850
return result;
18141851
}

0 commit comments

Comments
 (0)