PHP extension-integrate snappy into xhprof object introduction
Xhprof: a PHP performance analysis tool developed by facebook. it records the call chains of function/class methods during PHP script running and the time consumed by each call, memory usage and other data;
Snappy: a string compression/decompression tool developed by google, which has the advantage of high compression speed.
Target
The xhprof extension provides two PHP functions: xhprof_compress ($ str) and xhprof_uncompress ($ str) for compression and decompression.
Specific process
1. download xhprof source code to php-5.6.24/ext/xhprof
2. follow the normal method./configure and make to ensure that xhprof. so works normally.
3. download snappy source code to php-5.6.24/ext/xhprof/snappy
4. edit the file php-5.6.24/ext/xhprof/php_xhprof.h and add the following lines:
...
PHP_FUNCTION (xhprof_compress );
PHP_FUNCTION (xhprof_uncompress );
...
5. edit the file php-5.6.24/ext/xhprof. c and add the following lines:
... #include "snappy/snappy-c.h" ... zend_function_entry xhprof_functions[] = { ... PHP_FE(xhprof_compress, NULL) PHP_FE(xhprof_uncompress, NULL) ... }; PHP_FUNCTION(xhprof_compress) { zval *data; char *output; size_t output_len; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &data) == FAILURE) { RETURN_FALSE; } if (Z_TYPE_P(data) != IS_STRING) { zend_error(E_WARNING, "snappy_compress : expects parameter to be string."); RETURN_FALSE; } output_len = snappy_max_compressed_length(Z_STRLEN_P(data)); output = (char *)emalloc(output_len); if (!output) { zend_error(E_WARNING, "snappy_compress : memory error"); RETURN_FALSE; } if (snappy_compress(Z_STRVAL_P(data), Z_STRLEN_P(data), output, &output_len) == SNAPPY_OK) { #if ZEND_MODULE_API_NO >= 20141001 RETVAL_STRINGL(output, output_len); #else RETVAL_STRINGL(output, output_len, 1); #endif } else { RETVAL_FALSE; } efree(output); } PHP_FUNCTION(xhprof_uncompress) { zval *data; char *output = NULL; size_t output_len; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &data) == FAILURE) { RETURN_FALSE; } if (Z_TYPE_P(data) != IS_STRING) { zend_error(E_WARNING, "snappy_uncompress : expects parameter to be string."); RETURN_FALSE; } if (snappy_uncompressed_length(Z_STRVAL_P(data), Z_STRLEN_P(data), &output_len) != SNAPPY_OK) { zend_error(E_WARNING, "snappy_uncompress : output length error"); RETURN_FALSE; } output = (char *)emalloc(output_len); if (!output) { zend_error(E_WARNING, "snappy_uncompress : memory error"); RETURN_FALSE; } if (snappy_uncompress(Z_STRVAL_P(data), Z_STRLEN_P(data), output, &output_len) == SNAPPY_OK) { #if ZEND_MODULE_API_NO >= 20141001 RETVAL_STRINGL(output, output_len); #else RETVAL_STRINGL(output, output_len, 1); #endif } else { zend_error(E_WARNING, "snappy_uncompress : data error"); RETVAL_FALSE; } efree(output); }...
The above code is not original and is taken from snappy's PHP extension: php-ext-snappy
6. edit the config. m4 file and specify the snappy compilation method.
The complete config. m4 code is as follows, and snappy is directly edited into xhprof. so. The better way is to first check whether the current host has installed snappy. If yes, specify the link library path and do not need to compile the snappy function into xhprof. so.
PHP_ARG_ENABLE(xhprof, whether to enable xhprof support, [ --enable-xhprof Enable xhprof support]) dnl compiler C++: PHP_REQUIRE_CXX() dnl snappy SNAPPY_MAJOR="1" SNAPPY_MINOR="1" SNAPPY_PATCHLEVEL="3" AC_PROG_CXX AC_LANG([C++]) AC_C_BIGENDIAN AC_CHECK_HEADERS([stdint.h stddef.h sys/mman.h sys/resource.h windows.h byteswap.h sys/byteswap. h sys/endian.h sys/time.h]) AC_CHECK_FUNC([mmap]) AC_MSG_CHECKING([if the compiler supports __builtin_expect]) AC_TRY_COMPILE(, [ return __builtin_expect(1, 1) ? 1 : 0 ], [ snappy_have_builtin_expect=yes AC_MSG_RESULT([yes]) ], [ snappy_have_builtin_expect=no AC_MSG_RESULT([no]) ]) if test x$snappy_have_builtin_expect = xyes ; then AC_DEFINE([HAVE_BUILTIN_EXPECT], [1], [Define to 1 if the compiler supports __builtin_expect.]) fi AC_MSG_CHECKING([if the compiler supports __builtin_ctzll]) AC_TRY_COMPILE(, [ return (__builtin_ctzll(0x100000000LL) == 32) ? 1 : 0 ], [ snappy_have_builtin_ctz=yes AC_MSG_RESULT([yes]) ], [ snappy_have_builtin_ctz=no AC_MSG_RESULT([no]) ]) if test x$snappy_have_builtin_ctz = xyes ; then AC_DEFINE([HAVE_BUILTIN_CTZ], [1], [Define to 1 if the compiler supports __builtin_ctz and friends.]) fi if test "$ac_cv_header_stdint_h" = "yes"; then AC_SUBST([ac_cv_have_stdint_h], [1]) else AC_SUBST([ac_cv_have_stdint_h], [0]) fi if test "$ac_cv_header_stddef_h" = "yes"; then AC_SUBST([ac_cv_have_stddef_h], [1]) else AC_SUBST([ac_cv_have_stddef_h], [0]) fi if test "$ac_cv_header_sys_uio_h" = "yes"; then AC_SUBST([ac_cv_have_sys_uio_h], [1]) else AC_SUBST([ac_cv_have_sys_uio_h], [0]) fi AC_SUBST([SNAPPY_MAJOR]) AC_SUBST([SNAPPY_MINOR]) AC_SUBST([SNAPPY_PATCHLEVEL]) AC_CONFIG_FILES([snappy/snappy-stubs-public.h]) AC_OUTPUTdnl Check for stdc++ LIBNAME=stdc++ AC_MSG_CHECKING([for stdc++]) AC_LANG_SAVE AC_LANG_CPLUSPLUS AC_TRY_COMPILE( [ #include
using namespace std; ],[ string dummy; ],[ AC_MSG_RESULT(yes) PHP_ADD_LIBRARY($LIBNAME, , XHPROF_SHARED_LIBADD) ],[ AC_MSG_ERROR([wrong stdc++ library not found]) ]) AC_LANG_RESTORE PHP_SUBST(XHPROF_SHARED_LIBADD) dnl Sources SNAPPY_SOURCES="snappy/snappy-c.cc snappy/snappy.cc snappy/snappy-stubs-internal.cc snappy/ snappy-sinksource.cc" if test "$PHP_XHPROF" != "no"; then PHP_NEW_EXTENSION(xhprof, xhprof.c $SNAPPY_SOURCES, $ext_shared) fi
The above code is not original and is taken from snappy's PHP extension: php-ext-snappy
7. run phpize again and run make to generate a new xhprof. so
8. execute the command nm xhprof. so check whether the snappy-related functions have been compiled. the memory addresses of _ snappy_compress, _ snappy_uncompress, and so on are all non-empty. This indicates that all functions are compiled into xhprof. so.
➜ xhprof nm modules/xhprof.so0000000000008a98 s GCC_except_table100000000000008ad8 s GCC_except_table110000000000008b24 s GCC_except_table120000000000008b70 s GCC_except_table130000000000008bb0 s GCC_except_table140000000000008bfc s GCC_except_table160000000000008c48 s GCC_except_table180000000000008cbc s GCC_except_table190000000000008d4c s GCC_except_table2300000000000088f4 s GCC_except_table50000000000008934 s GCC_except_table70000000000008a0c s GCC_except_table80000000000008a4c s GCC_except_table9...0000000000002510 T _restore_cpu_affinity0000000000003f00 T _snappy_compress0000000000003f60 T _snappy_max_compressed_length0000000000003f70 T _snappy_uncompress0000000000003fe0 T _snappy_uncompressed_length0000000000004000 T _snappy_validate_compressed_buffer... U _zend_register_long_constant U _zend_unregister_ini_entries00000000000013a0 T _zif_xhprof_compress0000000000001090 T _zif_xhprof_disable0000000000001350 T _zif_xhprof_dump0000000000001040 T _zif_xhprof_enable0000000000001200 T _zif_xhprof_sample_disable00000000000011e0 T _zif_xhprof_sample_enable0000000000001470 T _zif_xhprof_uncompress0000000000001700 T _zm_activate_xhprof0000000000001720 T _zm_deactivate_xhprof0000000000001960 T _zm_info_xhprof0000000000001660 T _zm_shutdown_xhprof0000000000001560 T _zm_startup_xhprof0000000000001f00 t _zval_dump U _zval_used_for_init
9. you can use xhprof_compress () and xhrof_uncompress () in the php script.