This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: PCH assumes there is no information before the object
On Mon, 8 Sep 2003, Geoff Keating wrote:
> Daniel Berlin <dberlin@dberlin.org> writes:
>
> > On Mon, 8 Sep 2003, Geoff Keating wrote:
> >
> > > Daniel Berlin <dberlin@dberlin.org> writes:
> > >
> > > > I'm implementing PCH for the new zone collector in my spare
> > > > time, and currently, PCH assumes it can simply read in the object at the correct
> > > > address, and that will put everything right.
> > > > This may work for ggc-page, but it won't work for ggc-simple (which has
> > > > no PCH implemented), or the new zone collector. This is because both put
> > > > information before ggc allocated objects.
> > > >
> > > > There seems to be no way to support this without significantly modifying
> > > > the PCH reading/writing machinery, which assumes it only has to write the
> > > > object out.
> > > >
> > > > I can't even just make a table of the object header info, and write it
> > > > out in the zone collector, because we'd still need to put it before each
> > > > object, which we have no hook for.
> > > >
> > > > Geoff, have i missed something?
> > >
> > > I believe you can easily handle this using the current machinery.
> > > ggc_pch_write_object would write out the header for the current
> > > object, then the object, then enough padding to go up to the place
> > > where it will write out the next object's header. You do not have to
> > > keep the file pointer positioned at the place where the next object's
> > > data will be.
> > >
> > > Of course, ggc_pch_count_object and ggc_pch_alloc_object will have to
> > > allow for the header in their calculations.
> >
> > Not only that, but because strings are not really ggc allocated, you have
> > to be able to distinguish between strings and non-strings.
> >
> > This means passing the damn note_ptr_fn down to some more functions.
>
> Can't you just pretend that strings *are* ggc allocated?
No, because they don't have the header!
> You don't
> really want to be freeing any PCH memory anyway, that just makes pages
> dirty.
Of course. I'll probably throw PCH stuff in a seperate zone that is
uncollected.
*** ggc-simple.c.~1.47.~ Mon Jul 21 14:53:43 2003
--- ggc-simple.c Mon Sep 8 17:10:13 2003
***************
*** 486,539 ****
SCALE(G.allocated), LABEL(G.allocated));
}
struct ggc_pch_data *
init_ggc_pch (void)
{
! sorry ("Generating PCH files is not supported when using ggc-simple.c");
! /* It could be supported, but the code is not yet written. */
! return NULL;
}
void
! ggc_pch_count_object (struct ggc_pch_data *d ATTRIBUTE_UNUSED,
! void *x ATTRIBUTE_UNUSED,
! size_t size ATTRIBUTE_UNUSED)
{
}
size_t
! ggc_pch_total_size (struct ggc_pch_data *d ATTRIBUTE_UNUSED)
{
! return 0;
}
void
! ggc_pch_this_base (struct ggc_pch_data *d ATTRIBUTE_UNUSED,
! void *base ATTRIBUTE_UNUSED)
{
}
char *
! ggc_pch_alloc_object (struct ggc_pch_data *d ATTRIBUTE_UNUSED,
! void *x ATTRIBUTE_UNUSED,
! size_t size ATTRIBUTE_UNUSED)
{
! return NULL;
}
void
ggc_pch_prepare_write (struct ggc_pch_data *d ATTRIBUTE_UNUSED,
! FILE * f ATTRIBUTE_UNUSED)
{
}
void
! ggc_pch_write_object (struct ggc_pch_data *d ATTRIBUTE_UNUSED,
! FILE *f ATTRIBUTE_UNUSED, void *x ATTRIBUTE_UNUSED,
! void *newx ATTRIBUTE_UNUSED,
! size_t size ATTRIBUTE_UNUSED)
{
}
void
--- 486,560 ----
SCALE(G.allocated), LABEL(G.allocated));
}
+ /* The biggest alignment required. */
+ #define PADDING(x) (((size_t)-(x)) % offsetof (struct ggc_mem, u))
+
+ struct ggc_pch_data
+ {
+ size_t allocated;
+ size_t written;
+ };
+
struct ggc_pch_data *
init_ggc_pch (void)
{
! return xcalloc (sizeof (struct ggc_pch_data), 1);
}
void
! ggc_pch_count_object (struct ggc_pch_data *d, void *x, size_t size)
{
+ d->allocated += size + offsetof (struct ggc_mem, u) + PADDING(size);
}
size_t
! ggc_pch_total_size (struct ggc_pch_data *d)
{
! return d->allocated;
}
void
! ggc_pch_this_base (struct ggc_pch_data *d, void *base)
{
+ d->written = (size_t) base;
}
char *
! ggc_pch_alloc_object (struct ggc_pch_data *d, void *x ATTRIBUTE_UNUSED,
! size_t size)
{
! char *result;
! d->written += offsetof (struct ggc_mem, u);
! result = (char *) written;
! d->written += size + PADDING (size);
}
void
ggc_pch_prepare_write (struct ggc_pch_data *d ATTRIBUTE_UNUSED,
! FILE *f ATTRIBUTE_UNUSED)
{
+ /* Nothing to do. */
}
void
! ggc_pch_write_object (struct ggc_pch_data *d ATTRIBUTE_UNUSED,
! FILE *f, void *x_p, void *newx ATTRIBUTE_UNUSED,
! size_t size)
{
+ static const char zeros [sizeof (struct max_alignment)];
+
+ char *x = (char *)x_p - offsetof (struct ggc_mem, u);
+
+ /* FIXME: There needs to be some code here to relocate the 'sub' fields
+ of the ggc_mem, which should form a new tree in PTR_KEY(newx) order.
+ We would construct the tree in ggc_pch_alloc_object.
+ It should be rooted at the first element written out. */
+
+ if (fwrite (x, offsetof (struct ggc_mem, u), 1, f) != 1
+ || fwrite (x_p, size, 1, f) != 1
+ || fwrite (zeros, PADDING (size), 1, f) != 1)
+ fatal_error ("can't write PCH file: %m");
}
void
***************
*** 543,551 ****
}
void
! ggc_pch_read (FILE *f ATTRIBUTE_UNUSED, void *addr ATTRIBUTE_UNUSED)
{
! /* This should be impossible, since we won't generate any valid PCH
! files for this configuration. */
! abort ();
}
--- 564,571 ----
}
void
! ggc_pch_read (FILE *f ATTRIBUTE_UNUSED, void *addr)
{
! /* The first element read will be at the root of the tree. */
! G.root = addr;
}
--
- Geoffrey Keating <geoffk@geoffk.org>