Also fix a GC bug, where symbols with position were not being disabled.
* src/lisp.h (union Lisp_Function): New type.
(struct Lisp_Subr): Add fields normal_function, BC_function, and next.
(DEFUN): Setup all three function fields to the subr (BC_function is still a
dummy), set field next to NULL.
* src/alloc.c (Fgarbage_collect): Move the binding of
Qsymbols_with_pos_enabled to garbage_collect_1 so that it gets bound when GC
is invoked via garbage_collect.
* src/lread.c (subr_ptr, using_BC_subrs): New static variables.
(Fswitch_to_BC_subrs, Fswitch_to_normal_subrs): New defuns.
(defsubr): Chain new subr to previous using field next and variable subr_ptr.
(init_lread): Initialise subr_ptr to NULL.
(syms_of_lread): Create subrs Sswitch_to_BC_subrs and Sswitch_to_normal_subrs.
* src/pdumper.c (dump_subr): Enhance to dump struct Lisp_Subr's new fields.
Update the expected value of HASH_Lisp_Subr_xxxxxxxxxx.
(dump_vectorlike): Also dump PVEC_SYMBOL_WITH_POSes.
struct timespec start;
byte_ct tot_before = 0;
+ specbind (Qsymbols_with_pos_enabled, Qnil);
+
eassert (weak_hash_tables == NULL);
/* Can't GC if pure storage overflowed because we can't determine
if something is a pure object or not. */
if (pure_bytes_used_before_overflow)
- return false;
+ {
+ unbind_to (count, Qnil);
+ return false;
+ }
/* Record this function, so it appears on the profiler's backtraces. */
record_in_backtrace (QAutomatic_GC, 0, 0);
malloc_probe (min (swept, SIZE_MAX));
}
+ unbind_to (count, Qnil);
return true;
}
See Info node `(elisp)Garbage Collection'. */)
(void)
{
- ptrdiff_t count = SPECPDL_INDEX ();
struct gcstat gcst;
- specbind (Qsymbols_with_pos_enabled, Qnil);
if (!garbage_collect_1 (&gcst))
- return unbind_to (count, Qnil);
+ return Qnil;
Lisp_Object total[] = {
list4 (Qconses, make_fixnum (sizeof (struct Lisp_Cons)),
make_int ((mallinfo ().fordblks + 1023) >> 10)),
#endif
};
- return unbind_to (count, CALLMANY (Flist, total));
+ return CALLMANY (Flist, total);
}
/* Mark Lisp objects in glyph matrix MATRIX. Currently the
It is generated by the DEFUN macro only.
defsubr makes it into a Lisp object. */
-struct Lisp_Subr
- {
- union vectorlike_header header;
- union {
+union Lisp_Function {
Lisp_Object (*a0) (void);
Lisp_Object (*a1) (Lisp_Object);
Lisp_Object (*a2) (Lisp_Object, Lisp_Object);
Lisp_Object (*a8) (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object);
Lisp_Object (*aUNEVALLED) (Lisp_Object args);
Lisp_Object (*aMANY) (ptrdiff_t, Lisp_Object *);
- } function;
+};
+
+struct Lisp_Subr
+ {
+ union vectorlike_header header;
+ union Lisp_Function function;
+ union Lisp_Function normal_function;
+ union Lisp_Function BC_function;
short min_args, max_args;
const char *symbol_name;
const char *intspec;
+ union Aligned_Lisp_Subr *next;
EMACS_INT doc;
} GCALIGNED_STRUCT;
union Aligned_Lisp_Subr
static union Aligned_Lisp_Subr sname = \
{{{ PVEC_SUBR << PSEUDOVECTOR_AREA_BITS }, \
{ .a ## maxargs = fnname }, \
- minargs, maxargs, lname, intspec, 0}}; \
+ { .a ## maxargs = fnname }, \
+ { .a ## maxargs = /* BC_ ## */fnname }, \
+ minargs, maxargs, lname, intspec, \
+ NULL, \
+ 0}}; \
Lisp_Object fnname
/* defsubr (Sname);
}
\f
+static union Aligned_Lisp_Subr *subr_ptr = NULL;
+static bool using_BC_subrs = false;
+
+DEFUN ("switch-to-BC-subrs", Fswitch_to_BC_subrs, Sswitch_to_BC_subrs, 0, 0, 0,
+ doc: /* Switch all subrs to using the byte compiler versions. */)
+ (void)
+{
+ union Aligned_Lisp_Subr *ptr = subr_ptr;
+ if (!using_BC_subrs)
+ while (ptr)
+ {
+ ptr->s.function = ptr->s.BC_function;
+ ptr = ptr->s.next;
+ }
+ using_BC_subrs = true;
+ return Qnil;
+}
+
+DEFUN ("switch-to-normal-subrs", Fswitch_to_normal_subrs,
+ Sswitch_to_normal_subrs, 0, 0, 0,
+ doc: /* Switch all subrs to using the normal versions. */)
+ (void)
+{
+ union Aligned_Lisp_Subr *ptr = subr_ptr;
+ if (using_BC_subrs)
+ while (ptr)
+ {
+ ptr->s.function = ptr->s.normal_function;
+ ptr = ptr->s.next;
+ }
+ using_BC_subrs = false;
+ return Qnil;
+}
+
void
defsubr (union Aligned_Lisp_Subr *aname)
{
XSETPVECTYPE (sname, PVEC_SUBR);
XSETSUBR (tem, sname);
set_symbol_function (sym, tem);
+ sname->next = subr_ptr;
+ subr_ptr = aname;
}
#ifdef NOTDEF /* Use fset in subr.el now! */
if (NILP (Vpurify_flag) && !NILP (Ffboundp (Qfile_truename)))
Vsource_directory = call1 (Qfile_truename, Vsource_directory);
+ subr_ptr = NULL;
+
/* First, set Vload_path. */
/* Ignore EMACSLOADPATH when dumping. */
defsubr (&Sintern);
defsubr (&Sintern_soft);
defsubr (&Sunintern);
+ defsubr (&Sswitch_to_BC_subrs);
+ defsubr (&Sswitch_to_normal_subrs);
defsubr (&Sget_load_suffixes);
defsubr (&Sload);
defsubr (&Seval_buffer);
static dump_off
dump_subr (struct dump_context *ctx, const struct Lisp_Subr *subr)
{
-#if CHECK_STRUCTS && !defined (HASH_Lisp_Subr_594AB72B54)
+#if CHECK_STRUCTS && !defined (HASH_Lisp_Subr_6AE56C1912)
# error "Lisp_Subr changed. See CHECK_STRUCTS comment."
#endif
struct Lisp_Subr out;
dump_object_start (ctx, &out, sizeof (out));
DUMP_FIELD_COPY (&out, subr, header.size);
dump_field_emacs_ptr (ctx, &out, subr, &subr->function.a0);
+ dump_field_emacs_ptr (ctx, &out, subr, &subr->normal_function.a0);
+ dump_field_emacs_ptr (ctx, &out, subr, &subr->BC_function.a0);
DUMP_FIELD_COPY (&out, subr, min_args);
DUMP_FIELD_COPY (&out, subr, max_args);
dump_field_emacs_ptr (ctx, &out, subr, &subr->symbol_name);
dump_field_emacs_ptr (ctx, &out, subr, &subr->intspec);
+ dump_field_emacs_ptr (ctx, &out, subr, &subr->next);
DUMP_FIELD_COPY (&out, subr, doc);
return dump_object_finish (ctx, &out, sizeof (out));
}
Lisp_Object lv,
dump_off offset)
{
-#if CHECK_STRUCTS && !defined (HASH_pvec_type_549C833A54)
+#if CHECK_STRUCTS && !defined (HASH_pvec_type_3C7A719153)
# error "pvec_type changed. See CHECK_STRUCTS comment."
#endif
const struct Lisp_Vector *v = XVECTOR (lv);
case PVEC_CHAR_TABLE:
case PVEC_SUB_CHAR_TABLE:
case PVEC_RECORD:
+ case PVEC_SYMBOL_WITH_POS:
offset = dump_vectorlike_generic (ctx, &v->header);
break;
case PVEC_BOOL_VECTOR: