XCache is a fast, stable PHP opcode cacher that has been proven and is now running on production servers under high load. https://xcache.lighttpd.net/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

113 lines
3.9 KiB

  1. #ifdef ZEND_ENGINE_2
  2. static void xc_var_collect_object(xc_processor_t *processor, zend_object_handle handle TSRMLS_DC);
  3. static void xc_var_collect_object_in_zval(xc_processor_t *processor, zval *zv TSRMLS_DC);
  4. static void xc_var_collect_object_in_hashtable(xc_processor_t *processor, HashTable *ht TSRMLS_DC);
  5. static void xc_var_collect_object_in_hashtable(xc_processor_t *processor, HashTable *ht TSRMLS_DC) /* {{{ */
  6. {
  7. Bucket *bucket;
  8. for (bucket = ht->pListHead; bucket; bucket = bucket->pListNext) {
  9. xc_var_collect_object_in_zval(processor, *(zval **) bucket->pData TSRMLS_CC);
  10. }
  11. }
  12. /* }}} */
  13. static void xc_var_collect_object_in_zval(xc_processor_t *processor, zval *zv TSRMLS_DC) /* {{{ */
  14. {
  15. switch (Z_TYPE_P(zv)) {
  16. case IS_OBJECT:
  17. xc_var_collect_object(processor, Z_OBJ_HANDLE_P(zv) TSRMLS_CC);
  18. break;
  19. case IS_ARRAY:
  20. xc_var_collect_object_in_hashtable(processor, Z_ARRVAL_P(zv) TSRMLS_CC);
  21. break;
  22. }
  23. }
  24. /* }}} */
  25. static void xc_var_collect_object(xc_processor_t *processor, zend_object_handle handle TSRMLS_DC) /* {{{ */
  26. {
  27. size_t next_index;
  28. if (!xc_vector_initialized(&processor->objects)) {
  29. if (zend_hash_num_elements(&processor->handle_to_index)) {
  30. /* collecting process is stopped, may reach here by xc_entry_src_t.objects.properties */
  31. return;
  32. }
  33. xc_vector_init(zend_object, &processor->objects);
  34. zend_hash_init(&processor->handle_to_index, 0, NULL, NULL, 0);
  35. }
  36. next_index = xc_vector_size(&processor->objects);
  37. if (_zend_hash_index_update_or_next_insert(&processor->handle_to_index, handle, (void *) &next_index, sizeof(next_index), NULL, HASH_ADD ZEND_FILE_LINE_CC) == SUCCESS) {
  38. zend_object *object = zend_object_store_get_object_by_handle(handle TSRMLS_CC);
  39. xc_vector_push_back(&processor->objects, object);
  40. if (object->properties) {
  41. xc_var_collect_object_in_hashtable(processor, object->properties TSRMLS_CC);
  42. }
  43. #ifdef ZEND_ENGINE_2_4
  44. /* TODO: is this necessary? */
  45. if (object->properties_table) {
  46. int i, count = zend_hash_num_elements(&object->ce->properties_info);
  47. for (i = 0; i < count; ++i) {
  48. xc_var_collect_object_in_zval(processor, object->properties_table[i] TSRMLS_CC);
  49. }
  50. }
  51. #endif
  52. }
  53. }
  54. /* }}} */
  55. static size_t xc_var_store_handle(xc_processor_t *processor, zend_object_handle handle TSRMLS_DC) /* {{{ */
  56. {
  57. size_t *index;
  58. if (zend_hash_index_find(&processor->handle_to_index, handle, (void **) &index) != SUCCESS) {
  59. php_error_docref(NULL TSRMLS_CC, E_CORE_ERROR, "Internal error: handle %d not found on store", handle);
  60. return (size_t) -1;
  61. }
  62. return *index;
  63. }
  64. /* }}} */
  65. static zend_object_handle xc_var_restore_handle(xc_processor_t *processor, size_t index TSRMLS_DC) /* {{{ */
  66. {
  67. zend_object_handle handle = processor->object_handles[index];
  68. zend_objects_store_add_ref_by_handle(handle TSRMLS_CC);
  69. return handle;
  70. }
  71. /* }}} */
  72. #endif
  73. static void xc_var_collect_class(xc_processor_t *processor, zend_class_entry *ce TSRMLS_DC) /* {{{ */
  74. {
  75. size_t next_index;
  76. if (!xc_vector_initialized(&processor->class_names)) {
  77. xc_vector_init(xc_constant_string_t, &processor->class_names);
  78. zend_hash_init(&processor->class_name_to_index, 0, NULL, NULL, 0);
  79. }
  80. /* HashTable <=PHP_4 cannot handle NULL pointers, +1 needed */
  81. next_index = xc_vector_size(&processor->class_names) + 1;
  82. if (zend_hash_add(&processor->class_name_to_index, ce->name, ce->name_length, (void *) &next_index, sizeof(next_index), NULL) == SUCCESS) {
  83. xc_constant_string_t class_name;
  84. class_name.str = (char *) ce->name;
  85. class_name.len = ce->name_length;
  86. xc_vector_push_back(&processor->class_names, &class_name);
  87. }
  88. }
  89. /* }}} */
  90. static size_t xc_var_store_ce(xc_processor_t *processor, zend_class_entry *ce TSRMLS_DC) /* {{{ */
  91. {
  92. size_t *index;
  93. if (zend_hash_find(&processor->class_name_to_index, ce->name, ce->name_length, (void **) &index) != SUCCESS) {
  94. php_error_docref(NULL TSRMLS_CC, E_CORE_ERROR, "Internal error: class name not found in class names");
  95. return (size_t) - 1;
  96. }
  97. return *index - 1;
  98. }
  99. /* }}} */
  100. /* on restore */