commit 52a6299a4846ead4f969c8574d61fe5785349fb8
parent 2e9710546f1320ff63abf641f4b321f5ebc5a5c9
Author: Andres Navarro <canavarro82@gmail.com>
Date: Fri, 25 Mar 2011 02:54:45 -0300
Added rudimentary mark balance checking. Bug is related to pairs remaining marked after equal?.
Diffstat:
3 files changed, 25 insertions(+), 0 deletions(-)
diff --git a/src/kgequalp.c b/src/kgequalp.c
@@ -165,6 +165,7 @@ inline bool equal_find2_mergep(klisp_State *K, TValue obj1, TValue obj2)
bool equal2p(klisp_State *K, TValue obj1, TValue obj2)
{
assert(ks_sisempty(K));
+ kcheck_mark_balance();
/* the stack has the elements to be compaired, always in pairs.
So the top should be compared with the one below, the third with
@@ -207,5 +208,6 @@ bool equal2p(klisp_State *K, TValue obj1, TValue obj2)
unmark_tree(K, obj1);
unmark_tree(K, obj2);
+ kcheck_mark_balance();
return result;
}
diff --git a/src/kobject.c b/src/kobject.c
@@ -6,6 +6,9 @@
#include "kobject.h"
+#ifdef KTRACK_MARKS
+int32_t kmark_count = 0;
+#endif
/*
** The global const variables
*/
diff --git a/src/kobject.h b/src/kobject.h
@@ -32,6 +32,9 @@
#include <stdint.h>
#include <stdio.h>
+/* This should be in a configuration .h */
+#define KTRACK_MARKS (true)
+
/*
** Union of all collectible objects
*/
@@ -462,10 +465,27 @@ extern char *ktv_names[];
/* Macros to handle marks */
/* NOTE: this only works in markable objects */
#define kget_mark(p_) (tv2mgch(p_)->mark)
+
+#ifdef KTRACK_MARKS
+int32_t kmark_count;
+#define kset_mark(p_, m_) ({ TValue new_mark_ = (m_); \
+ TValue obj_ = (p_); \
+ TValue old_mark_ = kget_mark(p_); \
+ if (kis_false(old_mark_) && !kis_false(new_mark_)) \
+ ++kmark_count; \
+ else if (kis_false(new_mark_) && !kis_false(old_mark_)) \
+ --kmark_count; \
+ kget_mark(obj_) = new_mark_; })
+#define kcheck_mark_balance() (assert(kmark_count == 0))
+#else
#define kset_mark(p_, m_) (kget_mark(p_) = (m_))
+#define kcheck_mark_balance()
+#endif
+
/* simple boolean #t mark */
#define kmark(p_) (kset_mark(p_, KTRUE))
#define kunmark(p_) (kset_mark(p_, KFALSE))
+
#define kis_marked(p_) (!kis_unmarked(p_))
#define kis_unmarked(p_) (tv_equal(kget_mark(p_), KFALSE))