Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deduplicate macros, Fix memleak in PHP < 5.4 #916

Merged
merged 2 commits into from Jul 25, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ext/http/response.c
Original file line number Diff line number Diff line change
Expand Up @@ -640,7 +640,7 @@ PHP_METHOD(Phalcon_Http_Response, appendContent){

PHALCON_OBS_VAR(_content);
phalcon_read_property_this(&_content, this_ptr, SL("_content"), PH_NOISY_CC);
PHALCON_ALLOC_ZVAL_MM(r0);
PHALCON_INIT_VAR(r0);
concat_function(r0, _content, content TSRMLS_CC);
phalcon_update_property_this(this_ptr, SL("_content"), r0 TSRMLS_CC);
RETURN_THIS();
Expand Down
4 changes: 2 additions & 2 deletions ext/kernel/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -259,12 +259,12 @@ extern int phalcon_fetch_parameters(int grow_stack, int num_args TSRMLS_DC, int
#define phalcon_is_iterable(var, array_hash, hash_pointer, duplicate, reverse) if (!phalcon_is_iterable_ex(var, array_hash, hash_pointer, duplicate, reverse)) { return; }

#define PHALCON_GET_FOREACH_VALUE(var) \
PHALCON_OBSERVE_VAR(var); \
PHALCON_OBS_NVAR(var); \
var = *hd; \
Z_ADDREF_P(var);

#define PHALCON_GET_HVALUE(var) \
PHALCON_OBSERVE_VAR(var); \
PHALCON_OBS_NVAR(var); \
var = *hd; \
Z_ADDREF_P(var);

Expand Down
16 changes: 3 additions & 13 deletions ext/kernel/memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ int PHALCON_FASTCALL phalcon_memory_restore_stack(TSRMLS_D) {
* Check for non freed hash key zvals, mark as null to avoid string freeing
*/
for (i = 0; i < active_memory->hash_pointer; ++i) {
assert(active_memory->hash_addresses[i] != NULL && *(active_memory->hash_addresses[i]) != NULL);
if (Z_REFCOUNT_PP(active_memory->hash_addresses[i]) <= 1) {
ZVAL_NULL(*active_memory->hash_addresses[i]);
} else {
Expand All @@ -174,7 +175,7 @@ int PHALCON_FASTCALL phalcon_memory_restore_stack(TSRMLS_D) {
* Traverse all zvals allocated, reduce the reference counting or free them
*/
for (i = 0; i < active_memory->pointer; ++i) {
if (likely(active_memory->addresses[i] != NULL)) {
if (likely(active_memory->addresses[i] != NULL && *(active_memory->addresses[i]) != NULL)) {
if (Z_REFCOUNT_PP(active_memory->addresses[i]) == 1) {
zval_ptr_dtor(active_memory->addresses[i]);
} else {
Expand Down Expand Up @@ -208,18 +209,6 @@ int PHALCON_FASTCALL phalcon_memory_restore_stack(TSRMLS_D) {
return SUCCESS;
}

/**
* Finishes memory stack when PHP throws a fatal error
*/
int PHALCON_FASTCALL phalcon_clean_shutdown_stack(TSRMLS_D)
{
#if !ZEND_DEBUG && PHP_VERSION_ID <= 50400
return phalcon_clean_restore_stack(TSRMLS_C);
#else
return SUCCESS;
#endif
}

static void phalcon_reallocate_memory(phalcon_memory_entry *frame)
{
void *buf = perealloc(frame->addresses, sizeof(zval **) * (frame->capacity + 16), unlikely(frame->prev == NULL));
Expand Down Expand Up @@ -260,6 +249,7 @@ static inline void phalcon_do_memory_observe(zval **var, phalcon_memory_entry *f
void PHALCON_FASTCALL phalcon_memory_observe(zval **var TSRMLS_DC) {

phalcon_do_memory_observe(var, PHALCON_GLOBAL(active_memory));
*var = NULL; /* In case an exception or error happens BEFORE the observed variable gets initialized */
}

/**
Expand Down
39 changes: 2 additions & 37 deletions ext/kernel/memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ extern void PHALCON_FASTCALL phalcon_memory_remove(zval **var TSRMLS_DC);
extern void PHALCON_FASTCALL phalcon_memory_alloc(zval **var TSRMLS_DC);
extern void PHALCON_FASTCALL phalcon_memory_alloc_pnull(zval **var TSRMLS_DC);

extern int PHALCON_FASTCALL phalcon_clean_shutdown_stack(TSRMLS_D);
extern int PHALCON_FASTCALL phalcon_clean_restore_stack(TSRMLS_D);

/* Virtual symbol tables */
Expand Down Expand Up @@ -131,10 +130,6 @@ extern void PHALCON_FASTCALL phalcon_copy_ctor(zval *destiny, zval *origin);
phalcon_memory_observe(&z TSRMLS_CC); \
}

#define PHALCON_ALLOC_ZVAL_MM(z) \
PHALCON_ALLOC_ZVAL(z); \
phalcon_memory_observe(&z TSRMLS_CC);

#define PHALCON_SEPARATE_ARRAY(a) \
{ \
if (Z_REFCOUNT_P(a) > 1) { \
Expand All @@ -147,38 +142,14 @@ extern void PHALCON_FASTCALL phalcon_copy_ctor(zval *destiny, zval *origin);
} \
}

#define PHALCON_SEPARATE(z) \
{ \
zval *orig_ptr = z; \
if (Z_REFCOUNT_P(orig_ptr) > 1) { \
Z_DELREF_P(orig_ptr); \
ALLOC_ZVAL(z); \
*z = *orig_ptr; \
zval_copy_ctor(z); \
Z_SET_REFCOUNT_P(z, 1); \
Z_UNSET_ISREF_P(z); \
} \
}

#define PHALCON_SEPARATE_NMO(z) \
{\
zval *orig_ptr = z;\
if (Z_REFCOUNT_P(orig_ptr) > 1) {\
Z_DELREF_P(orig_ptr);\
ALLOC_ZVAL(z);\
*z = *orig_ptr;\
zval_copy_ctor(z);\
Z_SET_REFCOUNT_P(z, 1);\
Z_UNSET_ISREF_P(z);\
}\
}
#define PHALCON_SEPARATE(z) SEPARATE_ZVAL(&z)

#define PHALCON_SEPARATE_PARAM(z) \
{\
zval *orig_ptr = z;\
if (Z_REFCOUNT_P(orig_ptr) > 1) {\
ALLOC_ZVAL(z);\
phalcon_memory_observe(&z TSRMLS_CC);\
ALLOC_ZVAL(z);\
*z = *orig_ptr;\
zval_copy_ctor(z);\
Z_SET_REFCOUNT_P(z, 1);\
Expand All @@ -197,9 +168,3 @@ extern void PHALCON_FASTCALL phalcon_copy_ctor(zval *destiny, zval *origin);
} \
}

#define PHALCON_OBSERVE_VAR(var) \
if (!var) { \
phalcon_memory_observe(&var TSRMLS_CC); \
} else { \
zval_ptr_dtor(&var); \
}
6 changes: 2 additions & 4 deletions ext/mvc/model/transaction.c
Original file line number Diff line number Diff line change
Expand Up @@ -350,16 +350,14 @@ PHP_METHOD(Phalcon_Mvc_Model_Transaction, setRollbackOnAbort){
PHP_METHOD(Phalcon_Mvc_Model_Transaction, isManaged){

zval *manager;
zval *r0 = NULL;

PHALCON_MM_GROW();

PHALCON_OBS_VAR(manager);
phalcon_read_property_this(&manager, this_ptr, SL("_manager"), PH_NOISY_CC);

PHALCON_ALLOC_ZVAL_MM(r0);
boolean_not_function(r0, manager TSRMLS_CC);
RETURN_NCTOR(r0);
boolean_not_function(return_value, manager TSRMLS_CC);
PHALCON_MM_RESTORE();
}

/**
Expand Down
1 change: 0 additions & 1 deletion ext/paginator/adapter/nativearray.c
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,6 @@ PHP_METHOD(Phalcon_Paginator_Adapter_NativeArray, getPaginate){
* Increase total_pages if wasn't integer
*/
if (!PHALCON_IS_EQUAL(total_pages, rounded_total)) {
PHALCON_SEPARATE_NMO(total_pages);
phalcon_increment(total_pages);
}

Expand Down
36 changes: 35 additions & 1 deletion ext/phalcon.c
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,36 @@ zend_class_entry *phalcon_exception_ce;

ZEND_DECLARE_MODULE_GLOBALS(phalcon)

static void (*old_error_cb)(int, const char *, const uint, const char *, va_list) = NULL;

static void phalcon_error_cb(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args)
{
TSRMLS_FETCH();
phalcon_clean_restore_stack(TSRMLS_C);

if (likely(old_error_cb != NULL)) {
/**
* va_copy() is __va_copy() in old gcc versions.
* According to the autoconf manual, using memcpy(&dst, &src, sizeof(va_list))
* gives maximum portability.
*/
#ifndef va_copy
# ifdef __va_copy
# define va_copy(dest, src) __va_copy((dest), (src))
# else
# define va_copy(dest, src) memcpy(&(dest), &(src), sizeof(va_list))
# endif
#endif
va_list copy;
va_copy(copy, args);
old_error_cb(type, error_filename, error_lineno, format, copy);
va_end(copy);
}
else {
exit(255);
}
}

static PHP_MINIT_FUNCTION(phalcon){

if (!spl_ce_Countable) {
Expand Down Expand Up @@ -678,12 +708,16 @@ static PHP_MINIT_FUNCTION(phalcon){
PHALCON_INIT(Phalcon_Events_Manager);
PHALCON_INIT(Phalcon_Events_Exception);

old_error_cb = zend_error_cb;
zend_error_cb = phalcon_error_cb;
return SUCCESS;
}


static PHP_MSHUTDOWN_FUNCTION(phalcon){

zend_error_cb = old_error_cb;

assert(PHALCON_GLOBAL(function_cache) == NULL);
assert(PHALCON_GLOBAL(orm).parser_cache == NULL);
assert(PHALCON_GLOBAL(orm).ast_cache == NULL);
Expand All @@ -701,7 +735,7 @@ static PHP_RINIT_FUNCTION(phalcon){
static PHP_RSHUTDOWN_FUNCTION(phalcon){

if (PHALCON_GLOBAL(start_memory) != NULL) {
phalcon_clean_shutdown_stack(TSRMLS_C);
phalcon_clean_restore_stack(TSRMLS_C);
}

if (PHALCON_GLOBAL(function_cache) != NULL) {
Expand Down
6 changes: 3 additions & 3 deletions ext/tag.c
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ PHP_METHOD(Phalcon_Tag, setDefault){
return;
}
}
PHALCON_OBSERVE_VAR(t0);
PHALCON_OBS_NVAR(t0);
phalcon_read_static_property(&t0, SL("phalcon\\tag"), SL("_displayValues") TSRMLS_CC);
if (Z_TYPE_P(t0) != IS_ARRAY) {
convert_to_array(t0);
Expand Down Expand Up @@ -1338,7 +1338,7 @@ PHP_METHOD(Phalcon_Tag, appendTitle){

PHALCON_OBS_VAR(t0);
phalcon_read_static_property(&t0, SL("phalcon\\tag"), SL("_documentTitle") TSRMLS_CC);
PHALCON_ALLOC_ZVAL_MM(r0);
PHALCON_INIT_VAR(r0);
concat_function(r0, t0, title TSRMLS_CC);
phalcon_update_static_property(SL("phalcon\\tag"), SL("_documentTitle"), r0 TSRMLS_CC);

Expand Down Expand Up @@ -1826,7 +1826,7 @@ PHP_METHOD(Phalcon_Tag, getDocType){

PHALCON_MM_GROW();

PHALCON_OBSERVE_VAR(doctype);
PHALCON_OBS_NVAR(doctype);
phalcon_read_static_property(&doctype, SL("phalcon\\tag"), SL("_documentType") TSRMLS_CC);

PHALCON_INIT_VAR(eol);
Expand Down