#include "pdumper.h"
#include "window.h"
+#include "dmpstruct.h"
/*
TODO:
- Compressed dump support.
- - Automate detection of struct layout changes.
-
*/
-
#ifdef HAVE_PDUMPER
+/* CHECK_STRUCTS being true makes the build break if we notice
+ changes to the source defining certain Lisp structures we dump. If
+ you change one of these structures, check that the pdumper code is
+ still valid and update the hash from the dmpstruct.h generated by
+ your new code. */
+#ifndef CHECK_STRUCTS
+# define CHECK_STRUCTS 1
+#endif
+
#ifdef __GNUC__
# pragma GCC diagnostic error "-Wconversion"
# pragma GCC diagnostic error "-Wshadow"
static dump_off
dump_cons (struct dump_context *ctx, const struct Lisp_Cons *cons)
{
+#if CHECK_STRUCTS && !defined (HASH_Lisp_Cons_F25EE3E42E)
+# error "Lisp_Cons changed. See CHECK_STRUCTS comment."
+#endif
struct Lisp_Cons out;
dump_object_start (ctx, GCALIGNMENT, &out, sizeof (out));
dump_field_lv (ctx, &out, cons, &cons->u.s.car, WEIGHT_STRONG);
INTERVAL tree,
dump_off parent_offset)
{
+#if CHECK_STRUCTS && !defined (HASH_interval_9110163DA0)
+# error "interval changed. See CHECK_STRUCTS comment."
+#endif
// TODO: output tree breadth-first?
struct interval out;
dump_object_start (ctx, GCALIGNMENT, &out, sizeof (out));
static dump_off
dump_string (struct dump_context *ctx, const struct Lisp_String *string)
{
+#if CHECK_STRUCTS && !defined (HASH_Lisp_Symbol_EB06C0D9EA)
+# error "Lisp_String changed. See CHECK_STRUCTS comment."
+#endif
/* If we have text properties, write them _after_ the string so that
at runtime, the prefetcher and cache will DTRT. (We access the
string before its properties.).
static dump_off
dump_marker (struct dump_context *ctx, const struct Lisp_Marker *marker)
{
+#if CHECK_STRUCTS && !defined (HASH_Lisp_Marker_3C824B47DB)
+# error "Lisp_Marker changed. See CHECK_STRUCTS comment."
+#endif
struct Lisp_Marker out;
dump_object_start (ctx, GCALIGNMENT, &out, sizeof (out));
DUMP_FIELD_COPY (&out, marker, type);
static dump_off
dump_overlay (struct dump_context *ctx, const struct Lisp_Overlay *overlay)
{
+#if CHECK_STRUCTS && !defined (HASH_Lisp_Overlay_CD6BBB22F3)
+# error "Lisp_Overlay changed. See CHECK_STRUCTS comment."
+#endif
struct Lisp_Overlay out;
dump_object_start (ctx, GCALIGNMENT, &out, sizeof (out));
DUMP_FIELD_COPY (&out, overlay, type);
dump_save_value (struct dump_context *ctx,
const struct Lisp_Save_Value *ptr)
{
+#if CHECK_STRUCTS && !defined (HASH_Lisp_Save_Value_9DB4B1A97C)
+# error "Lisp_Save_Value changed. See CHECK_STRUCTS comment."
+#endif
+#if CHECK_STRUCTS && !defined (HASH_Lisp_Save_Type_5202541810)
+# error "Lisp_Save_Type changed. See CHECK_STRUCTS comment."
+#endif
struct Lisp_Save_Value out;
dump_object_start (ctx, GCALIGNMENT, &out, sizeof (out));
DUMP_FIELD_COPY (&out, ptr, type);
dump_finalizer (struct dump_context *ctx,
const struct Lisp_Finalizer *finalizer)
{
+#if CHECK_STRUCTS && !defined (HASH_Lisp_Finalizer_514A6407BC)
+# error "Lisp_Finalizer changed. See CHECK_STRUCTS comment."
+#endif
struct Lisp_Finalizer out;
dump_object_start (ctx, GCALIGNMENT, &out, sizeof (out));
DUMP_FIELD_COPY (&out, finalizer, base.type);
static dump_off
dump_misc_any (struct dump_context *ctx, struct Lisp_Misc_Any *misc_any)
{
+#if CHECK_STRUCTS && !defined (HASH_Lisp_Misc_Any_8909174119)
+# error "Lisp_Misc_Any changed. See CHECK_STRUCTS comment."
+#endif
+#if CHECK_STRUCTS && !defined (HASH_Lisp_Misc_Type_FC6C8DD619)
+# error "Lisp_Misc_Type changed. See CHECK_STRUCTS comment."
+#endif
dump_off result;
switch (misc_any->type)
static dump_off
dump_float (struct dump_context *ctx, const struct Lisp_Float *lfloat)
{
+#if CHECK_STRUCTS && !defined (HASH_Lisp_Float_938B4A25C3)
+# error "Lisp_Float changed. See CHECK_STRUCTS comment."
+#endif
eassert (ctx->header.cold_start);
struct Lisp_Float out;
dump_object_start (ctx, GCALIGNMENT, &out, sizeof (out));
static dump_off
dump_fwd_int (struct dump_context *ctx, const struct Lisp_Intfwd *intfwd)
{
+#if CHECK_STRUCTS && !defined (HASH_Lisp_Intfwd_1225FA32CC)
+# error "Lisp_Intfwd changed. See CHECK_STRUCTS comment."
+#endif
dump_emacs_reloc_immediate_emacs_int (ctx, intfwd->intvar, *intfwd->intvar);
struct Lisp_Intfwd out;
dump_object_start (ctx, GCALIGNMENT, &out, sizeof (out));
static dump_off
dump_fwd_bool (struct dump_context *ctx, const struct Lisp_Boolfwd *boolfwd)
{
+#if CHECK_STRUCTS && !defined (HASH_Lisp_Boolfwd_0EA1C7ADCC)
+# error "Lisp_Boolfwd changed. See CHECK_STRUCTS comment."
+#endif
dump_emacs_reloc_immediate_bool (ctx, boolfwd->boolvar, *boolfwd->boolvar);
struct Lisp_Boolfwd out;
dump_object_start (ctx, GCALIGNMENT, &out, sizeof (out));
static dump_off
dump_fwd_obj (struct dump_context *ctx, const struct Lisp_Objfwd *objfwd)
{
+#if CHECK_STRUCTS && !defined (HASH_Lisp_Objfwd_45D3E513DC)
+# error "Lisp_Objfwd changed. See CHECK_STRUCTS comment."
+#endif
dump_emacs_reloc_to_dump_lv (ctx, objfwd->objvar, *objfwd->objvar);
struct Lisp_Objfwd out;
dump_object_start (ctx, GCALIGNMENT, &out, sizeof (out));
dump_fwd_buffer_obj (struct dump_context *ctx,
const struct Lisp_Buffer_Objfwd *buffer_objfwd)
{
+#if CHECK_STRUCTS && !defined (HASH_Lisp_Buffer_Objfwd_611EBD13FF)
+# error "Lisp_Buffer_Objfwd changed. See CHECK_STRUCTS comment."
+#endif
struct Lisp_Buffer_Objfwd out;
dump_object_start (ctx, GCALIGNMENT, &out, sizeof (out));
DUMP_FIELD_COPY (&out, buffer_objfwd, type);
dump_fwd_kboard_obj (struct dump_context *ctx,
const struct Lisp_Kboard_Objfwd *kboard_objfwd)
{
+#if CHECK_STRUCTS && !defined (HASH_Lisp_Kboard_Objfwd_CAA7E71069)
+# error "Lisp_Intfwd changed. See CHECK_STRUCTS comment."
+#endif
struct Lisp_Kboard_Objfwd out;
dump_object_start (ctx, GCALIGNMENT, &out, sizeof (out));
DUMP_FIELD_COPY (&out, kboard_objfwd, type);
static dump_off
dump_fwd (struct dump_context *ctx, union Lisp_Fwd *fwd)
{
+#if CHECK_STRUCTS && !defined (HASH_Lisp_Fwd_5227B18E87)
+# error "Lisp_Fwd changed. See CHECK_STRUCTS comment."
+#endif
+#if CHECK_STRUCTS && !defined (HASH_Lisp_Fwd_Type_9CBA6EE55E)
+# error "Lisp_Fwd_Type changed. See CHECK_STRUCTS comment."
+#endif
dump_off offset;
switch (XFWDTYPE (fwd))
dump_blv (struct dump_context *ctx,
const struct Lisp_Buffer_Local_Value *blv)
{
+#if CHECK_STRUCTS && !defined (HASH_Lisp_Buffer_Local_Value_2B3BD67753)
+# error "Lisp_Buffer_Local_Value changed. See CHECK_STRUCTS comment."
+#endif
struct Lisp_Buffer_Local_Value out;
dump_object_start (ctx, GCALIGNMENT, &out, sizeof (out));
DUMP_FIELD_COPY (&out, blv, local_if_set);
static dump_off
dump_symbol (struct dump_context *ctx, struct Lisp_Symbol *symbol)
{
+#if CHECK_STRUCTS && !defined (HASH_Lisp_Symbol_EB06C0D9EA)
+# error "Lisp_Symbol changed. See CHECK_STRUCTS comment."
+#endif
+#if CHECK_STRUCTS && !defined (HASH_symbol_redirect_ADB4F5B113)
+# error "symbol_redirect changed. See CHECK_STRUCTS comment."
+#endif
if (ctx->flags.defer_symbols)
{
/* Scan everything to which this symbol refers. */
struct dump_context *ctx,
const union vectorlike_header *header)
{
+#if CHECK_STRUCTS && !defined (HASH_vectorlike_header_8409709BAF)
+# error "vectorlike_header changed. See CHECK_STRUCTS comment."
+#endif
const struct Lisp_Vector *v = (const struct Lisp_Vector *) header;
ptrdiff_t size = header->size;
enum pvec_type pvectype = PSEUDOVECTOR_TYPE (v);
dump_hash_table (struct dump_context *ctx,
const struct Lisp_Hash_Table *hash_in)
{
+#if CHECK_STRUCTS && !defined (HASH_Lisp_Hash_Table_400EA529E0)
+# error "Lisp_Hash_Table changed. See CHECK_STRUCTS comment."
+#endif
bool is_stable = dump_hash_table_stable_p (hash_in);
/* If the hash table is likely to be modified in memory (either
because we need to rehash, and thus toggle hash->count, or
static dump_off
dump_buffer (struct dump_context *ctx, const struct buffer *in_buffer)
{
+#if CHECK_STRUCTS && !defined (HASH_buffer_E8695CAE09)
+# error "buffer changed. See CHECK_STRUCTS comment."
+#endif
struct buffer munged_buffer = *in_buffer;
struct buffer *buffer = &munged_buffer;
static dump_off
dump_bool_vector (struct dump_context *ctx, const struct Lisp_Vector *v)
{
+#if CHECK_STRUCTS && !defined (HASH_Lisp_Vector_2FA5E2F339)
+# error "Lisp_Vector changed. See CHECK_STRUCTS comment."
+#endif
/* No relocation needed, so we don't need dump_object_start. */
dump_align_output (ctx, GCALIGNMENT);
eassert (ctx->offset >= ctx->header.cold_start);
static dump_off
dump_subr (struct dump_context *ctx, const struct Lisp_Subr *subr)
{
+#if CHECK_STRUCTS && !defined (HASH_Lisp_Subr_B0DEEE4344)
+# error "Lisp_Subr changed. See CHECK_STRUCTS comment."
+#endif
struct Lisp_Subr out;
dump_object_start (ctx, GCALIGNMENT, &out, sizeof (out));
DUMP_FIELD_COPY (&out, subr, header.size);
static dump_off
dump_vectorlike (struct dump_context *ctx, const struct Lisp_Vector *v)
{
+#if CHECK_STRUCTS && !defined (HASH_pvec_type_69A8BF53D8)
+# error "pvec_type changed. See CHECK_STRUCTS comment."
+#endif
dump_off offset;
Lisp_Object lv = make_lisp_ptr ((void *) v, Lisp_Vectorlike);
switch (PSEUDOVECTOR_TYPE (v))
static dump_off
dump_object_1 (struct dump_context *ctx, Lisp_Object object)
{
+#if CHECK_STRUCTS && !defined (HASH_Lisp_Type_C9E246F617)
+# error "Lisp_Type changed. See CHECK_STRUCTS comment."
+#endif
#ifdef ENABLE_CHECKING
/* Vdead is extern only when ENABLE_CHECKING. */
eassert (!EQ (object, Vdead));
#endif
-
dump_off offset = dump_recall_object (ctx, object);
if (offset > 0)
{
static dump_off
dump_charset (struct dump_context *ctx, int cs_i)
{
+#if CHECK_STRUCTS && !defined (HASH_charset_317C49E291)
+# error "charset changed. See CHECK_STRUCTS comment."
+#endif
const struct charset *cs = charset_table + cs_i;
struct charset out;
dump_object_start (ctx, sizeof (int), &out, sizeof (out));