pike.git/
src/
las.c
Branch:
Tag:
Non-build tags
All tags
No tags
2000-09-13
2000-09-13 12:13:57 by Henrik Grubbström (Grubba) <grubba@grubba.org>
03ef8bc8870632ee70d096b39a2d75ff5d2856c8 (
191
lines) (+
156
/-
35
)
[
Show
|
Annotate
]
Branch:
7.9
debug_free_node() is no longer recursive.
Partially fixes [Bug
218 (#218)
].
Rev: src/las.c:1.211
5:
\*/ /**/ #include "global.h"
-
RCSID("$Id: las.c,v 1.
210
2000/09/
12
17
:
06
:
38
grubba Exp $");
+
RCSID("$Id: las.c,v 1.
211
2000/09/
13
12:
13
:
57
grubba Exp $");
#include "language.h" #include "interpret.h"
547:
} }
-
/* FIXME: Ought to use parent pointer to avoid recursion. */
+
void debug_free_node(node *n) { if(!n) return;
-
+
+
#ifdef SHARED_NODES
+
if (--n->refs) {
#ifdef PIKE_DEBUG if(l_flag>9) print_tree(n);
-
+
{
+
size_t hash;
+
if ((hash = hash_node(n)) != n->hash) {
+
fprintf(stderr, "Hash-value is bad 0x%08lx != 0x%08lx\n",
+
DO_NOT_WARN((unsigned long)hash),
+
DO_NOT_WARN((unsigned long)n->hash));
+
print_tree(n);
+
fatal("token:%d, car:%p cdr:%p file:%s line:%d\n",
+
n->token, _CAR(n), _CDR(n), n->current_file->str, n->line_number);
+
}
+
}
+
#endif /* PIKE_DEBUG */
+
return;
+
}
+
#endif /* SHARED_NODES */
+
+
n->parent = NULL;
+
+
do {
+
#ifdef PIKE_DEBUG
+
if(l_flag>9)
+
print_tree(n);
+
#ifdef SHARED_NODES { size_t hash;
570:
#endif /* SHARED_NODES */ #endif /* PIKE_DEBUG */
-
#ifdef
SHARED_NODES
-
if
(
dmalloc_touch(node *, n) &&
--
(n->refs)
)
{
-
return
;
+
dmalloc_touch(node *, n)
;
+
+
#if
defined(SHARED_NODES)
&&
defined
(
PIKE_DEBUG)
+
if (
n->refs) {
+
fatal("Node with refs left about to be killed: %8p\n", n)
;
} sub_node(dmalloc_touch(node *, n)); #endif /* SHARED_NODES */
-
fatal_check_c_stack(16384);
-
+
switch(n->token) { case USHRT_MAX:
588:
case F_CONSTANT: free_svalue(&(n->u.sval)); break;
+
}
-
default:
-
if(car_is_node(n))
free
_
node
(CAR(n))
;
-
if
(
cdr
_
is
_
node
(n))
free
_
node
(
CDR(
n)
)
;
+
if
(car_is_node(n))
{
+
/* Free CAR */
+
+
#ifdef SHARED
_
NODES
+
if
(
--_
CAR(n)
->refs
)
{
+
_CAR(n) = NULL
;
+
} else {
+
#endif /* SHARED
_
NODES */
+
_
CAR
(n)
->parent = n;
+
n = _CAR(n
)
;
+
_
CAR
(n
->parent
)
= NULL
;
+
continue;
+
#ifdef SHARED_NODES
}
-
n->token=USHRT_MAX;
+
#endif
/*
SHARED_NODES */
+
}
+
if (cdr_is_node(
n
)) {
+
/* Free CDR */
+
+
#ifdef SHARED_NODES
+
if (
-
-_CDR(n)-
>
refs) {
+
_CDR(n) = NULL;
+
} else {
+
#endif /* SHARED_NODES */
+
_CDR(n)->parent = n;
+
n = _CDR(n);
+
_CDR(n->parent) = NULL;
+
continue;
+
#ifdef SHARED_NODES
+
}
+
#endif /* SHARED_NODES */
+
}
+
backtrack:
+
while (n->parent && !cdr_is_node(n->parent)) {
+
/* Kill the node and backtrack */
+
node *dead = n;
+
+
#if defined(SHARED_NODES) && defined(PIKE_DEBUG)
+
if (dead->refs) {
+
fatal("Killed node %08p still has refs: %d\n", dead, dead->refs);
+
}
+
#endif /* SHARED_NODES && PIKE_DEBUG */
+
+
n = n->parent;
+
+
if(dead->type) free_string(dead->type);
+
if(dead->name) free_string(dead->name);
+
#ifdef PIKE_DEBUG
+
if(dead->current_file) free_string(dead->current_file);
+
#endif
+
dead->
token=USHRT_MAX;
+
really_free_node_s(dead);
+
}
+
if (n->parent && cdr_is_node(n->parent)) {
+
/* Kill node and jump to the sibling. */
+
node *dead = n;
+
+
#if defined(SHARED_NODES) && defined(PIKE_DEBUG)
+
if (dead->refs) {
+
fatal("Killed node %08p still has refs: %d\n", dead, dead->refs);
+
}
+
#endif /* SHARED_NODES && PIKE_DEBUG */
+
+
n = n->parent;
+
if(dead->type) free_string(dead->type);
+
if(dead->name) free_string(dead->name);
+
#ifdef PIKE_DEBUG
+
if(dead->current_file) free_string(dead->current_file);
+
#endif
+
dead->token=USHRT_MAX;
+
really_free_node_s(dead);
+
+
#ifdef SHARED_NODES
+
if (--_CDR(n)->refs) {
+
_CDR(n) = NULL;
+
goto backtrack;
+
} else {
+
#endif /* SHARED_NODES */
+
_CDR(n)->parent = n;
+
n = _CDR(n);
+
_CDR(n->parent) = NULL;
+
continue;
+
#ifdef SHARED_NODES
+
}
+
#endif /* SHARED_NODES */
+
}
+
+
/* Kill root node. */
+
+
#if defined(SHARED_NODES) && defined(PIKE_DEBUG)
+
if (n->refs) {
+
fatal("Killed node %08p still has refs: %d\n", n, n->refs);
+
}
+
#endif /* SHARE_NODES && PIKE_DEBUG */
+
if(n->type) free_string(n->type); if(n->name) free_string(n->name); #ifdef PIKE_DEBUG if(n->current_file) free_string(n->current_file); #endif
-
+
+
n->token=USHRT_MAX;
really_free_node_s(n);
-
+
break;
+
} while (n->parent);
}