This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PATCH to replace alloca with xmalloc
- To: gcc-patches at gcc dot gnu dot org
- Subject: PATCH to replace alloca with xmalloc
- From: "Mark P. Mitchell" <mark at codesourcery dot com>
- Date: Mon, 1 Nov 1999 15:50:02 -0700 (MST)
- Reply-to: mark at codesourcery dot com
While looking at memory usage issues, I went barking up the wrong tree
for a while thinking that alloca was burning us. It turns out that we
don't usually alloca *that* much memory. On the other hand, we really
shouldn't be using alloca for lots of reasons:
o It's not portable. The C version of alloca pretty much works, but
requires remembering to call `alloca (0)' in some circumstances.
o We do still use a lot of stack space. That's silly because when
we're done with it we can't reuse it as xmalloc space; we can end
up with lots of now-unused stack space, and be busily sbrk'ing to
get more space for the malloc arena.
o Because we alloca so much space, we silently set the user's stack
rlimit as high as possible. This is extremely rude behavior; only
the user, via the shell, should typically be messing with limits.
The idea of a soft limit is so that a user can rasise it if necessary,
not so that applications can.
Concretely, on RedHat Linux, this behavior is very dangerous. If
GCC ends up recursing infinitely (as it did after one of the GCC2
merge checkins yesterday), it will suck up all available memory,
causing daemons to crash, and the system to grind to a halt. (There
are default soft limits on stacksize, but not hard limits.) Yes,
having unlimited hard limits is probably not a good idea, but that
is how RedHat is set up. So, by mucking with the rlimit, we are
not only being rude to users, we're compromising system
robustness.
In order to safely remove the rlimit code, we need to remove the
uses of alloca.
So, I'm going to gradually pull out uses of alloca over the next few
weeks.
Here's one example.
--
Mark Mitchell mark@codesourcery.com
CodeSourcery, LLC http://www.codesourcery.com
Mon Nov 1 15:41:01 1999 Mark P. Mitchell <mark@codesourcery.com>
* combine.c (combine_instructions): Use xmalloc instead of alloca.
Index: combine.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/combine.c,v
retrieving revision 1.89
diff -c -p -r1.89 combine.c
*** combine.c 1999/11/01 01:11:19 1.89
--- combine.c 1999/11/01 22:20:19
*************** combine_instructions (f, nregs)
*** 499,523 ****
combine_max_regno = nregs;
! reg_nonzero_bits
! = (unsigned HOST_WIDE_INT *) alloca (nregs * sizeof (HOST_WIDE_INT));
! reg_sign_bit_copies = (char *) alloca (nregs * sizeof (char));
!
! bzero ((char *) reg_nonzero_bits, nregs * sizeof (HOST_WIDE_INT));
! bzero (reg_sign_bit_copies, nregs * sizeof (char));
!
! reg_last_death = (rtx *) alloca (nregs * sizeof (rtx));
! reg_last_set = (rtx *) alloca (nregs * sizeof (rtx));
! reg_last_set_value = (rtx *) alloca (nregs * sizeof (rtx));
! reg_last_set_table_tick = (int *) alloca (nregs * sizeof (int));
! reg_last_set_label = (int *) alloca (nregs * sizeof (int));
! reg_last_set_invalid = (char *) alloca (nregs * sizeof (char));
reg_last_set_mode
! = (enum machine_mode *) alloca (nregs * sizeof (enum machine_mode));
reg_last_set_nonzero_bits
! = (unsigned HOST_WIDE_INT *) alloca (nregs * sizeof (HOST_WIDE_INT));
reg_last_set_sign_bit_copies
! = (char *) alloca (nregs * sizeof (char));
init_reg_last_arrays ();
--- 499,520 ----
combine_max_regno = nregs;
! reg_nonzero_bits = ((unsigned HOST_WIDE_INT *)
! xcalloc (nregs, sizeof (unsigned HOST_WIDE_INT)));
! reg_sign_bit_copies = (char *) xcalloc (nregs, sizeof (char));
!
! reg_last_death = (rtx *) xmalloc (nregs * sizeof (rtx));
! reg_last_set = (rtx *) xmalloc (nregs * sizeof (rtx));
! reg_last_set_value = (rtx *) xmalloc (nregs * sizeof (rtx));
! reg_last_set_table_tick = (int *) xmalloc (nregs * sizeof (int));
! reg_last_set_label = (int *) xmalloc (nregs * sizeof (int));
! reg_last_set_invalid = (char *) xmalloc (nregs * sizeof (char));
reg_last_set_mode
! = (enum machine_mode *) xmalloc (nregs * sizeof (enum machine_mode));
reg_last_set_nonzero_bits
! = (unsigned HOST_WIDE_INT *) xmalloc (nregs * sizeof (HOST_WIDE_INT));
reg_last_set_sign_bit_copies
! = (char *) xmalloc (nregs * sizeof (char));
init_reg_last_arrays ();
*************** combine_instructions (f, nregs)
*** 529,535 ****
if (INSN_UID (insn) > i)
i = INSN_UID (insn);
! uid_cuid = (int *) alloca ((i + 1) * sizeof (int));
max_uid_cuid = i;
nonzero_bits_mode = mode_for_size (HOST_BITS_PER_WIDE_INT, MODE_INT, 0);
--- 526,532 ----
if (INSN_UID (insn) > i)
i = INSN_UID (insn);
! uid_cuid = (int *) xmalloc ((i + 1) * sizeof (int));
max_uid_cuid = i;
nonzero_bits_mode = mode_for_size (HOST_BITS_PER_WIDE_INT, MODE_INT, 0);
*************** combine_instructions (f, nregs)
*** 704,710 ****
--- 701,721 ----
update_life_info (refresh_blocks, UPDATE_LIFE_GLOBAL_RM_NOTES,
PROP_DEATH_NOTES);
}
+
+ /* Clean up. */
sbitmap_free (refresh_blocks);
+ free (reg_nonzero_bits);
+ free (reg_sign_bit_copies);
+ free (reg_last_death);
+ free (reg_last_set);
+ free (reg_last_set_value);
+ free (reg_last_set_table_tick);
+ free (reg_last_set_label);
+ free (reg_last_set_invalid);
+ free (reg_last_set_mode);
+ free (reg_last_set_nonzero_bits);
+ free (reg_last_set_sign_bit_copies);
+ free (uid_cuid);
total_attempts += combine_attempts;
total_merges += combine_merges;