Use one active frag and one obstack per frag chain:
* frags.c (frags): Variable deleted. (frag_alloc): New function. (frag_grow, frag_more, frag_variant, frag_now_fix, frag_append_1_char): Refer to frchain_now->frch_obstack instead of frags variable. (frag_new): Ditto. Verify that frch_last and frag_now match on entry and exit, and that old frag_now has non-zero type. Replace "know" uses with "assert". Use frag_alloc instead of mucking with obstack alignment. * frags.h (frags): Declaration deleted. * subsegs.h (struct frchain): Add new field frch_frag_now. * subsegs.c (frchains, dummy_frag, absolute_frchain): New static variables. (subsegs_begin): Initialize frchains obstack. Under gcc, don't give it any stricter alignment than frchainS structures need. Do not initialize frags obstack. Set frag_now to point to dummy_obstack. Initialize absolute_frchain. (subseg_set_rest): Save and restore frag_now in frch_frag_now field of frchainS. Don't create new frags on section switch, and use frag_alloc when creating a new frag chain. For absolute section, set frchain_now to absolute_frchain. Verify that frch_last and frag_now match on entry and exit. Initialize per-chain obstack, and under gcc, set required alignment to that needed by fragS structure. * write.c (chain_frchains_together_1): Verify fr_type is nonzero. In one test case of Mike's (i386-linux, over 300K lines of .s code with lots of stabs records), run time and memory use are reduced by about 1/3. Might introduce some problems in cases that use the frag obstacks in unusual ways. Test suite does pass for i386-linux and sparc-solaris targets though.
This commit is contained in:
parent
5a2846e3dd
commit
d19dcb6715
117
gas/subsegs.c
117
gas/subsegs.c
@ -29,6 +29,8 @@
|
||||
|
||||
frchainS *frchain_root, *frchain_now;
|
||||
|
||||
static struct obstack frchains;
|
||||
|
||||
#ifndef BFD_ASSEMBLER
|
||||
#ifdef MANY_SEGMENTS
|
||||
segment_info_type segment_info[SEG_MAXIMUM_ORDINAL];
|
||||
@ -67,6 +69,10 @@ static segment_info_type *und_seg_info;
|
||||
#endif /* BFD_ASSEMBLER */
|
||||
|
||||
static void subseg_set_rest PARAMS ((segT, subsegT));
|
||||
|
||||
static fragS dummy_frag;
|
||||
|
||||
static frchainS absolute_frchain;
|
||||
|
||||
void
|
||||
subsegs_begin ()
|
||||
@ -87,16 +93,17 @@ subsegs_begin ()
|
||||
know (SEG_MAXIMUM_ORDINAL == SEG_REGISTER);
|
||||
#endif
|
||||
|
||||
obstack_begin (&frchains, chunksize);
|
||||
#if __GNUC__ >= 2
|
||||
obstack_alignment_mask (&frchains) = __alignof__ (frchainS) - 1;
|
||||
#endif
|
||||
|
||||
frchain_root = NULL;
|
||||
frchain_now = NULL; /* Warn new_subseg() that we are booting. */
|
||||
/* Fake up 1st frag. It won't be used=> is ok if obstack...
|
||||
pads the end of it for alignment. */
|
||||
frag_now = (fragS *) obstack_alloc (&frags, SIZEOF_STRUCT_FRAG);
|
||||
memset (frag_now, 0, SIZEOF_STRUCT_FRAG);
|
||||
|
||||
frag_now = &dummy_frag;
|
||||
|
||||
#ifndef BFD_ASSEMBLER
|
||||
/* This 1st frag will not be in any frchain.
|
||||
We simply give subseg_new somewhere to scribble. */
|
||||
now_subseg = 42; /* Lie for 1st call to subseg_new. */
|
||||
#ifdef MANY_SEGMENTS
|
||||
{
|
||||
@ -117,6 +124,11 @@ subsegs_begin ()
|
||||
#endif /* ! MANY_SEGMENTS */
|
||||
#endif /* ! BFD_ASSEMBLER */
|
||||
|
||||
absolute_frchain.frch_seg = absolute_section;
|
||||
absolute_frchain.frch_subseg = 0;
|
||||
absolute_frchain.fix_root = absolute_frchain.fix_tail = 0;
|
||||
absolute_frchain.frch_frag_now = &zero_address_frag;
|
||||
absolute_frchain.frch_root = absolute_frchain.frch_last = &zero_address_frag;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -137,6 +149,9 @@ subseg_change (seg, subseg)
|
||||
now_seg = seg;
|
||||
now_subseg = subseg;
|
||||
|
||||
if (now_seg == absolute_section)
|
||||
return;
|
||||
|
||||
#ifdef BFD_ASSEMBLER
|
||||
{
|
||||
segment_info_type *seginfo;
|
||||
@ -195,26 +210,29 @@ subseg_set_rest (seg, subseg)
|
||||
register fragS *former_last_fragP;
|
||||
register fragS *new_fragP;
|
||||
|
||||
if (frag_now) /* If not bootstrapping. */
|
||||
{
|
||||
frag_now->fr_fix = frag_now_fix ();
|
||||
frag_wane (frag_now); /* Close off any frag in old subseg. */
|
||||
}
|
||||
/*
|
||||
* It would be nice to keep an obstack for each subsegment, if we swap
|
||||
* subsegments a lot. Hence we would have much fewer frag_wanes().
|
||||
*/
|
||||
{
|
||||
obstack_finish (&frags);
|
||||
/*
|
||||
* If we don't do the above, the next object we put on obstack frags
|
||||
* will appear to start at the fr_literal of the current frag.
|
||||
* Also, above ensures that the next object will begin on a
|
||||
* address that is aligned correctly for the engine that runs
|
||||
* this program.
|
||||
*/
|
||||
}
|
||||
mri_common_symbol = NULL;
|
||||
|
||||
if (frag_now && frchain_now)
|
||||
frchain_now->frch_frag_now = frag_now;
|
||||
|
||||
assert (frchain_now == 0
|
||||
|| now_seg == undefined_section
|
||||
|| now_seg == absolute_section
|
||||
|| frchain_now->frch_last == frag_now);
|
||||
|
||||
subseg_change (seg, (int) subseg);
|
||||
|
||||
if (seg == absolute_section)
|
||||
{
|
||||
frchain_now = &absolute_frchain;
|
||||
frag_now = &zero_address_frag;
|
||||
return;
|
||||
}
|
||||
|
||||
assert (frchain_now == 0
|
||||
|| now_seg == undefined_section
|
||||
|| frchain_now->frch_last == frag_now);
|
||||
|
||||
/*
|
||||
* Attempt to find or make a frchain for that sub seg.
|
||||
* Crawl along chain of frchainSs, begins @ frchain_root.
|
||||
@ -259,16 +277,22 @@ subseg_set_rest (seg, subseg)
|
||||
/*
|
||||
* This should be the only code that creates a frchainS.
|
||||
*/
|
||||
newP = (frchainS *) obstack_alloc (&frags, sizeof (frchainS));
|
||||
newP->frch_root = 0;
|
||||
extern fragS *frag_alloc ();
|
||||
newP = (frchainS *) obstack_alloc (&frchains, sizeof (frchainS));
|
||||
newP->frch_subseg = subseg;
|
||||
newP->frch_seg = seg;
|
||||
newP->frch_last = NULL;
|
||||
#ifdef BFD_ASSEMBLER
|
||||
newP->fix_root = NULL;
|
||||
newP->fix_tail = NULL;
|
||||
#endif
|
||||
obstack_begin (&newP->frch_obstack, 5000);
|
||||
#if __GNUC__ >= 2
|
||||
obstack_alignment_mask (&newP->frch_obstack) = __alignof__ (fragS) - 1;
|
||||
#endif
|
||||
newP->frch_frag_now = frag_alloc (&newP->frch_obstack);
|
||||
newP->frch_frag_now->fr_type = rs_fill;
|
||||
|
||||
newP->frch_root = newP->frch_last = newP->frch_frag_now;
|
||||
|
||||
*lastPP = newP;
|
||||
newP->frch_next = frcP; /* perhaps NULL */
|
||||
@ -278,37 +302,9 @@ subseg_set_rest (seg, subseg)
|
||||
* Here with frcP pointing to the frchainS for subseg.
|
||||
*/
|
||||
frchain_now = frcP;
|
||||
/*
|
||||
* Make a fresh frag for the subsegment.
|
||||
*/
|
||||
/* We expect this to happen on a correct boundary since it was
|
||||
proceeded by a obstack_done(). */
|
||||
tmp = obstack_alignment_mask (&frags); /* JF disable alignment */
|
||||
obstack_alignment_mask (&frags) = 0;
|
||||
frag_now = (fragS *) obstack_alloc (&frags, SIZEOF_STRUCT_FRAG);
|
||||
memset (frag_now, 0, SIZEOF_STRUCT_FRAG);
|
||||
obstack_alignment_mask (&frags) = tmp;
|
||||
/* But we want any more chars to come immediately after the
|
||||
structure we just made. */
|
||||
new_fragP = frag_now;
|
||||
new_fragP->fr_next = NULL;
|
||||
/*
|
||||
* Append new frag to current frchain.
|
||||
*/
|
||||
former_last_fragP = frcP->frch_last;
|
||||
if (former_last_fragP)
|
||||
{
|
||||
know (former_last_fragP->fr_next == NULL);
|
||||
know (frchain_now->frch_root);
|
||||
former_last_fragP->fr_next = new_fragP;
|
||||
}
|
||||
else
|
||||
{
|
||||
frcP->frch_root = new_fragP;
|
||||
}
|
||||
frcP->frch_last = new_fragP;
|
||||
frag_now = frcP->frch_frag_now;
|
||||
|
||||
mri_common_symbol = NULL;
|
||||
assert (frchain_now->frch_last == frag_now);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -379,7 +375,10 @@ subseg_set (seg, subseg) /* begin assembly for a new sub-segment */
|
||||
register subsegT subseg;
|
||||
{
|
||||
#ifndef MANY_SEGMENTS
|
||||
know (seg == SEG_DATA || seg == SEG_TEXT || seg == SEG_BSS);
|
||||
know (seg == SEG_DATA
|
||||
|| seg == SEG_TEXT
|
||||
|| seg == SEG_BSS
|
||||
|| seg == SEG_ABSOLUTE);
|
||||
#endif
|
||||
|
||||
if (seg != now_seg || subseg != now_subseg)
|
||||
|
Loading…
Reference in New Issue
Block a user