summaryrefslogtreecommitdiff
path: root/gcc/ggc-common.c
diff options
context:
space:
mode:
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2002-04-28 20:40:39 +0000
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2002-04-28 20:40:39 +0000
commitec1d95967451333d9e9633d851a76ac98e7b526a (patch)
tree2d1cd87e9ec72ca228d2bfd87f65be0151f4781f /gcc/ggc-common.c
parent73c5fe4f950e8d8b4085d363dc143422807d7e9a (diff)
downloadgcc-ec1d95967451333d9e9633d851a76ac98e7b526a.tar.gz
* ggc-common.c (ggc_mark_rtx_children_1): Rename from...
(ggc_mark_rtx_children): New. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@52864 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ggc-common.c')
-rw-r--r--gcc/ggc-common.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/gcc/ggc-common.c b/gcc/ggc-common.c
index 6a6b69b3dd8..a90a01fb51a 100644
--- a/gcc/ggc-common.c
+++ b/gcc/ggc-common.c
@@ -38,6 +38,7 @@ static ggc_statistics *ggc_stats;
/* Trees that have been marked, but whose children still need marking. */
varray_type ggc_pending_trees;
+static void ggc_mark_rtx_children_1 PARAMS ((rtx));
static void ggc_mark_rtx_ptr PARAMS ((void *));
static void ggc_mark_tree_ptr PARAMS ((void *));
static void ggc_mark_rtx_varray_ptr PARAMS ((void *));
@@ -272,6 +273,43 @@ void
ggc_mark_rtx_children (r)
rtx r;
{
+ rtx i, last;
+
+ /* Special case the instruction chain. This is a data structure whose
+ chain length is potentially unbounded, and which contain references
+ within the chain (e.g. label_ref and insn_list). If do nothing here,
+ we risk blowing the stack recursing through a long chain of insns.
+
+ Combat this by marking all of the instructions in the chain before
+ marking the contents of those instructions. */
+
+ switch (GET_CODE (r))
+ {
+ case INSN:
+ case JUMP_INSN:
+ case CALL_INSN:
+ case NOTE:
+ case CODE_LABEL:
+ case BARRIER:
+ for (i = NEXT_INSN (r); ; i = NEXT_INSN (i))
+ if (! ggc_test_and_set_mark (i))
+ break;
+ last = i;
+
+ for (i = NEXT_INSN (r); i != last; i = NEXT_INSN (i))
+ ggc_mark_rtx_children_1 (i);
+
+ default:
+ break;
+ }
+
+ ggc_mark_rtx_children_1 (r);
+}
+
+static void
+ggc_mark_rtx_children_1 (r)
+ rtx r;
+{
const char *fmt;
int i;
rtx next_rtx;