diff --git a/.arcconfig b/.arcconfig
index 30d1e80d..9e489cb8 100644
--- a/.arcconfig
+++ b/.arcconfig
@@ -1,6 +1,5 @@
{
- "project_id" : "xhprof",
- "conduit_uri" : "https://secure.phabricator.com/",
- "remote_hooks_installed" : true,
- "copyright_holder" : "Facebook, Inc."
-}
\ No newline at end of file
+ "phabricator.uri": "https://secure.phabricator.com/",
+ "load": ["support/libxhprof"],
+ "unit.engine": "XHProfExtensionUnitTestEngine"
+}
diff --git a/.arclint b/.arclint
new file mode 100644
index 00000000..e141495b
--- /dev/null
+++ b/.arclint
@@ -0,0 +1,30 @@
+{
+ "exclude": [
+ "(^xhprof_html/jquery/)",
+ "(^xhprof_html/docs/)",
+ "(^extension/Makefile.local)"
+ ],
+ "linters": {
+ "chmod": {
+ "type": "chmod"
+ },
+ "filename": {
+ "type": "filename"
+ },
+ "generated": {
+ "type": "generated"
+ },
+ "merge-conflict": {
+ "type": "merge-conflict"
+ },
+ "nolint": {
+ "type": "nolint"
+ },
+ "text-without-length": {
+ "type": "text",
+ "severity": {
+ "3": "disabled"
+ }
+ }
+ }
+}
diff --git a/.gitignore b/.gitignore
index e75f3af4..f1631981 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,12 @@ extension/*
!extension/php_xhprof.h
!extension/tests/
!extension/xhprof.c
+
+extension/tests/*.sh
+extension/tests/*.exp
+extension/tests/*.out
+extension/tests/*.diff
+extension/tests/*.log
+extension/tests/*.php
+
+support/libxhprof/.phutil_module_cache
diff --git a/CREDITS b/CREDITS
index fd032202..1b9af6b8 100644
--- a/CREDITS
+++ b/CREDITS
@@ -1,5 +1,7 @@
Originally developed at Facebook, XHProf was open sourced in Mar, 2009.
+XHProf is now maintained by Phacility.
+
Creators:
Changhao Jiang
Kannan Muthukkaruppan
@@ -9,4 +11,3 @@ Creators:
Additional Contributors:
George Cabrera - UI enhancements
Paul Saab - FreeBSD port
-
diff --git a/LICENSE b/LICENSE
index f433b1a5..d9a10c0d 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,3 @@
-
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
diff --git a/README b/README
index 309dcfe2..a8c15fa9 100644
--- a/README
+++ b/README
@@ -3,5 +3,3 @@ For installation and usage notes refer to:
To view the latest version of the doc, go to:
http://pecl.php.net/package/xhprof ---> [View Documentation]
-
-
diff --git a/bin/xhprofile b/bin/xhprofile
new file mode 120000
index 00000000..56da2f66
--- /dev/null
+++ b/bin/xhprofile
@@ -0,0 +1 @@
+../scripts/xhprofile.php
\ No newline at end of file
diff --git a/composer.json b/composer.json
deleted file mode 100644
index 2efe9628..00000000
--- a/composer.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "name": "facebook/xhprof",
- "type": "library",
- "description": "XHProf: A Hierarchical Profiler for PHP",
- "keywords": ["profiling", "performance"],
- "homepage": "http://pecl.php.net/package/xhprof",
- "license": "Apache-2.0",
- "require": {
- "php": ">=5.2.0"
- },
- "autoload": {
- "files": [
- "xhprof_lib/utils/xhprof_lib.php",
- "xhprof_lib/utils/xhprof_runs.php"
- ]
- }
-}
diff --git a/extension/config.m4 b/extension/config.m4
index 351786bd..75401474 100644
--- a/extension/config.m4
+++ b/extension/config.m4
@@ -1,4 +1,3 @@
-
PHP_ARG_ENABLE(xhprof, whether to enable xhprof support,
[ --enable-xhprof Enable xhprof support])
diff --git a/extension/php_xhprof.h b/extension/php_xhprof.h
index 42fb23b4..13d914c6 100644
--- a/extension/php_xhprof.h
+++ b/extension/php_xhprof.h
@@ -42,4 +42,4 @@ PHP_FUNCTION(xhprof_disable);
PHP_FUNCTION(xhprof_sample_enable);
PHP_FUNCTION(xhprof_sample_disable);
-#endif /* PHP_XHPROF_H */
+#endif /* PHP_XHPROF_H */
diff --git a/extension/tests/common.php b/extension/tests/common.php
index 23b2f719..f808ff38 100644
--- a/extension/tests/common.php
+++ b/extension/tests/common.php
@@ -32,4 +32,3 @@ function print_canonical($xhprof_data) {
echo "\n";
}
}
-
diff --git a/extension/tests/xhprof_001.phpt b/extension/tests/xhprof_001.phpt
index dc14c28c..40d76f02 100644
--- a/extension/tests/xhprof_001.phpt
+++ b/extension/tests/xhprof_001.phpt
@@ -1,5 +1,5 @@
--TEST--
-XHPRrof: Basic Profiling Test
+XHProf: Basic Profiling Test
Author: Kannan
--FILE--
+$xhprof_ignored_functions = array( 'ignored_functions' =>
array('call_user_func',
'call_user_func_array',
'my_call_user_func_safe',
@@ -20,8 +20,8 @@ function foo($x) {
for ($idx = 0; $idx < 2; $idx++) {
$sum += bar();
}
- echo "hello: {$x}\n" ;
- return strlen("hello: {$x}");
+ echo @"hello: {$x}\n" ;
+ return @strlen("hello: {$x}");
}
function foo_array($x1, $x2 = 'test') {
@@ -30,8 +30,8 @@ function foo_array($x1, $x2 = 'test') {
foreach ($x as $idx) {
$sum += bar();
}
- echo "hello: " . $x[0] . $x[1] . "\n";
- return strlen("hello: {$x[0]} {$x[1]}");
+ echo @"hello: {$x[0]}{$x[1]}\n";
+ return @strlen("hello: {$x[0]} {$x[1]}");
}
function my_call_user_func_safe($function, $args = 'my_safe') {
@@ -161,7 +161,7 @@ echo "\n";
// 5c: Sanity test to only ignore my_call_user_func_array_safe
echo "Part 5c: Only ignore call_user_func_array\n";
-$xhprof_ignored_functions = array('ignored_functions' =>
+$xhprof_ignored_functions = array('ignored_functions' =>
'my_call_user_func_array_safe');
xhprof_enable(XHPROF_FLAGS_MEMORY, $xhprof_ignored_functions);
test_my_call_user_func_array_safe('foo_array');
diff --git a/extension/tests/xhprof_008.phpt b/extension/tests/xhprof_008.phpt
index b0f4af57..e62849f1 100644
--- a/extension/tests/xhprof_008.phpt
+++ b/extension/tests/xhprof_008.phpt
@@ -1,5 +1,5 @@
--TEST--
-XHPRrof: Sampling Mode Test
+XHProf: Sampling Mode Test
Author: kannan
--FILE--
+}
+
+spl_autoload_register('loader', $throw = true);
+
+xhprof_enable();
+
+class_exists('ThisClassDoesNotExist');
+echo "OK\n";
+
+--EXPECT--
+OK
diff --git a/extension/tests/xhprof_010.phpt b/extension/tests/xhprof_010.phpt
new file mode 100644
index 00000000..33b4a14e
--- /dev/null
+++ b/extension/tests/xhprof_010.phpt
@@ -0,0 +1,16 @@
+--TEST--
+XHProf: Crash with auto_append_file
+Author: epriestley
+--INI--
+include_path={PWD}
+auto_append_file=xhprof_010_append.php
+--FILE--
+
+--EXPECTF--
+MAIN
+APPENDED
diff --git a/extension/tests/xhprof_010_append.php b/extension/tests/xhprof_010_append.php
new file mode 100644
index 00000000..7e569914
--- /dev/null
+++ b/extension/tests/xhprof_010_append.php
@@ -0,0 +1,3 @@
+
+--EXPECTF--
+PREPENDED
+MAIN
diff --git a/extension/tests/xhprof_011_prepend.php b/extension/tests/xhprof_011_prepend.php
new file mode 100644
index 00000000..22386904
--- /dev/null
+++ b/extension/tests/xhprof_011_prepend.php
@@ -0,0 +1,4 @@
+ array($large)));
+xhprof_disable();
+unset($large);
+
+xhprof_enable();
+xhprof_disable();
+
+$new = memory_get_usage();
+
+$missing = ($new - $old);
+
+if ($missing >= (1024 * 1024 * 16)) {
+ echo "LEAKED A LOT OF MEMORY\n";
+} else {
+ echo "DID NOT LEAK A LOT OF MEMORY\n";
+}
+
+?>
+--EXPECTF--
+DID NOT LEAK A LOT OF MEMORY
diff --git a/extension/xhprof.c b/extension/xhprof.c
index f97bcf1d..66aa041e 100644
--- a/extension/xhprof.c
+++ b/extension/xhprof.c
@@ -596,6 +596,11 @@ static inline uint8 hp_inline_hash(char * str) {
* @author mpal
*/
static void hp_get_ignored_functions_from_arg(zval *args) {
+
+ if (hp_globals.ignored_function_names) {
+ hp_array_del(hp_globals.ignored_function_names);
+ }
+
if (args != NULL) {
zval *zresult = NULL;
@@ -961,7 +966,13 @@ static char *hp_get_function_name(zend_op_array *ops TSRMLS_DC) {
/* we are dealing with a special directive/function like
* include, eval, etc.
*/
-#if ZEND_EXTENSION_API_NO >= 220100525
+#if ZEND_EXTENSION_API_NO >= 220121212
+ if (data->prev_execute_data) {
+ curr_op = data->prev_execute_data->opline->extended_value;
+ } else {
+ curr_op = data->opline->extended_value;
+ }
+#elif ZEND_EXTENSION_API_NO >= 220100525
curr_op = data->opline->extended_value;
#else
curr_op = data->opline->op2.u.constant.value.lval;
@@ -1703,8 +1714,30 @@ ZEND_DLEXPORT void hp_execute_internal(zend_execute_data *execute_data,
if (!_zend_execute_internal) {
/* no old override to begin with. so invoke the builtin's implementation */
+
+#if ZEND_EXTENSION_API_NO >= 220121212
+ /* PHP 5.5. This is just inlining a copy of execute_internal(). */
+
+ if (fci != NULL) {
+ ((zend_internal_function *) execute_data->function_state.function)->handler(
+ fci->param_count,
+ *fci->retval_ptr_ptr,
+ fci->retval_ptr_ptr,
+ fci->object_ptr,
+ 1 TSRMLS_CC);
+ } else {
+ zval **return_value_ptr = &EX_TMP_VAR(execute_data, execute_data->opline->result.var)->var.ptr;
+ ((zend_internal_function *) execute_data->function_state.function)->handler(
+ execute_data->opline->extended_value,
+ *return_value_ptr,
+ (execute_data->function_state.function->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
+ ? return_value_ptr
+ : NULL,
+ execute_data->object,
+ ret TSRMLS_CC);
+ }
+#elif ZEND_EXTENSION_API_NO >= 220100525
zend_op *opline = EX(opline);
-#if ZEND_EXTENSION_API_NO >= 220100525
temp_variable *retvar = &EX_T(opline->result.var);
((zend_internal_function *) EX(function_state).function)->handler(
opline->extended_value,
@@ -1713,6 +1746,7 @@ ZEND_DLEXPORT void hp_execute_internal(zend_execute_data *execute_data,
&retvar->var.ptr:NULL,
EX(object), ret TSRMLS_CC);
#else
+ zend_op *opline = EX(opline);
((zend_internal_function *) EX(function_state).function)->handler(
opline->extended_value,
EX_T(opline->result.u.var).var.ptr,
@@ -2016,4 +2050,3 @@ static inline void hp_array_del(char **name_array) {
efree(name_array);
}
}
-
diff --git a/package.xml b/package.xml
index 478ee25f..59e92a75 100644
--- a/package.xml
+++ b/package.xml
@@ -50,7 +50,7 @@ XHProf is a function-level hierarchical profiler for PHP and has a simple HTML b
macvicar
scott@fb.com
yes
-
+
2009-03-28
0.9.2
diff --git a/scripts/xhprofile.php b/scripts/xhprofile.php
new file mode 100755
index 00000000..36891e99
--- /dev/null
+++ b/scripts/xhprofile.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+');
+}
+
+$__xhprof_target__ = $argv[1];
+
+$argv = array_slice($argv, 1);
+$argc = count($argv);
+
+xhprof_enable();
+require_once $__xhprof_target__;
+$xhprof_data = xhprof_disable();
+
+var_dump($xhprof_data);
diff --git a/support/libxhprof/__phutil_library_init__.php b/support/libxhprof/__phutil_library_init__.php
new file mode 100644
index 00000000..31f0c680
--- /dev/null
+++ b/support/libxhprof/__phutil_library_init__.php
@@ -0,0 +1,3 @@
+ 2,
+ 'class' => array(
+ 'XHProfExtensionUnitTestEngine' => 'unit/XHProfUnitTestEngine.php',
+ ),
+ 'function' => array(),
+ 'xmap' => array(
+ 'XHProfExtensionUnitTestEngine' => 'ArcanistUnitTestEngine',
+ ),
+));
diff --git a/support/libxhprof/unit/XHProfUnitTestEngine.php b/support/libxhprof/unit/XHProfUnitTestEngine.php
new file mode 100644
index 00000000..955261a2
--- /dev/null
+++ b/support/libxhprof/unit/XHProfUnitTestEngine.php
@@ -0,0 +1,53 @@
+getWorkingCopy()->getProjectRoot().'/extension/';
+
+ $start_time = microtime(true);
+
+ id(new ExecFuture('phpize && ./configure && make -j4'))
+ ->setCWD($root)
+ ->resolvex();
+
+ $out = id(new ExecFuture('make -f Makefile.local test_with_exit_status'))
+ ->setCWD($root)
+ ->setEnv(
+ array(
+ 'TEST_PHP_ARGS' => '-q',
+ ))
+ ->resolvex();
+
+ // NOTE: REPORT_EXIT_STATUS doesn't seem to work properly in some versions
+ // of PHP. Just "parse" stdout to approximate the results.
+
+ list($stdout) = $out;
+
+ $tests = array();
+
+ foreach (phutil_split_lines($stdout) as $line) {
+ $matches = null;
+
+ // NOTE: The test script writes the name of the test originally, then
+ // uses "\r" to erase it and write the result. This splits as a single
+ // line.
+ if (preg_match('/^TEST .*\r(PASS|FAIL) (.*)/', $line, $matches)) {
+ if ($matches[1] == 'PASS') {
+ $result = ArcanistUnitTestResult::RESULT_PASS;
+ } else {
+ $result = ArcanistUnitTestResult::RESULT_FAIL;
+ }
+
+ $name = trim($matches[2]);
+
+ $tests[] = id(new ArcanistUnitTestResult())
+ ->setName($name)
+ ->setResult($result)
+ ->setDuration(microtime(true) - $start_time);
+ }
+ }
+
+ return $tests;
+ }
+}
diff --git a/xhprof_html/css/xhprof.css b/xhprof_html/css/xhprof.css
index 88933db3..c3abf862 100644
--- a/xhprof_html/css/xhprof.css
+++ b/xhprof_html/css/xhprof.css
@@ -79,4 +79,3 @@ ul.xhprof_actions li a:hover {
background:#3B5998 none repeat scroll 0 0;
color:#FFFFFF;
}
-
diff --git a/xhprof_lib/display/typeahead_common.php b/xhprof_lib/display/typeahead_common.php
index 7b1098f4..0cd304d6 100644
--- a/xhprof_lib/display/typeahead_common.php
+++ b/xhprof_lib/display/typeahead_common.php
@@ -77,4 +77,3 @@
foreach ($functions as $f) {
echo $f."\n";
}
-
diff --git a/xhprof_lib/display/xhprof.php b/xhprof_lib/display/xhprof.php
index 4be67bc8..a57ec175 100644
--- a/xhprof_lib/display/xhprof.php
+++ b/xhprof_lib/display/xhprof.php
@@ -1003,7 +1003,7 @@ function print_pc_array($url_params, $results, $base_ct, $base_info, $parent,
function print_source_link($info) {
if (strncmp($info['fn'], 'run_init', 8) && $info['fn'] !== 'main()') {
- if (defined('XHPROF_SYMBOL_LOOKUP_URL')) {
+ if (defined('XHPROF_SYMBOL_LOOKUP_URL')) {
$link = xhprof_render_link(
'source',
XHPROF_SYMBOL_LOOKUP_URL . '?symbol='.rawurlencode($info["fn"]));
diff --git a/xhprof_lib/utils/xhprof_lib.php b/xhprof_lib/utils/xhprof_lib.php
index 1e398a9d..4a07e900 100644
--- a/xhprof_lib/utils/xhprof_lib.php
+++ b/xhprof_lib/utils/xhprof_lib.php
@@ -943,4 +943,3 @@ function xhprof_get_matching_functions($q, $xhprof_data) {
return ($res);
}
-
diff --git a/xhprof_lib/utils/xhprof_runs.php b/xhprof_lib/utils/xhprof_runs.php
index cde5ff55..2a22a5dc 100644
--- a/xhprof_lib/utils/xhprof_runs.php
+++ b/xhprof_lib/utils/xhprof_runs.php
@@ -95,8 +95,7 @@ public function __construct($dir = null) {
$dir = ini_get("xhprof.output_dir");
if (empty($dir)) {
- // some default that at least works on unix...
- $dir = "/tmp";
+ $dir = sys_get_temp_dir();
xhprof_error("Warning: Must specify directory location for XHProf runs. ".
"Trying {$dir} as default. You can either pass the " .