From 1c26fda54f128c619f403823241936832932dd55 Mon Sep 17 00:00:00 2001 From: Lars Maier Date: Mon, 4 Jun 2018 17:04:23 +0200 Subject: [PATCH 01/64] Hooked memory manager to measure number of allocs, number of frees and total allocation amount per frame. --- php_tideways_xhprof.h | 4 +++ tests/common.php | 2 +- tideways_xhprof.c | 64 +++++++++++++++++++++++++++++++++++++++++++ tracing.c | 3 ++ tracing.h | 8 ++++++ 5 files changed, 80 insertions(+), 1 deletion(-) diff --git a/php_tideways_xhprof.h b/php_tideways_xhprof.h index b9309c9..f23738b 100644 --- a/php_tideways_xhprof.h +++ b/php_tideways_xhprof.h @@ -42,6 +42,8 @@ typedef struct xhprof_callgraph_bucket_t { zend_long cpu_time; zend_long memory; zend_long memory_peak; + long int num_alloc, num_free; + long int amount_alloc; } xhprof_callgraph_bucket; /* Tracer maintains a stack of entries being profiled. @@ -57,6 +59,8 @@ struct xhprof_frame_t { uint64 cpu_start; /* start value for CPU clock timer */ long int mu_start; /* memory usage */ long int pmu_start; /* peak memory usage */ + long int num_alloc, num_free; + long int amount_alloc; int recurse_level; zend_ulong hash_code; /* hash_code for the function name */ }; diff --git a/tests/common.php b/tests/common.php index d6b15c8..5675f09 100644 --- a/tests/common.php +++ b/tests/common.php @@ -37,7 +37,7 @@ function print_canonical($xhprof_data) // Only call counts are stable. // Wild card everything else. We still print // the metric name to ensure it was collected. - if ($name != "ct") { + if (!in_array($name, array("ct", "mem.na", "mem.nf", "mem.aa"))) { $value = "*"; } else { $value = str_pad($value, 8, " ", STR_PAD_LEFT); diff --git a/tideways_xhprof.c b/tideways_xhprof.c index b0eb75e..af95943 100644 --- a/tideways_xhprof.c +++ b/tideways_xhprof.c @@ -17,6 +17,14 @@ static void (*_zend_execute_internal) (zend_execute_data *execute_data, zval *re ZEND_DLEXPORT void tideways_xhprof_execute_internal(zend_execute_data *execute_data, zval *return_value); ZEND_DLEXPORT void tideways_xhprof_execute_ex (zend_execute_data *execute_data); +static void *(*_zend_malloc) (size_t); +static void (*_zend_free) (void *); +static void *(*_zend_realloc) (void *, size_t); + +void *tideways_malloc (size_t size); +void tideways_free (void *ptr); +void *tideways_realloc (void *ptr, size_t size); + PHP_INI_BEGIN() STD_PHP_INI_ENTRY("tideways_xhprof.clock_use_rdtsc", "0", PHP_INI_ALL, OnUpdateBool, clock_use_rdtsc, zend_tideways_xhprof_globals, tideways_xhprof_globals) PHP_INI_END() @@ -68,11 +76,19 @@ PHP_MINIT_FUNCTION(tideways_xhprof) _zend_execute_ex = zend_execute_ex; zend_execute_ex = tideways_xhprof_execute_ex; + zend_mm_heap *heap = zend_mm_get_heap(); + zend_mm_get_custom_handlers (heap, &_zend_malloc, &_zend_free, &_zend_realloc); + zend_mm_set_custom_handlers (heap, &tideways_malloc, &tideways_free, &tideways_realloc); + + + return SUCCESS; } PHP_MSHUTDOWN_FUNCTION(tideways_xhprof) { + zend_mm_heap *heap = zend_mm_get_heap(); + *((int *) heap) = 0; return SUCCESS; } @@ -198,6 +214,54 @@ ZEND_DLEXPORT void tideways_xhprof_execute_ex (zend_execute_data *execute_data) } } +void *tideways_malloc (size_t size) +{ + xhprof_frame_t *current_frame = TXRG(callgraph_frames); + if (current_frame) { + current_frame->num_alloc += 1; + current_frame->amount_alloc += size; + } + + if (_zend_malloc) { + return _zend_malloc(size); + } + + zend_mm_heap *heap = zend_mm_get_heap(); + return zend_mm_alloc(heap, size); +} + +void tideways_free (void *ptr) +{ + xhprof_frame_t *current_frame = TXRG(callgraph_frames); + if (current_frame) { + current_frame->num_free += 1; + } + + if (_zend_free) { + return _zend_free(ptr); + } + + zend_mm_heap *heap = zend_mm_get_heap(); + return zend_mm_free(heap, ptr); +} + +void *tideways_realloc (void *ptr, size_t size) +{ + xhprof_frame_t *current_frame = TXRG(callgraph_frames); + if (current_frame) { + current_frame->num_alloc += 1; + current_frame->num_free += 1; + current_frame->amount_alloc += size; + } + + if (_zend_realloc) { + return _zend_realloc(ptr, size); + } + + zend_mm_heap *heap = zend_mm_get_heap(); + return zend_mm_realloc(heap, ptr, size); +} + const zend_function_entry tideways_xhprof_functions[] = { PHP_FE(tideways_xhprof_enable, NULL) PHP_FE(tideways_xhprof_disable, NULL) diff --git a/tracing.c b/tracing.c index 5481264..3f493e1 100644 --- a/tracing.c +++ b/tracing.c @@ -214,6 +214,9 @@ void tracing_callgraph_append_to_array(zval *return_value TSRMLS_DC) array_init(stats); add_assoc_long(stats, "ct", bucket->count); add_assoc_long(stats, "wt", bucket->wall_time); + add_assoc_long(stats, "mem.na", bucket->num_alloc); + add_assoc_long(stats, "mem.nf", bucket->num_free); + add_assoc_long(stats, "mem.aa", bucket->amount_alloc); if (TXRG(flags) & TIDEWAYS_XHPROF_FLAGS_CPU) { add_assoc_long(stats, "cpu", bucket->cpu_time); diff --git a/tracing.h b/tracing.h index 1f1b699..8e07908 100644 --- a/tracing.h +++ b/tracing.h @@ -127,6 +127,10 @@ zend_always_inline static int tracing_enter_frame_callgraph(zend_string *root_sy current_frame->mu_start = zend_memory_usage(0 TSRMLS_CC); } + current_frame->num_alloc = 0; + current_frame->num_free = 0; + current_frame->amount_alloc = 0; + /* We only need to compute the hash for the function name, * that should be "good" enough, we sort into 1024 buckets only anyways */ current_frame->hash_code = ZSTR_HASH(function_name) % TIDEWAYS_XHPROF_CALLGRAPH_COUNTER_SIZE; @@ -193,6 +197,10 @@ zend_always_inline static void tracing_exit_frame_callgraph(TSRMLS_D) bucket->count++; bucket->wall_time += duration; + bucket->num_alloc += current_frame->num_alloc; + bucket->num_free += current_frame->num_free; + bucket->amount_alloc += current_frame->amount_alloc; + if (TXRG(flags) & TIDEWAYS_XHPROF_FLAGS_CPU) { bucket->cpu_time += (cpu_timer() - current_frame->cpu_start); } From a01bcc34f1bbd610169a48ea8a5bd7d55ba65485 Mon Sep 17 00:00:00 2001 From: Lars Maier Date: Tue, 5 Jun 2018 11:44:46 +0200 Subject: [PATCH 02/64] Updated tests to new output. --- tests/common.php | 2 +- tests/xhprof_001.phpt | 40 +++++++++++++++++++--------------------- tests/xhprof_002.phpt | 36 ++++++++++++++++++------------------ tests/xhprof_003.phpt | 15 +++++++-------- tests/xhprof_004.phpt | 8 ++++---- tests/xhprof_006.phpt | 6 +++--- tests/xhprof_007.phpt | 10 +++++----- 7 files changed, 57 insertions(+), 60 deletions(-) diff --git a/tests/common.php b/tests/common.php index 5675f09..895739e 100644 --- a/tests/common.php +++ b/tests/common.php @@ -37,7 +37,7 @@ function print_canonical($xhprof_data) // Only call counts are stable. // Wild card everything else. We still print // the metric name to ensure it was collected. - if (!in_array($name, array("ct", "mem.na", "mem.nf", "mem.aa"))) { + if (!in_array($name, array("ct"))) { $value = "*"; } else { $value = str_pad($value, 8, " ", STR_PAD_LEFT); diff --git a/tests/xhprof_001.phpt b/tests/xhprof_001.phpt index 7fe1cbf..ee37639 100644 --- a/tests/xhprof_001.phpt +++ b/tests/xhprof_001.phpt @@ -65,32 +65,30 @@ echo "\n"; ?> --EXPECT-- Part 1: Default Flags -foo==>bar : ct= 2; wt=*; -main() : ct= 1; wt=*; -main()==>foo : ct= 1; wt=*; -main()==>tideways_xhprof_disable : ct= 1; wt=*; +foo==>bar : ct= 2; mem.aa=*; mem.na=*; mem.nf=*; wt=*; +main() : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; +main()==>foo : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; +main()==>tideways_xhprof_disable : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; Part 2: CPU -foo==>bar : cpu=*; ct= 2; wt=*; -main() : cpu=*; ct= 1; wt=*; -main()==>foo : cpu=*; ct= 1; wt=*; -main()==>tideways_xhprof_disable : cpu=*; ct= 1; wt=*; +foo==>bar : cpu=*; ct= 2; mem.aa=*; mem.na=*; mem.nf=*; wt=*; +main() : cpu=*; ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; +main()==>foo : cpu=*; ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; +main()==>tideways_xhprof_disable : cpu=*; ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; Part 3: No Builtins -foo==>bar : ct= 2; wt=*; -main() : ct= 1; wt=*; -main()==>foo : ct= 1; wt=*; +foo==>bar : ct= 2; mem.aa=*; mem.na=*; mem.nf=*; wt=*; +main() : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; +main()==>foo : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; Part 4: Memory -foo==>bar : ct= 2; mu=*; pmu=*; wt=*; -main() : ct= 1; mu=*; pmu=*; wt=*; -main()==>foo : ct= 1; mu=*; pmu=*; wt=*; -main()==>tideways_xhprof_disable : ct= 1; mu=*; pmu=*; wt=*; +foo==>bar : ct= 2; mem.aa=*; mem.na=*; mem.nf=*; mu=*; pmu=*; wt=*; +main() : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; mu=*; pmu=*; wt=*; +main()==>foo : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; mu=*; pmu=*; wt=*; +main()==>tideways_xhprof_disable : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; mu=*; pmu=*; wt=*; Part 5: Memory & CPU -foo==>bar : cpu=*; ct= 2; mu=*; pmu=*; wt=*; -main() : cpu=*; ct= 1; mu=*; pmu=*; wt=*; -main()==>foo : cpu=*; ct= 1; mu=*; pmu=*; wt=*; -main()==>tideways_xhprof_disable : cpu=*; ct= 1; mu=*; pmu=*; wt=*; - - +foo==>bar : cpu=*; ct= 2; mem.aa=*; mem.na=*; mem.nf=*; mu=*; pmu=*; wt=*; +main() : cpu=*; ct= 1; mem.aa=*; mem.na=*; mem.nf=*; mu=*; pmu=*; wt=*; +main()==>foo : cpu=*; ct= 1; mem.aa=*; mem.na=*; mem.nf=*; mu=*; pmu=*; wt=*; +main()==>tideways_xhprof_disable : cpu=*; ct= 1; mem.aa=*; mem.na=*; mem.nf=*; mu=*; pmu=*; wt=*; \ No newline at end of file diff --git a/tests/xhprof_002.phpt b/tests/xhprof_002.phpt index 8e9db3c..0911179 100644 --- a/tests/xhprof_002.phpt +++ b/tests/xhprof_002.phpt @@ -40,23 +40,23 @@ echo "\n"; ?> --EXPECT-- Direct Recursion -foo==>foo@1 : ct= 1; wt=*; -foo@1==>foo@2 : ct= 1; wt=*; -foo@2==>foo@3 : ct= 1; wt=*; -foo@3==>foo@4 : ct= 1; wt=*; -main() : ct= 1; wt=*; -main()==>foo : ct= 1; wt=*; -main()==>tideways_xhprof_disable : ct= 1; wt=*; +foo==>foo@1 : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; +foo@1==>foo@2 : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; +foo@2==>foo@3 : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; +foo@3==>foo@4 : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; +main() : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; +main()==>foo : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; +main()==>tideways_xhprof_disable : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; Indirect Recursion -bar==>foo@1 : ct= 1; wt=*; -bar@1==>foo@2 : ct= 1; wt=*; -bar@2==>foo@3 : ct= 1; wt=*; -bar@3==>foo@4 : ct= 1; wt=*; -foo==>bar : ct= 1; wt=*; -foo@1==>bar@1 : ct= 1; wt=*; -foo@2==>bar@2 : ct= 1; wt=*; -foo@3==>bar@3 : ct= 1; wt=*; -main() : ct= 1; wt=*; -main()==>foo : ct= 1; wt=*; -main()==>tideways_xhprof_disable : ct= 1; wt=*; +bar==>foo@1 : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; +bar@1==>foo@2 : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; +bar@2==>foo@3 : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; +bar@3==>foo@4 : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; +foo==>bar : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; +foo@1==>bar@1 : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; +foo@2==>bar@2 : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; +foo@3==>bar@3 : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; +main() : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; +main()==>foo : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; +main()==>tideways_xhprof_disable : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; \ No newline at end of file diff --git a/tests/xhprof_003.phpt b/tests/xhprof_003.phpt index 00ffce7..6f559d9 100644 --- a/tests/xhprof_003.phpt +++ b/tests/xhprof_003.phpt @@ -58,11 +58,10 @@ i am a class static In constructor... Destroying class Hello World Profiler data for 'Class' tests: -C::outer_static==>C::inner_static : ct= 1; wt=*; -main() : ct= 1; wt=*; -main()==>C::__construct : ct= 1; wt=*; -main()==>C::__destruct : ct= 1; wt=*; -main()==>C::get_attr : ct= 1; wt=*; -main()==>C::outer_static : ct= 1; wt=*; -main()==>tideways_xhprof_disable : ct= 1; wt=*; - +C::outer_static==>C::inner_static : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; +main() : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; +main()==>C::__construct : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; +main()==>C::__destruct : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; +main()==>C::get_attr : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; +main()==>C::outer_static : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; +main()==>tideways_xhprof_disable : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; \ No newline at end of file diff --git a/tests/xhprof_004.phpt b/tests/xhprof_004.phpt index e098191..2f32045 100644 --- a/tests/xhprof_004.phpt +++ b/tests/xhprof_004.phpt @@ -22,7 +22,7 @@ print_canonical($output); ?> --EXPECTF-- -main() : ct= 1; wt=*; -main()==>class@anonymous::baz : ct= 1; wt=*; -main()==>tideways_xhprof_disable : ct= 1; wt=*; -main()==>{closure} : ct= 1; wt=*; +main() : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; +main()==>class@anonymous::baz : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; +main()==>tideways_xhprof_disable : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; +main()==>{closure} : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; \ No newline at end of file diff --git a/tests/xhprof_006.phpt b/tests/xhprof_006.phpt index 46885b9..1e3a9b2 100644 --- a/tests/xhprof_006.phpt +++ b/tests/xhprof_006.phpt @@ -37,6 +37,6 @@ print_canonical($output); --EXPECTF-- string(1) "1" Clock Source => tsc -main() : ct= 1; wt=*; -main()==>foo : ct= 1; wt=*; -main()==>tideways_xhprof_disable : ct= 1; wt=*; +main() : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; +main()==>foo : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; +main()==>tideways_xhprof_disable : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; \ No newline at end of file diff --git a/tests/xhprof_007.phpt b/tests/xhprof_007.phpt index 373299c..306cc78 100644 --- a/tests/xhprof_007.phpt +++ b/tests/xhprof_007.phpt @@ -26,8 +26,8 @@ $output = tideways_xhprof_disable(); print_canonical($output); --EXPECTF-- -main() : ct= 1; wt=*; -main()==>class@anonymous::__invoke : ct= 1; wt=*; -main()==>foo : ct= 2; wt=*; -main()==>tideways_xhprof_disable : ct= 1; wt=*; -main()==>{closure} : ct= 1; wt=*; +main() : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; +main()==>class@anonymous::__invoke : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; +main()==>foo : ct= 2; mem.aa=*; mem.na=*; mem.nf=*; wt=*; +main()==>tideways_xhprof_disable : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; +main()==>{closure} : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; \ No newline at end of file From d77c788f9f6c4503f77b5dbc77e828ea2f45bdd4 Mon Sep 17 00:00:00 2001 From: Lars Maier Date: Tue, 5 Jun 2018 15:02:34 +0200 Subject: [PATCH 03/64] Hooking moved to `tracing_begin`/`tracing_end` in order to hook only if `TIDEWAYS_XHPROF_FLAGS_MEMORY_EXT` is set. --- tests/xhprof_001.phpt | 53 +++++++++++++++++++----------- tests/xhprof_002.phpt | 36 ++++++++++---------- tests/xhprof_003.phpt | 14 ++++---- tests/xhprof_004.phpt | 8 ++--- tests/xhprof_006.phpt | 6 ++-- tests/xhprof_007.phpt | 10 +++--- tideways_xhprof.c | 65 +----------------------------------- tracing.c | 76 +++++++++++++++++++++++++++++++++++++++++-- tracing.h | 1 + 9 files changed, 146 insertions(+), 123 deletions(-) diff --git a/tests/xhprof_001.phpt b/tests/xhprof_001.phpt index ee37639..bf40ced 100644 --- a/tests/xhprof_001.phpt +++ b/tests/xhprof_001.phpt @@ -62,33 +62,48 @@ echo "Part 5: Memory & CPU\n"; print_canonical($output); echo "\n"; +// 6: Sanity test extended memory profiling +tideways_xhprof_enable(TIDEWAYS_XHPROF_FLAGS_MEMORY_EXT); +foo("this is a test"); +$output = tideways_xhprof_disable(); + +echo "Part 6: Extended Memory Profiling\n"; +print_canonical($output); +echo "\n"; + ?> --EXPECT-- Part 1: Default Flags -foo==>bar : ct= 2; mem.aa=*; mem.na=*; mem.nf=*; wt=*; -main() : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; -main()==>foo : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; -main()==>tideways_xhprof_disable : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; +foo==>bar : ct= 2; wt=*; +main() : ct= 1; wt=*; +main()==>foo : ct= 1; wt=*; +main()==>tideways_xhprof_disable : ct= 1; wt=*; Part 2: CPU -foo==>bar : cpu=*; ct= 2; mem.aa=*; mem.na=*; mem.nf=*; wt=*; -main() : cpu=*; ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; -main()==>foo : cpu=*; ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; -main()==>tideways_xhprof_disable : cpu=*; ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; +foo==>bar : cpu=*; ct= 2; wt=*; +main() : cpu=*; ct= 1; wt=*; +main()==>foo : cpu=*; ct= 1; wt=*; +main()==>tideways_xhprof_disable : cpu=*; ct= 1; wt=*; Part 3: No Builtins -foo==>bar : ct= 2; mem.aa=*; mem.na=*; mem.nf=*; wt=*; -main() : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; -main()==>foo : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; +foo==>bar : ct= 2; wt=*; +main() : ct= 1; wt=*; +main()==>foo : ct= 1; wt=*; Part 4: Memory -foo==>bar : ct= 2; mem.aa=*; mem.na=*; mem.nf=*; mu=*; pmu=*; wt=*; -main() : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; mu=*; pmu=*; wt=*; -main()==>foo : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; mu=*; pmu=*; wt=*; -main()==>tideways_xhprof_disable : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; mu=*; pmu=*; wt=*; +foo==>bar : ct= 2; mu=*; pmu=*; wt=*; +main() : ct= 1; mu=*; pmu=*; wt=*; +main()==>foo : ct= 1; mu=*; pmu=*; wt=*; +main()==>tideways_xhprof_disable : ct= 1; mu=*; pmu=*; wt=*; Part 5: Memory & CPU -foo==>bar : cpu=*; ct= 2; mem.aa=*; mem.na=*; mem.nf=*; mu=*; pmu=*; wt=*; -main() : cpu=*; ct= 1; mem.aa=*; mem.na=*; mem.nf=*; mu=*; pmu=*; wt=*; -main()==>foo : cpu=*; ct= 1; mem.aa=*; mem.na=*; mem.nf=*; mu=*; pmu=*; wt=*; -main()==>tideways_xhprof_disable : cpu=*; ct= 1; mem.aa=*; mem.na=*; mem.nf=*; mu=*; pmu=*; wt=*; \ No newline at end of file +foo==>bar : cpu=*; ct= 2; mu=*; pmu=*; wt=*; +main() : cpu=*; ct= 1; mu=*; pmu=*; wt=*; +main()==>foo : cpu=*; ct= 1; mu=*; pmu=*; wt=*; +main()==>tideways_xhprof_disable : cpu=*; ct= 1; mu=*; pmu=*; wt=*; + +Part 6: Extended Memory Profiling +foo==>bar : ct= 2; mem.aa=*; mem.na=*; mem.nf=*; wt=*; +main() : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; +main()==>foo : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; +main()==>tideways_xhprof_disable : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; diff --git a/tests/xhprof_002.phpt b/tests/xhprof_002.phpt index 0911179..8e9db3c 100644 --- a/tests/xhprof_002.phpt +++ b/tests/xhprof_002.phpt @@ -40,23 +40,23 @@ echo "\n"; ?> --EXPECT-- Direct Recursion -foo==>foo@1 : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; -foo@1==>foo@2 : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; -foo@2==>foo@3 : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; -foo@3==>foo@4 : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; -main() : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; -main()==>foo : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; -main()==>tideways_xhprof_disable : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; +foo==>foo@1 : ct= 1; wt=*; +foo@1==>foo@2 : ct= 1; wt=*; +foo@2==>foo@3 : ct= 1; wt=*; +foo@3==>foo@4 : ct= 1; wt=*; +main() : ct= 1; wt=*; +main()==>foo : ct= 1; wt=*; +main()==>tideways_xhprof_disable : ct= 1; wt=*; Indirect Recursion -bar==>foo@1 : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; -bar@1==>foo@2 : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; -bar@2==>foo@3 : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; -bar@3==>foo@4 : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; -foo==>bar : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; -foo@1==>bar@1 : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; -foo@2==>bar@2 : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; -foo@3==>bar@3 : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; -main() : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; -main()==>foo : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; -main()==>tideways_xhprof_disable : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; \ No newline at end of file +bar==>foo@1 : ct= 1; wt=*; +bar@1==>foo@2 : ct= 1; wt=*; +bar@2==>foo@3 : ct= 1; wt=*; +bar@3==>foo@4 : ct= 1; wt=*; +foo==>bar : ct= 1; wt=*; +foo@1==>bar@1 : ct= 1; wt=*; +foo@2==>bar@2 : ct= 1; wt=*; +foo@3==>bar@3 : ct= 1; wt=*; +main() : ct= 1; wt=*; +main()==>foo : ct= 1; wt=*; +main()==>tideways_xhprof_disable : ct= 1; wt=*; diff --git a/tests/xhprof_003.phpt b/tests/xhprof_003.phpt index 6f559d9..fe93214 100644 --- a/tests/xhprof_003.phpt +++ b/tests/xhprof_003.phpt @@ -58,10 +58,10 @@ i am a class static In constructor... Destroying class Hello World Profiler data for 'Class' tests: -C::outer_static==>C::inner_static : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; -main() : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; -main()==>C::__construct : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; -main()==>C::__destruct : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; -main()==>C::get_attr : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; -main()==>C::outer_static : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; -main()==>tideways_xhprof_disable : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; \ No newline at end of file +C::outer_static==>C::inner_static : ct= 1; wt=*; +main() : ct= 1; wt=*; +main()==>C::__construct : ct= 1; wt=*; +main()==>C::__destruct : ct= 1; wt=*; +main()==>C::get_attr : ct= 1; wt=*; +main()==>C::outer_static : ct= 1; wt=*; +main()==>tideways_xhprof_disable : ct= 1; wt=*; diff --git a/tests/xhprof_004.phpt b/tests/xhprof_004.phpt index 2f32045..e098191 100644 --- a/tests/xhprof_004.phpt +++ b/tests/xhprof_004.phpt @@ -22,7 +22,7 @@ print_canonical($output); ?> --EXPECTF-- -main() : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; -main()==>class@anonymous::baz : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; -main()==>tideways_xhprof_disable : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; -main()==>{closure} : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; \ No newline at end of file +main() : ct= 1; wt=*; +main()==>class@anonymous::baz : ct= 1; wt=*; +main()==>tideways_xhprof_disable : ct= 1; wt=*; +main()==>{closure} : ct= 1; wt=*; diff --git a/tests/xhprof_006.phpt b/tests/xhprof_006.phpt index 1e3a9b2..46885b9 100644 --- a/tests/xhprof_006.phpt +++ b/tests/xhprof_006.phpt @@ -37,6 +37,6 @@ print_canonical($output); --EXPECTF-- string(1) "1" Clock Source => tsc -main() : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; -main()==>foo : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; -main()==>tideways_xhprof_disable : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; \ No newline at end of file +main() : ct= 1; wt=*; +main()==>foo : ct= 1; wt=*; +main()==>tideways_xhprof_disable : ct= 1; wt=*; diff --git a/tests/xhprof_007.phpt b/tests/xhprof_007.phpt index 306cc78..373299c 100644 --- a/tests/xhprof_007.phpt +++ b/tests/xhprof_007.phpt @@ -26,8 +26,8 @@ $output = tideways_xhprof_disable(); print_canonical($output); --EXPECTF-- -main() : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; -main()==>class@anonymous::__invoke : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; -main()==>foo : ct= 2; mem.aa=*; mem.na=*; mem.nf=*; wt=*; -main()==>tideways_xhprof_disable : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; -main()==>{closure} : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; \ No newline at end of file +main() : ct= 1; wt=*; +main()==>class@anonymous::__invoke : ct= 1; wt=*; +main()==>foo : ct= 2; wt=*; +main()==>tideways_xhprof_disable : ct= 1; wt=*; +main()==>{closure} : ct= 1; wt=*; diff --git a/tideways_xhprof.c b/tideways_xhprof.c index af95943..5db081c 100644 --- a/tideways_xhprof.c +++ b/tideways_xhprof.c @@ -17,14 +17,6 @@ static void (*_zend_execute_internal) (zend_execute_data *execute_data, zval *re ZEND_DLEXPORT void tideways_xhprof_execute_internal(zend_execute_data *execute_data, zval *return_value); ZEND_DLEXPORT void tideways_xhprof_execute_ex (zend_execute_data *execute_data); -static void *(*_zend_malloc) (size_t); -static void (*_zend_free) (void *); -static void *(*_zend_realloc) (void *, size_t); - -void *tideways_malloc (size_t size); -void tideways_free (void *ptr); -void *tideways_realloc (void *ptr, size_t size); - PHP_INI_BEGIN() STD_PHP_INI_ENTRY("tideways_xhprof.clock_use_rdtsc", "0", PHP_INI_ALL, OnUpdateBool, clock_use_rdtsc, zend_tideways_xhprof_globals, tideways_xhprof_globals) PHP_INI_END() @@ -69,6 +61,7 @@ PHP_MINIT_FUNCTION(tideways_xhprof) REGISTER_LONG_CONSTANT("TIDEWAYS_XHPROF_FLAGS_MEMORY_PMU", TIDEWAYS_XHPROF_FLAGS_MEMORY_PMU, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("TIDEWAYS_XHPROF_FLAGS_CPU", TIDEWAYS_XHPROF_FLAGS_CPU, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("TIDEWAYS_XHPROF_FLAGS_NO_BUILTINS", TIDEWAYS_XHPROF_FLAGS_NO_BUILTINS, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("TIDEWAYS_XHPROF_FLAGS_MEMORY_EXT", TIDEWAYS_XHPROF_FLAGS_MEMORY_EXT, CONST_CS | CONST_PERSISTENT); _zend_execute_internal = zend_execute_internal; zend_execute_internal = tideways_xhprof_execute_internal; @@ -76,19 +69,11 @@ PHP_MINIT_FUNCTION(tideways_xhprof) _zend_execute_ex = zend_execute_ex; zend_execute_ex = tideways_xhprof_execute_ex; - zend_mm_heap *heap = zend_mm_get_heap(); - zend_mm_get_custom_handlers (heap, &_zend_malloc, &_zend_free, &_zend_realloc); - zend_mm_set_custom_handlers (heap, &tideways_malloc, &tideways_free, &tideways_realloc); - - - return SUCCESS; } PHP_MSHUTDOWN_FUNCTION(tideways_xhprof) { - zend_mm_heap *heap = zend_mm_get_heap(); - *((int *) heap) = 0; return SUCCESS; } @@ -214,54 +199,6 @@ ZEND_DLEXPORT void tideways_xhprof_execute_ex (zend_execute_data *execute_data) } } -void *tideways_malloc (size_t size) -{ - xhprof_frame_t *current_frame = TXRG(callgraph_frames); - if (current_frame) { - current_frame->num_alloc += 1; - current_frame->amount_alloc += size; - } - - if (_zend_malloc) { - return _zend_malloc(size); - } - - zend_mm_heap *heap = zend_mm_get_heap(); - return zend_mm_alloc(heap, size); -} - -void tideways_free (void *ptr) -{ - xhprof_frame_t *current_frame = TXRG(callgraph_frames); - if (current_frame) { - current_frame->num_free += 1; - } - - if (_zend_free) { - return _zend_free(ptr); - } - - zend_mm_heap *heap = zend_mm_get_heap(); - return zend_mm_free(heap, ptr); -} - -void *tideways_realloc (void *ptr, size_t size) -{ - xhprof_frame_t *current_frame = TXRG(callgraph_frames); - if (current_frame) { - current_frame->num_alloc += 1; - current_frame->num_free += 1; - current_frame->amount_alloc += size; - } - - if (_zend_realloc) { - return _zend_realloc(ptr, size); - } - - zend_mm_heap *heap = zend_mm_get_heap(); - return zend_mm_realloc(heap, ptr, size); -} - const zend_function_entry tideways_xhprof_functions[] = { PHP_FE(tideways_xhprof_enable, NULL) PHP_FE(tideways_xhprof_disable, NULL) diff --git a/tracing.c b/tracing.c index 3f493e1..2c153f7 100644 --- a/tracing.c +++ b/tracing.c @@ -12,6 +12,14 @@ extern ZEND_DECLARE_MODULE_GLOBALS(tideways_xhprof); static const char digits[] = "0123456789abcdef"; +static void *(*_zend_malloc) (size_t); +static void (*_zend_free) (void *); +static void *(*_zend_realloc) (void *, size_t); + +void *tideways_malloc (size_t size); +void tideways_free (void *ptr); +void *tideways_realloc (void *ptr, size_t size); + void tracing_determine_clock_source(TSRMLS_D) { #ifdef __APPLE__ TXRG(clock_source) = TIDEWAYS_XHPROF_CLOCK_MACH; @@ -70,6 +78,11 @@ void tracing_end(TSRMLS_D) TXRG(enabled) = 0; TXRG(callgraph_frames) = NULL; + + if (TXRG(flags) & TIDEWAYS_XHPROF_FLAGS_MEMORY_EXT) { + zend_mm_heap *heap = zend_mm_get_heap(); + *((int *) heap) = 0; + } } } @@ -214,9 +227,12 @@ void tracing_callgraph_append_to_array(zval *return_value TSRMLS_DC) array_init(stats); add_assoc_long(stats, "ct", bucket->count); add_assoc_long(stats, "wt", bucket->wall_time); - add_assoc_long(stats, "mem.na", bucket->num_alloc); - add_assoc_long(stats, "mem.nf", bucket->num_free); - add_assoc_long(stats, "mem.aa", bucket->amount_alloc); + + if (TXRG(flags) & TIDEWAYS_XHPROF_FLAGS_MEMORY_EXT) { + add_assoc_long(stats, "mem.na", bucket->num_alloc); + add_assoc_long(stats, "mem.nf", bucket->num_free); + add_assoc_long(stats, "mem.aa", bucket->amount_alloc); + } if (TXRG(flags) & TIDEWAYS_XHPROF_FLAGS_CPU) { add_assoc_long(stats, "cpu", bucket->cpu_time); @@ -253,6 +269,12 @@ void tracing_begin(zend_long flags TSRMLS_DC) for (i = 0; i < TIDEWAYS_XHPROF_CALLGRAPH_COUNTER_SIZE; i++) { TXRG(function_hash_counters)[i] = 0; } + + if (flags & TIDEWAYS_XHPROF_FLAGS_MEMORY_EXT) { + zend_mm_heap *heap = zend_mm_get_heap(); + zend_mm_get_custom_handlers (heap, &_zend_malloc, &_zend_free, &_zend_realloc); + zend_mm_set_custom_handlers (heap, &tideways_malloc, &tideways_free, &tideways_realloc); + } } void tracing_request_init(TSRMLS_D) @@ -267,3 +289,51 @@ void tracing_request_shutdown() { tracing_free_the_free_list(); } + +void *tideways_malloc (size_t size) +{ + xhprof_frame_t *current_frame = TXRG(callgraph_frames); + if (current_frame) { + current_frame->num_alloc += 1; + current_frame->amount_alloc += size; + } + + if (_zend_malloc) { + return _zend_malloc(size); + } + + zend_mm_heap *heap = zend_mm_get_heap(); + return zend_mm_alloc(heap, size); +} + +void tideways_free (void *ptr) +{ + xhprof_frame_t *current_frame = TXRG(callgraph_frames); + if (current_frame) { + current_frame->num_free += 1; + } + + if (_zend_free) { + return _zend_free(ptr); + } + + zend_mm_heap *heap = zend_mm_get_heap(); + return zend_mm_free(heap, ptr); +} + +void *tideways_realloc (void *ptr, size_t size) +{ + xhprof_frame_t *current_frame = TXRG(callgraph_frames); + if (current_frame) { + current_frame->num_alloc += 1; + current_frame->num_free += 1; + current_frame->amount_alloc += size; + } + + if (_zend_realloc) { + return _zend_realloc(ptr, size); + } + + zend_mm_heap *heap = zend_mm_get_heap(); + return zend_mm_realloc(heap, ptr, size); +} \ No newline at end of file diff --git a/tracing.h b/tracing.h index 8e07908..65f9e3b 100644 --- a/tracing.h +++ b/tracing.h @@ -7,6 +7,7 @@ #define TIDEWAYS_XHPROF_FLAGS_MEMORY_MU 2 #define TIDEWAYS_XHPROF_FLAGS_MEMORY_PMU 4 #define TIDEWAYS_XHPROF_FLAGS_MEMORY 6 +#define TIDEWAYS_XHPROF_FLAGS_MEMORY_EXT 16 #define TIDEWAYS_XHPROF_FLAGS_NO_BUILTINS 8 void tracing_callgraph_append_to_array(zval *return_value TSRMLS_DC); From 4ce8625b5b3ddaf1604a302eae9984b22afc904c Mon Sep 17 00:00:00 2001 From: Lars Maier Date: Tue, 5 Jun 2018 15:51:40 +0200 Subject: [PATCH 04/64] Added missing initialisation for buckets. --- tracing.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tracing.h b/tracing.h index 65f9e3b..f63f8f1 100644 --- a/tracing.h +++ b/tracing.h @@ -189,6 +189,9 @@ zend_always_inline static void tracing_exit_frame_callgraph(TSRMLS_D) bucket->cpu_time = 0; bucket->memory = 0; bucket->memory_peak = 0; + bucket->num_alloc = 0; + bucket->num_free = 0; + bucket->amount_alloc = 0; bucket->child_recurse_level = current_frame->recurse_level; bucket->next = TXRG(callgraph_buckets)[slot]; From e53c7e1156fda723f3568d4d4c21cb596f8b83e3 Mon Sep 17 00:00:00 2001 From: Lars Maier Date: Tue, 5 Jun 2018 15:58:10 +0200 Subject: [PATCH 05/64] Renamed flag to `MEM_ALLOC` instead of `MEM_EXT`. --- tests/xhprof_001.phpt | 2 +- tideways_xhprof.c | 2 +- tracing.c | 6 +++--- tracing.h | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/xhprof_001.phpt b/tests/xhprof_001.phpt index bf40ced..b6d117e 100644 --- a/tests/xhprof_001.phpt +++ b/tests/xhprof_001.phpt @@ -63,7 +63,7 @@ print_canonical($output); echo "\n"; // 6: Sanity test extended memory profiling -tideways_xhprof_enable(TIDEWAYS_XHPROF_FLAGS_MEMORY_EXT); +tideways_xhprof_enable(TIDEWAYS_XHPROF_FLAGS_MEMORY_ALLOC); foo("this is a test"); $output = tideways_xhprof_disable(); diff --git a/tideways_xhprof.c b/tideways_xhprof.c index 5db081c..cc084f6 100644 --- a/tideways_xhprof.c +++ b/tideways_xhprof.c @@ -61,7 +61,7 @@ PHP_MINIT_FUNCTION(tideways_xhprof) REGISTER_LONG_CONSTANT("TIDEWAYS_XHPROF_FLAGS_MEMORY_PMU", TIDEWAYS_XHPROF_FLAGS_MEMORY_PMU, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("TIDEWAYS_XHPROF_FLAGS_CPU", TIDEWAYS_XHPROF_FLAGS_CPU, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("TIDEWAYS_XHPROF_FLAGS_NO_BUILTINS", TIDEWAYS_XHPROF_FLAGS_NO_BUILTINS, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("TIDEWAYS_XHPROF_FLAGS_MEMORY_EXT", TIDEWAYS_XHPROF_FLAGS_MEMORY_EXT, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("TIDEWAYS_XHPROF_FLAGS_MEMORY_ALLOC", TIDEWAYS_XHPROF_FLAGS_MEMORY_ALLOC, CONST_CS | CONST_PERSISTENT); _zend_execute_internal = zend_execute_internal; zend_execute_internal = tideways_xhprof_execute_internal; diff --git a/tracing.c b/tracing.c index 2c153f7..02c2ab2 100644 --- a/tracing.c +++ b/tracing.c @@ -79,7 +79,7 @@ void tracing_end(TSRMLS_D) TXRG(enabled) = 0; TXRG(callgraph_frames) = NULL; - if (TXRG(flags) & TIDEWAYS_XHPROF_FLAGS_MEMORY_EXT) { + if (TXRG(flags) & TIDEWAYS_XHPROF_FLAGS_MEMORY_ALLOC) { zend_mm_heap *heap = zend_mm_get_heap(); *((int *) heap) = 0; } @@ -228,7 +228,7 @@ void tracing_callgraph_append_to_array(zval *return_value TSRMLS_DC) add_assoc_long(stats, "ct", bucket->count); add_assoc_long(stats, "wt", bucket->wall_time); - if (TXRG(flags) & TIDEWAYS_XHPROF_FLAGS_MEMORY_EXT) { + if (TXRG(flags) & TIDEWAYS_XHPROF_FLAGS_MEMORY_ALLOC) { add_assoc_long(stats, "mem.na", bucket->num_alloc); add_assoc_long(stats, "mem.nf", bucket->num_free); add_assoc_long(stats, "mem.aa", bucket->amount_alloc); @@ -270,7 +270,7 @@ void tracing_begin(zend_long flags TSRMLS_DC) TXRG(function_hash_counters)[i] = 0; } - if (flags & TIDEWAYS_XHPROF_FLAGS_MEMORY_EXT) { + if (flags & TIDEWAYS_XHPROF_FLAGS_MEMORY_ALLOC) { zend_mm_heap *heap = zend_mm_get_heap(); zend_mm_get_custom_handlers (heap, &_zend_malloc, &_zend_free, &_zend_realloc); zend_mm_set_custom_handlers (heap, &tideways_malloc, &tideways_free, &tideways_realloc); diff --git a/tracing.h b/tracing.h index f63f8f1..1874c13 100644 --- a/tracing.h +++ b/tracing.h @@ -7,7 +7,7 @@ #define TIDEWAYS_XHPROF_FLAGS_MEMORY_MU 2 #define TIDEWAYS_XHPROF_FLAGS_MEMORY_PMU 4 #define TIDEWAYS_XHPROF_FLAGS_MEMORY 6 -#define TIDEWAYS_XHPROF_FLAGS_MEMORY_EXT 16 +#define TIDEWAYS_XHPROF_FLAGS_MEMORY_ALLOC 16 #define TIDEWAYS_XHPROF_FLAGS_NO_BUILTINS 8 void tracing_callgraph_append_to_array(zval *return_value TSRMLS_DC); From 3a6eb48fb669ec15867ce0e3dfad6e73472ce479 Mon Sep 17 00:00:00 2001 From: Lars Maier Date: Tue, 5 Jun 2018 16:03:25 +0200 Subject: [PATCH 06/64] Updates README.md with new output format. --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index f8b3f67..243dbd1 100644 --- a/README.md +++ b/README.md @@ -95,6 +95,11 @@ function names as a key concatenated with ==> and an array value with 2 to 5 ent - `mu` The sum of increase in `memory_get_usage` for this parent ==> child function pair. - `pmu` The sum of increase in `memory_get_peak_usage` for this parent ==> child function pair. +When `TIDEWAYS_XHPROF_FLAGS_MEMORY_ALLOC` flag is set, the following additional values are set: +- `mem.na` The sum of the number of all allocations in this function. +- `mem.nf` The sum of the number of all frees in this function. +- `mem.aa` The amount of allocated memory. + There is a "magic" function call called "main()" that represents the entry into the profiling. The wall time on this performance data describes the full timeframe that the profiling ran. From be9ad929ef100285c126aa4858d4c30394d8a8ba Mon Sep 17 00:00:00 2001 From: Lars Maier Date: Wed, 6 Jun 2018 09:32:30 +0200 Subject: [PATCH 07/64] Reset custom handlers properly when already replaced. --- tracing.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/tracing.c b/tracing.c index 02c2ab2..5055156 100644 --- a/tracing.c +++ b/tracing.c @@ -81,7 +81,17 @@ void tracing_end(TSRMLS_D) if (TXRG(flags) & TIDEWAYS_XHPROF_FLAGS_MEMORY_ALLOC) { zend_mm_heap *heap = zend_mm_get_heap(); - *((int *) heap) = 0; + + if (_zend_malloc || _zend_free || _zend_realloc) { + zend_mm_set_custom_handlers(heap, _zend_malloc, _zend_free, _zend_realloc); + _zend_malloc = NULL; + _zend_free = NULL; + _zend_realloc = NULL; + } else { + // zend_mm_heap is incomplete type, hence one can not access it + // the following line is equivalent to heap->use_custom_heap = 0; + *((int*) heap) = 0; + } } } } From ed74fa433212b277f3e1fadfee1a0d7908475aeb Mon Sep 17 00:00:00 2001 From: Lars Maier Date: Wed, 6 Jun 2018 10:21:28 +0200 Subject: [PATCH 08/64] Added `MEMORY_ALLOC_AS_MU` flag that returns the allocated memory additionally in the `mu` field. --- README.md | 3 +++ tests/xhprof_001.phpt | 15 +++++++++++++++ tideways_xhprof.c | 1 + tracing.c | 8 ++++++++ tracing.h | 1 + 5 files changed, 28 insertions(+) diff --git a/README.md b/README.md index 243dbd1..41a59f8 100644 --- a/README.md +++ b/README.md @@ -100,6 +100,9 @@ When `TIDEWAYS_XHPROF_FLAGS_MEMORY_ALLOC` flag is set, the following additional - `mem.nf` The sum of the number of all frees in this function. - `mem.aa` The amount of allocated memory. +If `TIDEWAYS_XHPROF_FLAGS_MEMORY_ALLOC_AS_MU` is set, `TIDEWAYS_XHPROF_FLAGS_MEMORY_ALLOC` is activated +and, if `TIDEWAYS_XHPROF_FLAGS_MEMORY_MU` is not set, `mem.aa` is additionally returned in `mu`. + There is a "magic" function call called "main()" that represents the entry into the profiling. The wall time on this performance data describes the full timeframe that the profiling ran. diff --git a/tests/xhprof_001.phpt b/tests/xhprof_001.phpt index b6d117e..1429165 100644 --- a/tests/xhprof_001.phpt +++ b/tests/xhprof_001.phpt @@ -71,6 +71,15 @@ echo "Part 6: Extended Memory Profiling\n"; print_canonical($output); echo "\n"; +// 7: Sanity test extended memory profiling as mu +tideways_xhprof_enable(TIDEWAYS_XHPROF_FLAGS_MEMORY_ALLOC_AS_MU); +foo("this is a test"); +$output = tideways_xhprof_disable(); + +echo "Part 7: Extended Memory Profiling as mu\n"; +print_canonical($output); +echo "\n"; + ?> --EXPECT-- Part 1: Default Flags @@ -107,3 +116,9 @@ foo==>bar : ct= 2; mem.aa=*; mem.na=*; mem.n main() : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; main()==>foo : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; main()==>tideways_xhprof_disable : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; + +Part 7: Extended Memory Profiling as mu +foo==>bar : ct= 2; mem.aa=*; mem.na=*; mem.nf=*; mu=*; wt=*; +main() : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; mu=*; wt=*; +main()==>foo : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; mu=*; wt=*; +main()==>tideways_xhprof_disable : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; mu=*; wt=*; diff --git a/tideways_xhprof.c b/tideways_xhprof.c index cc084f6..b50d065 100644 --- a/tideways_xhprof.c +++ b/tideways_xhprof.c @@ -62,6 +62,7 @@ PHP_MINIT_FUNCTION(tideways_xhprof) REGISTER_LONG_CONSTANT("TIDEWAYS_XHPROF_FLAGS_CPU", TIDEWAYS_XHPROF_FLAGS_CPU, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("TIDEWAYS_XHPROF_FLAGS_NO_BUILTINS", TIDEWAYS_XHPROF_FLAGS_NO_BUILTINS, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("TIDEWAYS_XHPROF_FLAGS_MEMORY_ALLOC", TIDEWAYS_XHPROF_FLAGS_MEMORY_ALLOC, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("TIDEWAYS_XHPROF_FLAGS_MEMORY_ALLOC_AS_MU", TIDEWAYS_XHPROF_FLAGS_MEMORY_ALLOC_AS_MU, CONST_CS | CONST_PERSISTENT); _zend_execute_internal = zend_execute_internal; zend_execute_internal = tideways_xhprof_execute_internal; diff --git a/tracing.c b/tracing.c index 5055156..e8b5858 100644 --- a/tracing.c +++ b/tracing.c @@ -242,6 +242,14 @@ void tracing_callgraph_append_to_array(zval *return_value TSRMLS_DC) add_assoc_long(stats, "mem.na", bucket->num_alloc); add_assoc_long(stats, "mem.nf", bucket->num_free); add_assoc_long(stats, "mem.aa", bucket->amount_alloc); + + int as_mu = + (TXRG(flags) & (TIDEWAYS_XHPROF_FLAGS_MEMORY_ALLOC_AS_MU | TIDEWAYS_XHPROF_FLAGS_MEMORY_MU)) + == TIDEWAYS_XHPROF_FLAGS_MEMORY_ALLOC_AS_MU; + + if (as_mu) { + add_assoc_long(stats, "mu", bucket->amount_alloc); + } } if (TXRG(flags) & TIDEWAYS_XHPROF_FLAGS_CPU) { diff --git a/tracing.h b/tracing.h index 1874c13..72bf70f 100644 --- a/tracing.h +++ b/tracing.h @@ -8,6 +8,7 @@ #define TIDEWAYS_XHPROF_FLAGS_MEMORY_PMU 4 #define TIDEWAYS_XHPROF_FLAGS_MEMORY 6 #define TIDEWAYS_XHPROF_FLAGS_MEMORY_ALLOC 16 +#define TIDEWAYS_XHPROF_FLAGS_MEMORY_ALLOC_AS_MU (32|16) #define TIDEWAYS_XHPROF_FLAGS_NO_BUILTINS 8 void tracing_callgraph_append_to_array(zval *return_value TSRMLS_DC); From 013a19f3ef25d68e503ce778bdc0deb90839863e Mon Sep 17 00:00:00 2001 From: Lars Maier Date: Wed, 6 Jun 2018 10:40:44 +0200 Subject: [PATCH 09/64] Clean up. --- tracing.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tracing.c b/tracing.c index e8b5858..63cf1dd 100644 --- a/tracing.c +++ b/tracing.c @@ -228,6 +228,10 @@ void tracing_callgraph_append_to_array(zval *return_value TSRMLS_DC) char symbol[512] = ""; zval stats_zv, *stats = &stats_zv; + int as_mu = + (TXRG(flags) & (TIDEWAYS_XHPROF_FLAGS_MEMORY_ALLOC_AS_MU | TIDEWAYS_XHPROF_FLAGS_MEMORY_MU)) + == TIDEWAYS_XHPROF_FLAGS_MEMORY_ALLOC_AS_MU; + for (i = 0; i < TIDEWAYS_XHPROF_CALLGRAPH_SLOTS; i++) { bucket = TXRG(callgraph_buckets)[i]; @@ -243,10 +247,6 @@ void tracing_callgraph_append_to_array(zval *return_value TSRMLS_DC) add_assoc_long(stats, "mem.nf", bucket->num_free); add_assoc_long(stats, "mem.aa", bucket->amount_alloc); - int as_mu = - (TXRG(flags) & (TIDEWAYS_XHPROF_FLAGS_MEMORY_ALLOC_AS_MU | TIDEWAYS_XHPROF_FLAGS_MEMORY_MU)) - == TIDEWAYS_XHPROF_FLAGS_MEMORY_ALLOC_AS_MU; - if (as_mu) { add_assoc_long(stats, "mu", bucket->amount_alloc); } From eb227920ef5d3f5782c796c4180d490d143f38a9 Mon Sep 17 00:00:00 2001 From: Lars Maier Date: Mon, 11 Jun 2018 12:09:51 +0200 Subject: [PATCH 10/64] Fix to, correctly sum up exclusive and inclusive memory values. --- php_tideways_xhprof.h | 3 +++ tracing.c | 25 ++++++++----------------- tracing.h | 12 ++++++------ 3 files changed, 17 insertions(+), 23 deletions(-) diff --git a/php_tideways_xhprof.h b/php_tideways_xhprof.h index f23738b..88161d9 100644 --- a/php_tideways_xhprof.h +++ b/php_tideways_xhprof.h @@ -78,6 +78,9 @@ ZEND_BEGIN_MODULE_GLOBALS(tideways_xhprof) zend_ulong function_hash_counters[TIDEWAYS_XHPROF_CALLGRAPH_COUNTER_SIZE]; xhprof_callgraph_bucket* callgraph_buckets[TIDEWAYS_XHPROF_CALLGRAPH_SLOTS]; zend_long flags; + long int num_alloc; + long int num_free; + long int amount_alloc; ZEND_END_MODULE_GLOBALS(tideways_xhprof) #if defined(__GNUC__) && __GNUC__ >= 4 diff --git a/tracing.c b/tracing.c index 63cf1dd..bad8466 100644 --- a/tracing.c +++ b/tracing.c @@ -310,11 +310,8 @@ void tracing_request_shutdown() void *tideways_malloc (size_t size) { - xhprof_frame_t *current_frame = TXRG(callgraph_frames); - if (current_frame) { - current_frame->num_alloc += 1; - current_frame->amount_alloc += size; - } + TXRG(num_alloc) += 1; + TXRG(amount_alloc) += size; if (_zend_malloc) { return _zend_malloc(size); @@ -326,10 +323,7 @@ void *tideways_malloc (size_t size) void tideways_free (void *ptr) { - xhprof_frame_t *current_frame = TXRG(callgraph_frames); - if (current_frame) { - current_frame->num_free += 1; - } + TXRG(num_free) += 1; if (_zend_free) { return _zend_free(ptr); @@ -341,17 +335,14 @@ void tideways_free (void *ptr) void *tideways_realloc (void *ptr, size_t size) { - xhprof_frame_t *current_frame = TXRG(callgraph_frames); - if (current_frame) { - current_frame->num_alloc += 1; - current_frame->num_free += 1; - current_frame->amount_alloc += size; - } - + TXRG(num_alloc) += 1; + TXRG(num_free) += 1; + TXRG(amount_alloc) += size; + if (_zend_realloc) { return _zend_realloc(ptr, size); } zend_mm_heap *heap = zend_mm_get_heap(); return zend_mm_realloc(heap, ptr, size); -} \ No newline at end of file +} diff --git a/tracing.h b/tracing.h index 72bf70f..a678664 100644 --- a/tracing.h +++ b/tracing.h @@ -129,9 +129,9 @@ zend_always_inline static int tracing_enter_frame_callgraph(zend_string *root_sy current_frame->mu_start = zend_memory_usage(0 TSRMLS_CC); } - current_frame->num_alloc = 0; - current_frame->num_free = 0; - current_frame->amount_alloc = 0; + current_frame->num_alloc = TXRG(num_alloc); + current_frame->num_free = TXRG(num_free); + current_frame->amount_alloc = TXRG(amount_alloc); /* We only need to compute the hash for the function name, * that should be "good" enough, we sort into 1024 buckets only anyways */ @@ -202,9 +202,9 @@ zend_always_inline static void tracing_exit_frame_callgraph(TSRMLS_D) bucket->count++; bucket->wall_time += duration; - bucket->num_alloc += current_frame->num_alloc; - bucket->num_free += current_frame->num_free; - bucket->amount_alloc += current_frame->amount_alloc; + bucket->num_alloc += TXRG(num_alloc) - current_frame->num_alloc; + bucket->num_free += TXRG(num_free) - current_frame->num_free; + bucket->amount_alloc += TXRG(amount_alloc) - current_frame->amount_alloc; if (TXRG(flags) & TIDEWAYS_XHPROF_FLAGS_CPU) { bucket->cpu_time += (cpu_timer() - current_frame->cpu_start); From feec81dfda0b172f93602dd1b199b841eda67098 Mon Sep 17 00:00:00 2001 From: Lars Maier Date: Mon, 11 Jun 2018 15:24:46 +0200 Subject: [PATCH 11/64] Don't forget to initialise globals. --- tracing.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tracing.c b/tracing.c index bad8466..297af28 100644 --- a/tracing.c +++ b/tracing.c @@ -301,6 +301,10 @@ void tracing_request_init(TSRMLS_D) TXRG(enabled) = 0; TXRG(flags) = 0; TXRG(frame_free_list) = NULL; + + TXRG(num_alloc) = 0; + TXRG(num_free) = 0; + TXRG(amount_alloc) = 0; } void tracing_request_shutdown() From a617df1973c8434f51bb3bc8ee85210f0e2b0af3 Mon Sep 17 00:00:00 2001 From: Sergey Gripinskiy Date: Fri, 22 Jun 2018 13:05:12 +0300 Subject: [PATCH 12/64] More convenient usage example More robust usage example; Dump file name meets old xhprof_html viewer issue: it won't open if file has another name format; --- README.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 41a59f8..86d1512 100644 --- a/README.md +++ b/README.md @@ -64,9 +64,11 @@ tideways_xhprof_enable(); my_application(); -$data = tideways_xhprof_disable(); +file_put_contents( + sys_get_temp_dir() . DIRECTORY_SEPARATOR . uniqid() . '.myapplication.xhprof', + serialize(tideways_xhprof_disable()) +); -file_put_contents("/tmp/profile.xhprof", serialize($data)); ``` By default only wall clock time is measured, you can enable @@ -79,7 +81,10 @@ tideways_xhprof_enable(TIDEWAYS_XHPROF_FLAGS_MEMORY | TIDEWAYS_XHPROF_FLAGS_CPU) my_application(); -$data = tideways_xhprof_disable(); +file_put_contents( + sys_get_temp_dir() . DIRECTORY_SEPARATOR . uniqid() . '.myapplication.xhprof', + serialize(tideways_xhprof_disable()) +); ``` ## Data-Format From 494e35b717f256846968e493a01280d5dc4058e5 Mon Sep 17 00:00:00 2001 From: GITSRC <34047788+gitsrc@users.noreply.github.com> Date: Wed, 25 Jul 2018 15:38:41 +0800 Subject: [PATCH 13/64] fix --- tracing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tracing.c b/tracing.c index 297af28..e2bf092 100644 --- a/tracing.c +++ b/tracing.c @@ -309,7 +309,7 @@ void tracing_request_init(TSRMLS_D) void tracing_request_shutdown() { - tracing_free_the_free_list(); + tracing_free_the_free_list(TSRMLS_C); } void *tideways_malloc (size_t size) From a88c690380f668309fc3edca2935b498e3ff2e63 Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Fri, 24 Aug 2018 19:40:25 +0200 Subject: [PATCH 14/64] Update SDK. --- .appveyor.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index 15a85bf..cd62da9 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -9,9 +9,9 @@ environment: PHP_BUILD_CACHE_BASE_DIR: c:\build-cache PHP_BUILD_OBJ_DIR: c:\obj PHP_BUILD_CACHE_SDK_DIR: c:\build-cache\sdk - PHP_BUILD_SDK_BRANCH: php-sdk-2.0.13 + PHP_BUILD_SDK_BRANCH: php-sdk-2.1.1 SDK_REMOTE: https://github.com/OSTC/php-sdk-binary-tools.git - SDK_BRANCH: php-sdk-2.0.13 + SDK_BRANCH: php-sdk-2.1.1 matrix: - PHP_REL: 7.2 From 536921564178409d6726de49c37091b28c134cea Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Fri, 24 Aug 2018 19:48:14 +0200 Subject: [PATCH 15/64] Update SDK. --- .appveyor.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index cd62da9..d42692a 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -2,8 +2,7 @@ image: Visual Studio 2015 version: '{branch}.{build}' cache: - - c:\build-cache -> .appveyor.yml - - c:\build-cache\sdk -> .appveyor.yml + - c:\build-cache -> .appveyor.yml, .appveyor/*.cmd environment: PHP_BUILD_CACHE_BASE_DIR: c:\build-cache From 0be3228afbea40d6175de4622b2bfd5c2d6db637 Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Fri, 24 Aug 2018 19:49:27 +0200 Subject: [PATCH 16/64] Update appveyor build --- .appveyor/install.cmd | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.appveyor/install.cmd b/.appveyor/install.cmd index cbc4a64..5cf50e3 100644 --- a/.appveyor/install.cmd +++ b/.appveyor/install.cmd @@ -31,10 +31,10 @@ setlocal enableextensions enabledelayedexpansion git clone -q --depth=1 --branch=PHP-%PHP_REL% https://github.com/php/php-src C:\projects\php-src ) - xcopy %APPVEYOR_BUILD_FOLDER% C:\projects\php-src\ext\tideways_xhprof\ /s /e /y /f + xcopy %APPVEYOR_BUILD_FOLDER% C:\projects\php-src\ext\tideways_xhprof\ /s /e /y /q - xcopy %APPVEYOR_BUILD_FOLDER%\LICENSE %APPVEYOR_BUILD_FOLDER%\artifacts\ /y /f - xcopy %APPVEYOR_BUILD_FOLDER%\NOTICE %APPVEYOR_BUILD_FOLDER%\artifacts\ /y /f + xcopy %APPVEYOR_BUILD_FOLDER%\LICENSE %APPVEYOR_BUILD_FOLDER%\artifacts\ /y /q + xcopy %APPVEYOR_BUILD_FOLDER%\NOTICE %APPVEYOR_BUILD_FOLDER%\artifacts\ /y /q if "%APPVEYOR%" equ "True" rmdir /s /q C:\cygwin >NUL 2>NUL if %errorlevel% neq 0 exit /b 3 From 47de3ec79dc3f9ae709162bacb328e2e7405c227 Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Fri, 24 Aug 2018 21:23:33 +0200 Subject: [PATCH 17/64] Bugfix in appveyor Version detection. --- .appveyor/install.cmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.appveyor/install.cmd b/.appveyor/install.cmd index 5cf50e3..c7eab7b 100644 --- a/.appveyor/install.cmd +++ b/.appveyor/install.cmd @@ -51,7 +51,7 @@ setlocal enableextensions enabledelayedexpansion if not "%%l"=="" ( set line=%%l if "!line:~8,27!"=="PHP_TIDEWAYS_XHPROF_VERSION" ( - set APPVEYOR_REPO_TAG_NAME=!line:~30,-1!-%APPVEYOR_REPO_BRANCH%-%APPVEYOR_REPO_COMMIT:~0,8% + set APPVEYOR_REPO_TAG_NAME=!line:~39,-1!-%APPVEYOR_REPO_BRANCH%-%APPVEYOR_REPO_COMMIT:~0,8% ) ) ) From a64f03363d279437787b057bddfbd0f2fef209ed Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Fri, 24 Aug 2018 21:25:55 +0200 Subject: [PATCH 18/64] Bugfix in appveyor Version detection. --- .appveyor/install.cmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.appveyor/install.cmd b/.appveyor/install.cmd index c7eab7b..dc77448 100644 --- a/.appveyor/install.cmd +++ b/.appveyor/install.cmd @@ -51,7 +51,7 @@ setlocal enableextensions enabledelayedexpansion if not "%%l"=="" ( set line=%%l if "!line:~8,27!"=="PHP_TIDEWAYS_XHPROF_VERSION" ( - set APPVEYOR_REPO_TAG_NAME=!line:~39,-1!-%APPVEYOR_REPO_BRANCH%-%APPVEYOR_REPO_COMMIT:~0,8% + set APPVEYOR_REPO_TAG_NAME=!line:~38,-1!-%APPVEYOR_REPO_BRANCH%-%APPVEYOR_REPO_COMMIT:~0,8% ) ) ) From afc61bd1e3336ef207247c5e92ae6b5dab0a6e1c Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Fri, 24 Aug 2018 21:31:43 +0200 Subject: [PATCH 19/64] Update appveyor build --- .appveyor/install.cmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.appveyor/install.cmd b/.appveyor/install.cmd index dc77448..40649fd 100644 --- a/.appveyor/install.cmd +++ b/.appveyor/install.cmd @@ -51,7 +51,7 @@ setlocal enableextensions enabledelayedexpansion if not "%%l"=="" ( set line=%%l if "!line:~8,27!"=="PHP_TIDEWAYS_XHPROF_VERSION" ( - set APPVEYOR_REPO_TAG_NAME=!line:~38,-1!-%APPVEYOR_REPO_BRANCH%-%APPVEYOR_REPO_COMMIT:~0,8% + set APPVEYOR_REPO_TAG_NAME=!line:~37,-1!-%APPVEYOR_REPO_BRANCH%-%APPVEYOR_REPO_COMMIT:~0,8% ) ) ) From 6670474519ddd1852276bd8231d1387f8bab0474 Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Thu, 7 Feb 2019 17:46:10 +0100 Subject: [PATCH 20/64] Add #include "stdint.h" to please Alpine/Musl? --- timer.h | 1 + 1 file changed, 1 insertion(+) diff --git a/timer.h b/timer.h index ecd940f..8db0440 100644 --- a/timer.h +++ b/timer.h @@ -11,6 +11,7 @@ #include "win32/getrusage.h" #else +#include "stdint.h" #include #include #endif From 4f4ebbbaf2347436c18725e11bf3d03d6781ba05 Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Fri, 8 Feb 2019 19:46:05 +0100 Subject: [PATCH 21/64] Move type definition around. --- timer.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/timer.h b/timer.h index 8db0440..fd535e7 100644 --- a/timer.h +++ b/timer.h @@ -11,7 +11,6 @@ #include "win32/getrusage.h" #else -#include "stdint.h" #include #include #endif @@ -54,6 +53,9 @@ static zend_always_inline uint64 time_milliseconds(int source, double timebase_f struct timespec s; uint32 a, d; uint64 val; +#if defined(__i386__) + int64_t ret; +#endif switch (source) { #if HAVE_CLOCK_GETTIME @@ -77,7 +79,6 @@ static zend_always_inline uint64 time_milliseconds(int source, double timebase_f #endif case TIDEWAYS_XHPROF_CLOCK_TSC: #if defined(__i386__) - int64_t ret; __asm__ volatile("rdtsc" : "=A"(ret)); return ret; #elif defined(__x86_64__) || defined(__amd64__) From 520315b6b12f9cd0e1f0d5532a60d80039a25e2d Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Sun, 17 Feb 2019 22:25:26 +0100 Subject: [PATCH 22/64] Add ARM and s309 architectures to clock timing. --- timer.h | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/timer.h b/timer.h index fd535e7..9c1f2ff 100644 --- a/timer.h +++ b/timer.h @@ -38,8 +38,14 @@ static zend_always_inline uint64 current_timestamp() { * @author cjiang */ static zend_always_inline uint64 time_milliseconds(int source, double timebase_factor) { -#ifdef __APPLE__ +#if defined(_APPLE__) return mach_absolute_time() / timebase_factor; +#elif defined(__s390__) // Covers both s390 and s390x. + uint64_t tsc; + // Return the CPU clock. + asm("stck %0" : "=Q" (tsc) : : "cc"); + + return tsc; #elif defined(PHP_WIN32) LARGE_INTEGER count; @@ -49,12 +55,14 @@ static zend_always_inline uint64 time_milliseconds(int source, double timebase_f } return (double)(count.QuadPart) / timebase_factor; -#else +#elif defined(__x86_64__) || defined(__amd64__) struct timespec s; uint32 a, d; uint64 val; -#if defined(__i386__) +#elif defined(__i386__) int64_t ret; +#elif defined(__ARM_ARCH) + struct timeval tv; #endif switch (source) { @@ -84,17 +92,19 @@ static zend_always_inline uint64 time_milliseconds(int source, double timebase_f #elif defined(__x86_64__) || defined(__amd64__) asm volatile("rdtsc" : "=a" (a), "=d" (d)); (val) = ((uint64)a) | (((uint64)d)<<32); + return val / timebase_factor; #elif defined(__powerpc__) || defined(__ppc__) asm volatile ("mftb %0" : "=r" (val)); + return val / timebase_factor; +#elif defined(__ARM_ARCH) + gettimeofday(&tv, NULL); + return (tv.tv_sec) * 1000000 + tv.tv_usec; #else -#error You need to define CycleTimer for your OS and CPU + return 0; #endif - return val / timebase_factor; - default: return 0; } -#endif } /** From 71be12cc56f64faefbbd4dbaa67d69955393adbd Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Sun, 7 Apr 2019 11:11:23 +0200 Subject: [PATCH 23/64] Add PHP 7.3 to builds. --- .appveyor.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/.appveyor.yml b/.appveyor.yml index d42692a..d112a84 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -13,6 +13,11 @@ environment: SDK_BRANCH: php-sdk-2.1.1 matrix: + - PHP_REL: 7.3 + ARCHITECTURE: x64 + ZTS_STATE: enable + APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 + PHP_BUILD_CRT: vc15 - PHP_REL: 7.2 ARCHITECTURE: x64 ZTS_STATE: enable @@ -28,6 +33,11 @@ environment: ZTS_STATE: enable APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 PHP_BUILD_CRT: vc14 + - PHP_REL: 7.3 + ARCHITECTURE: x64 + ZTS_STATE: disable + APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 + PHP_BUILD_CRT: vc15 - PHP_REL: 7.2 ARCHITECTURE: x64 ZTS_STATE: disable @@ -43,6 +53,11 @@ environment: ZTS_STATE: disable APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 PHP_BUILD_CRT: vc14 + - PHP_REL: 7.3 + ARCHITECTURE: x86 + ZTS_STATE: enable + APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 + PHP_BUILD_CRT: vc15 - PHP_REL: 7.2 ARCHITECTURE: x86 ZTS_STATE: enable @@ -58,6 +73,11 @@ environment: ZTS_STATE: enable APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 PHP_BUILD_CRT: vc14 + - PHP_REL: 7.3 + ARCHITECTURE: x86 + ZTS_STATE: disable + APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 + PHP_BUILD_CRT: vc15 - PHP_REL: 7.2 ARCHITECTURE: x86 ZTS_STATE: disable From 39806cc88fc8445a85557773ed1531a2d418f2ec Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Sun, 7 Apr 2019 12:02:01 +0200 Subject: [PATCH 24/64] Remove PHP 7.0 from appveyor builds because current PHP-SDK doesnt support it anymore. --- .appveyor.yml | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index d112a84..674ebe8 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -28,11 +28,6 @@ environment: ZTS_STATE: enable APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 PHP_BUILD_CRT: vc14 - - PHP_REL: 7.0 - ARCHITECTURE: x64 - ZTS_STATE: enable - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 - PHP_BUILD_CRT: vc14 - PHP_REL: 7.3 ARCHITECTURE: x64 ZTS_STATE: disable @@ -48,11 +43,6 @@ environment: ZTS_STATE: disable APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 PHP_BUILD_CRT: vc14 - - PHP_REL: 7.0 - ARCHITECTURE: x64 - ZTS_STATE: disable - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 - PHP_BUILD_CRT: vc14 - PHP_REL: 7.3 ARCHITECTURE: x86 ZTS_STATE: enable @@ -68,11 +58,6 @@ environment: ZTS_STATE: enable APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 PHP_BUILD_CRT: vc14 - - PHP_REL: 7.0 - ARCHITECTURE: x86 - ZTS_STATE: enable - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 - PHP_BUILD_CRT: vc14 - PHP_REL: 7.3 ARCHITECTURE: x86 ZTS_STATE: disable @@ -88,11 +73,6 @@ environment: ZTS_STATE: disable APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 PHP_BUILD_CRT: vc14 - - PHP_REL: 7.0 - ARCHITECTURE: x86 - ZTS_STATE: disable - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 - PHP_BUILD_CRT: vc14 install: - .appveyor\install.cmd From fc798352fdea2e221a365beddc835dda3e95cc5a Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Sat, 17 Aug 2019 14:40:07 +0200 Subject: [PATCH 25/64] Rework and cleanup timer.h completly. --- tideways_xhprof.c | 4 +- timer.h | 232 ++++++++++++++++++++++++++++------------------ tracing.c | 20 ---- 3 files changed, 143 insertions(+), 113 deletions(-) diff --git a/tideways_xhprof.c b/tideways_xhprof.c index b50d065..ed1b44f 100644 --- a/tideways_xhprof.c +++ b/tideways_xhprof.c @@ -18,7 +18,7 @@ ZEND_DLEXPORT void tideways_xhprof_execute_internal(zend_execute_data *execute_d ZEND_DLEXPORT void tideways_xhprof_execute_ex (zend_execute_data *execute_data); PHP_INI_BEGIN() - STD_PHP_INI_ENTRY("tideways_xhprof.clock_use_rdtsc", "0", PHP_INI_ALL, OnUpdateBool, clock_use_rdtsc, zend_tideways_xhprof_globals, tideways_xhprof_globals) + STD_PHP_INI_ENTRY("tideways_xhprof.clock_use_rdtsc", "0", PHP_INI_SYSTEM, OnUpdateBool, clock_use_rdtsc, zend_tideways_xhprof_globals, tideways_xhprof_globals) PHP_INI_END() PHP_FUNCTION(tideways_xhprof_enable) @@ -81,7 +81,7 @@ PHP_MSHUTDOWN_FUNCTION(tideways_xhprof) PHP_RINIT_FUNCTION(tideways_xhprof) { tracing_request_init(TSRMLS_C); - tracing_determine_clock_source(TSRMLS_C); + TXRG(clock_source) = determine_clock_source(TXRG(clock_use_rdtsc)); return SUCCESS; } diff --git a/timer.h b/timer.h index 9c1f2ff..6c8ba50 100644 --- a/timer.h +++ b/timer.h @@ -9,43 +9,128 @@ #include "win32/time.h" #include "win32/unistd.h" #include "win32/getrusage.h" +#elif __APPLE__ +#include +#include #else - -#include +#include "sys/time.h" #include #endif -#if __APPLE__ -#include -#include +static int determine_clock_source(int clock_use_rdtsc) { +#if defined(__APPLE__) + return TIDEWAYS_XHPROF_CLOCK_MACH; +#elif defined(__powerpc__) || defined(__ppc__) + return TIDEWAYS_XHPROF_CLOCK_TSC; +#elif defined(__s390__) // Covers both s390 and s390x. + return TIDEWAYS_XHPROF_CLOCK_TSC; +#elif defined(PHP_WIN32) + return TIDEWAYS_XHPROF_CLOCK_QPC; +#else + struct timespec res; + + if (clock_use_rdtsc == 1) { + return TIDEWAYS_XHPROF_CLOCK_TSC; + } + +#if HAVE_CLOCK_GETTIME + if (clock_gettime(CLOCK_MONOTONIC, &res) == 0) { + return TIDEWAYS_XHPROF_CLOCK_CGT; + } +#endif + +#if HAVE_GETTIMEOFDAY + return TIDEWAYS_XHPROF_CLOCK_GTOD; +#endif + + return TIDEWAYS_XHPROF_CLOCK_TSC; #endif +} static zend_always_inline uint64 current_timestamp() { struct timeval tv; if (gettimeofday(&tv, NULL)) { php_error(E_ERROR, "tracer: Cannot acquire gettimeofday"); - return 0; + zend_bailout(); } return 1000 * (uint64) tv.tv_sec + (uint64) tv.tv_usec / 1000; } +static zend_always_inline uint64 time_milliseconds_cgt() +{ +#if HAVE_CLOCK_GETTIME + struct timespec s; + + if (clock_gettime(CLOCK_MONOTONIC, &s) == 0) { + return s.tv_sec * 1000000 + s.tv_nsec / 1000; + } else { + struct timeval now; + if (gettimeofday(&now, NULL) == 0) { + return now.tv_sec * 1000000 + now.tv_usec; + } + } +#endif + + return 0; +} + +static zend_always_inline uint64 time_milliseconds_gtod() +{ +#if HAVE_GETTIMEOFDAY + struct timeval now; + if (gettimeofday(&now, NULL) == 0) { + return now.tv_sec * 1000000 + now.tv_usec; + } +#endif + + return 0; +} + +static zend_always_inline uint64 time_milliseconds_tsc_query() +{ +#if defined(__s390__) // Covers both s390 and s390x. + + uint64_t tsc; + // Return the CPU clock. + asm("stck %0" : "=Q" (tsc) : : "cc"); + + return tsc; +#elif defined(__i386__) + int64_t ret; + __asm__ volatile("rdtsc" : "=A"(ret)); + return ret; +#elif defined(__x86_64__) || defined(__amd64__) + uint64 val; + uint32 a, d; + asm volatile("rdtsc" : "=a" (a), "=d" (d)); + (val) = ((uint64)a) | (((uint64)d)<<32); + return val; +#elif defined(__powerpc__) || defined(__ppc__) + uint64 val; + asm volatile ("mftb %0" : "=r" (val)); + return val; +#elif defined(__ARM_ARCH) + struct timeval tv; + gettimeofday(&tv, NULL); + return (tv.tv_sec) * 1000000 + tv.tv_usec; +#else + return 0; +#endif +} + /** * Get the current wallclock timer * * @return 64 bit unsigned integer * @author cjiang */ -static zend_always_inline uint64 time_milliseconds(int source, double timebase_factor) { +static zend_always_inline uint64 time_milliseconds(int source, double timebase_factor) +{ #if defined(_APPLE__) - return mach_absolute_time() / timebase_factor; -#elif defined(__s390__) // Covers both s390 and s390x. - uint64_t tsc; - // Return the CPU clock. - asm("stck %0" : "=Q" (tsc) : : "cc"); - return tsc; + return mach_absolute_time() / timebase_factor; #elif defined(PHP_WIN32) LARGE_INTEGER count; @@ -55,56 +140,19 @@ static zend_always_inline uint64 time_milliseconds(int source, double timebase_f } return (double)(count.QuadPart) / timebase_factor; -#elif defined(__x86_64__) || defined(__amd64__) - struct timespec s; - uint32 a, d; - uint64 val; -#elif defined(__i386__) - int64_t ret; -#elif defined(__ARM_ARCH) - struct timeval tv; -#endif - - switch (source) { -#if HAVE_CLOCK_GETTIME - case TIDEWAYS_XHPROF_CLOCK_CGT: - if (clock_gettime(CLOCK_MONOTONIC, &s) == 0) { - return s.tv_sec * 1000000 + s.tv_nsec / 1000; - } else { - struct timeval now; - if (gettimeofday(&now, NULL) == 0) { - return now.tv_sec * 1000000 + now.tv_usec; - } - } - return 0; -#elif HAVE_GETTIMEOFDAY - case TIDEWAYS_XHPROF_CLOCK_GTOD: - struct timeval now; - if (gettimeofday(&now, NULL) == 0) { - return now.tv_sec * 1000000 + now.tv_usec; - } - return 0; -#endif - case TIDEWAYS_XHPROF_CLOCK_TSC: -#if defined(__i386__) - __asm__ volatile("rdtsc" : "=A"(ret)); - return ret; -#elif defined(__x86_64__) || defined(__amd64__) - asm volatile("rdtsc" : "=a" (a), "=d" (d)); - (val) = ((uint64)a) | (((uint64)d)<<32); - return val / timebase_factor; -#elif defined(__powerpc__) || defined(__ppc__) - asm volatile ("mftb %0" : "=r" (val)); - return val / timebase_factor; -#elif defined(__ARM_ARCH) - gettimeofday(&tv, NULL); - return (tv.tv_sec) * 1000000 + tv.tv_usec; #else - return 0; -#endif - default: - return 0; + + if (source == TIDEWAYS_XHPROF_CLOCK_TSC) { + return time_milliseconds_tsc_query() / timebase_factor; + } else if (source == TIDEWAYS_XHPROF_CLOCK_GTOD) { + return time_milliseconds_gtod(); + } else if (source == TIDEWAYS_XHPROF_CLOCK_CGT) { + return time_milliseconds_cgt(); } + +#endif + + return 0; } /** @@ -116,12 +164,39 @@ static long get_us_interval(struct timeval *start, struct timeval *end) + (end->tv_usec - start->tv_usec)); } +static zend_always_inline double get_timebase_factor_tsc() +{ + struct timeval start; + struct timeval end; + uint64 tsc_start; + uint64 tsc_end; + volatile int i; + + if (gettimeofday(&start, 0)) { + perror("gettimeofday"); + return 0.0; + } + + tsc_start = time_milliseconds_tsc_query(); + /* Busy loop for 5 miliseconds. */ + do { + for (i = 0; i < 1000000; i++); + if (gettimeofday(&end, 0)) { + perror("gettimeofday"); + return 0.0; + } + tsc_end = time_milliseconds_tsc_query(); + } while (get_us_interval(&start, &end) < 5000); + + return (tsc_end - tsc_start) * 1.0 / (get_us_interval(&start, &end)); +} + /** * Get the timebase factor necessary to divide by in time_milliseconds() */ static zend_always_inline double get_timebase_factor(int source) { -#ifdef __APPLE__ +#if defined(__APPLE__) mach_timebase_info_data_t sTimebaseInfo; (void) mach_timebase_info(&sTimebaseInfo); @@ -135,35 +210,11 @@ static zend_always_inline double get_timebase_factor(int source) return (double)frequency/1000000.0; #else - struct timeval start; - struct timeval end; - uint64 tsc_start; - uint64 tsc_end; - volatile int i; - - switch (source) { - case TIDEWAYS_XHPROF_CLOCK_TSC: - - if (gettimeofday(&start, 0)) { - perror("gettimeofday"); - return 0.0; - } - - tsc_start = time_milliseconds(source, 1.0); - /* Busy loop for 5 miliseconds. */ - do { - for (i = 0; i < 1000000; i++); - if (gettimeofday(&end, 0)) { - perror("gettimeofday"); - return 0.0; - } - tsc_end = time_milliseconds(source, 1.0); - } while (get_us_interval(&start, &end) < 5000); - - return (tsc_end - tsc_start) * 1.0 / (get_us_interval(&start, &end)); - default: - return 1.0; + if (source == TIDEWAYS_XHPROF_CLOCK_TSC) { + return get_timebase_factor_tsc(); } + + return 1.0; #endif } @@ -189,4 +240,3 @@ static uint64 cpu_timer() { } #endif - diff --git a/tracing.c b/tracing.c index e2bf092..c43dac3 100644 --- a/tracing.c +++ b/tracing.c @@ -20,26 +20,6 @@ void *tideways_malloc (size_t size); void tideways_free (void *ptr); void *tideways_realloc (void *ptr, size_t size); -void tracing_determine_clock_source(TSRMLS_D) { -#ifdef __APPLE__ - TXRG(clock_source) = TIDEWAYS_XHPROF_CLOCK_MACH; -#elif defined(__powerpc__) || defined(__ppc__) - TXRG(clock_source) = TIDEWAYS_XHPROF_CLOCK_TSC; -#elif defined(PHP_WIN32) - TXRG(clock_source) = TIDEWAYS_XHPROF_CLOCK_QPC; -#else - struct timespec res; - - if (TXRG(clock_use_rdtsc) == 1) { - TXRG(clock_source) = TIDEWAYS_XHPROF_CLOCK_TSC; - } else if (clock_gettime(CLOCK_MONOTONIC, &res) == 0) { - TXRG(clock_source) = TIDEWAYS_XHPROF_CLOCK_CGT; - } else { - TXRG(clock_source) = TIDEWAYS_XHPROF_CLOCK_GTOD; - } -#endif -} - /** * Free any items in the free list. */ From 6498313bd2b39f6fbc7765b3939f9873f22613be Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Sat, 17 Aug 2019 14:54:23 +0200 Subject: [PATCH 26/64] Refactor ARM gtod support to be selected at determine clock source time. --- timer.h | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/timer.h b/timer.h index 6c8ba50..185a1e8 100644 --- a/timer.h +++ b/timer.h @@ -24,6 +24,8 @@ static int determine_clock_source(int clock_use_rdtsc) { return TIDEWAYS_XHPROF_CLOCK_TSC; #elif defined(__s390__) // Covers both s390 and s390x. return TIDEWAYS_XHPROF_CLOCK_TSC; +#elif defined(__ARM_ARCH) + return TIDEWAYS_XHPROF_CLOCK_GTOD; #elif defined(PHP_WIN32) return TIDEWAYS_XHPROF_CLOCK_QPC; #else @@ -65,11 +67,6 @@ static zend_always_inline uint64 time_milliseconds_cgt() if (clock_gettime(CLOCK_MONOTONIC, &s) == 0) { return s.tv_sec * 1000000 + s.tv_nsec / 1000; - } else { - struct timeval now; - if (gettimeofday(&now, NULL) == 0) { - return now.tv_sec * 1000000 + now.tv_usec; - } } #endif @@ -111,10 +108,6 @@ static zend_always_inline uint64 time_milliseconds_tsc_query() uint64 val; asm volatile ("mftb %0" : "=r" (val)); return val; -#elif defined(__ARM_ARCH) - struct timeval tv; - gettimeofday(&tv, NULL); - return (tv.tv_sec) * 1000000 + tv.tv_usec; #else return 0; #endif From d0abfa0847d59027be261df1e4a47de2ed1cc41b Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Sat, 17 Aug 2019 15:20:21 +0200 Subject: [PATCH 27/64] Add buildkite pipline. --- .buildkite/build_extension.sh | 12 +++++ .buildkite/pipeline.yml | 94 +++++++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+) create mode 100755 .buildkite/build_extension.sh create mode 100644 .buildkite/pipeline.yml diff --git a/.buildkite/build_extension.sh b/.buildkite/build_extension.sh new file mode 100755 index 0000000..8825641 --- /dev/null +++ b/.buildkite/build_extension.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +set -e + +PHP_VERSION=$1 + +make distclean || true +/opt/php/php-${PHP_VERSION}/bin/phpize +CFLAGS="-O2" ./configure --with-php-config=/opt/php/php-${PHP_VERSION}/bin/php-config +make -j2 + +REPORT_EXIT_STATUS=1 /opt/php/php-${PHP_VERSION}/bin/php run-tests.php -p /opt/php/php-${PHP_VERSION}/bin/php --show-diff -d extension=`pwd`/.libs/tideways_xhprof.so -q diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml new file mode 100644 index 0000000..fedaef4 --- /dev/null +++ b/.buildkite/pipeline.yml @@ -0,0 +1,94 @@ +env: + NO_INTERACTION: 1 + +steps: + - label: ":php: 7.3 amd64" + command: ./.buildkite/build_extension.sh 7.3 + agents: + phpbuild: "no-debug" + queue: "build" + + - label: ":php: 7.2 amd64" + command: ./.buildkite/build_extension.sh 7.2 + agents: + phpbuild: "no-debug" + queue: "build" + + - label: ":php: 7.1 amd64" + command: ./.buildkite/build_extension.sh 7.1 + agents: + phpbuild: "no-debug" + queue: "build" + + - label: ":php: 7.0 amd64" + command: ./.buildkite/build_extension.sh 7.0 + agents: + phpbuild: "no-debug" + queue: "build" + + - label: ":php: 7.3-zts amd64" + command: ./.buildkite/build_extension.sh 7.3-zts + agents: + phpbuild: "no-debug" + queue: "build" + + - label: ":php: 7.2-zts amd64" + command: ./.buildkite/build_extension.sh 7.2-zts + agents: + phpbuild: "no-debug" + queue: "build" + + - label: ":php: 7.1-zts amd64" + command: ./.buildkite/build_extension.sh 7.1-zts + agents: + phpbuild: "no-debug" + queue: "build" + + - label: ":php: 7.3 i386" + command: ./.buildkite/build_extension.sh 7.3 + agents: + phpbuild: "no-debug" + queue: "build" + arch: "i386" + + - label: ":php: 7.2 i386" + command: ./.buildkite/build_extension.sh 7.2 + agents: + phpbuild: "no-debug" + queue: "build" + arch: "i386" + + - label: ":php: 7.1 i386" + command: ./.buildkite/build_extension.sh 7.1 + agents: + phpbuild: "no-debug" + queue: "build" + arch: "i386" + + - label: ":php: 7.0 i386" + command: ./.buildkite/build_extension.sh 7.0 + agents: + phpbuild: "no-debug" + queue: "build" + arch: "i386" + + - label: ":php: 7.3-zts i386" + command: ./.buildkite/build_extension.sh 7.3-zts + agents: + phpbuild: "no-debug" + queue: "build" + arch: "i386" + + - label: ":php: 7.2-zts i386" + command: ./.buildkite/build_extension.sh 7.2-zts + agents: + phpbuild: "no-debug" + queue: "build" + arch: "i386" + + - label: ":php: 7.1-zts i386" + command: ./.buildkite/build_extension.sh 7.1-zts + agents: + phpbuild: "no-debug" + queue: "build" + arch: "i386" From 710f532cb3a3c2b6d7808f35bab4182a19f723bd Mon Sep 17 00:00:00 2001 From: Patrick O'Lone Date: Tue, 21 Aug 2018 14:50:42 -0500 Subject: [PATCH 28/64] Fixed issues with custom frames and recursion --- tracing.c | 4 ++-- tracing.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tracing.c b/tracing.c index e2bf092..055c6f7 100644 --- a/tracing.c +++ b/tracing.c @@ -123,7 +123,7 @@ xhprof_callgraph_bucket *tracing_callgraph_bucket_find(xhprof_callgraph_bucket * if (bucket->key == key && bucket->child_recurse_level == current_frame->recurse_level && bucket->child_class == current_frame->class_name && - bucket->child_function == current_frame->function_name) { + zend_string_equals(bucket->child_function, current_frame->function_name)) { if (previous == NULL && bucket->parent_class == NULL && bucket->parent_function == NULL ) { // special handling for the root @@ -131,7 +131,7 @@ xhprof_callgraph_bucket *tracing_callgraph_bucket_find(xhprof_callgraph_bucket * } else if (previous && previous->recurse_level == bucket->parent_recurse_level && previous->class_name == bucket->parent_class && - previous->function_name == bucket->parent_function) { + zend_string_equals(previous->function_name, bucket->parent_function)) { // parent matches as well return bucket; } diff --git a/tracing.h b/tracing.h index a678664..d466bce 100644 --- a/tracing.h +++ b/tracing.h @@ -143,7 +143,7 @@ zend_always_inline static int tracing_enter_frame_callgraph(zend_string *root_sy if (TXRG(function_hash_counters)[current_frame->hash_code] > 0) { /* Find this symbols recurse level */ for(p = current_frame->previous_frame; p; p = p->previous_frame) { - if (current_frame->function_name == p->function_name && (!current_frame->class_name || current_frame->class_name == p->class_name)) { + if (zend_string_equals(current_frame->function_name, p->function_name) && (!current_frame->class_name || current_frame->class_name == p->class_name)) { recurse_level = (p->recurse_level) + 1; break; } From ac0062b7dec1bc4bb1913dd28ac1cff5d5b0576a Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Sat, 17 Aug 2019 22:16:12 +0200 Subject: [PATCH 29/64] Set ZEND_COMPILE_NO_BUILTINS compiler_options. --- tests/xhprof_007.phpt | 9 ++++++--- tideways_xhprof.c | 2 ++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/tests/xhprof_007.phpt b/tests/xhprof_007.phpt index 373299c..35bdcff 100644 --- a/tests/xhprof_007.phpt +++ b/tests/xhprof_007.phpt @@ -26,8 +26,11 @@ $output = tideways_xhprof_disable(); print_canonical($output); --EXPECTF-- +call_user_func==>foo : ct= 1; wt=*; +call_user_func_array==>class@anonymous::__invoke: ct= 1; wt=*; +call_user_func_array==>foo : ct= 1; wt=*; +call_user_func_array==>{closure} : ct= 1; wt=*; main() : ct= 1; wt=*; -main()==>class@anonymous::__invoke : ct= 1; wt=*; -main()==>foo : ct= 2; wt=*; +main()==>call_user_func : ct= 1; wt=*; +main()==>call_user_func_array : ct= 3; wt=*; main()==>tideways_xhprof_disable : ct= 1; wt=*; -main()==>{closure} : ct= 1; wt=*; diff --git a/tideways_xhprof.c b/tideways_xhprof.c index b50d065..22f726c 100644 --- a/tideways_xhprof.c +++ b/tideways_xhprof.c @@ -83,6 +83,8 @@ PHP_RINIT_FUNCTION(tideways_xhprof) tracing_request_init(TSRMLS_C); tracing_determine_clock_source(TSRMLS_C); + CG(compiler_options) = CG(compiler_options) | ZEND_COMPILE_NO_BUILTINS; + return SUCCESS; } From 8ee920e77595bc6fa378f56bfc2a548afe8e904f Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Sun, 18 Aug 2019 20:28:14 +0200 Subject: [PATCH 30/64] Make clock test more generic --- tests/xhprof_006.phpt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/xhprof_006.phpt b/tests/xhprof_006.phpt index 46885b9..48b91ea 100644 --- a/tests/xhprof_006.phpt +++ b/tests/xhprof_006.phpt @@ -36,7 +36,7 @@ $output = tideways_xhprof_disable(); print_canonical($output); --EXPECTF-- string(1) "1" -Clock Source => tsc +Clock Source => %s main() : ct= 1; wt=*; main()==>foo : ct= 1; wt=*; main()==>tideways_xhprof_disable : ct= 1; wt=*; From 32bee646278e9b1e621d376389b69ba588ac2440 Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Mon, 19 Aug 2019 10:12:47 +0200 Subject: [PATCH 31/64] Update README --- README.md | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 86d1512..37cd4fd 100644 --- a/README.md +++ b/README.md @@ -2,23 +2,19 @@ Home of the `tideways_xhprof` extension - a hierarchical Profiler for PHP. -**Looking for `tideways` Extension to report to tideways.io?** [Go here](https://tideways.io/profiler/downloads). -**Why did we rename the extension?** [Blog post here](https://tideways.io/profiler/blog/releasing-new-tideways-xhprof-extension). +**This extensions is not compatible with our Tideways service. Are you looking +for `tideways` Extension to use with tideways.com?** [Download here](https://tideways.io/profiler/downloads). This PHP extension is a complete, modernized open-source rewrite of the original XHProf extension, with a new core datastructure and specifically optimized for PHP 7. The result is an XHProf data-format compatible extension with a much reduced overhead in the critical path that you are profiling. -The code for this extension is extracted from the [main Tideways -extension](https://tideways.io) as we are moving to a new extension with -incompatible data-format. - We are committed to provide support for this extension and port it to as many platforms as possible. **Note:** The public API is not compatible to previous xhprof extensions and -forks, as function names are different. Only the data format is compatible. +forks, but function names are different. Only the data format is compatible. ## About tideways and tideways_xhprof Extensions @@ -36,6 +32,7 @@ page](https://tideways.io/profiler/downloads). - PHP >= 7.0 - OS: Linux, MacOS, Windows ([Download DLLs](https://ci.appveyor.com/project/tideways/php-profiler-extension)) +- Architectures: x64/amd64, x86, ARM, PowerPC ## Installation From ce1d455ca70bc6b26a18bf901963ea88e73f934b Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Wed, 11 Sep 2019 11:25:16 +0200 Subject: [PATCH 32/64] Add packaging step to Buildkite --- .buildkite/build_extension.sh | 3 ++ .buildkite/package_extension.sh | 64 +++++++++++++++++++++++++++++++++ .buildkite/pipeline.yml | 9 +++++ NOTICE | 2 +- 4 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 .buildkite/package_extension.sh diff --git a/.buildkite/build_extension.sh b/.buildkite/build_extension.sh index 8825641..f7b931e 100755 --- a/.buildkite/build_extension.sh +++ b/.buildkite/build_extension.sh @@ -9,4 +9,7 @@ make distclean || true CFLAGS="-O2" ./configure --with-php-config=/opt/php/php-${PHP_VERSION}/bin/php-config make -j2 +cp modules/tideways.so modules/tideways-xhprof-${PHP_VERSION}.so +buildkite-agent artifact upload modules/tideways-xhprof-${PHP_VERSION}.so + REPORT_EXIT_STATUS=1 /opt/php/php-${PHP_VERSION}/bin/php run-tests.php -p /opt/php/php-${PHP_VERSION}/bin/php --show-diff -d extension=`pwd`/.libs/tideways_xhprof.so -q diff --git a/.buildkite/package_extension.sh b/.buildkite/package_extension.sh new file mode 100644 index 0000000..c7e44f2 --- /dev/null +++ b/.buildkite/package_extension.sh @@ -0,0 +1,64 @@ +#!/bin/bash + +set -e + +BASEDIR=`dirname $0` +PACKAGENAME="tideways-xhprof" +DESCRIPTION="tideways-xhprof is a modern XHProf fork built for PHP 7." +EXTENSION="tideways_xhprof" +VERSIONS=( "7.0" "7.1" "7.2" "7.3" "7.0-zts" "7.1-zts" "7.2-zts" "7.3-zts" ) +PACKAGES=( "deb" "rpm" ) +ARCHITECTURE=`uname -m` +ARCHITECTURE=${ARCHITECTURE/686/386} + +mkdir packaging/dist -p +mkdir packaging/root/usr/lib/${EXTENSION} -p +mkdir packaging/root/usr/share/doc/${PACKAGENAME} -p + +for VERSION in "${VERSIONS[@]}" +do + if [ -f "/opt/php/php-${VERSION}/bin/php" ]; then + EXTVERSION=`/opt/php/php-${VERSION}/bin/php -dextension=modules/${EXTENSION}-${VERSION}.so -r "echo phpversion(\"${EXTENSION}\");"` + fi +done + +mkdir packaging/tarball/${EXTENSION}-${EXTVERSION} -p + +buildkite-agent artifact download "modules/*.so" . --step=${BUILDKITE_JOB_ID} +cp modules/*.so packaging/tarball/${EXTENSION}-${EXTVERSION}/ +cp modules/*.so packaging/root/usr/lib/${EXTENSION}/ + +cp LICENSE packaging/tarball/${EXTENSION}-${EXTVERSION}/LICENSE || true +cp NOTICE packaging/tarball/${EXTENSION}-${EXTVERSION}/NOTICE || true +cp config/${EXTENSION}.ini packaging/tarball/${EXTENSION}-${EXTVERSION}/${EXTENSION}.ini || true + +cp LICENSE packaging/root/usr/share/doc/${PACKAGENAME}/LICENSE || true +cp NOTICE packaging/root/usr/share/doc/${PACKAGENAME}/NOTICE || true +cp config/${EXTENSION}.ini packaging/root/usr/lib/${EXTENSION}/${EXTENSION}.ini || true + +pushd . + +cd packaging/tarball +tar czvf ../dist/${PACKAGENAME}-${EXTVERSION}-${ARCHITECTURE}.tar.gz . + +popd + +buildkite-agent artifact upload packaging/dist/${PACKAGENAME}-${EXTVERSION}-${ARCHITECTURE}.tar.gz + +for PKG in "${PACKAGES[@]}" +do + fpm --maintainer "support@tideways.com" \ + --url "https://tideways.com/" \ + --description "${DESCRIPTION}" \ + --vendor "Tideways GmbH" \ + -f \ + -s dir \ + -t ${PKG} \ + -C "${BASEDIR}/packaging/root" \ + -n "${PACKAGENAME}" \ + -a "${ARCHITECTURE}" \ + -v "${EXTVERSION}" \ + . + + buildkite-agent artifact upload "${PACKAGENAME}*.${PKG}" +done diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index fedaef4..26ae46c 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -92,3 +92,12 @@ steps: phpbuild: "no-debug" queue: "build" arch: "i386" + + - wait + + - label: ":package::debian: amd64" + command: ./package_extension.sh + agents: + queue: "build" + phpbuild: "no-debug" + arch: "x86_64" diff --git a/NOTICE b/NOTICE index 8675d29..5788c1a 100644 --- a/NOTICE +++ b/NOTICE @@ -1,5 +1,5 @@ Tideways PHP XHProf Profiler -Copyright (c) 2014-2017 Tideways GmbH +Copyright (c) 2014 - 2019 Tideways GmbH This product includes work from the following third-party libraries: From 4fa960aaf7db2bec6c827fb26b385feea6123dd5 Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Wed, 11 Sep 2019 11:27:59 +0200 Subject: [PATCH 33/64] Fix reference to tideways.so meaning tideways_xhprof.so --- .buildkite/build_extension.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.buildkite/build_extension.sh b/.buildkite/build_extension.sh index f7b931e..6a0509a 100755 --- a/.buildkite/build_extension.sh +++ b/.buildkite/build_extension.sh @@ -3,13 +3,14 @@ set -e PHP_VERSION=$1 +EXTENSION="tideways_xhprof" make distclean || true /opt/php/php-${PHP_VERSION}/bin/phpize CFLAGS="-O2" ./configure --with-php-config=/opt/php/php-${PHP_VERSION}/bin/php-config make -j2 -cp modules/tideways.so modules/tideways-xhprof-${PHP_VERSION}.so -buildkite-agent artifact upload modules/tideways-xhprof-${PHP_VERSION}.so +cp modules/${EXTENSION}.so modules/${EXTENSION}-${PHP_VERSION}.so +buildkite-agent artifact upload modules/${EXTENSION}-${PHP_VERSION}.so -REPORT_EXIT_STATUS=1 /opt/php/php-${PHP_VERSION}/bin/php run-tests.php -p /opt/php/php-${PHP_VERSION}/bin/php --show-diff -d extension=`pwd`/.libs/tideways_xhprof.so -q +REPORT_EXIT_STATUS=1 /opt/php/php-${PHP_VERSION}/bin/php run-tests.php -p /opt/php/php-${PHP_VERSION}/bin/php --show-diff -d extension=`pwd`/.libs/${EXTENSION}.so -q From 48cb7772d3de846b84638abf2a79f171cec9d3ba Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Wed, 11 Sep 2019 12:22:37 +0200 Subject: [PATCH 34/64] Fix path to command --- .buildkite/pipeline.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index 26ae46c..a3a2d2f 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -96,7 +96,7 @@ steps: - wait - label: ":package::debian: amd64" - command: ./package_extension.sh + command: ./.buildkite/package_extension.sh agents: queue: "build" phpbuild: "no-debug" From 295a6eb1fa3cf980d900ef2201ee104b89b7aea6 Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Wed, 11 Sep 2019 12:30:31 +0200 Subject: [PATCH 35/64] Download artifacts earlier and from all steps. --- .buildkite/package_extension.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.buildkite/package_extension.sh b/.buildkite/package_extension.sh index c7e44f2..c6395c3 100644 --- a/.buildkite/package_extension.sh +++ b/.buildkite/package_extension.sh @@ -11,6 +11,8 @@ PACKAGES=( "deb" "rpm" ) ARCHITECTURE=`uname -m` ARCHITECTURE=${ARCHITECTURE/686/386} +buildkite-agent artifact download "modules/*.so" . + mkdir packaging/dist -p mkdir packaging/root/usr/lib/${EXTENSION} -p mkdir packaging/root/usr/share/doc/${PACKAGENAME} -p @@ -24,7 +26,6 @@ done mkdir packaging/tarball/${EXTENSION}-${EXTVERSION} -p -buildkite-agent artifact download "modules/*.so" . --step=${BUILDKITE_JOB_ID} cp modules/*.so packaging/tarball/${EXTENSION}-${EXTVERSION}/ cp modules/*.so packaging/root/usr/lib/${EXTENSION}/ From ab6e00ecde8749d78d41cc6dc5da5e88d12ec288 Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Wed, 11 Sep 2019 18:11:14 +0200 Subject: [PATCH 36/64] Remove i386 builds and fix more packaging. --- .buildkite/package_extension.sh | 10 +++---- .buildkite/pipeline.yml | 49 --------------------------------- 2 files changed, 4 insertions(+), 55 deletions(-) diff --git a/.buildkite/package_extension.sh b/.buildkite/package_extension.sh index c6395c3..eef97b1 100644 --- a/.buildkite/package_extension.sh +++ b/.buildkite/package_extension.sh @@ -29,13 +29,11 @@ mkdir packaging/tarball/${EXTENSION}-${EXTVERSION} -p cp modules/*.so packaging/tarball/${EXTENSION}-${EXTVERSION}/ cp modules/*.so packaging/root/usr/lib/${EXTENSION}/ -cp LICENSE packaging/tarball/${EXTENSION}-${EXTVERSION}/LICENSE || true -cp NOTICE packaging/tarball/${EXTENSION}-${EXTVERSION}/NOTICE || true -cp config/${EXTENSION}.ini packaging/tarball/${EXTENSION}-${EXTVERSION}/${EXTENSION}.ini || true +cp ../LICENSE packaging/tarball/${EXTENSION}-${EXTVERSION}/LICENSE || true +cp ../NOTICE packaging/tarball/${EXTENSION}-${EXTVERSION}/NOTICE || true -cp LICENSE packaging/root/usr/share/doc/${PACKAGENAME}/LICENSE || true -cp NOTICE packaging/root/usr/share/doc/${PACKAGENAME}/NOTICE || true -cp config/${EXTENSION}.ini packaging/root/usr/lib/${EXTENSION}/${EXTENSION}.ini || true +cp ../LICENSE packaging/root/usr/share/doc/${PACKAGENAME}/LICENSE || true +cp ../NOTICE packaging/root/usr/share/doc/${PACKAGENAME}/NOTICE || true pushd . diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index a3a2d2f..87a8c98 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -44,55 +44,6 @@ steps: phpbuild: "no-debug" queue: "build" - - label: ":php: 7.3 i386" - command: ./.buildkite/build_extension.sh 7.3 - agents: - phpbuild: "no-debug" - queue: "build" - arch: "i386" - - - label: ":php: 7.2 i386" - command: ./.buildkite/build_extension.sh 7.2 - agents: - phpbuild: "no-debug" - queue: "build" - arch: "i386" - - - label: ":php: 7.1 i386" - command: ./.buildkite/build_extension.sh 7.1 - agents: - phpbuild: "no-debug" - queue: "build" - arch: "i386" - - - label: ":php: 7.0 i386" - command: ./.buildkite/build_extension.sh 7.0 - agents: - phpbuild: "no-debug" - queue: "build" - arch: "i386" - - - label: ":php: 7.3-zts i386" - command: ./.buildkite/build_extension.sh 7.3-zts - agents: - phpbuild: "no-debug" - queue: "build" - arch: "i386" - - - label: ":php: 7.2-zts i386" - command: ./.buildkite/build_extension.sh 7.2-zts - agents: - phpbuild: "no-debug" - queue: "build" - arch: "i386" - - - label: ":php: 7.1-zts i386" - command: ./.buildkite/build_extension.sh 7.1-zts - agents: - phpbuild: "no-debug" - queue: "build" - arch: "i386" - - wait - label: ":package::debian: amd64" From 2d2961ec859ce2e22c46825b64e20f06889bddb0 Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Wed, 11 Sep 2019 18:20:04 +0200 Subject: [PATCH 37/64] Fix more packaging script problems. --- .buildkite/package_extension.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.buildkite/package_extension.sh b/.buildkite/package_extension.sh index eef97b1..5786d54 100644 --- a/.buildkite/package_extension.sh +++ b/.buildkite/package_extension.sh @@ -2,11 +2,11 @@ set -e -BASEDIR=`dirname $0` +BASEDIR=`dirname $0/..` PACKAGENAME="tideways-xhprof" DESCRIPTION="tideways-xhprof is a modern XHProf fork built for PHP 7." EXTENSION="tideways_xhprof" -VERSIONS=( "7.0" "7.1" "7.2" "7.3" "7.0-zts" "7.1-zts" "7.2-zts" "7.3-zts" ) +VERSIONS=( "7.0" "7.1" "7.2" "7.3" "7.1-zts" "7.2-zts" "7.3-zts" ) PACKAGES=( "deb" "rpm" ) ARCHITECTURE=`uname -m` ARCHITECTURE=${ARCHITECTURE/686/386} @@ -29,8 +29,8 @@ mkdir packaging/tarball/${EXTENSION}-${EXTVERSION} -p cp modules/*.so packaging/tarball/${EXTENSION}-${EXTVERSION}/ cp modules/*.so packaging/root/usr/lib/${EXTENSION}/ -cp ../LICENSE packaging/tarball/${EXTENSION}-${EXTVERSION}/LICENSE || true -cp ../NOTICE packaging/tarball/${EXTENSION}-${EXTVERSION}/NOTICE || true +cp LICENSE packaging/tarball/${EXTENSION}-${EXTVERSION}/LICENSE || true +cp NOTICE packaging/tarball/${EXTENSION}-${EXTVERSION}/NOTICE || true cp ../LICENSE packaging/root/usr/share/doc/${PACKAGENAME}/LICENSE || true cp ../NOTICE packaging/root/usr/share/doc/${PACKAGENAME}/NOTICE || true From 60b10fa232434a5db432bc886b7dc17a4664f193 Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Wed, 11 Sep 2019 18:26:35 +0200 Subject: [PATCH 38/64] Fix more packaging script problems. --- .buildkite/package_extension.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.buildkite/package_extension.sh b/.buildkite/package_extension.sh index 5786d54..b221904 100644 --- a/.buildkite/package_extension.sh +++ b/.buildkite/package_extension.sh @@ -2,7 +2,8 @@ set -e -BASEDIR=`dirname $0/..` +BASEDIR=`dirname $0` +BASEDIR=`dirname $BASEDIR` PACKAGENAME="tideways-xhprof" DESCRIPTION="tideways-xhprof is a modern XHProf fork built for PHP 7." EXTENSION="tideways_xhprof" From 37613fb903e7f32d3bbec8e2e17840539a3a4d2b Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Wed, 11 Sep 2019 18:30:39 +0200 Subject: [PATCH 39/64] Fix more packaging script problems. --- .buildkite/package_extension.sh | 8 ++++---- .buildkite/pipeline.yml | 7 +++++++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/.buildkite/package_extension.sh b/.buildkite/package_extension.sh index b221904..3b739dc 100644 --- a/.buildkite/package_extension.sh +++ b/.buildkite/package_extension.sh @@ -30,11 +30,11 @@ mkdir packaging/tarball/${EXTENSION}-${EXTVERSION} -p cp modules/*.so packaging/tarball/${EXTENSION}-${EXTVERSION}/ cp modules/*.so packaging/root/usr/lib/${EXTENSION}/ -cp LICENSE packaging/tarball/${EXTENSION}-${EXTVERSION}/LICENSE || true -cp NOTICE packaging/tarball/${EXTENSION}-${EXTVERSION}/NOTICE || true +cp ${BASEDIR}/LICENSE packaging/tarball/${EXTENSION}-${EXTVERSION}/LICENSE || true +cp ${BASEDIR}/NOTICE packaging/tarball/${EXTENSION}-${EXTVERSION}/NOTICE || true -cp ../LICENSE packaging/root/usr/share/doc/${PACKAGENAME}/LICENSE || true -cp ../NOTICE packaging/root/usr/share/doc/${PACKAGENAME}/NOTICE || true +cp ${BASEDIR}/LICENSE packaging/root/usr/share/doc/${PACKAGENAME}/LICENSE || true +cp ${BASEDIR}/NOTICE packaging/root/usr/share/doc/${PACKAGENAME}/NOTICE || true pushd . diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index 87a8c98..5a45291 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -7,42 +7,49 @@ steps: agents: phpbuild: "no-debug" queue: "build" + arch: "x86_64" - label: ":php: 7.2 amd64" command: ./.buildkite/build_extension.sh 7.2 agents: phpbuild: "no-debug" queue: "build" + arch: "x86_64" - label: ":php: 7.1 amd64" command: ./.buildkite/build_extension.sh 7.1 agents: phpbuild: "no-debug" queue: "build" + arch: "x86_64" - label: ":php: 7.0 amd64" command: ./.buildkite/build_extension.sh 7.0 agents: phpbuild: "no-debug" queue: "build" + arch: "x86_64" - label: ":php: 7.3-zts amd64" command: ./.buildkite/build_extension.sh 7.3-zts agents: phpbuild: "no-debug" queue: "build" + arch: "x86_64" - label: ":php: 7.2-zts amd64" command: ./.buildkite/build_extension.sh 7.2-zts agents: phpbuild: "no-debug" queue: "build" + arch: "x86_64" - label: ":php: 7.1-zts amd64" command: ./.buildkite/build_extension.sh 7.1-zts agents: phpbuild: "no-debug" queue: "build" + arch: "x86_64" - wait From e1b0b15f81e8007b77379c0a959075127b4791df Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Wed, 11 Sep 2019 19:05:58 +0200 Subject: [PATCH 40/64] More info on pre-compiled binaries. --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index 37cd4fd..2b5438f 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ page](https://tideways.io/profiler/downloads). - PHP >= 7.0 - OS: Linux, MacOS, Windows ([Download DLLs](https://ci.appveyor.com/project/tideways/php-profiler-extension)) - Architectures: x64/amd64, x86, ARM, PowerPC +- Non-Threaded (NTS) or Threaded (ZTS) support ## Installation @@ -49,6 +50,15 @@ Configure the extension to load with this PHP INI directive: Restart Apache or PHP-FPM. +### Download Pre-Compiled Binaries + +We pre-compile binaries for Linux AMD64 and for Windows. See the [releases page for the downloads](https://github.com/tideways/php-xhprof-extension/releases) for each tagged version. + +The Debian and RPM packages install the PHP extension to `/usr/lib/tideways_xhprof` and doesn't automatically put it into your PHP installation extension directory. +You should link the package by full path for a simple installation: + + extension=/usr/lib/tideways_xhprof/tideways_xhprof-7.3.so + ## Usage The API is not compatible to previous xhprof extensions and forks, From 3dbaac1bdff259cc3220a7e7faa23a0bdddc623d Mon Sep 17 00:00:00 2001 From: Gilles BOUVIER Date: Sat, 14 Sep 2019 20:46:23 -0700 Subject: [PATCH 41/64] Fix typo on __APPLE__ in timer.h. --- timer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/timer.h b/timer.h index 185a1e8..ece2bc0 100644 --- a/timer.h +++ b/timer.h @@ -121,7 +121,7 @@ static zend_always_inline uint64 time_milliseconds_tsc_query() */ static zend_always_inline uint64 time_milliseconds(int source, double timebase_factor) { -#if defined(_APPLE__) +#if defined(__APPLE__) return mach_absolute_time() / timebase_factor; #elif defined(PHP_WIN32) From c0303e252649ee23aa3217c1eb71aafaf06eda04 Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Wed, 9 Oct 2019 15:37:35 +0200 Subject: [PATCH 42/64] Release v5.0.1 --- php_tideways_xhprof.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php_tideways_xhprof.h b/php_tideways_xhprof.h index 88161d9..248d571 100644 --- a/php_tideways_xhprof.h +++ b/php_tideways_xhprof.h @@ -4,7 +4,7 @@ extern zend_module_entry tideways_xhprof_module_entry; #define phpext_tideways_xhprof_ptr &tideways_xhprof_module_entry -#define PHP_TIDEWAYS_XHPROF_VERSION "5.0.0" +#define PHP_TIDEWAYS_XHPROF_VERSION "5.0.1" #define TIDEWAYS_XHPROF_CALLGRAPH_COUNTER_SIZE 1024 #define TIDEWAYS_XHPROF_CALLGRAPH_SLOTS 8192 #define TIDEWAYS_XHPROF_CLOCK_CGT 0 From fc9da2ef67635e90ade2bd822fc7040574cfa50e Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Fri, 1 Nov 2019 16:20:38 +0100 Subject: [PATCH 43/64] Add changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..e92285e --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,3 @@ +# 5.0.1 + +- [#86](https://github.com/tideways/php-xhprof-extension/pull/86): Fix bug in Apple/MacOS timer code that prevented wall time measurements from working. From 9caa610a11fab00f28cb8bc6ba2f8b62c0b94b40 Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Wed, 13 Nov 2019 15:51:39 +0100 Subject: [PATCH 44/64] Add packaging for PHP 7.4 --- .buildkite/package_extension.sh | 2 +- .buildkite/pipeline.yml | 14 ++++++++++++++ CHANGELOG.md | 4 ++++ php_tideways_xhprof.h | 2 +- 4 files changed, 20 insertions(+), 2 deletions(-) diff --git a/.buildkite/package_extension.sh b/.buildkite/package_extension.sh index 3b739dc..9858466 100644 --- a/.buildkite/package_extension.sh +++ b/.buildkite/package_extension.sh @@ -7,7 +7,7 @@ BASEDIR=`dirname $BASEDIR` PACKAGENAME="tideways-xhprof" DESCRIPTION="tideways-xhprof is a modern XHProf fork built for PHP 7." EXTENSION="tideways_xhprof" -VERSIONS=( "7.0" "7.1" "7.2" "7.3" "7.1-zts" "7.2-zts" "7.3-zts" ) +VERSIONS=( "7.0" "7.1" "7.2" "7.3" "7.4" "7.1-zts" "7.2-zts" "7.3-zts" "7.4-zts" ) PACKAGES=( "deb" "rpm" ) ARCHITECTURE=`uname -m` ARCHITECTURE=${ARCHITECTURE/686/386} diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index 5a45291..42ca63b 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -2,6 +2,13 @@ env: NO_INTERACTION: 1 steps: + - label: ":php: 7.4 amd64" + command: ./.buildkite/build_extension.sh 7.4 + agents: + phpbuild: "no-debug" + queue: "build" + arch: "x86_64" + - label: ":php: 7.3 amd64" command: ./.buildkite/build_extension.sh 7.3 agents: @@ -30,6 +37,13 @@ steps: queue: "build" arch: "x86_64" + - label: ":php: 7.4-zts amd64" + command: ./.buildkite/build_extension.sh 7.4-zts + agents: + phpbuild: "no-debug" + queue: "build" + arch: "x86_64" + - label: ":php: 7.3-zts amd64" command: ./.buildkite/build_extension.sh 7.3-zts agents: diff --git a/CHANGELOG.md b/CHANGELOG.md index e92285e..6ae0514 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 5.0.2 + +- [#90](https://github.com/tideways/php-xhprof-extension/issues/90): Add packaging for PHP 7.4 + # 5.0.1 - [#86](https://github.com/tideways/php-xhprof-extension/pull/86): Fix bug in Apple/MacOS timer code that prevented wall time measurements from working. diff --git a/php_tideways_xhprof.h b/php_tideways_xhprof.h index 248d571..98a274d 100644 --- a/php_tideways_xhprof.h +++ b/php_tideways_xhprof.h @@ -4,7 +4,7 @@ extern zend_module_entry tideways_xhprof_module_entry; #define phpext_tideways_xhprof_ptr &tideways_xhprof_module_entry -#define PHP_TIDEWAYS_XHPROF_VERSION "5.0.1" +#define PHP_TIDEWAYS_XHPROF_VERSION "5.0.2" #define TIDEWAYS_XHPROF_CALLGRAPH_COUNTER_SIZE 1024 #define TIDEWAYS_XHPROF_CALLGRAPH_SLOTS 8192 #define TIDEWAYS_XHPROF_CLOCK_CGT 0 From d732f2b7456ff899fcc29e49dfa63df830b4fd4d Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Thu, 14 Nov 2019 16:41:41 +0100 Subject: [PATCH 45/64] Add PHP 7.4 builds on Appveyor. --- .appveyor.yml | 24 ++++++++++++++++++++++-- .appveyor/build_task.cmd | 2 +- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index 674ebe8..ec1f265 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -8,11 +8,16 @@ environment: PHP_BUILD_CACHE_BASE_DIR: c:\build-cache PHP_BUILD_OBJ_DIR: c:\obj PHP_BUILD_CACHE_SDK_DIR: c:\build-cache\sdk - PHP_BUILD_SDK_BRANCH: php-sdk-2.1.1 + PHP_BUILD_SDK_BRANCH: php-sdk-2.2.0beta6 SDK_REMOTE: https://github.com/OSTC/php-sdk-binary-tools.git - SDK_BRANCH: php-sdk-2.1.1 + SDK_BRANCH: php-sdk-2.2.0beta6 matrix: + - PHP_REL: 7.4 + ARCHITECTURE: x64 + ZTS_STATE: enable + APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 + PHP_BUILD_CRT: vc15 - PHP_REL: 7.3 ARCHITECTURE: x64 ZTS_STATE: enable @@ -28,6 +33,11 @@ environment: ZTS_STATE: enable APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 PHP_BUILD_CRT: vc14 + - PHP_REL: 7.4 + ARCHITECTURE: x64 + ZTS_STATE: disable + APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 + PHP_BUILD_CRT: vc15 - PHP_REL: 7.3 ARCHITECTURE: x64 ZTS_STATE: disable @@ -43,6 +53,11 @@ environment: ZTS_STATE: disable APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 PHP_BUILD_CRT: vc14 + - PHP_REL: 7.4 + ARCHITECTURE: x86 + ZTS_STATE: enable + APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 + PHP_BUILD_CRT: vc15 - PHP_REL: 7.3 ARCHITECTURE: x86 ZTS_STATE: enable @@ -58,6 +73,11 @@ environment: ZTS_STATE: enable APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 PHP_BUILD_CRT: vc14 + - PHP_REL: 7.4 + ARCHITECTURE: x86 + ZTS_STATE: disable + APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 + PHP_BUILD_CRT: vc15 - PHP_REL: 7.3 ARCHITECTURE: x86 ZTS_STATE: disable diff --git a/.appveyor/build_task.cmd b/.appveyor/build_task.cmd index 64ab78f..19ebaed 100644 --- a/.appveyor/build_task.cmd +++ b/.appveyor/build_task.cmd @@ -46,7 +46,7 @@ setlocal enableextensions enabledelayedexpansion set TEST_PHP_EXECUTABLE=%APPVEYOR_BUILD_FOLDER%\build\php.exe set TEST_PHP_JUNIT=c:\tests_tmp\tests-junit.xml if "%OPCACHE%" equ "1" set TEST_PHP_ARGS=!TEST_PHP_ARGS! -d extension=%APPVEYOR_BUILD_FOLDER%\build\ext\php_opcache.so -d opcache.enable=1 -d opcache.enable_cli=1 - set TEST_PHP_ARGS=-n -d -foo=1 -d extension=%APPVEYOR_BUILD_FOLDER%\build\ext\php_tideways_xhprof.dll + set TEST_PHP_ARGS=-n -d foo=1 -d extension=%APPVEYOR_BUILD_FOLDER%\build\ext\php_tideways_xhprof.dll set SKIP_DBGP_TESTS=1 set SKIP_IPV6_TESTS=1 set REPORT_EXIT_STATUS=1 From 9357da02d8ff2c5510e374bf920fdb3e103e1f66 Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Fri, 10 Apr 2020 20:43:06 +0200 Subject: [PATCH 46/64] Update README.md with fix to ini setting name and docker+mac clock performance reference. --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2b5438f..9e551bb 100644 --- a/README.md +++ b/README.md @@ -163,5 +163,6 @@ is slower compared to other mechanisms that the kernel provides: use without having to force the current process to a specific CPU. Tideways on Linux defaults to using `clock_gettime(CLOCK_MONOTONIC)`, but if -you are running on Xen based virtualization, you could try to reduce the -overhead by setting `tideways.clock_use_rdtsc=1" in your PHP.ini. +you are running on Xen based virtualization or Docker on Mac, you could try to +reduce the overhead by setting `tideways_xhprof.clock_use_rdtsc=1" in your +PHP.ini. From 6d2f44be8af278f2a3af9a472ad67fb182e14430 Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Tue, 14 Apr 2020 16:48:52 +0200 Subject: [PATCH 47/64] Adapt to experimental zend_instrument API proposed for PHP 8 --- php_tideways_xhprof.h | 8 ++++ tests/xhprof_001.phpt | 6 --- tests/xhprof_002.phpt | 2 - tests/xhprof_003.phpt | 1 - tests/xhprof_004.phpt | 1 - tests/xhprof_006.phpt | 1 - tests/xhprof_007.phpt | 10 ++--- tideways_xhprof.c | 94 +++++++++++++++++++++---------------------- 8 files changed, 56 insertions(+), 67 deletions(-) diff --git a/php_tideways_xhprof.h b/php_tideways_xhprof.h index 98a274d..6cebe1e 100644 --- a/php_tideways_xhprof.h +++ b/php_tideways_xhprof.h @@ -14,6 +14,14 @@ extern zend_module_entry tideways_xhprof_module_entry; #define TIDEWAYS_XHPROF_CLOCK_QPC 4 #define TIDEWAYS_XHPROF_CLOCK_NONE 255 +#ifndef TSRMLS_CC +#define TSRMLS_FETCH() +#define TSRMLS_CC +#define TSRMLS_DC +#define TSRMLS_D +#define TSRMLS_C +#endif + #ifdef ZTS #include "TSRM.h" #endif diff --git a/tests/xhprof_001.phpt b/tests/xhprof_001.phpt index 1429165..74f5241 100644 --- a/tests/xhprof_001.phpt +++ b/tests/xhprof_001.phpt @@ -86,13 +86,11 @@ Part 1: Default Flags foo==>bar : ct= 2; wt=*; main() : ct= 1; wt=*; main()==>foo : ct= 1; wt=*; -main()==>tideways_xhprof_disable : ct= 1; wt=*; Part 2: CPU foo==>bar : cpu=*; ct= 2; wt=*; main() : cpu=*; ct= 1; wt=*; main()==>foo : cpu=*; ct= 1; wt=*; -main()==>tideways_xhprof_disable : cpu=*; ct= 1; wt=*; Part 3: No Builtins foo==>bar : ct= 2; wt=*; @@ -103,22 +101,18 @@ Part 4: Memory foo==>bar : ct= 2; mu=*; pmu=*; wt=*; main() : ct= 1; mu=*; pmu=*; wt=*; main()==>foo : ct= 1; mu=*; pmu=*; wt=*; -main()==>tideways_xhprof_disable : ct= 1; mu=*; pmu=*; wt=*; Part 5: Memory & CPU foo==>bar : cpu=*; ct= 2; mu=*; pmu=*; wt=*; main() : cpu=*; ct= 1; mu=*; pmu=*; wt=*; main()==>foo : cpu=*; ct= 1; mu=*; pmu=*; wt=*; -main()==>tideways_xhprof_disable : cpu=*; ct= 1; mu=*; pmu=*; wt=*; Part 6: Extended Memory Profiling foo==>bar : ct= 2; mem.aa=*; mem.na=*; mem.nf=*; wt=*; main() : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; main()==>foo : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; -main()==>tideways_xhprof_disable : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; Part 7: Extended Memory Profiling as mu foo==>bar : ct= 2; mem.aa=*; mem.na=*; mem.nf=*; mu=*; wt=*; main() : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; mu=*; wt=*; main()==>foo : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; mu=*; wt=*; -main()==>tideways_xhprof_disable : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; mu=*; wt=*; diff --git a/tests/xhprof_002.phpt b/tests/xhprof_002.phpt index 8e9db3c..44e3da2 100644 --- a/tests/xhprof_002.phpt +++ b/tests/xhprof_002.phpt @@ -46,7 +46,6 @@ foo@2==>foo@3 : ct= 1; wt=*; foo@3==>foo@4 : ct= 1; wt=*; main() : ct= 1; wt=*; main()==>foo : ct= 1; wt=*; -main()==>tideways_xhprof_disable : ct= 1; wt=*; Indirect Recursion bar==>foo@1 : ct= 1; wt=*; @@ -59,4 +58,3 @@ foo@2==>bar@2 : ct= 1; wt=*; foo@3==>bar@3 : ct= 1; wt=*; main() : ct= 1; wt=*; main()==>foo : ct= 1; wt=*; -main()==>tideways_xhprof_disable : ct= 1; wt=*; diff --git a/tests/xhprof_003.phpt b/tests/xhprof_003.phpt index fe93214..93b260d 100644 --- a/tests/xhprof_003.phpt +++ b/tests/xhprof_003.phpt @@ -64,4 +64,3 @@ main()==>C::__construct : ct= 1; wt=*; main()==>C::__destruct : ct= 1; wt=*; main()==>C::get_attr : ct= 1; wt=*; main()==>C::outer_static : ct= 1; wt=*; -main()==>tideways_xhprof_disable : ct= 1; wt=*; diff --git a/tests/xhprof_004.phpt b/tests/xhprof_004.phpt index e098191..7cbaddf 100644 --- a/tests/xhprof_004.phpt +++ b/tests/xhprof_004.phpt @@ -24,5 +24,4 @@ print_canonical($output); --EXPECTF-- main() : ct= 1; wt=*; main()==>class@anonymous::baz : ct= 1; wt=*; -main()==>tideways_xhprof_disable : ct= 1; wt=*; main()==>{closure} : ct= 1; wt=*; diff --git a/tests/xhprof_006.phpt b/tests/xhprof_006.phpt index 48b91ea..df7742c 100644 --- a/tests/xhprof_006.phpt +++ b/tests/xhprof_006.phpt @@ -39,4 +39,3 @@ string(1) "1" Clock Source => %s main() : ct= 1; wt=*; main()==>foo : ct= 1; wt=*; -main()==>tideways_xhprof_disable : ct= 1; wt=*; diff --git a/tests/xhprof_007.phpt b/tests/xhprof_007.phpt index 35bdcff..f12522e 100644 --- a/tests/xhprof_007.phpt +++ b/tests/xhprof_007.phpt @@ -26,11 +26,7 @@ $output = tideways_xhprof_disable(); print_canonical($output); --EXPECTF-- -call_user_func==>foo : ct= 1; wt=*; -call_user_func_array==>class@anonymous::__invoke: ct= 1; wt=*; -call_user_func_array==>foo : ct= 1; wt=*; -call_user_func_array==>{closure} : ct= 1; wt=*; main() : ct= 1; wt=*; -main()==>call_user_func : ct= 1; wt=*; -main()==>call_user_func_array : ct= 3; wt=*; -main()==>tideways_xhprof_disable : ct= 1; wt=*; +main()==>class@anonymous::__invoke : ct= 1; wt=*; +main()==>foo : ct= 2; wt=*; +main()==>{closure} : ct= 1; wt=*; diff --git a/tideways_xhprof.c b/tideways_xhprof.c index 72e0dbf..1db1469 100644 --- a/tideways_xhprof.c +++ b/tideways_xhprof.c @@ -11,16 +11,49 @@ ZEND_DECLARE_MODULE_GLOBALS(tideways_xhprof) #include "tracing.h" - -static void (*_zend_execute_ex) (zend_execute_data *execute_data); -static void (*_zend_execute_internal) (zend_execute_data *execute_data, zval *return_value); -ZEND_DLEXPORT void tideways_xhprof_execute_internal(zend_execute_data *execute_data, zval *return_value); -ZEND_DLEXPORT void tideways_xhprof_execute_ex (zend_execute_data *execute_data); +#include "Zend/zend_instrument.h" PHP_INI_BEGIN() STD_PHP_INI_ENTRY("tideways_xhprof.clock_use_rdtsc", "0", PHP_INI_SYSTEM, OnUpdateBool, clock_use_rdtsc, zend_tideways_xhprof_globals, tideways_xhprof_globals) PHP_INI_END() +static void tracer_observer_begin(zend_execute_data *ex) { + if (!TXRG(enabled)) { + return; + } + + tracing_enter_frame_callgraph(NULL, ex); +} + +static void tracer_observer_end(zend_execute_data *ex/*, zval *return_value*/) { + if (!TXRG(enabled)) { + return; + } + + if (TXRG(callgraph_frames)) { + tracing_exit_frame_callgraph(TSRMLS_C); + } +} + + +static zend_instrument_handlers tracer_observer_instrument(zend_function *func) { + zend_instrument_handlers handlers = {NULL, NULL}; + + if (!TXRG(enabled) || (TXRG(flags) & TIDEWAYS_XHPROF_FLAGS_NO_BUILTINS) > 0) { + return handlers; + } + + if (!func->common.function_name) { + return handlers; + } + + handlers.begin = tracer_observer_begin; + handlers.end = tracer_observer_end; + + return handlers; +} + + PHP_FUNCTION(tideways_xhprof_enable) { zend_long flags = 0; @@ -64,11 +97,7 @@ PHP_MINIT_FUNCTION(tideways_xhprof) REGISTER_LONG_CONSTANT("TIDEWAYS_XHPROF_FLAGS_MEMORY_ALLOC", TIDEWAYS_XHPROF_FLAGS_MEMORY_ALLOC, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("TIDEWAYS_XHPROF_FLAGS_MEMORY_ALLOC_AS_MU", TIDEWAYS_XHPROF_FLAGS_MEMORY_ALLOC_AS_MU, CONST_CS | CONST_PERSISTENT); - _zend_execute_internal = zend_execute_internal; - zend_execute_internal = tideways_xhprof_execute_internal; - - _zend_execute_ex = zend_execute_ex; - zend_execute_ex = tideways_xhprof_execute_ex; + zend_instrument_register(tracer_observer_instrument); return SUCCESS; } @@ -163,48 +192,15 @@ PHP_MINFO_FUNCTION(tideways_xhprof) } -ZEND_DLEXPORT void tideways_xhprof_execute_internal(zend_execute_data *execute_data, zval *return_value) { - int is_profiling = 1; - - if (!TXRG(enabled) || (TXRG(flags) & TIDEWAYS_XHPROF_FLAGS_NO_BUILTINS) > 0) { - execute_internal(execute_data, return_value TSRMLS_CC); - return; - } - - is_profiling = tracing_enter_frame_callgraph(NULL, execute_data TSRMLS_CC); - - if (!_zend_execute_internal) { - execute_internal(execute_data, return_value TSRMLS_CC); - } else { - _zend_execute_internal(execute_data, return_value TSRMLS_CC); - } - - if (is_profiling == 1 && TXRG(callgraph_frames)) { - tracing_exit_frame_callgraph(TSRMLS_C); - } -} - -ZEND_DLEXPORT void tideways_xhprof_execute_ex (zend_execute_data *execute_data) { - zend_execute_data *real_execute_data = execute_data; - int is_profiling = 0; - - if (!TXRG(enabled)) { - _zend_execute_ex(execute_data TSRMLS_CC); - return; - } - - is_profiling = tracing_enter_frame_callgraph(NULL, real_execute_data TSRMLS_CC); - - _zend_execute_ex(execute_data TSRMLS_CC); +ZEND_BEGIN_ARG_INFO_EX(arginfo_tideways_xhprof_enable, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 0) +ZEND_END_ARG_INFO() - if (is_profiling == 1 && TXRG(callgraph_frames)) { - tracing_exit_frame_callgraph(TSRMLS_C); - } -} +ZEND_BEGIN_ARG_INFO_EX(arginfo_tideways_xhprof_disable, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 0) +ZEND_END_ARG_INFO() const zend_function_entry tideways_xhprof_functions[] = { - PHP_FE(tideways_xhprof_enable, NULL) - PHP_FE(tideways_xhprof_disable, NULL) + PHP_FE(tideways_xhprof_enable, arginfo_tideways_xhprof_enable) + PHP_FE(tideways_xhprof_disable, arginfo_tideways_xhprof_disable) PHP_FE_END }; From f6aed09e98caf1eab58d2fd12dd42fe23e33c7dc Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Tue, 14 Apr 2020 16:59:55 +0200 Subject: [PATCH 48/64] Adjustments that PHP 8 needs. --- php_tideways_xhprof.h | 8 ++++++++ tideways_xhprof.c | 10 ++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/php_tideways_xhprof.h b/php_tideways_xhprof.h index 98a274d..6cebe1e 100644 --- a/php_tideways_xhprof.h +++ b/php_tideways_xhprof.h @@ -14,6 +14,14 @@ extern zend_module_entry tideways_xhprof_module_entry; #define TIDEWAYS_XHPROF_CLOCK_QPC 4 #define TIDEWAYS_XHPROF_CLOCK_NONE 255 +#ifndef TSRMLS_CC +#define TSRMLS_FETCH() +#define TSRMLS_CC +#define TSRMLS_DC +#define TSRMLS_D +#define TSRMLS_C +#endif + #ifdef ZTS #include "TSRM.h" #endif diff --git a/tideways_xhprof.c b/tideways_xhprof.c index 72e0dbf..767e620 100644 --- a/tideways_xhprof.c +++ b/tideways_xhprof.c @@ -202,9 +202,15 @@ ZEND_DLEXPORT void tideways_xhprof_execute_ex (zend_execute_data *execute_data) } } +ZEND_BEGIN_ARG_INFO_EX(arginfo_tideways_xhprof_enable, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_tideways_xhprof_disable, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 0) +ZEND_END_ARG_INFO() + const zend_function_entry tideways_xhprof_functions[] = { - PHP_FE(tideways_xhprof_enable, NULL) - PHP_FE(tideways_xhprof_disable, NULL) + PHP_FE(tideways_xhprof_enable, arginfo_tideways_xhprof_enable) + PHP_FE(tideways_xhprof_disable, arginfo_tideways_xhprof_disable) PHP_FE_END }; From 119716c3539e7dd39375e7f028f4f3fd188228be Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Tue, 14 Apr 2020 17:03:36 +0200 Subject: [PATCH 49/64] Fix merge conflict --- tideways_xhprof.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tideways_xhprof.c b/tideways_xhprof.c index a659e38..1db1469 100644 --- a/tideways_xhprof.c +++ b/tideways_xhprof.c @@ -198,12 +198,6 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_tideways_xhprof_disable, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 0) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(arginfo_tideways_xhprof_enable, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 0) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_tideways_xhprof_disable, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 0) -ZEND_END_ARG_INFO() - const zend_function_entry tideways_xhprof_functions[] = { PHP_FE(tideways_xhprof_enable, arginfo_tideways_xhprof_enable) PHP_FE(tideways_xhprof_disable, arginfo_tideways_xhprof_disable) From 0ca7b91d0f2ad18554055bac1b57ecbe321dbc96 Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Sun, 19 Apr 2020 12:28:52 +0200 Subject: [PATCH 50/64] Add test for internal functions calling userland functions --- tests/xhprof_008.phpt | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 tests/xhprof_008.phpt diff --git a/tests/xhprof_008.phpt b/tests/xhprof_008.phpt new file mode 100644 index 0000000..009e6c5 --- /dev/null +++ b/tests/xhprof_008.phpt @@ -0,0 +1,24 @@ +--TEST-- +xhprof: internal functions calling userland functions +--FILE-- +double : ct= 10; wt=*; +main() : ct= 1; wt=*; +main()==>array_map : ct= 1; wt=*; +main()==>range : ct= 1; wt=*; +main()==>tideways_xhprof_disable : ct= 1; wt=*; From e7f7b722a845d315c9afc03d3470d615348e7a33 Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Sat, 25 Apr 2020 19:18:57 +0200 Subject: [PATCH 51/64] savepoint for changes to instrumentation --- tests/xhprof_008.inc | 7 +++++++ tests/xhprof_008.phpt | 6 +----- tideways_xhprof.c | 4 ---- 3 files changed, 8 insertions(+), 9 deletions(-) create mode 100644 tests/xhprof_008.inc diff --git a/tests/xhprof_008.inc b/tests/xhprof_008.inc new file mode 100644 index 0000000..df9211f --- /dev/null +++ b/tests/xhprof_008.inc @@ -0,0 +1,7 @@ + 0) { - return handlers; - } - if (!func->common.function_name) { return handlers; } From 72a76217c28469c5f8f953a312136e3e7771687f Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Wed, 2 Sep 2020 19:15:50 +0200 Subject: [PATCH 52/64] Use final zend_observer API. --- tests/xhprof_001.phpt | 6 ++++++ tests/xhprof_002.phpt | 2 ++ tests/xhprof_003.phpt | 1 + tests/xhprof_004.phpt | 1 + tests/xhprof_006.phpt | 1 + tests/xhprof_007.phpt | 10 +++++++--- tideways_xhprof.c | 44 ++++++++++++++++++++++++++++++++----------- 7 files changed, 51 insertions(+), 14 deletions(-) diff --git a/tests/xhprof_001.phpt b/tests/xhprof_001.phpt index 74f5241..1429165 100644 --- a/tests/xhprof_001.phpt +++ b/tests/xhprof_001.phpt @@ -86,11 +86,13 @@ Part 1: Default Flags foo==>bar : ct= 2; wt=*; main() : ct= 1; wt=*; main()==>foo : ct= 1; wt=*; +main()==>tideways_xhprof_disable : ct= 1; wt=*; Part 2: CPU foo==>bar : cpu=*; ct= 2; wt=*; main() : cpu=*; ct= 1; wt=*; main()==>foo : cpu=*; ct= 1; wt=*; +main()==>tideways_xhprof_disable : cpu=*; ct= 1; wt=*; Part 3: No Builtins foo==>bar : ct= 2; wt=*; @@ -101,18 +103,22 @@ Part 4: Memory foo==>bar : ct= 2; mu=*; pmu=*; wt=*; main() : ct= 1; mu=*; pmu=*; wt=*; main()==>foo : ct= 1; mu=*; pmu=*; wt=*; +main()==>tideways_xhprof_disable : ct= 1; mu=*; pmu=*; wt=*; Part 5: Memory & CPU foo==>bar : cpu=*; ct= 2; mu=*; pmu=*; wt=*; main() : cpu=*; ct= 1; mu=*; pmu=*; wt=*; main()==>foo : cpu=*; ct= 1; mu=*; pmu=*; wt=*; +main()==>tideways_xhprof_disable : cpu=*; ct= 1; mu=*; pmu=*; wt=*; Part 6: Extended Memory Profiling foo==>bar : ct= 2; mem.aa=*; mem.na=*; mem.nf=*; wt=*; main() : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; main()==>foo : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; +main()==>tideways_xhprof_disable : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; wt=*; Part 7: Extended Memory Profiling as mu foo==>bar : ct= 2; mem.aa=*; mem.na=*; mem.nf=*; mu=*; wt=*; main() : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; mu=*; wt=*; main()==>foo : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; mu=*; wt=*; +main()==>tideways_xhprof_disable : ct= 1; mem.aa=*; mem.na=*; mem.nf=*; mu=*; wt=*; diff --git a/tests/xhprof_002.phpt b/tests/xhprof_002.phpt index 44e3da2..8e9db3c 100644 --- a/tests/xhprof_002.phpt +++ b/tests/xhprof_002.phpt @@ -46,6 +46,7 @@ foo@2==>foo@3 : ct= 1; wt=*; foo@3==>foo@4 : ct= 1; wt=*; main() : ct= 1; wt=*; main()==>foo : ct= 1; wt=*; +main()==>tideways_xhprof_disable : ct= 1; wt=*; Indirect Recursion bar==>foo@1 : ct= 1; wt=*; @@ -58,3 +59,4 @@ foo@2==>bar@2 : ct= 1; wt=*; foo@3==>bar@3 : ct= 1; wt=*; main() : ct= 1; wt=*; main()==>foo : ct= 1; wt=*; +main()==>tideways_xhprof_disable : ct= 1; wt=*; diff --git a/tests/xhprof_003.phpt b/tests/xhprof_003.phpt index 93b260d..fe93214 100644 --- a/tests/xhprof_003.phpt +++ b/tests/xhprof_003.phpt @@ -64,3 +64,4 @@ main()==>C::__construct : ct= 1; wt=*; main()==>C::__destruct : ct= 1; wt=*; main()==>C::get_attr : ct= 1; wt=*; main()==>C::outer_static : ct= 1; wt=*; +main()==>tideways_xhprof_disable : ct= 1; wt=*; diff --git a/tests/xhprof_004.phpt b/tests/xhprof_004.phpt index 7cbaddf..e098191 100644 --- a/tests/xhprof_004.phpt +++ b/tests/xhprof_004.phpt @@ -24,4 +24,5 @@ print_canonical($output); --EXPECTF-- main() : ct= 1; wt=*; main()==>class@anonymous::baz : ct= 1; wt=*; +main()==>tideways_xhprof_disable : ct= 1; wt=*; main()==>{closure} : ct= 1; wt=*; diff --git a/tests/xhprof_006.phpt b/tests/xhprof_006.phpt index df7742c..48b91ea 100644 --- a/tests/xhprof_006.phpt +++ b/tests/xhprof_006.phpt @@ -39,3 +39,4 @@ string(1) "1" Clock Source => %s main() : ct= 1; wt=*; main()==>foo : ct= 1; wt=*; +main()==>tideways_xhprof_disable : ct= 1; wt=*; diff --git a/tests/xhprof_007.phpt b/tests/xhprof_007.phpt index f12522e..35bdcff 100644 --- a/tests/xhprof_007.phpt +++ b/tests/xhprof_007.phpt @@ -26,7 +26,11 @@ $output = tideways_xhprof_disable(); print_canonical($output); --EXPECTF-- +call_user_func==>foo : ct= 1; wt=*; +call_user_func_array==>class@anonymous::__invoke: ct= 1; wt=*; +call_user_func_array==>foo : ct= 1; wt=*; +call_user_func_array==>{closure} : ct= 1; wt=*; main() : ct= 1; wt=*; -main()==>class@anonymous::__invoke : ct= 1; wt=*; -main()==>foo : ct= 2; wt=*; -main()==>{closure} : ct= 1; wt=*; +main()==>call_user_func : ct= 1; wt=*; +main()==>call_user_func_array : ct= 3; wt=*; +main()==>tideways_xhprof_disable : ct= 1; wt=*; diff --git a/tideways_xhprof.c b/tideways_xhprof.c index 9376e36..8156ccb 100644 --- a/tideways_xhprof.c +++ b/tideways_xhprof.c @@ -11,7 +11,10 @@ ZEND_DECLARE_MODULE_GLOBALS(tideways_xhprof) #include "tracing.h" -#include "Zend/zend_instrument.h" +#include "Zend/zend_observer.h" + +static void (*_zend_execute_internal) (zend_execute_data *execute_data, zval *return_value); +ZEND_DLEXPORT void tideways_xhprof_execute_internal(zend_execute_data *execute_data, zval *return_value); PHP_INI_BEGIN() STD_PHP_INI_ENTRY("tideways_xhprof.clock_use_rdtsc", "0", PHP_INI_SYSTEM, OnUpdateBool, clock_use_rdtsc, zend_tideways_xhprof_globals, tideways_xhprof_globals) @@ -25,7 +28,7 @@ static void tracer_observer_begin(zend_execute_data *ex) { tracing_enter_frame_callgraph(NULL, ex); } -static void tracer_observer_end(zend_execute_data *ex/*, zval *return_value*/) { +static void tracer_observer_end(zend_execute_data *ex, zval *return_value) { if (!TXRG(enabled)) { return; } @@ -36,17 +39,12 @@ static void tracer_observer_end(zend_execute_data *ex/*, zval *return_value*/) { } -static zend_instrument_handlers tracer_observer_instrument(zend_function *func) { - zend_instrument_handlers handlers = {NULL, NULL}; - +static zend_observer_fcall tracer_observer(zend_function *func) { if (!func->common.function_name) { - return handlers; + return (zend_observer_fcall){NULL, NULL}; } - handlers.begin = tracer_observer_begin; - handlers.end = tracer_observer_end; - - return handlers; + return (zend_observer_fcall){tracer_observer_begin, tracer_observer_end}; } @@ -93,7 +91,10 @@ PHP_MINIT_FUNCTION(tideways_xhprof) REGISTER_LONG_CONSTANT("TIDEWAYS_XHPROF_FLAGS_MEMORY_ALLOC", TIDEWAYS_XHPROF_FLAGS_MEMORY_ALLOC, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("TIDEWAYS_XHPROF_FLAGS_MEMORY_ALLOC_AS_MU", TIDEWAYS_XHPROF_FLAGS_MEMORY_ALLOC_AS_MU, CONST_CS | CONST_PERSISTENT); - zend_instrument_register(tracer_observer_instrument); + _zend_execute_internal = zend_execute_internal; + zend_execute_internal = tideways_xhprof_execute_internal; + + zend_observer_fcall_register(tracer_observer); return SUCCESS; } @@ -188,6 +189,27 @@ PHP_MINFO_FUNCTION(tideways_xhprof) } +ZEND_DLEXPORT void tideways_xhprof_execute_internal(zend_execute_data *execute_data, zval *return_value) { + int is_profiling = 1; + + if (!TXRG(enabled) || (TXRG(flags) & TIDEWAYS_XHPROF_FLAGS_NO_BUILTINS) > 0) { + execute_internal(execute_data, return_value TSRMLS_CC); + return; + } + + is_profiling = tracing_enter_frame_callgraph(NULL, execute_data TSRMLS_CC); + + if (!_zend_execute_internal) { + execute_internal(execute_data, return_value TSRMLS_CC); + } else { + _zend_execute_internal(execute_data, return_value TSRMLS_CC); + } + + if (is_profiling == 1 && TXRG(callgraph_frames)) { + tracing_exit_frame_callgraph(TSRMLS_C); + } +} + ZEND_BEGIN_ARG_INFO_EX(arginfo_tideways_xhprof_enable, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 0) ZEND_END_ARG_INFO() From ff3c01ec8951c0b268235893dee95a30d7486e80 Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Tue, 1 Dec 2020 22:32:48 +0100 Subject: [PATCH 53/64] Final adjustments for PHP 8 --- tideways_xhprof.c | 17 +++++++---------- tideways_xhprof.stub.php | 4 ++++ tideways_xhprof_arginfo.h | 9 +++++++++ 3 files changed, 20 insertions(+), 10 deletions(-) create mode 100644 tideways_xhprof.stub.php create mode 100644 tideways_xhprof_arginfo.h diff --git a/tideways_xhprof.c b/tideways_xhprof.c index 8156ccb..036dfa3 100644 --- a/tideways_xhprof.c +++ b/tideways_xhprof.c @@ -7,11 +7,12 @@ #include "SAPI.h" #include "ext/standard/info.h" #include "php_tideways_xhprof.h" +#include "tideways_xhprof_arginfo.h" ZEND_DECLARE_MODULE_GLOBALS(tideways_xhprof) #include "tracing.h" -#include "Zend/zend_observer.h" +#include "zend_observer.h" static void (*_zend_execute_internal) (zend_execute_data *execute_data, zval *return_value); ZEND_DLEXPORT void tideways_xhprof_execute_internal(zend_execute_data *execute_data, zval *return_value); @@ -39,12 +40,14 @@ static void tracer_observer_end(zend_execute_data *ex, zval *return_value) { } -static zend_observer_fcall tracer_observer(zend_function *func) { +static zend_observer_fcall_handlers tracer_observer(zend_execute_data *execute_data) { + zend_function *func = execute_data->func; + if (!func->common.function_name) { - return (zend_observer_fcall){NULL, NULL}; + return (zend_observer_fcall_handlers){NULL, NULL}; } - return (zend_observer_fcall){tracer_observer_begin, tracer_observer_end}; + return (zend_observer_fcall_handlers){tracer_observer_begin, tracer_observer_end}; } @@ -210,12 +213,6 @@ ZEND_DLEXPORT void tideways_xhprof_execute_internal(zend_execute_data *execute_d } } -ZEND_BEGIN_ARG_INFO_EX(arginfo_tideways_xhprof_enable, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 0) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_tideways_xhprof_disable, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 0) -ZEND_END_ARG_INFO() - const zend_function_entry tideways_xhprof_functions[] = { PHP_FE(tideways_xhprof_enable, arginfo_tideways_xhprof_enable) PHP_FE(tideways_xhprof_disable, arginfo_tideways_xhprof_disable) diff --git a/tideways_xhprof.stub.php b/tideways_xhprof.stub.php new file mode 100644 index 0000000..a60153a --- /dev/null +++ b/tideways_xhprof.stub.php @@ -0,0 +1,4 @@ + Date: Thu, 3 Dec 2020 13:28:32 +0100 Subject: [PATCH 54/64] Reintroduce PHP 7 support conditionally. --- tideways_xhprof.c | 41 ++++++++++++++++++++++++++++---- tideways_xhprof.stub.php | 15 ++++++++++-- tideways_xhprof_arginfo.h | 8 +++---- tideways_xhprof_legacy_arginfo.h | 9 +++++++ 4 files changed, 62 insertions(+), 11 deletions(-) create mode 100644 tideways_xhprof_legacy_arginfo.h diff --git a/tideways_xhprof.c b/tideways_xhprof.c index 036dfa3..05429dc 100644 --- a/tideways_xhprof.c +++ b/tideways_xhprof.c @@ -7,20 +7,26 @@ #include "SAPI.h" #include "ext/standard/info.h" #include "php_tideways_xhprof.h" -#include "tideways_xhprof_arginfo.h" ZEND_DECLARE_MODULE_GLOBALS(tideways_xhprof) #include "tracing.h" -#include "zend_observer.h" - -static void (*_zend_execute_internal) (zend_execute_data *execute_data, zval *return_value); -ZEND_DLEXPORT void tideways_xhprof_execute_internal(zend_execute_data *execute_data, zval *return_value); +#if PHP_VERSION_ID >= 80000 +#include "tideways_xhprof_arginfo.h" +#else +#include "tideways_xhprof_legacy_arginfo.h" +#endif PHP_INI_BEGIN() STD_PHP_INI_ENTRY("tideways_xhprof.clock_use_rdtsc", "0", PHP_INI_SYSTEM, OnUpdateBool, clock_use_rdtsc, zend_tideways_xhprof_globals, tideways_xhprof_globals) PHP_INI_END() +static void (*_zend_execute_internal) (zend_execute_data *execute_data, zval *return_value); +ZEND_DLEXPORT void tideways_xhprof_execute_internal(zend_execute_data *execute_data, zval *return_value); + +#if PHP_VERSION_ID >= 80000 +#include "zend_observer.h" + static void tracer_observer_begin(zend_execute_data *ex) { if (!TXRG(enabled)) { return; @@ -49,7 +55,27 @@ static zend_observer_fcall_handlers tracer_observer(zend_execute_data *execute_d return (zend_observer_fcall_handlers){tracer_observer_begin, tracer_observer_end}; } +#else +static void (*_zend_execute_ex) (zend_execute_data *execute_data); +void tideways_xhprof_execute_ex (zend_execute_data *execute_data) { + zend_execute_data *real_execute_data = execute_data; + int is_profiling = 0; + + if (!TXRG(enabled)) { + _zend_execute_ex(execute_data TSRMLS_CC); + return; + } + + is_profiling = tracing_enter_frame_callgraph(NULL, real_execute_data TSRMLS_CC); + + _zend_execute_ex(execute_data TSRMLS_CC); + + if (is_profiling == 1 && TXRG(callgraph_frames)) { + tracing_exit_frame_callgraph(TSRMLS_C); + } +} +#endif PHP_FUNCTION(tideways_xhprof_enable) { @@ -97,7 +123,12 @@ PHP_MINIT_FUNCTION(tideways_xhprof) _zend_execute_internal = zend_execute_internal; zend_execute_internal = tideways_xhprof_execute_internal; +#if PHP_VERSION_ID >= 80000 zend_observer_fcall_register(tracer_observer); +#else + _zend_execute_ex = zend_execute_ex; + zend_execute_ex = tideways_xhprof_execute_ex; +#endif return SUCCESS; } diff --git a/tideways_xhprof.stub.php b/tideways_xhprof.stub.php index a60153a..ff94ab9 100644 --- a/tideways_xhprof.stub.php +++ b/tideways_xhprof.stub.php @@ -1,4 +1,15 @@ Date: Wed, 16 Dec 2020 20:49:22 +0100 Subject: [PATCH 55/64] Add PHP 8.0 to Buildkite Pipeline --- .buildkite/package_extension.sh | 2 +- .buildkite/pipeline.yml | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/.buildkite/package_extension.sh b/.buildkite/package_extension.sh index 9858466..ee4c468 100644 --- a/.buildkite/package_extension.sh +++ b/.buildkite/package_extension.sh @@ -7,7 +7,7 @@ BASEDIR=`dirname $BASEDIR` PACKAGENAME="tideways-xhprof" DESCRIPTION="tideways-xhprof is a modern XHProf fork built for PHP 7." EXTENSION="tideways_xhprof" -VERSIONS=( "7.0" "7.1" "7.2" "7.3" "7.4" "7.1-zts" "7.2-zts" "7.3-zts" "7.4-zts" ) +VERSIONS=( "7.0" "7.1" "7.2" "7.3" "7.4" "8.0" "7.1-zts" "7.2-zts" "7.3-zts" "7.4-zts" "8.0-zts" ) PACKAGES=( "deb" "rpm" ) ARCHITECTURE=`uname -m` ARCHITECTURE=${ARCHITECTURE/686/386} diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index 42ca63b..36b0bb4 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -2,6 +2,13 @@ env: NO_INTERACTION: 1 steps: + - label: ":php: 8.0 amd64" + command: ./.buildkite/build_extension.sh 8.0 + agents: + phpbuild: "no-debug" + queue: "build" + arch: "x86_64" + - label: ":php: 7.4 amd64" command: ./.buildkite/build_extension.sh 7.4 agents: @@ -37,6 +44,13 @@ steps: queue: "build" arch: "x86_64" + - label: ":php: 8.0-zts amd64" + command: ./.buildkite/build_extension.sh 8.0-zts + agents: + phpbuild: "no-debug" + queue: "build" + arch: "x86_64" + - label: ":php: 7.4-zts amd64" command: ./.buildkite/build_extension.sh 7.4-zts agents: From ab391914cd59b95ea1a6904eacad6960a696a50b Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Wed, 16 Dec 2020 20:51:53 +0100 Subject: [PATCH 56/64] Bump version to 5.0.4 --- php_tideways_xhprof.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php_tideways_xhprof.h b/php_tideways_xhprof.h index 6cebe1e..7a79cda 100644 --- a/php_tideways_xhprof.h +++ b/php_tideways_xhprof.h @@ -4,7 +4,7 @@ extern zend_module_entry tideways_xhprof_module_entry; #define phpext_tideways_xhprof_ptr &tideways_xhprof_module_entry -#define PHP_TIDEWAYS_XHPROF_VERSION "5.0.2" +#define PHP_TIDEWAYS_XHPROF_VERSION "5.0.4" #define TIDEWAYS_XHPROF_CALLGRAPH_COUNTER_SIZE 1024 #define TIDEWAYS_XHPROF_CALLGRAPH_SLOTS 8192 #define TIDEWAYS_XHPROF_CLOCK_CGT 0 From 9f1c1bfad492b52eae8d20bbe0fbde3a68f6786c Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Wed, 16 Dec 2020 21:21:31 +0100 Subject: [PATCH 57/64] Remove Travis CI [ci-skip] --- .travis.yml | 26 -------------------------- 1 file changed, 26 deletions(-) delete mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 1905b4f..0000000 --- a/.travis.yml +++ /dev/null @@ -1,26 +0,0 @@ -language: php -dist: precise - -notifications: - email: false - -sudo: false - -php: - - 7.0 - - 7.1 - - 7.2 - -env: - global: - - NO_INTERACTION=1 - - REPORT_EXIT_STATUS=1 - -before_script: - - phpize - - ./configure - - make - -script: make test - -after_failure: "cat tests/*.diff" From 7b86097dbddbb2000358b23825f54b156f49170c Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Fri, 29 Jan 2021 18:16:23 +0100 Subject: [PATCH 58/64] Prevent nesting of XHProf Profiler. --- tests/xhprof_009.phpt | 34 ++++++++++++++++++++++++++++++++++ tests/xhprof_010.phpt | 17 +++++++++++++++++ tideways_xhprof.c | 4 ++++ 3 files changed, 55 insertions(+) create mode 100644 tests/xhprof_009.phpt create mode 100644 tests/xhprof_010.phpt diff --git a/tests/xhprof_009.phpt b/tests/xhprof_009.phpt new file mode 100644 index 0000000..5c1c081 --- /dev/null +++ b/tests/xhprof_009.phpt @@ -0,0 +1,34 @@ +--TEST-- +Tideways: Nested Profiling Test +--FILE-- +bar : ct= 4; wt=*; +main() : ct= 1; wt=*; +main()==>foo : ct= 2; wt=*; +main()==>tideways_xhprof_disable : ct= 1; wt=*; +main()==>tideways_xhprof_enable : ct= 1; wt=*; diff --git a/tests/xhprof_010.phpt b/tests/xhprof_010.phpt new file mode 100644 index 0000000..1d42b55 --- /dev/null +++ b/tests/xhprof_010.phpt @@ -0,0 +1,17 @@ +--TEST-- +Tideways: Disabling without start first +--FILE-- + Date: Sat, 24 Apr 2021 16:18:22 +0200 Subject: [PATCH 59/64] Add PHP 8.0 to Appveyor for Windows builds. --- .appveyor.yml | 48 ++++++++++++++++++++++++++---------------------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index ec1f265..7ee65ad 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -8,11 +8,35 @@ environment: PHP_BUILD_CACHE_BASE_DIR: c:\build-cache PHP_BUILD_OBJ_DIR: c:\obj PHP_BUILD_CACHE_SDK_DIR: c:\build-cache\sdk - PHP_BUILD_SDK_BRANCH: php-sdk-2.2.0beta6 + PHP_BUILD_SDK_BRANCH: php-sdk-2.2.0 SDK_REMOTE: https://github.com/OSTC/php-sdk-binary-tools.git - SDK_BRANCH: php-sdk-2.2.0beta6 + SDK_BRANCH: php-sdk-2.2.0 matrix: + - PHP_VER: 8.0 + ARCHITECTURE: x64 + ZTS_STATE: enable + OPCACHE: yes + APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 + PHP_BUILD_CRT: vs16 + - PHP_VER: 8.0 + ARCHITECTURE: x64 + ZTS_STATE: disable + OPCACHE: yes + APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 + PHP_BUILD_CRT: vs16 + - PHP_VER: 8.0 + ARCHITECTURE: x86 + ZTS_STATE: enable + OPCACHE: yes + APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 + PHP_BUILD_CRT: vs16 + - PHP_VER: 8.0 + ARCHITECTURE: x86 + ZTS_STATE: disable + OPCACHE: yes + APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 + PHP_BUILD_CRT: vs16 - PHP_REL: 7.4 ARCHITECTURE: x64 ZTS_STATE: enable @@ -28,11 +52,6 @@ environment: ZTS_STATE: enable APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 PHP_BUILD_CRT: vc15 - - PHP_REL: 7.1 - ARCHITECTURE: x64 - ZTS_STATE: enable - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 - PHP_BUILD_CRT: vc14 - PHP_REL: 7.4 ARCHITECTURE: x64 ZTS_STATE: disable @@ -48,11 +67,6 @@ environment: ZTS_STATE: disable APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 PHP_BUILD_CRT: vc15 - - PHP_REL: 7.1 - ARCHITECTURE: x64 - ZTS_STATE: disable - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 - PHP_BUILD_CRT: vc14 - PHP_REL: 7.4 ARCHITECTURE: x86 ZTS_STATE: enable @@ -68,11 +82,6 @@ environment: ZTS_STATE: enable APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 PHP_BUILD_CRT: vc15 - - PHP_REL: 7.1 - ARCHITECTURE: x86 - ZTS_STATE: enable - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 - PHP_BUILD_CRT: vc14 - PHP_REL: 7.4 ARCHITECTURE: x86 ZTS_STATE: disable @@ -88,11 +97,6 @@ environment: ZTS_STATE: disable APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 PHP_BUILD_CRT: vc15 - - PHP_REL: 7.1 - ARCHITECTURE: x86 - ZTS_STATE: disable - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 - PHP_BUILD_CRT: vc14 install: - .appveyor\install.cmd From ef8f56c0759db0a708bce0742e8fea5f87b517ff Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Sat, 24 Apr 2021 18:56:42 +0200 Subject: [PATCH 60/64] Fix variable --- .appveyor.yml | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index 7ee65ad..15d6986 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -13,28 +13,24 @@ environment: SDK_BRANCH: php-sdk-2.2.0 matrix: - - PHP_VER: 8.0 + - PHP_REL: 8.0 ARCHITECTURE: x64 ZTS_STATE: enable - OPCACHE: yes APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 PHP_BUILD_CRT: vs16 - - PHP_VER: 8.0 + - PHP_REL: 8.0 ARCHITECTURE: x64 ZTS_STATE: disable - OPCACHE: yes APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 PHP_BUILD_CRT: vs16 - - PHP_VER: 8.0 + - PHP_REL: 8.0 ARCHITECTURE: x86 ZTS_STATE: enable - OPCACHE: yes APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 PHP_BUILD_CRT: vs16 - - PHP_VER: 8.0 + - PHP_REL: 8.0 ARCHITECTURE: x86 ZTS_STATE: disable - OPCACHE: yes APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 PHP_BUILD_CRT: vs16 - PHP_REL: 7.4 From 762c768cc1339303bf1d163bd57a91894534f5ac Mon Sep 17 00:00:00 2001 From: Fabian Franz Date: Sun, 17 Apr 2022 14:12:29 +0200 Subject: [PATCH 61/64] Issue #111: Fix timebase calculation --- tideways_xhprof.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tideways_xhprof.c b/tideways_xhprof.c index 66e55bd..1901a7d 100644 --- a/tideways_xhprof.c +++ b/tideways_xhprof.c @@ -144,8 +144,8 @@ PHP_MSHUTDOWN_FUNCTION(tideways_xhprof) PHP_RINIT_FUNCTION(tideways_xhprof) { - tracing_request_init(TSRMLS_C); TXRG(clock_source) = determine_clock_source(TXRG(clock_use_rdtsc)); + tracing_request_init(TSRMLS_C); CG(compiler_options) = CG(compiler_options) | ZEND_COMPILE_NO_BUILTINS; From b6c383f87112286d602104aae95500db57377814 Mon Sep 17 00:00:00 2001 From: Fabian Franz Date: Sun, 17 Apr 2022 14:12:47 +0200 Subject: [PATCH 62/64] Issue #113: TSC - Add support for aarch64 --- timer.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/timer.h b/timer.h index ece2bc0..1331abe 100644 --- a/timer.h +++ b/timer.h @@ -24,7 +24,7 @@ static int determine_clock_source(int clock_use_rdtsc) { return TIDEWAYS_XHPROF_CLOCK_TSC; #elif defined(__s390__) // Covers both s390 and s390x. return TIDEWAYS_XHPROF_CLOCK_TSC; -#elif defined(__ARM_ARCH) +#elif defined(__ARM_ARCH) && !defined(__aarch64__) return TIDEWAYS_XHPROF_CLOCK_GTOD; #elif defined(PHP_WIN32) return TIDEWAYS_XHPROF_CLOCK_QPC; @@ -108,6 +108,10 @@ static zend_always_inline uint64 time_milliseconds_tsc_query() uint64 val; asm volatile ("mftb %0" : "=r" (val)); return val; +#elif defined(__aarch64__) + uint64 val; + asm volatile("mrs %0, cntvct_el0" : "=r" (val)); + return val; #else return 0; #endif From 767fcd7f6a09954a77f48321ea3c7078de694c9b Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Fri, 6 Oct 2023 16:23:02 +0200 Subject: [PATCH 63/64] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 9e551bb..dd7ed24 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,6 @@ +> [!IMPORTANT] +> This PHP extension is archived in favor of the revitalized [PECL XHProf extension](https://pecl.php.net/package/xhprof) ([GitHub](https://github.com/longxinH/xhprof)) that is also using the modern PHP profiling abilities and performant timer APIs. + # Tideways XHProf Extension Home of the `tideways_xhprof` extension - a hierarchical Profiler for PHP. From 7877082945fcccced12676749676af1736a00f65 Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Fri, 6 Oct 2023 16:25:59 +0200 Subject: [PATCH 64/64] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index dd7ed24..9525eed 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ > [!IMPORTANT] -> This PHP extension is archived in favor of the revitalized [PECL XHProf extension](https://pecl.php.net/package/xhprof) ([GitHub](https://github.com/longxinH/xhprof)) that is also using the modern PHP profiling abilities and performant timer APIs. +> This XHProf PHP extension fork has outlived its purpose and is archived in favor of the revitalized [PECL XHProf extension](https://pecl.php.net/package/xhprof) ([GitHub](https://github.com/longxinH/xhprof)) that is also using the modern PHP profiling abilities and performant timer APIs. +> +> If you are looking for a full-stack Profiling Experience from Trigger through the Browser to modern UI [try out Tideways](https://tideways.com). # Tideways XHProf Extension