From ad929b4a244fe87b8ed10bf210f10569dda622ec Mon Sep 17 00:00:00 2001
From: David Soria Parra <dsp@php.net>
Date: Mon, 16 Nov 2009 03:10:25 +0000
Subject: [PATCH] Add object-create and object-destroy dtrace probe

---
 Zend/zend_API.c     | 18 ++++++++++++++++++
 Zend/zend_dtrace.c  |  2 +-
 Zend/zend_dtrace.d  |  2 ++
 Zend/zend_dtrace.h  |  1 +
 Zend/zend_objects.c | 17 +++++++++++++++++
 configure.in        |  2 +-
 6 files changed, 40 insertions(+), 2 deletions(-)

diff --git a/Zend/zend_API.c b/Zend/zend_API.c
index 9a018cffd5..d291fca97b 100644
--- a/Zend/zend_API.c
+++ b/Zend/zend_API.c
@@ -27,6 +27,7 @@
 #include "zend_constants.h"
 #include "zend_exceptions.h"
 #include "zend_closures.h"
+#include "zend_dtrace.h"
 
 #ifdef HAVE_STDARG_H
 #include <stdarg.h>
@@ -1351,6 +1352,23 @@ ZEND_API int _object_and_properties_init(zval *arg, zend_class_entry *class_type
 		zend_error(E_ERROR, "Cannot instantiate %s %v", what, class_type->name);
 	}
 
+#ifdef HAVE_DTRACE
+	if (DTRACE_OBJECT_CREATE_ENABLED()) {
+		char *s_classname, *filename;
+		int s_classname_len, lineno;
+
+		filename = dtrace_get_executed_filename(TSRMLS_C);
+		lineno = zend_get_executed_lineno(TSRMLS_C);
+		if (u_strlen(class_type->name.u) > 0) {
+			zend_unicode_to_string(ZEND_U_CONVERTER(UG(utf8_conv)), &s_classname, &s_classname_len, class_type->name.u, u_strlen(class_type->name.u) TSRMLS_CC);
+		}
+		DTRACE_OBJECT_CREATE(s_classname, filename, lineno);
+		if (s_classname != NULL) {
+			efree(s_classname);
+		}
+	}
+#endif /* HAVE_DTRACE */
+
 	zend_update_class_constants(class_type TSRMLS_CC);
 
 	Z_TYPE_P(arg) = IS_OBJECT;
diff --git a/Zend/zend_dtrace.c b/Zend/zend_dtrace.c
index d00dd970e0..4b074d5f8f 100644
--- a/Zend/zend_dtrace.c
+++ b/Zend/zend_dtrace.c
@@ -24,7 +24,7 @@
 
 #ifdef HAVE_DTRACE
 /* PHP DTrace probes {{{ */
-static inline char *dtrace_get_executed_filename(TSRMLS_D)
+ZEND_API char *dtrace_get_executed_filename(TSRMLS_D)
 {
 	if (EG(current_execute_data) && EG(current_execute_data)->op_array) {
 		return EG(current_execute_data)->op_array->filename;
diff --git a/Zend/zend_dtrace.d b/Zend/zend_dtrace.d
index 9b8f36518e..4f9059d191 100644
--- a/Zend/zend_dtrace.d
+++ b/Zend/zend_dtrace.d
@@ -30,6 +30,8 @@ provider php {
 	probe execute__return(char* request_file, int lineno);
 	probe function__entry(char* function_name, char* request_file, int lineno, char* classname, char* scope);
 	probe function__return(char* function_name, char* request_file, int lineno, char* classname, char* scope);
+  	probe object__create(char *classname, char* request_file, int lineno);
+  	probe object__destroy(char *classname, char* request_file, int lineno);
 };
 
 #pragma D attributes Evolving/Evolving/Common provider php provider
diff --git a/Zend/zend_dtrace.h b/Zend/zend_dtrace.h
index 65d19ef346..9d8219ba14 100644
--- a/Zend/zend_dtrace.h
+++ b/Zend/zend_dtrace.h
@@ -37,6 +37,7 @@ ZEND_API void (*zend_dtrace_execute_internal)(zend_execute_data *execute_data_pt
 ZEND_API zend_op_array *dtrace_compile_file(zend_file_handle *file_handle, int type TSRMLS_DC);
 ZEND_API void dtrace_execute(zend_op_array *op_array TSRMLS_DC);
 ZEND_API void dtrace_execute_internal(zend_execute_data *execute_data_ptr, int return_value_used TSRMLS_DC);
+ZEND_API char *dtrace_get_executed_filename(TSRMLS_D);
 #include <zend_dtrace_gen.h>
 
 #endif /* HAVE_DTRACE */
diff --git a/Zend/zend_objects.c b/Zend/zend_objects.c
index d6699a8589..4f5d489141 100644
--- a/Zend/zend_objects.c
+++ b/Zend/zend_objects.c
@@ -25,6 +25,7 @@
 #include "zend_API.h"
 #include "zend_interfaces.h"
 #include "zend_exceptions.h"
+#include "zend_dtrace.h"
 
 ZEND_API void zend_object_std_init(zend_object *object, zend_class_entry *ce TSRMLS_DC) /* {{{ */
 {
@@ -53,6 +54,22 @@ ZEND_API void zend_objects_destroy_object(zend_object *object, zend_object_handl
 {
 	zend_function *destructor = object ? object->ce->destructor : NULL;
 
+#ifdef HAVE_DTRACE
+	if (DTRACE_OBJECT_DESTROY_ENABLED()) {
+		char *s_classname, *filename;
+		int s_classname_len, lineno;
+
+		filename = dtrace_get_executed_filename(TSRMLS_C);
+		lineno = zend_get_executed_lineno(TSRMLS_C);
+		if (u_strlen(object->ce->name.u) > 0) {
+			zend_unicode_to_string(ZEND_U_CONVERTER(UG(utf8_conv)), &s_classname, &s_classname_len, object->ce->name.u, u_strlen(object->ce->name.u) TSRMLS_CC);
+		}
+		DTRACE_OBJECT_DESTROY(s_classname, filename, lineno);
+		if (s_classname != NULL) {
+			efree(s_classname);
+		}
+	}
+#endif /* HAVE_DTRACE */
 	if (destructor) {
 		zval *obj;
 		zend_object_store_bucket *obj_bucket;
diff --git a/configure.in b/configure.in
index 4e20143a0a..7c15f25b3d 100644
--- a/configure.in
+++ b/configure.in
@@ -896,7 +896,7 @@ dnl ## this needs to be done before SAPI configureation
 if test "$PHP_DTRACE" = "yes"; then
   AC_CHECK_HEADERS([sys/sdt.h],
     [PHP_ADD_DTRACE([Zend/zend_dtrace.d], [main/main.c, Zend/zend_API.c \
-       Zend/zend_execute.c Zend/zend_exceptions.c \
+       Zend/zend_execute.c Zend/zend_exceptions.c Zend/zend_objects.c \
        Zend/zend_dtrace.c Zend/zend.c])
      PHP_INIT_DTRACE([Zend/zend_dtrace.d], [Zend/zend_dtrace_gen.h])
      AC_DEFINE(HAVE_DTRACE, 1, [Whether to enable DTrace support])],
-- 
2.40.0