Skip to content

Commit

Permalink
Add refcounting mechanism to xdebug_str to avoid copies
Browse files Browse the repository at this point in the history
  • Loading branch information
derickr committed Sep 10, 2024
1 parent 12adc63 commit 4198eb5
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 14 deletions.
4 changes: 2 additions & 2 deletions src/develop/stack.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| Xdebug |
+----------------------------------------------------------------------+
| Copyright (c) 2002-2023 Derick Rethans |
| Copyright (c) 2002-2024 Derick Rethans |
+----------------------------------------------------------------------+
| This source file is subject to version 1.01 of the Xdebug license, |
| that is bundled with this package in the file LICENSE, and is |
Expand Down Expand Up @@ -1273,7 +1273,7 @@ void xdebug_develop_throw_exception_hook(zend_object *exception, zval *file, zva
xdebug_append_error_footer(&displ_tmp_str, PG(html_errors));

php_printf("%s", displ_tmp_str.d);
xdebug_str_dtor(displ_tmp_str);
xdebug_str_destroy(&displ_tmp_str);
}
}
}
Expand Down
33 changes: 29 additions & 4 deletions src/lib/str.c
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,8 @@ xdebug_str *xdebug_str_new(void)
tmp->l = 0;
tmp->a = 0;
tmp->d = NULL;
tmp->rc = 1;
tmp->is_static = false;

return tmp;
}
Expand All @@ -206,9 +208,11 @@ xdebug_str *xdebug_str_create_from_char(char *c)
return xdebug_str_create(c, strlen(c));
}

xdebug_str *xdebug_str_copy(xdebug_str *orig)
xdebug_str *xdebug_str_clone(xdebug_str *orig)
{
xdebug_str *tmp = xdebug_str_new();
xdebug_str *tmp;

tmp = xdebug_str_new();

tmp->l = tmp->a = orig->l;
tmp->a++;
Expand All @@ -219,16 +223,37 @@ xdebug_str *xdebug_str_copy(xdebug_str *orig)
return tmp;
}

void xdebug_str_destroy(xdebug_str *s)
xdebug_str *xdebug_str_copy(xdebug_str *orig)
{
orig->rc++;

return orig;
}

static void xdebug_str_free_storage(xdebug_str *s)
{
if (s->d) {
xdfree(s->d);
}
}

void xdebug_str_destroy(xdebug_str *s)
{
assert(s->is_static);
xdebug_str_free_storage(s);
}

void xdebug_str_free(xdebug_str *s)
{
xdebug_str_destroy(s);
assert(!s->is_static);

s->rc--;

if (s->rc > 0) {
return;
}

xdebug_str_free_storage(s);
xdfree(s);
}

Expand Down
10 changes: 6 additions & 4 deletions src/lib/str.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| Xdebug |
+----------------------------------------------------------------------+
| Copyright (c) 2002-2020 Derick Rethans |
| Copyright (c) 2002-2024 Derick Rethans |
+----------------------------------------------------------------------+
| This source file is subject to version 1.01 of the Xdebug license, |
| that is bundled with this package in the file LICENSE, and is |
Expand All @@ -23,16 +23,17 @@

#include "mm.h"

#define XDEBUG_STR_INITIALIZER { 0, 0, NULL }
#define XDEBUG_STR_INITIALIZER { 0, 0, NULL, 0, true }
#define XDEBUG_STR_PREALLOC 1024
#define xdebug_str_dtor(str) xdfree(str.d)

#define XDEBUG_STR_WRAP_CHAR(v) (&((xdebug_str){strlen(v), strlen(v)+1, ((char*)(v))}))

typedef struct xdebug_str {
size_t l;
size_t a;
char *d;
size_t rc; // refcount
bool is_static; // not an allocated xdebug_str
} xdebug_str;

void xdebug_str_add(xdebug_str *xs, const char *str, int f);
Expand All @@ -52,7 +53,8 @@ xdebug_str *xdebug_str_new(void);
xdebug_str *xdebug_str_create_from_char(char *c);
#define xdebug_str_create_from_const_char(c) xdebug_str_create_from_char((char*) (c))
xdebug_str *xdebug_str_create(const char *c, size_t len);
xdebug_str *xdebug_str_copy(xdebug_str *orig);
xdebug_str *xdebug_str_copy(xdebug_str *orig); // uses refcounting
xdebug_str *xdebug_str_clone(xdebug_str *orig); // new allocation + copying data
void xdebug_str_destroy(xdebug_str *s);
void xdebug_str_free(xdebug_str *s);

Expand Down
4 changes: 2 additions & 2 deletions src/lib/var_export_xml.c
Original file line number Diff line number Diff line change
Expand Up @@ -798,8 +798,8 @@ xdebug_xml_node* xdebug_get_zval_value_xml_node_ex(xdebug_str *name, zval *val,
xdebug_str_add_literal(&tmp_formatted_name, "::");
xdebug_str_add_str(&tmp_formatted_name, name);

short_name = xdebug_str_copy(&tmp_formatted_name);
full_name = xdebug_str_copy(&tmp_formatted_name);
short_name = xdebug_str_clone(&tmp_formatted_name);
full_name = xdebug_str_clone(&tmp_formatted_name);

xdebug_str_destroy(&tmp_formatted_name);
} break;
Expand Down
4 changes: 2 additions & 2 deletions src/profiler/profiler.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| Xdebug |
+----------------------------------------------------------------------+
| Copyright (c) 2002-2023 Derick Rethans |
| Copyright (c) 2002-2024 Derick Rethans |
+----------------------------------------------------------------------+
| This source file is subject to version 1.01 of the Xdebug license, |
| that is bundled with this package in the file LICENSE, and is |
Expand Down Expand Up @@ -528,7 +528,7 @@ void xdebug_profiler_function_end(function_stack_entry *fse)
xdebug_str_addc(&file_buffer, '\n');

xdebug_file_write(file_buffer.d, sizeof(char), file_buffer.l, &XG_PROF(profile_file));
xdebug_str_dtor(file_buffer);
xdebug_str_destroy(&file_buffer);
}

void xdebug_profiler_free_function_details(function_stack_entry *fse)
Expand Down

0 comments on commit 4198eb5

Please sign in to comment.