unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: Pip Cet <pipcet@gmail.com>
To: Paul Eggert <eggert@cs.ucla.edu>
Cc: 36649@debbugs.gnu.org
Subject: bug#36649: 27.0.50; pure space and pdumper
Date: Sun, 21 Jul 2019 12:53:21 +0000	[thread overview]
Message-ID: <CAOqdjBdF0JgDJj1H5hc=XBnOxJc=dyCMb=+OhbVh1Tb6fiVnCQ@mail.gmail.com> (raw)
In-Reply-To: <bc2d941d-fdd9-0c99-3da0-953bd1f132fe@cs.ucla.edu>

[-- Attachment #1: Type: text/plain, Size: 1418 bytes --]

On Sun, Jul 21, 2019 at 7:29 AM Paul Eggert <eggert@cs.ucla.edu> wrote:
> > I think we have the following options:
> >
> > 1. remove pure space entirely
> > 2. remove pure space, but leave PURE_P and CHECK_IMPURE as reminders
> > to do something about it.
> > 3. move pure space to BSS
> > 4. xmalloc() pure space, only when needed
> > 5. modify pdumper to mark and recognize pure objects
> > 6. do nothing and accept the wastefulness
>
> I suggest (1), since it will result in simpler code.

I think we should do (1) for now, since it simplifies the code enough
to introduce immutable objects "soon"; but until that time, we waste
more space on duplicate objects that we no longer know to be
immutable, so cannot merge.

I'm attaching a first patch that removes pure space, pinned symbols,
pinned objects, but keeps Fpurecopy (for hash consing), and doesn't
touch the Lisp codebase.

With this patch, I have:
-rw-r--r-- 2 pip pip 11102752 Jul 21 12:28 src/emacs.pdmp

before:
-rw-r--r-- 2 pip pip 10381464 Jul 21 12:29 src/emacs.pdmp

However, the (uncompressed) disk space requirement is about the same,
since the emacs binary is a lot smaller.

I think the next steps are to look at actual live memory usage (which
will increase due to the non-duplication of objects, but not by an
entire megabyte because some of that data is relocations), and GC
performance (no prediction here, it could improve or deteriorate).

[-- Attachment #2: 0001-Remove-pure-space.patch --]
[-- Type: text/x-patch, Size: 84651 bytes --]

From 92ed5b8604363fe546aacd7a4bd3856f8ea56a4b Mon Sep 17 00:00:00 2001
From: Pip Cet <pipcet@gmail.com>
Date: Sun, 21 Jul 2019 12:51:21 +0000
Subject: [PATCH] Remove pure space

* src/lisp.h (struct Lisp_Symbol): Remove `pinned' flag.
(build_pure_c_string, pure_listn): Remove.  All calls removed.
* src/puresize.h: Remove file.
* src/fns.c (Fmake_hash_table): Ignore `:purecopy' argument.
* src/doc.c (store_function_docstring): Remove comment about pure
space.
* src/data.c (pure_write_error): Remove.  All calls removed.
* src/conf_post.h (SYSTEM_PURESIZE_EXTRA): Remove.
* src/fns.c (make_hash_table): Drop `purecopy' argument.  All
callers changed to remove argument.
* src/alloc.c (make_pure_string, make_pure_c_string, pure_cons)
(pure_list): Remove.  All calls removed.
(check_pure_size): Remove.  All calls removed.
(cons_listn): Simplify.
(Fmake_byte_code): Remove comment about pure space.
(pointer_align): Move definition to avoid warning.
* src/Makefile.in: Remove comment about pure space.
---
 src/Makefile.in    |   2 -
 src/alloc.c        | 537 ++++-----------------------------------------
 src/buffer.c       |  16 +-
 src/callint.c      |   8 +-
 src/category.c     |   4 +-
 src/coding.c       |  18 +-
 src/conf_post.h    |  33 ---
 src/data.c         |  29 +--
 src/dbusbind.c     |   4 +-
 src/deps.mk        |  10 +-
 src/doc.c          |   3 -
 src/emacs-module.c |  26 +--
 src/emacs.c        |   3 -
 src/eval.c         |  12 +-
 src/fileio.c       |  20 +-
 src/fns.c          |  29 +--
 src/fontset.c      |   4 +-
 src/frame.c        |   2 +-
 src/intervals.c    |   2 -
 src/json.c         |   4 +-
 src/keyboard.c     |   8 +-
 src/keymap.c       |  33 ++-
 src/lisp.h         |  41 +---
 src/lread.c        |  45 ++--
 src/pdumper.c      |   2 -
 src/print.c        |   6 -
 src/process.c      |   4 +-
 src/profiler.c     |   2 +-
 src/puresize.h     | 115 ----------
 src/search.c       |  12 +-
 src/syntax.c       |   4 +-
 src/w32fns.c       |   4 +-
 src/xdisp.c        |  20 +-
 src/xfaces.c       |   2 +-
 src/xfns.c         |   9 +-
 src/xterm.c        |   4 +-
 36 files changed, 182 insertions(+), 895 deletions(-)

diff --git a/src/Makefile.in b/src/Makefile.in
index fd05a45df5..d6e489d822 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -403,8 +403,6 @@ .c.o:
 .m.o:
 	$(AM_V_CC)$(CC) -c $(CPPFLAGS) $(ALL_OBJC_CFLAGS) $(PROFILING_CFLAGS) $<
 
-## lastfile must follow all files whose initialized data areas should
-## be dumped as pure by dump-emacs.
 base_obj = dispnew.o frame.o scroll.o xdisp.o menu.o $(XMENU_OBJ) window.o \
 	charset.o coding.o category.o ccl.o character.o chartab.o bidi.o \
 	$(CM_OBJ) term.o terminal.o xfaces.o $(XOBJ) $(GTK_OBJ) $(DBUS_OBJ) \
diff --git a/src/alloc.c b/src/alloc.c
index 1718ce0faf..df8b1caf4e 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -35,7 +35,6 @@ Copyright (C) 1985-1986, 1988, 1993-1995, 1997-2019 Free Software
 #include "dispextern.h"
 #include "intervals.h"
 #include "ptr-bounds.h"
-#include "puresize.h"
 #include "sheap.h"
 #include "sysstdio.h"
 #include "systime.h"
@@ -265,33 +264,6 @@ #define GC_DEFAULT_THRESHOLD (100000 * word_size)
 
 #define SPARE_MEMORY (1 << 14)
 
-/* Initialize it to a nonzero value to force it into data space
-   (rather than bss space).  That way unexec will remap it into text
-   space (pure), on some systems.  We have not implemented the
-   remapping on more recent systems because this is less important
-   nowadays than in the days of small memories and timesharing.  */
-
-EMACS_INT pure[(PURESIZE + sizeof (EMACS_INT) - 1) / sizeof (EMACS_INT)] = {1,};
-#define PUREBEG (char *) pure
-
-/* Pointer to the pure area, and its size.  */
-
-static char *purebeg;
-static ptrdiff_t pure_size;
-
-/* Number of bytes of pure storage used before pure storage overflowed.
-   If this is non-zero, this implies that an overflow occurred.  */
-
-static ptrdiff_t pure_bytes_used_before_overflow;
-
-/* Index in pure at which next pure Lisp object will be allocated..  */
-
-static ptrdiff_t pure_bytes_used_lisp;
-
-/* Number of bytes allocated for non-Lisp objects in pure storage.  */
-
-static ptrdiff_t pure_bytes_used_non_lisp;
-
 /* If positive, garbage collection is inhibited.  Otherwise, zero.  */
 
 static intptr_t garbage_collection_inhibited;
@@ -366,7 +338,6 @@ no_sanitize_memcpy (void *dest, void const *src, size_t size)
 static void unchain_finalizer (struct Lisp_Finalizer *);
 static void mark_terminals (void);
 static void gc_sweep (void);
-static Lisp_Object make_pure_vector (ptrdiff_t);
 static void mark_buffer (struct buffer *);
 
 #if !defined REL_ALLOC || defined SYSTEM_MALLOC || defined HYBRID_MALLOC
@@ -509,16 +480,6 @@ #define MEM_NIL &mem_z
 
 int staticidx;
 
-static void *pure_alloc (size_t, int);
-
-/* Return PTR rounded up to the next multiple of ALIGNMENT.  */
-
-static void *
-pointer_align (void *ptr, int alignment)
-{
-  return (void *) ROUNDUP ((uintptr_t) ptr, alignment);
-}
-
 /* Extract the pointer hidden within O.  */
 
 static ATTRIBUTE_NO_SANITIZE_UNDEFINED void *
@@ -1002,6 +963,15 @@ verify (POWER_OF_2 (BLOCK_ALIGN));
 # elif !defined HYBRID_MALLOC && defined HAVE_POSIX_MEMALIGN
 #  define USE_ALIGNED_ALLOC 1
 #  define aligned_alloc my_aligned_alloc /* Avoid collision with lisp.h.  */
+
+/* Return PTR rounded up to the next multiple of ALIGNMENT.  */
+
+static void *
+pointer_align (void *ptr, int alignment)
+{
+  return (void *) ROUNDUP ((uintptr_t) ptr, alignment);
+}
+
 static void *
 aligned_alloc (size_t alignment, size_t size)
 {
@@ -1605,9 +1575,9 @@ #define GC_STRING_EXTRA GC_STRING_OVERRUN_COOKIE_SIZE
 static void
 init_strings (void)
 {
-  empty_unibyte_string = make_pure_string ("", 0, 0, 0);
+  empty_unibyte_string = make_specified_string ("", 0, 0, false);
   staticpro (&empty_unibyte_string);
-  empty_multibyte_string = make_pure_string ("", 0, 0, 1);
+  empty_multibyte_string = make_specified_string ("", 0, 0, true);
   staticpro (&empty_multibyte_string);
 }
 
@@ -1625,7 +1595,7 @@ string_bytes (struct Lisp_String *s)
   ptrdiff_t nbytes =
     (s->u.s.size_byte < 0 ? s->u.s.size & ~ARRAY_MARK_FLAG : s->u.s.size_byte);
 
-  if (!PURE_P (s) && !pdumper_object_p (s) && s->u.s.data
+  if (!pdumper_object_p (s) && s->u.s.data
       && nbytes != SDATA_NBYTES (SDATA_OF_STRING (s)))
     emacs_abort ();
   return nbytes;
@@ -2302,7 +2272,7 @@ make_specified_string (const char *contents,
 {
   Lisp_Object val;
 
-  if (nchars < 0)
+  if (nchars <= 0)
     {
       if (multibyte)
 	nchars = multibyte_chars_in_text ((const unsigned char *) contents,
@@ -2326,8 +2296,6 @@ make_uninit_string (EMACS_INT length)
 {
   Lisp_Object val;
 
-  if (!length)
-    return empty_unibyte_string;
   val = make_uninit_multibyte_string (length, length);
   STRING_SET_UNIBYTE (val);
   return val;
@@ -2345,8 +2313,6 @@ make_uninit_multibyte_string (EMACS_INT nchars, EMACS_INT nbytes)
 
   if (nchars < 0)
     emacs_abort ();
-  if (!nbytes)
-    return empty_multibyte_string;
 
   s = allocate_string ();
   s->u.s.intervals = NULL;
@@ -2636,17 +2602,16 @@ list5 (Lisp_Object arg1, Lisp_Object arg2, Lisp_Object arg3, Lisp_Object arg4,
 }
 
 /* Make a list of COUNT Lisp_Objects, where ARG is the first one.
-   Use CONS to construct the pairs.  AP has any remaining args.  */
+   AP has any remaining args.  */
 static Lisp_Object
-cons_listn (ptrdiff_t count, Lisp_Object arg,
-	    Lisp_Object (*cons) (Lisp_Object, Lisp_Object), va_list ap)
+cons_listn (ptrdiff_t count, Lisp_Object arg, va_list ap)
 {
   eassume (0 < count);
-  Lisp_Object val = cons (arg, Qnil);
+  Lisp_Object val = Fcons (arg, Qnil);
   Lisp_Object tail = val;
   for (ptrdiff_t i = 1; i < count; i++)
     {
-      Lisp_Object elem = cons (va_arg (ap, Lisp_Object), Qnil);
+      Lisp_Object elem = Fcons (va_arg (ap, Lisp_Object), Qnil);
       XSETCDR (tail, elem);
       tail = elem;
     }
@@ -2659,18 +2624,7 @@ listn (ptrdiff_t count, Lisp_Object arg1, ...)
 {
   va_list ap;
   va_start (ap, arg1);
-  Lisp_Object val = cons_listn (count, arg1, Fcons, ap);
-  va_end (ap);
-  return val;
-}
-
-/* Make a pure list of COUNT Lisp_Objects, where ARG1 is the first one.  */
-Lisp_Object
-pure_listn (ptrdiff_t count, Lisp_Object arg1, ...)
-{
-  va_list ap;
-  va_start (ap, arg1);
-  Lisp_Object val = cons_listn (count, arg1, pure_cons, ap);
+  Lisp_Object val = cons_listn (count, arg1, ap);
   va_end (ap);
   return val;
 }
@@ -2836,7 +2790,7 @@ large_vector_vec (struct large_vector *p)
 
 static struct large_vector *large_vectors;
 
-/* The only vector with 0 slots, allocated from pure space.  */
+/* The only vector with 0 slots.  */
 
 Lisp_Object zero_vector;
 
@@ -2874,15 +2828,6 @@ allocate_vector_block (void)
   return block;
 }
 
-/* Called once to initialize vector allocation.  */
-
-static void
-init_vectors (void)
-{
-  zero_vector = make_pure_vector (0);
-  staticpro (&zero_vector);
-}
-
 /* Allocate vector from a vector block.  */
 
 static struct Lisp_Vector *
@@ -3200,6 +3145,17 @@ allocate_vector (ptrdiff_t len)
 }
 
 
+/* Called once to initialize vector allocation.  */
+
+static void
+init_vectors (void)
+{
+  zero_vector =
+    make_lisp_ptr (allocate_vectorlike (sizeof (struct Lisp_Vector)),
+		   Lisp_Vectorlike);
+  staticpro (&zero_vector);
+}
+
 /* Allocate other vector-like structures.  */
 
 struct Lisp_Vector *
@@ -3354,14 +3310,6 @@ and (optional) INTERACTIVE-SPEC.
   Lisp_Object val = make_uninit_vector (nargs);
   struct Lisp_Vector *p = XVECTOR (val);
 
-  /* We used to purecopy everything here, if purify-flag was set.  This worked
-     OK for Emacs-23, but with Emacs-24's lexical binding code, it can be
-     dangerous, since make-byte-code is used during execution to build
-     closures, so any closure built during the preload phase would end up
-     copied into pure space, including its free variables, which is sometimes
-     just wasteful and other times plainly wrong (e.g. those free vars may want
-     to be setcar'd).  */
-
   memcpy (p->contents, args, nargs * sizeof *args);
   make_byte_code (p);
   XSETCOMPILED (val, p);
@@ -3393,13 +3341,6 @@ #define SYMBOL_BLOCK_SIZE \
 
 static struct symbol_block *symbol_block;
 static int symbol_block_index = SYMBOL_BLOCK_SIZE;
-/* Pointer to the first symbol_block that contains pinned symbols.
-   Tests for 24.4 showed that at dump-time, Emacs contains about 15K symbols,
-   10K of which are pinned (and all but 250 of them are interned in obarray),
-   whereas a "typical session" has in the order of 30K symbols.
-   `symbol_block_pinned' lets mark_pinned_symbols scan only 15K symbols rather
-   than 30K to find the 10K symbols we need to mark.  */
-static struct symbol_block *symbol_block_pinned;
 
 /* List of free symbols.  */
 
@@ -3425,7 +3366,6 @@ init_symbol (Lisp_Object val, Lisp_Object name)
   p->u.s.interned = SYMBOL_UNINTERNED;
   p->u.s.trapped_write = SYMBOL_UNTRAPPED_WRITE;
   p->u.s.declared_special = false;
-  p->u.s.pinned = false;
 }
 
 DEFUN ("make-symbol", Fmake_symbol, Smake_symbol, 1, 1, 0,
@@ -5021,8 +4961,6 @@ valid_lisp_object_p (Lisp_Object obj)
     return 1;
 
   void *p = XPNTR (obj);
-  if (PURE_P (p))
-    return 1;
 
   if (SYMBOLP (obj) && c_symbol_p (p))
     return ((char *) p - (char *) lispsym) % sizeof lispsym[0] == 0;
@@ -5079,287 +5017,8 @@ valid_lisp_object_p (Lisp_Object obj)
   return 0;
 }
 
-/***********************************************************************
-		       Pure Storage Management
- ***********************************************************************/
-
-/* Allocate room for SIZE bytes from pure Lisp storage and return a
-   pointer to it.  TYPE is the Lisp type for which the memory is
-   allocated.  TYPE < 0 means it's not used for a Lisp object,
-   and that the result should have an alignment of -TYPE.  */
-
-static void *
-pure_alloc (size_t size, int type)
-{
-  void *result;
-
- again:
-  if (type >= 0)
-    {
-      /* Allocate space for a Lisp object from the beginning of the free
-	 space with taking account of alignment.  */
-      result = pointer_align (purebeg + pure_bytes_used_lisp, LISP_ALIGNMENT);
-      pure_bytes_used_lisp = ((char *)result - (char *)purebeg) + size;
-    }
-  else
-    {
-      /* Allocate space for a non-Lisp object from the end of the free
-	 space.  */
-      ptrdiff_t unaligned_non_lisp = pure_bytes_used_non_lisp + size;
-      char *unaligned = purebeg + pure_size - unaligned_non_lisp;
-      int decr = (intptr_t) unaligned & (-1 - type);
-      pure_bytes_used_non_lisp = unaligned_non_lisp + decr;
-      result = unaligned - decr;
-    }
-  pure_bytes_used = pure_bytes_used_lisp + pure_bytes_used_non_lisp;
-
-  if (pure_bytes_used <= pure_size)
-    return ptr_bounds_clip (result, size);
-
-  /* Don't allocate a large amount here,
-     because it might get mmap'd and then its address
-     might not be usable.  */
-  purebeg = xmalloc (10000);
-  pure_size = 10000;
-  pure_bytes_used_before_overflow += pure_bytes_used - size;
-  pure_bytes_used = 0;
-  pure_bytes_used_lisp = pure_bytes_used_non_lisp = 0;
-
-  /* Can't GC if pure storage overflowed because we can't determine
-     if something is a pure object or not.  */
-  garbage_collection_inhibited++;
-  goto again;
-}
-
-
-#ifdef HAVE_UNEXEC
-
-/* Print a warning if PURESIZE is too small.  */
-
-void
-check_pure_size (void)
-{
-  if (pure_bytes_used_before_overflow)
-    message (("emacs:0:Pure Lisp storage overflow (approx. %"pI"d"
-	      " bytes needed)"),
-	     pure_bytes_used + pure_bytes_used_before_overflow);
-}
-#endif
-
-
-/* Find the byte sequence {DATA[0], ..., DATA[NBYTES-1], '\0'} from
-   the non-Lisp data pool of the pure storage, and return its start
-   address.  Return NULL if not found.  */
-
-static char *
-find_string_data_in_pure (const char *data, ptrdiff_t nbytes)
-{
-  int i;
-  ptrdiff_t skip, bm_skip[256], last_char_skip, infinity, start, start_max;
-  const unsigned char *p;
-  char *non_lisp_beg;
-
-  if (pure_bytes_used_non_lisp <= nbytes)
-    return NULL;
-
-  /* Set up the Boyer-Moore table.  */
-  skip = nbytes + 1;
-  for (i = 0; i < 256; i++)
-    bm_skip[i] = skip;
-
-  p = (const unsigned char *) data;
-  while (--skip > 0)
-    bm_skip[*p++] = skip;
-
-  last_char_skip = bm_skip['\0'];
-
-  non_lisp_beg = purebeg + pure_size - pure_bytes_used_non_lisp;
-  start_max = pure_bytes_used_non_lisp - (nbytes + 1);
-
-  /* See the comments in the function `boyer_moore' (search.c) for the
-     use of `infinity'.  */
-  infinity = pure_bytes_used_non_lisp + 1;
-  bm_skip['\0'] = infinity;
-
-  p = (const unsigned char *) non_lisp_beg + nbytes;
-  start = 0;
-  do
-    {
-      /* Check the last character (== '\0').  */
-      do
-	{
-	  start += bm_skip[*(p + start)];
-	}
-      while (start <= start_max);
-
-      if (start < infinity)
-	/* Couldn't find the last character.  */
-	return NULL;
-
-      /* No less than `infinity' means we could find the last
-	 character at `p[start - infinity]'.  */
-      start -= infinity;
-
-      /* Check the remaining characters.  */
-      if (memcmp (data, non_lisp_beg + start, nbytes) == 0)
-	/* Found.  */
-	return ptr_bounds_clip (non_lisp_beg + start, nbytes + 1);
-
-      start += last_char_skip;
-    }
-  while (start <= start_max);
-
-  return NULL;
-}
-
-
-/* Return a string allocated in pure space.  DATA is a buffer holding
-   NCHARS characters, and NBYTES bytes of string data.  MULTIBYTE
-   means make the result string multibyte.
-
-   Must get an error if pure storage is full, since if it cannot hold
-   a large string it may be able to hold conses that point to that
-   string; then the string is not protected from gc.  */
-
-Lisp_Object
-make_pure_string (const char *data,
-		  ptrdiff_t nchars, ptrdiff_t nbytes, bool multibyte)
-{
-  Lisp_Object string;
-  struct Lisp_String *s = pure_alloc (sizeof *s, Lisp_String);
-  s->u.s.data = (unsigned char *) find_string_data_in_pure (data, nbytes);
-  if (s->u.s.data == NULL)
-    {
-      s->u.s.data = pure_alloc (nbytes + 1, -1);
-      memcpy (s->u.s.data, data, nbytes);
-      s->u.s.data[nbytes] = '\0';
-    }
-  s->u.s.size = nchars;
-  s->u.s.size_byte = multibyte ? nbytes : -1;
-  s->u.s.intervals = NULL;
-  XSETSTRING (string, s);
-  return string;
-}
-
-/* Return a string allocated in pure space.  Do not
-   allocate the string data, just point to DATA.  */
-
-Lisp_Object
-make_pure_c_string (const char *data, ptrdiff_t nchars)
-{
-  Lisp_Object string;
-  struct Lisp_String *s = pure_alloc (sizeof *s, Lisp_String);
-  s->u.s.size = nchars;
-  s->u.s.size_byte = -2;
-  s->u.s.data = (unsigned char *) data;
-  s->u.s.intervals = NULL;
-  XSETSTRING (string, s);
-  return string;
-}
-
-static Lisp_Object purecopy (Lisp_Object obj);
-
-/* Return a cons allocated from pure space.  Give it pure copies
-   of CAR as car and CDR as cdr.  */
-
-Lisp_Object
-pure_cons (Lisp_Object car, Lisp_Object cdr)
-{
-  Lisp_Object new;
-  struct Lisp_Cons *p = pure_alloc (sizeof *p, Lisp_Cons);
-  XSETCONS (new, p);
-  XSETCAR (new, purecopy (car));
-  XSETCDR (new, purecopy (cdr));
-  return new;
-}
-
-
-/* Value is a float object with value NUM allocated from pure space.  */
-
-static Lisp_Object
-make_pure_float (double num)
-{
-  Lisp_Object new;
-  struct Lisp_Float *p = pure_alloc (sizeof *p, Lisp_Float);
-  XSETFLOAT (new, p);
-  XFLOAT_INIT (new, num);
-  return new;
-}
-
-/* Value is a bignum object with value VALUE allocated from pure
-   space.  */
-
-static Lisp_Object
-make_pure_bignum (struct Lisp_Bignum *value)
-{
-  size_t i, nlimbs = mpz_size (value->value);
-  size_t nbytes = nlimbs * sizeof (mp_limb_t);
-  mp_limb_t *pure_limbs;
-  mp_size_t new_size;
-
-  struct Lisp_Bignum *b = pure_alloc (sizeof *b, Lisp_Vectorlike);
-  XSETPVECTYPESIZE (b, PVEC_BIGNUM, 0, VECSIZE (struct Lisp_Bignum));
-
-  int limb_alignment = alignof (mp_limb_t);
-  pure_limbs = pure_alloc (nbytes, - limb_alignment);
-  for (i = 0; i < nlimbs; ++i)
-    pure_limbs[i] = mpz_getlimbn (value->value, i);
-
-  new_size = nlimbs;
-  if (mpz_sgn (value->value) < 0)
-    new_size = -new_size;
-
-  mpz_roinit_n (b->value, pure_limbs, new_size);
-
-  return make_lisp_ptr (b, Lisp_Vectorlike);
-}
-
-/* Return a vector with room for LEN Lisp_Objects allocated from
-   pure space.  */
-
 static Lisp_Object
-make_pure_vector (ptrdiff_t len)
-{
-  Lisp_Object new;
-  size_t size = header_size + len * word_size;
-  struct Lisp_Vector *p = pure_alloc (size, Lisp_Vectorlike);
-  XSETVECTOR (new, p);
-  XVECTOR (new)->header.size = len;
-  return new;
-}
-
-/* Copy all contents and parameters of TABLE to a new table allocated
-   from pure space, return the purified table.  */
-static struct Lisp_Hash_Table *
-purecopy_hash_table (struct Lisp_Hash_Table *table)
-{
-  eassert (NILP (table->weak));
-  eassert (table->purecopy);
-
-  struct Lisp_Hash_Table *pure = pure_alloc (sizeof *pure, Lisp_Vectorlike);
-  struct hash_table_test pure_test = table->test;
-
-  /* Purecopy the hash table test.  */
-  pure_test.name = purecopy (table->test.name);
-  pure_test.user_hash_function = purecopy (table->test.user_hash_function);
-  pure_test.user_cmp_function = purecopy (table->test.user_cmp_function);
-
-  pure->header = table->header;
-  pure->weak = purecopy (Qnil);
-  pure->hash = purecopy (table->hash);
-  pure->next = purecopy (table->next);
-  pure->index = purecopy (table->index);
-  pure->count = table->count;
-  pure->next_free = table->next_free;
-  pure->purecopy = table->purecopy;
-  eassert (!pure->mutable);
-  pure->rehash_threshold = table->rehash_threshold;
-  pure->rehash_size = table->rehash_size;
-  pure->key_and_value = purecopy (table->key_and_value);
-  pure->test = pure_test;
-
-  return pure;
-}
+purecopy (Lisp_Object obj);
 
 DEFUN ("purecopy", Fpurecopy, Spurecopy, 1, 1, 0,
        doc: /* Make a copy of object OBJ in pure storage.
@@ -5376,100 +5035,23 @@ DEFUN ("purecopy", Fpurecopy, Spurecopy, 1, 1, 0,
     return purecopy (obj);
 }
 
-/* Pinned objects are marked before every GC cycle.  */
-static struct pinned_object
-{
-  Lisp_Object object;
-  struct pinned_object *next;
-} *pinned_objects;
-
 static Lisp_Object
 purecopy (Lisp_Object obj)
 {
-  if (FIXNUMP (obj)
-      || (! SYMBOLP (obj) && PURE_P (XPNTR (obj)))
-      || SUBRP (obj))
+  if (FIXNUMP (obj) || SUBRP (obj))
     return obj;    /* Already pure.  */
 
-  if (STRINGP (obj) && XSTRING (obj)->u.s.intervals)
-    message_with_string ("Dropping text-properties while making string `%s' pure",
-			 obj, true);
-
   if (HASH_TABLE_P (Vpurify_flag)) /* Hash consing.  */
     {
       Lisp_Object tmp = Fgethash (obj, Vpurify_flag, Qnil);
       if (!NILP (tmp))
 	return tmp;
+      Fputhash (obj, obj, Vpurify_flag);
     }
 
-  if (CONSP (obj))
-    obj = pure_cons (XCAR (obj), XCDR (obj));
-  else if (FLOATP (obj))
-    obj = make_pure_float (XFLOAT_DATA (obj));
-  else if (STRINGP (obj))
-    obj = make_pure_string (SSDATA (obj), SCHARS (obj),
-			    SBYTES (obj),
-			    STRING_MULTIBYTE (obj));
-  else if (HASH_TABLE_P (obj))
-    {
-      struct Lisp_Hash_Table *table = XHASH_TABLE (obj);
-      /* Do not purify hash tables which haven't been defined with
-         :purecopy as non-nil or are weak - they aren't guaranteed to
-         not change.  */
-      if (!NILP (table->weak) || !table->purecopy)
-        {
-          /* Instead, add the hash table to the list of pinned objects,
-             so that it will be marked during GC.  */
-          struct pinned_object *o = xmalloc (sizeof *o);
-          o->object = obj;
-          o->next = pinned_objects;
-          pinned_objects = o;
-          return obj; /* Don't hash cons it.  */
-        }
-
-      struct Lisp_Hash_Table *h = purecopy_hash_table (table);
-      XSET_HASH_TABLE (obj, h);
-    }
-  else if (COMPILEDP (obj) || VECTORP (obj) || RECORDP (obj))
-    {
-      struct Lisp_Vector *objp = XVECTOR (obj);
-      ptrdiff_t nbytes = vector_nbytes (objp);
-      struct Lisp_Vector *vec = pure_alloc (nbytes, Lisp_Vectorlike);
-      register ptrdiff_t i;
-      ptrdiff_t size = ASIZE (obj);
-      if (size & PSEUDOVECTOR_FLAG)
-	size &= PSEUDOVECTOR_SIZE_MASK;
-      memcpy (vec, objp, nbytes);
-      for (i = 0; i < size; i++)
-	vec->contents[i] = purecopy (vec->contents[i]);
-      XSETVECTOR (obj, vec);
-    }
-  else if (SYMBOLP (obj))
-    {
-      if (!XSYMBOL (obj)->u.s.pinned && !c_symbol_p (XSYMBOL (obj)))
-	{ /* We can't purify them, but they appear in many pure objects.
-	     Mark them as `pinned' so we know to mark them at every GC cycle.  */
-	  XSYMBOL (obj)->u.s.pinned = true;
-	  symbol_block_pinned = symbol_block;
-	}
-      /* Don't hash-cons it.  */
-      return obj;
-    }
-  else if (BIGNUMP (obj))
-    obj = make_pure_bignum (XBIGNUM (obj));
-  else
-    {
-      AUTO_STRING (fmt, "Don't know how to purify: %S");
-      Fsignal (Qerror, list1 (CALLN (Fformat, fmt, obj)));
-    }
-
-  if (HASH_TABLE_P (Vpurify_flag)) /* Hash consing.  */
-    Fputhash (obj, obj, Vpurify_flag);
-
   return obj;
 }
 
-
 \f
 /***********************************************************************
 			  Protection from GC
@@ -5658,31 +5240,6 @@ compact_undo_list (Lisp_Object list)
   return list;
 }
 
-static void
-mark_pinned_objects (void)
-{
-  for (struct pinned_object *pobj = pinned_objects; pobj; pobj = pobj->next)
-    mark_object (pobj->object);
-}
-
-static void
-mark_pinned_symbols (void)
-{
-  struct symbol_block *sblk;
-  int lim = (symbol_block_pinned == symbol_block
-	     ? symbol_block_index : SYMBOL_BLOCK_SIZE);
-
-  for (sblk = symbol_block_pinned; sblk; sblk = sblk->next)
-    {
-      struct Lisp_Symbol *sym = sblk->symbols, *end = sym + lim;
-      for (; sym < end; ++sym)
-	if (sym->u.s.pinned)
-	  mark_object (make_lisp_symbol (sym));
-
-      lim = SYMBOL_BLOCK_SIZE;
-    }
-}
-
 static void
 visit_vectorlike_root (struct gc_root_visitor visitor,
                        struct Lisp_Vector *ptr,
@@ -5869,8 +5426,6 @@ garbage_collect_1 (struct gcstat *gcst)
   struct gc_root_visitor visitor = { .visit = mark_object_root_visitor };
   visit_static_gc_roots (visitor);
 
-  mark_pinned_objects ();
-  mark_pinned_symbols ();
   mark_terminals ();
   mark_kboards ();
   mark_threads ();
@@ -6008,8 +5563,6 @@ DEFUN ("garbage-collect", Fgarbage_collect, Sgarbage_collect, 0, 0, "",
 - FREE is the number of those objects that are not live but that Emacs
   keeps around for future allocations (maybe because it does not know how
   to return them to the OS).
-However, if there was overflow in pure space, `garbage-collect'
-returns nil, because real GC can't be done.
 See Info node `(elisp)Garbage Collection'.  */)
   (void)
 {
@@ -6350,8 +5903,6 @@ mark_object (Lisp_Object arg)
  loop:
 
   po = XPNTR (obj);
-  if (PURE_P (po))
-    return;
 
   last_marked[last_marked_index++] = obj;
   last_marked_index &= LAST_MARKED_SIZE - 1;
@@ -6557,8 +6108,7 @@ #define CHECK_ALLOCATED_AND_LIVE_SYMBOL()	((void) 0)
 	    break;
 	  default: emacs_abort ();
 	  }
-	if (!PURE_P (XSTRING (ptr->u.s.name)))
-          set_string_marked (XSTRING (ptr->u.s.name));
+	set_string_marked (XSTRING (ptr->u.s.name));
         mark_interval_tree (string_intervals (ptr->u.s.name));
 	/* Inner loop to mark next symbol in this bucket, if any.  */
 	po = ptr = ptr->u.s.next;
@@ -6672,7 +6222,7 @@ survives_gc_p (Lisp_Object obj)
       emacs_abort ();
     }
 
-  return survives_p || PURE_P (XPNTR (obj));
+  return survives_p;
 }
 
 
@@ -7255,8 +6805,6 @@ init_alloc_once (void)
 static void
 init_alloc_once_for_pdumper (void)
 {
-  purebeg = PUREBEG;
-  pure_size = PURESIZE;
   mem_init ();
 
 #ifdef DOUG_LEA_MALLOC
@@ -7300,7 +6848,7 @@ syms_of_alloc (void)
   Vgc_cons_percentage = make_float (0.1);
 
   DEFVAR_INT ("pure-bytes-used", pure_bytes_used,
-	      doc: /* Number of bytes of shareable Lisp data allocated so far.  */);
+	      doc: /* No longer used.  */);
 
   DEFVAR_INT ("cons-cells-consed", cons_cells_consed,
 	      doc: /* Number of cons cells that have been consed so far.  */);
@@ -7325,10 +6873,7 @@ syms_of_alloc (void)
 	      doc: /* Number of strings that have been consed so far.  */);
 
   DEFVAR_LISP ("purify-flag", Vpurify_flag,
-	       doc: /* Non-nil means loading Lisp code in order to dump an executable.
-This means that certain objects should be allocated in shared (pure) space.
-It can also be set to a hash-table, in which case this table is used to
-do hash-consing of the objects allocated to pure space.  */);
+	       doc: /* No longer used.  */);
 
   DEFVAR_BOOL ("garbage-collection-messages", garbage_collection_messages,
 	       doc: /* Non-nil means display messages at start and end of garbage collection.  */);
@@ -7344,10 +6889,10 @@ syms_of_alloc (void)
   /* We build this in advance because if we wait until we need it, we might
      not be able to allocate the memory to hold it.  */
   Vmemory_signal_data
-    = pure_list (Qerror,
-		 build_pure_c_string ("Memory exhausted--use"
-				      " M-x save-some-buffers then"
-				      " exit and restart Emacs"));
+    = list (Qerror,
+	    build_string ("Memory exhausted--use"
+			  " M-x save-some-buffers then"
+			  " exit and restart Emacs"));
 
   DEFVAR_LISP ("memory-full", Vmemory_full,
 	       doc: /* Non-nil means Emacs cannot get much more Lisp memory.  */);
diff --git a/src/buffer.c b/src/buffer.c
index ea785bbcd7..4abab37abd 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -5222,8 +5222,8 @@ init_buffer_once (void)
   set_buffer_intervals (&buffer_defaults, NULL);
   set_buffer_intervals (&buffer_local_symbols, NULL);
   /* This is not strictly necessary, but let's make them initialized.  */
-  bset_name (&buffer_defaults, build_pure_c_string (" *buffer-defaults*"));
-  bset_name (&buffer_local_symbols, build_pure_c_string (" *buffer-local-symbols*"));
+  bset_name (&buffer_defaults, build_string (" *buffer-defaults*"));
+  bset_name (&buffer_local_symbols, build_string (" *buffer-local-symbols*"));
   BUFFER_PVEC_INIT (&buffer_defaults);
   BUFFER_PVEC_INIT (&buffer_local_symbols);
 
@@ -5231,7 +5231,7 @@ init_buffer_once (void)
   /* Must do these before making the first buffer! */
 
   /* real setup is done in bindings.el */
-  bset_mode_line_format (&buffer_defaults, build_pure_c_string ("%-"));
+  bset_mode_line_format (&buffer_defaults, build_string ("%-"));
   bset_header_line_format (&buffer_defaults, Qnil);
   bset_abbrev_mode (&buffer_defaults, Qnil);
   bset_overwrite_mode (&buffer_defaults, Qnil);
@@ -5299,7 +5299,7 @@ init_buffer_once (void)
   all_buffers = 0;
   pdumper_remember_lv_ptr_raw (&all_buffers, Lisp_Vectorlike);
 
-  QSFundamental = build_pure_c_string ("Fundamental");
+  QSFundamental = build_string ("Fundamental");
 
   DEFSYM (Qfundamental_mode, "fundamental-mode");
   bset_major_mode (&buffer_defaults, Qfundamental_mode);
@@ -5312,10 +5312,10 @@ init_buffer_once (void)
   Fput (Qkill_buffer_hook, Qpermanent_local, Qt);
 
   /* Super-magic invisible buffer.  */
-  Vprin1_to_string_buffer = Fget_buffer_create (build_pure_c_string (" prin1"));
+  Vprin1_to_string_buffer = Fget_buffer_create (build_string (" prin1"));
   Vbuffer_alist = Qnil;
 
-  Fset_buffer (Fget_buffer_create (build_pure_c_string ("*scratch*")));
+  Fset_buffer (Fget_buffer_create (build_string ("*scratch*")));
 
   inhibit_modification_hooks = 0;
 }
@@ -5500,9 +5500,9 @@ syms_of_buffer (void)
 	       Qoverwrite_mode_binary));
 
   Fput (Qprotected_field, Qerror_conditions,
-	pure_list (Qprotected_field, Qerror));
+	list (Qprotected_field, Qerror));
   Fput (Qprotected_field, Qerror_message,
-	build_pure_c_string ("Attempt to modify a protected field"));
+	build_string ("Attempt to modify a protected field"));
 
   DEFVAR_PER_BUFFER ("header-line-format",
 		     &BVAR (current_buffer, header_line_format),
diff --git a/src/callint.c b/src/callint.c
index 812287d365..910c1ab73f 100644
--- a/src/callint.c
+++ b/src/callint.c
@@ -816,10 +816,10 @@ syms_of_callint (void)
   callint_message = Qnil;
   staticpro (&callint_message);
 
-  preserved_fns = pure_list (intern_c_string ("region-beginning"),
-			     intern_c_string ("region-end"),
-			     intern_c_string ("point"),
-			     intern_c_string ("mark"));
+  preserved_fns = list (intern_c_string ("region-beginning"),
+			intern_c_string ("region-end"),
+			intern_c_string ("point"),
+			intern_c_string ("mark"));
   staticpro (&preserved_fns);
 
   DEFSYM (Qlist, "list");
diff --git a/src/category.c b/src/category.c
index 9e460cfc64..9e7864f319 100644
--- a/src/category.c
+++ b/src/category.c
@@ -53,7 +53,7 @@ hash_get_category_set (Lisp_Object table, Lisp_Object category_set)
       (table, 1,
        make_hash_table (hashtest_equal, DEFAULT_HASH_SIZE,
 			DEFAULT_REHASH_SIZE, DEFAULT_REHASH_THRESHOLD,
-			Qnil, false));
+			Qnil));
   struct Lisp_Hash_Table *h = XHASH_TABLE (XCHAR_TABLE (table)->extras[1]);
   Lisp_Object hash;
   ptrdiff_t i = hash_lookup (h, category_set, &hash);
@@ -120,8 +120,6 @@ DEFUN ("define-category", Fdefine_category, Sdefine_category, 2, 3, 0,
 
   if (!NILP (CATEGORY_DOCSTRING (table, XFIXNAT (category))))
     error ("Category `%c' is already defined", (int) XFIXNAT (category));
-  if (!NILP (Vpurify_flag))
-    docstring = Fpurecopy (docstring);
   SET_CATEGORY_DOCSTRING (table, XFIXNAT (category), docstring);
 
   return Qnil;
diff --git a/src/coding.c b/src/coding.c
index 189a4b39d1..5654ae333d 100644
--- a/src/coding.c
+++ b/src/coding.c
@@ -10821,7 +10821,7 @@ syms_of_coding (void)
   Vcode_conversion_reused_workbuf = Qnil;
 
   staticpro (&Vcode_conversion_workbuf_name);
-  Vcode_conversion_workbuf_name = build_pure_c_string (" *code-conversion-work*");
+  Vcode_conversion_workbuf_name = build_string (" *code-conversion-work*");
 
   reused_workbuf_in_use = 0;
   PDUMPER_REMEMBER_SCALAR (reused_workbuf_in_use);
@@ -10885,9 +10885,9 @@ syms_of_coding (void)
   /* Error signaled when there's a problem with detecting a coding system.  */
   DEFSYM (Qcoding_system_error, "coding-system-error");
   Fput (Qcoding_system_error, Qerror_conditions,
-	pure_list (Qcoding_system_error, Qerror));
+	list (Qcoding_system_error, Qerror));
   Fput (Qcoding_system_error, Qerror_message,
-	build_pure_c_string ("Invalid coding system"));
+	build_string ("Invalid coding system"));
 
   DEFSYM (Qtranslation_table, "translation-table");
   Fput (Qtranslation_table, Qchar_table_extra_slots, make_fixnum (2));
@@ -11154,22 +11154,22 @@ syms_of_coding (void)
   DEFVAR_LISP ("eol-mnemonic-unix", eol_mnemonic_unix,
 	       doc: /*
 String displayed in mode line for UNIX-like (LF) end-of-line format.  */);
-  eol_mnemonic_unix = build_pure_c_string (":");
+  eol_mnemonic_unix = build_string (":");
 
   DEFVAR_LISP ("eol-mnemonic-dos", eol_mnemonic_dos,
 	       doc: /*
 String displayed in mode line for DOS-like (CRLF) end-of-line format.  */);
-  eol_mnemonic_dos = build_pure_c_string ("\\");
+  eol_mnemonic_dos = build_string ("\\");
 
   DEFVAR_LISP ("eol-mnemonic-mac", eol_mnemonic_mac,
 	       doc: /*
 String displayed in mode line for MAC-like (CR) end-of-line format.  */);
-  eol_mnemonic_mac = build_pure_c_string ("/");
+  eol_mnemonic_mac = build_string ("/");
 
   DEFVAR_LISP ("eol-mnemonic-undecided", eol_mnemonic_undecided,
 	       doc: /*
 String displayed in mode line when end-of-line format is not yet determined.  */);
-  eol_mnemonic_undecided = build_pure_c_string (":");
+  eol_mnemonic_undecided = build_string (":");
 
   DEFVAR_LISP ("enable-character-translation", Venable_character_translation,
 	       doc: /*
@@ -11309,7 +11309,7 @@ system (e.g. `iso-2022-7bit').
       intern_c_string (":for-unibyte"),
       args[coding_arg_for_unibyte] = Qt,
       intern_c_string (":docstring"),
-      (build_pure_c_string
+      (build_string
        ("Do no conversion.\n"
 	"\n"
 	"When you visit a file with this coding, the file is read into a\n"
@@ -11329,7 +11329,7 @@ system (e.g. `iso-2022-7bit').
   plist[8] = intern_c_string (":charset-list");
   plist[9] = args[coding_arg_charset_list] = list1 (Qascii);
   plist[11] = args[coding_arg_for_unibyte] = Qnil;
-  plist[13] = build_pure_c_string ("No conversion on encoding, "
+  plist[13] = build_string ("No conversion on encoding, "
 				   "automatic conversion on decoding.");
   plist[15] = args[coding_arg_eol_type] = Qnil;
   args[coding_arg_plist] = CALLMANY (Flist, plist);
diff --git a/src/conf_post.h b/src/conf_post.h
index 4af1ba9331..92eaf75375 100644
--- a/src/conf_post.h
+++ b/src/conf_post.h
@@ -158,41 +158,8 @@ #define emacs_raise(sig) msdos_fatal_signal (sig)
 
 /* DATA_START is needed by vm-limit.c and unexcoff.c. */
 #define DATA_START (&etext + 1)
-
-/* Define one of these for easier conditionals.  */
-#ifdef HAVE_X_WINDOWS
-/* We need a little extra space, see ../../lisp/loadup.el and the
-   commentary below, in the non-X branch.  The 140KB number was
-   measured on GNU/Linux and on MS-Windows.  */
-#define SYSTEM_PURESIZE_EXTRA (-170000+140000)
-#else
-/* We need a little extra space, see ../../lisp/loadup.el.
-   As of 20091024, DOS-specific files use up 62KB of pure space.  But
-   overall, we end up wasting 130KB of pure space, because
-   BASE_PURESIZE starts at 1.47MB, while we need only 1.3MB (including
-   non-DOS specific files and load history; the latter is about 55K,
-   but depends on the depth of the top-level Emacs directory in the
-   directory tree).  Given the unknown policy of different DPMI
-   hosts regarding loading of untouched pages, I'm not going to risk
-   enlarging Emacs footprint by another 100+ KBytes.  */
-#define SYSTEM_PURESIZE_EXTRA (-170000+90000)
-#endif
 #endif  /* MSDOS */
 
-/* macOS / GNUstep need a bit more pure memory.  Of the existing knobs,
-   SYSTEM_PURESIZE_EXTRA seems like the least likely to cause problems.  */
-#ifdef HAVE_NS
-#if defined NS_IMPL_GNUSTEP
-#  define SYSTEM_PURESIZE_EXTRA 30000
-#elif defined DARWIN_OS
-#  define SYSTEM_PURESIZE_EXTRA 200000
-#endif
-#endif
-
-#ifdef CYGWIN
-#define SYSTEM_PURESIZE_EXTRA 50000
-#endif
-
 #if defined HAVE_NTGUI && !defined DebPrint
 # ifdef EMACSDEBUG
 extern void _DebPrint (const char *fmt, ...);
diff --git a/src/data.c b/src/data.c
index 46bd7e0e25..39d0d4bdfa 100644
--- a/src/data.c
+++ b/src/data.c
@@ -30,7 +30,6 @@
 
 #include "lisp.h"
 #include "bignum.h"
-#include "puresize.h"
 #include "character.h"
 #include "buffer.h"
 #include "keyboard.h"
@@ -155,12 +154,6 @@ wrong_type_argument (register Lisp_Object predicate, register Lisp_Object value)
   xsignal2 (Qwrong_type_argument, predicate, value);
 }
 
-void
-pure_write_error (Lisp_Object obj)
-{
-  xsignal2 (Qerror, build_string ("Attempt to modify read-only object"), obj);
-}
-
 void
 args_out_of_range (Lisp_Object a1, Lisp_Object a2)
 {
@@ -631,7 +624,6 @@ DEFUN ("setcar", Fsetcar, Ssetcar, 2, 2, 0,
   (register Lisp_Object cell, Lisp_Object newcar)
 {
   CHECK_CONS (cell);
-  CHECK_IMPURE (cell, XCONS (cell));
   XSETCAR (cell, newcar);
   return newcar;
 }
@@ -641,7 +633,6 @@ DEFUN ("setcdr", Fsetcdr, Ssetcdr, 2, 2, 0,
   (register Lisp_Object cell, Lisp_Object newcdr)
 {
   CHECK_CONS (cell);
-  CHECK_IMPURE (cell, XCONS (cell));
   XSETCDR (cell, newcdr);
   return newcdr;
 }
@@ -795,10 +786,6 @@ DEFUN ("defalias", Fdefalias, Sdefalias, 2, 3, 0,
   (register Lisp_Object symbol, Lisp_Object definition, Lisp_Object docstring)
 {
   CHECK_SYMBOL (symbol);
-  if (!NILP (Vpurify_flag)
-      /* If `definition' is a keymap, immutable (and copying) is wrong.  */
-      && !KEYMAPP (definition))
-    definition = Fpurecopy (definition);
 
   {
     bool autoload = AUTOLOADP (definition);
@@ -2271,7 +2258,6 @@ DEFUN ("aset", Faset, Saset, 3, 3, 0,
 
   if (VECTORP (array))
     {
-      CHECK_IMPURE (array, XVECTOR (array));
       if (idxval < 0 || idxval >= ASIZE (array))
 	args_out_of_range (array, idx);
       ASET (array, idxval, newelt);
@@ -2297,7 +2283,6 @@ DEFUN ("aset", Faset, Saset, 3, 3, 0,
     {
       int c;
 
-      CHECK_IMPURE (array, XSTRING (array));
       if (idxval < 0 || idxval >= SCHARS (array))
 	args_out_of_range (array, idx);
       CHECK_CHARACTER (newelt);
@@ -3854,7 +3839,7 @@ syms_of_data (void)
 
   DEFSYM (Qcdr, "cdr");
 
-  error_tail = pure_cons (Qerror, Qnil);
+  error_tail = Fcons (Qerror, Qnil);
 
   /* ERROR is used as a signaler for random errors for which nothing else is
      right.  */
@@ -3862,11 +3847,11 @@ syms_of_data (void)
   Fput (Qerror, Qerror_conditions,
 	error_tail);
   Fput (Qerror, Qerror_message,
-	build_pure_c_string ("error"));
+	build_string ("error"));
 
 #define PUT_ERROR(sym, tail, msg)			\
-  Fput (sym, Qerror_conditions, pure_cons (sym, tail)); \
-  Fput (sym, Qerror_message, build_pure_c_string (msg))
+  Fput (sym, Qerror_conditions, Fcons (sym, tail)); \
+  Fput (sym, Qerror_message, build_string (msg))
 
   PUT_ERROR (Qquit, Qnil, "Quit");
 
@@ -3894,14 +3879,14 @@ #define PUT_ERROR(sym, tail, msg)			\
   PUT_ERROR (Qno_catch, error_tail, "No catch for tag");
   PUT_ERROR (Qend_of_file, error_tail, "End of file during parsing");
 
-  arith_tail = pure_cons (Qarith_error, error_tail);
+  arith_tail = Fcons (Qarith_error, error_tail);
   Fput (Qarith_error, Qerror_conditions, arith_tail);
-  Fput (Qarith_error, Qerror_message, build_pure_c_string ("Arithmetic error"));
+  Fput (Qarith_error, Qerror_message, build_string ("Arithmetic error"));
 
   PUT_ERROR (Qbeginning_of_buffer, error_tail, "Beginning of buffer");
   PUT_ERROR (Qend_of_buffer, error_tail, "End of buffer");
   PUT_ERROR (Qbuffer_read_only, error_tail, "Buffer is read-only");
-  PUT_ERROR (Qtext_read_only, pure_cons (Qbuffer_read_only, error_tail),
+  PUT_ERROR (Qtext_read_only, Fcons (Qbuffer_read_only, error_tail),
 	     "Text is read-only");
 
   DEFSYM (Qrange_error, "range-error");
diff --git a/src/dbusbind.c b/src/dbusbind.c
index 90ba461c6b..4c9bb4abca 100644
--- a/src/dbusbind.c
+++ b/src/dbusbind.c
@@ -1690,7 +1690,7 @@ syms_of_dbusbind (void)
   Fput (Qdbus_error, Qerror_conditions,
 	list2 (Qdbus_error, Qerror));
   Fput (Qdbus_error, Qerror_message,
-	build_pure_c_string ("D-Bus error"));
+	build_string ("D-Bus error"));
 
   /* Lisp symbols of the system and session buses.  */
   DEFSYM (QCsystem, ":system");
@@ -1729,7 +1729,7 @@ syms_of_dbusbind (void)
 	       Vdbus_compiled_version,
     doc: /* The version of D-Bus Emacs is compiled against.  */);
 #ifdef DBUS_VERSION_STRING
-  Vdbus_compiled_version = build_pure_c_string (DBUS_VERSION_STRING);
+  Vdbus_compiled_version = build_string (DBUS_VERSION_STRING);
 #else
   Vdbus_compiled_version = Qnil;
 #endif
diff --git a/src/deps.mk b/src/deps.mk
index 2cdeba8d4a..637d82c35f 100644
--- a/src/deps.mk
+++ b/src/deps.mk
@@ -132,10 +132,10 @@ insdel.o:
 keyboard.o: keyboard.c termchar.h termhooks.h termopts.h buffer.h character.h \
    commands.h frame.h window.h macros.h disptab.h keyboard.h syssignal.h \
    systime.h syntax.h $(INTERVALS_H) blockinput.h atimer.h composite.h \
-   xterm.h puresize.h msdos.h keymap.h w32term.h nsterm.h nsgui.h coding.h \
+   xterm.h msdos.h keymap.h w32term.h nsterm.h nsgui.h coding.h \
    process.h ../lib/unistd.h gnutls.h lisp.h globals.h $(config_h)
 keymap.o: keymap.c buffer.h commands.h keyboard.h termhooks.h blockinput.h \
-   atimer.h systime.h puresize.h character.h charset.h $(INTERVALS_H) \
+   atimer.h systime.h character.h charset.h $(INTERVALS_H) \
    keymap.h window.h coding.h frame.h lisp.h globals.h $(config_h)
 lastfile.o: lastfile.c $(config_h)
 macros.o: macros.c window.h buffer.h commands.h macros.h keyboard.h msdos.h \
@@ -270,12 +270,12 @@ xsettings.o:
    atimer.h termopts.h globals.h
 
 ## The files of Lisp proper.
-alloc.o: alloc.c process.h frame.h window.h buffer.h  puresize.h syssignal.h \
+alloc.o: alloc.c process.h frame.h window.h buffer.h syssignal.h \
    keyboard.h blockinput.h atimer.h systime.h character.h lisp.h $(config_h) \
    $(INTERVALS_H) termhooks.h gnutls.h coding.h ../lib/unistd.h globals.h
 bytecode.o: bytecode.c buffer.h syntax.h character.h window.h dispextern.h \
   lisp.h globals.h $(config_h) msdos.h
-data.o: data.c buffer.h puresize.h character.h syssignal.h keyboard.h frame.h \
+data.o: data.c buffer.h character.h syssignal.h keyboard.h frame.h \
    termhooks.h systime.h coding.h composite.h dispextern.h font.h ccl.h \
    lisp.h globals.h $(config_h) msdos.h
 eval.o: eval.c commands.h keyboard.h blockinput.h atimer.h systime.h frame.h \
@@ -298,7 +298,7 @@ lread.o:
 composite.o: composite.c composite.h buffer.h character.h coding.h font.h \
    ccl.h frame.h termhooks.h $(INTERVALS_H) window.h \
    lisp.h globals.h $(config_h)
-intervals.o: intervals.c buffer.h $(INTERVALS_H) keyboard.h puresize.h \
+intervals.o: intervals.c buffer.h $(INTERVALS_H) keyboard.h \
    keymap.h lisp.h globals.h $(config_h) systime.h coding.h
 textprop.o: textprop.c buffer.h window.h $(INTERVALS_H) \
    lisp.h globals.h $(config_h)
diff --git a/src/doc.c b/src/doc.c
index 8b663f0f24..5cc268b7e9 100644
--- a/src/doc.c
+++ b/src/doc.c
@@ -500,8 +500,6 @@ store_function_docstring (Lisp_Object obj, EMACS_INT offset)
 	{
 	  tem = Fcdr (Fcdr (fun));
 	  if (CONSP (tem) && FIXNUMP (XCAR (tem)))
-	    /* FIXME: This modifies typically pure hash-cons'd data, so its
-	       correctness is quite delicate.  */
 	    XSETCAR (tem, make_fixnum (offset));
 	}
     }
@@ -585,7 +583,6 @@ DEFUN ("Snarf-documentation", Fsnarf_documentation, Ssnarf_documentation,
       int i = ARRAYELTS (buildobj);
       while (0 <= --i)
 	Vbuild_files = Fcons (build_string (buildobj[i]), Vbuild_files);
-      Vbuild_files = Fpurecopy (Vbuild_files);
     }
 
   fd = emacs_open (name, O_RDONLY, 0);
diff --git a/src/emacs-module.c b/src/emacs-module.c
index 4b991a1c74..cb302c7022 100644
--- a/src/emacs-module.c
+++ b/src/emacs-module.c
@@ -1328,40 +1328,40 @@ syms_of_module (void)
 
   DEFSYM (Qmodule_load_failed, "module-load-failed");
   Fput (Qmodule_load_failed, Qerror_conditions,
-	pure_list (Qmodule_load_failed, Qerror));
+	list (Qmodule_load_failed, Qerror));
   Fput (Qmodule_load_failed, Qerror_message,
-        build_pure_c_string ("Module load failed"));
+        build_string ("Module load failed"));
 
   DEFSYM (Qmodule_open_failed, "module-open-failed");
   Fput (Qmodule_open_failed, Qerror_conditions,
-	pure_list (Qmodule_open_failed, Qmodule_load_failed, Qerror));
+	list (Qmodule_open_failed, Qmodule_load_failed, Qerror));
   Fput (Qmodule_open_failed, Qerror_message,
-        build_pure_c_string ("Module could not be opened"));
+        build_string ("Module could not be opened"));
 
   DEFSYM (Qmodule_not_gpl_compatible, "module-not-gpl-compatible");
   Fput (Qmodule_not_gpl_compatible, Qerror_conditions,
-	pure_list (Qmodule_not_gpl_compatible, Qmodule_load_failed, Qerror));
+	list (Qmodule_not_gpl_compatible, Qmodule_load_failed, Qerror));
   Fput (Qmodule_not_gpl_compatible, Qerror_message,
-        build_pure_c_string ("Module is not GPL compatible"));
+        build_string ("Module is not GPL compatible"));
 
   DEFSYM (Qmissing_module_init_function, "missing-module-init-function");
   Fput (Qmissing_module_init_function, Qerror_conditions,
-	pure_list (Qmissing_module_init_function, Qmodule_load_failed,
-		   Qerror));
+	list (Qmissing_module_init_function, Qmodule_load_failed,
+	      Qerror));
   Fput (Qmissing_module_init_function, Qerror_message,
-        build_pure_c_string ("Module does not export an "
+        build_string ("Module does not export an "
                              "initialization function"));
 
   DEFSYM (Qmodule_init_failed, "module-init-failed");
   Fput (Qmodule_init_failed, Qerror_conditions,
-	pure_list (Qmodule_init_failed, Qmodule_load_failed, Qerror));
+	list (Qmodule_init_failed, Qmodule_load_failed, Qerror));
   Fput (Qmodule_init_failed, Qerror_message,
-        build_pure_c_string ("Module initialization failed"));
+        build_string ("Module initialization failed"));
 
   DEFSYM (Qinvalid_arity, "invalid-arity");
-  Fput (Qinvalid_arity, Qerror_conditions, pure_list (Qinvalid_arity, Qerror));
+  Fput (Qinvalid_arity, Qerror_conditions, list (Qinvalid_arity, Qerror));
   Fput (Qinvalid_arity, Qerror_message,
-        build_pure_c_string ("Invalid function arity"));
+        build_string ("Invalid function arity"));
 
   DEFSYM (Qmodule_function_p, "module-function-p");
 
diff --git a/src/emacs.c b/src/emacs.c
index ad661a081b..f4f42a908c 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -89,7 +89,6 @@ #define MAIN_PROGRAM
 #include "syntax.h"
 #include "sysselect.h"
 #include "systime.h"
-#include "puresize.h"
 
 #include "getpagesize.h"
 #include "gnutls.h"
@@ -2537,8 +2536,6 @@ DEFUN ("dump-emacs", Fdump_emacs, Sdump_emacs, 2, 2, 0,
   Lisp_Object symbol;
   ptrdiff_t count = SPECPDL_INDEX ();
 
-  check_pure_size ();
-
   if (! noninteractive)
     error ("Dumping Emacs works only in batch mode");
 
diff --git a/src/eval.c b/src/eval.c
index 02a6c3555a..a4f37c295a 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -725,8 +725,6 @@ DEFUN ("internal--define-uninitialized-variable",
   XSYMBOL (symbol)->u.s.declared_special = true;
   if (!NILP (doc))
     {
-      if (!NILP (Vpurify_flag))
-	doc = Fpurecopy (doc);
       Fput (symbol, Qvariable_documentation, doc);
     }
   LOADHIST_ATTACH (symbol);
@@ -840,8 +838,6 @@ DEFUN ("defconst", Fdefconst, Sdefconst, 2, UNEVALLED, 0,
 
   Finternal__define_uninitialized_variable (sym, docstring);
   tem = eval_sub (XCAR (XCDR (args)));
-  if (!NILP (Vpurify_flag))
-    tem = Fpurecopy (tem);
   Fset_default (sym, tem);      /* FIXME: set-default-toplevel-value? */
   Fput (sym, Qrisky_local_variable, Qt); /* FIXME: Why?  */
   return sym;
@@ -1986,12 +1982,6 @@ DEFUN ("autoload", Fautoload, Sautoload, 2, 5, 0,
       && !AUTOLOADP (XSYMBOL (function)->u.s.function))
     return Qnil;
 
-  if (!NILP (Vpurify_flag) && EQ (docstring, make_fixnum (0)))
-    /* `read1' in lread.c has found the docstring starting with "\
-       and assumed the docstring will be provided by Snarf-documentation, so it
-       passed us 0 instead.  But that leads to accidental sharing in purecopy's
-       hash-consing, so we use a (hopefully) unique integer instead.  */
-    docstring = make_fixnum (XHASH (function));
   return Fdefalias (function,
 		    list5 (Qautoload, file, docstring, interactive, type),
 		    Qnil);
@@ -4182,7 +4172,7 @@ syms_of_eval (void)
      also use something like Fcons (Qnil, Qnil), but json.c treats any
      cons cell as error data, so use an uninterned symbol instead.  */
   Qcatch_all_memory_full
-    = Fmake_symbol (build_pure_c_string ("catch-all-memory-full"));
+    = Fmake_symbol (build_string ("catch-all-memory-full"));
 
   defsubr (&Sor);
   defsubr (&Sand);
diff --git a/src/fileio.c b/src/fileio.c
index 7f83267956..5b0c9d4cab 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -6227,29 +6227,29 @@ syms_of_fileio (void)
   DEFSYM (Qcar_less_than_car, "car-less-than-car");
 
   Fput (Qfile_error, Qerror_conditions,
-	Fpurecopy (list2 (Qfile_error, Qerror)));
+	list2 (Qfile_error, Qerror));
   Fput (Qfile_error, Qerror_message,
-	build_pure_c_string ("File error"));
+	build_string ("File error"));
 
   Fput (Qfile_already_exists, Qerror_conditions,
-	Fpurecopy (list3 (Qfile_already_exists, Qfile_error, Qerror)));
+	list3 (Qfile_already_exists, Qfile_error, Qerror));
   Fput (Qfile_already_exists, Qerror_message,
-	build_pure_c_string ("File already exists"));
+	build_string ("File already exists"));
 
   Fput (Qfile_date_error, Qerror_conditions,
-	Fpurecopy (list3 (Qfile_date_error, Qfile_error, Qerror)));
+	list3 (Qfile_date_error, Qfile_error, Qerror));
   Fput (Qfile_date_error, Qerror_message,
-	build_pure_c_string ("Cannot set file date"));
+	build_string ("Cannot set file date"));
 
   Fput (Qfile_missing, Qerror_conditions,
-	Fpurecopy (list3 (Qfile_missing, Qfile_error, Qerror)));
+	list3 (Qfile_missing, Qfile_error, Qerror));
   Fput (Qfile_missing, Qerror_message,
-	build_pure_c_string ("File is missing"));
+	build_string ("File is missing"));
 
   Fput (Qfile_notify_error, Qerror_conditions,
-	Fpurecopy (list3 (Qfile_notify_error, Qfile_error, Qerror)));
+	list3 (Qfile_notify_error, Qfile_error, Qerror));
   Fput (Qfile_notify_error, Qerror_message,
-	build_pure_c_string ("File notification error"));
+	build_string ("File notification error"));
 
   DEFVAR_LISP ("file-name-handler-alist", Vfile_name_handler_alist,
 	       doc: /* Alist of elements (REGEXP . HANDLER) for file names handled specially.
diff --git a/src/fns.c b/src/fns.c
index d7e123122d..1297db9acf 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -35,7 +35,6 @@ Copyright (C) 1985-1987, 1993-1995, 1997-2019 Free Software Foundation,
 #include "buffer.h"
 #include "intervals.h"
 #include "window.h"
-#include "puresize.h"
 #include "gnutls.h"
 
 #if defined WINDOWSNT && defined HAVE_GNUTLS3
@@ -4066,16 +4065,12 @@ #define INDEX_SIZE_BOUND \
    size exceeds REHASH_THRESHOLD.
 
    WEAK specifies the weakness of the table.  If non-nil, it must be
-   one of the symbols `key', `value', `key-or-value', or `key-and-value'.
-
-   If PURECOPY is non-nil, the table can be copied to pure storage via
-   `purecopy' when Emacs is being dumped. Such tables can no longer be
-   changed after purecopy.  */
+   one of the symbols `key', `value', `key-or-value', or `key-and-value'. */
 
 Lisp_Object
 make_hash_table (struct hash_table_test test, EMACS_INT size,
 		 float rehash_size, float rehash_threshold,
-		 Lisp_Object weak, bool purecopy)
+		 Lisp_Object weak)
 {
   struct Lisp_Hash_Table *h;
   Lisp_Object table;
@@ -4114,7 +4109,6 @@ make_hash_table (struct hash_table_test test, EMACS_INT size,
   h->next = make_vector (size, make_fixnum (-1));
   h->index = make_vector (index_size, make_fixnum (-1));
   h->next_weak = NULL;
-  h->purecopy = purecopy;
   h->mutable = true;
 
   /* Set up the free list.  */
@@ -4214,10 +4208,6 @@ maybe_resize_hash_table (struct Lisp_Hash_Table *h)
 	    set_hash_index_slot (h, start_of_bucket, i);
 	  }
 
-#ifdef ENABLE_CHECKING
-      if (HASH_TABLE_P (Vpurify_flag) && XHASH_TABLE (Vpurify_flag) == h)
-	message ("Growing hash table to: %"pD"d", new_size);
-#endif
     }
 }
 
@@ -4302,7 +4292,6 @@ check_mutable_hash_table (Lisp_Object obj, struct Lisp_Hash_Table *h)
 {
   if (!h->mutable)
     signal_error ("hash table test modifies table", obj);
-  eassert (!PURE_P (h));
 }
 
 /* Put an entry into hash table H that associates KEY with VALUE.
@@ -4760,16 +4749,10 @@ DEFUN ("make-hash-table", Fmake_hash_table, Smake_hash_table, 0, MANY, 0,
 WEAK.  WEAK t is equivalent to `key-and-value'.  Default value of WEAK
 is nil.
 
-:purecopy PURECOPY -- If PURECOPY is non-nil, the table can be copied
-to pure storage when Emacs is being dumped, making the contents of the
-table read only. Any further changes to purified tables will result
-in an error.
-
 usage: (make-hash-table &rest KEYWORD-ARGS)  */)
   (ptrdiff_t nargs, Lisp_Object *args)
 {
   Lisp_Object test, weak;
-  bool purecopy;
   struct hash_table_test testdesc;
   ptrdiff_t i;
   USE_SAFE_ALLOCA;
@@ -4803,9 +4786,8 @@ DEFUN ("make-hash-table", Fmake_hash_table, Smake_hash_table, 0, MANY, 0,
       testdesc.cmpfn = cmpfn_user_defined;
     }
 
-  /* See if there's a `:purecopy PURECOPY' argument.  */
-  i = get_key_arg (QCpurecopy, nargs, args, used);
-  purecopy = i && !NILP (args[i]);
+  /* Ignore a `:purecopy PURECOPY' argument.  */
+  get_key_arg (QCpurecopy, nargs, args, used);
   /* See if there's a `:size SIZE' argument.  */
   i = get_key_arg (QCsize, nargs, args, used);
   Lisp_Object size_arg = i ? args[i] : Qnil;
@@ -4855,8 +4837,7 @@ DEFUN ("make-hash-table", Fmake_hash_table, Smake_hash_table, 0, MANY, 0,
       signal_error ("Invalid argument list", args[i]);
 
   SAFE_FREE ();
-  return make_hash_table (testdesc, size, rehash_size, rehash_threshold, weak,
-			  purecopy);
+  return make_hash_table (testdesc, size, rehash_size, rehash_threshold, weak);
 }
 
 
diff --git a/src/fontset.c b/src/fontset.c
index 828e7fe70c..c55196f324 100644
--- a/src/fontset.c
+++ b/src/fontset.c
@@ -2128,7 +2128,7 @@ syms_of_fontset (void)
   set_fontset_id (Vdefault_fontset, make_fixnum (0));
   set_fontset_name
     (Vdefault_fontset,
-     build_pure_c_string ("-*-*-*-*-*-*-*-*-*-*-*-*-fontset-default"));
+     build_string ("-*-*-*-*-*-*-*-*-*-*-*-*-fontset-default"));
   ASET (Vfontset_table, 0, Vdefault_fontset);
   next_fontset_id = 1;
   PDUMPER_REMEMBER_SCALAR (next_fontset_id);
@@ -2186,7 +2186,7 @@ syms_of_fontset (void)
 	       doc: /* Alist of fontset names vs the aliases.  */);
   Vfontset_alias_alist
     = list1 (Fcons (FONTSET_NAME (Vdefault_fontset),
-		    build_pure_c_string ("fontset-default")));
+		    build_string ("fontset-default")));
 
   DEFVAR_LISP ("vertical-centering-font-regexp",
 	       Vvertical_centering_font_regexp,
diff --git a/src/frame.c b/src/frame.c
index 6363a87368..a5e617b092 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -1068,7 +1068,7 @@ make_initial_frame (void)
   Vframe_list = Fcons (frame, Vframe_list);
 
   tty_frame_count = 1;
-  fset_name (f, build_pure_c_string ("F1"));
+  fset_name (f, build_string ("F1"));
 
   SET_FRAME_VISIBLE (f, 1);
 
diff --git a/src/intervals.c b/src/intervals.c
index 38367460a5..c58611cb21 100644
--- a/src/intervals.c
+++ b/src/intervals.c
@@ -44,7 +44,6 @@
 #include "lisp.h"
 #include "intervals.h"
 #include "buffer.h"
-#include "puresize.h"
 #include "keymap.h"
 
 /* Test for membership, allowing for t (actually any non-cons) to mean the
@@ -101,7 +100,6 @@ create_root_interval (Lisp_Object parent)
     }
   else
     {
-      CHECK_IMPURE (parent, XSTRING (parent));
       new->total_length = SCHARS (parent);
       eassert (TOTAL_LENGTH (new) >= 0);
       set_string_intervals (parent, new);
diff --git a/src/json.c b/src/json.c
index d05f2c54e2..0ce2ac94a6 100644
--- a/src/json.c
+++ b/src/json.c
@@ -1106,8 +1106,8 @@ define_error (Lisp_Object name, const char *message, Lisp_Object parent)
   eassert (CONSP (parent_conditions));
   eassert (!NILP (Fmemq (parent, parent_conditions)));
   eassert (NILP (Fmemq (name, parent_conditions)));
-  Fput (name, Qerror_conditions, pure_cons (name, parent_conditions));
-  Fput (name, Qerror_message, build_pure_c_string (message));
+  Fput (name, Qerror_conditions, Fcons (name, parent_conditions));
+  Fput (name, Qerror_message, build_string (message));
 }
 
 void
diff --git a/src/keyboard.c b/src/keyboard.c
index b86ad03851..1a784b5330 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -1106,8 +1106,6 @@ top_level_1 (Lisp_Object ignore)
   /* On entry to the outer level, run the startup file.  */
   if (!NILP (Vtop_level))
     internal_condition_case (top_level_2, Qerror, cmd_error);
-  else if (!NILP (Vpurify_flag))
-    message1 ("Bare impure Emacs (standard Lisp code not loaded)");
   else
     message1 ("Bare Emacs (standard Lisp code not loaded)");
   return Qnil;
@@ -11034,14 +11032,14 @@ syms_of_keyboard (void)
   pending_funcalls = Qnil;
   staticpro (&pending_funcalls);
 
-  Vlispy_mouse_stem = build_pure_c_string ("mouse");
+  Vlispy_mouse_stem = build_string ("mouse");
   staticpro (&Vlispy_mouse_stem);
 
-  regular_top_level_message = build_pure_c_string ("Back to top level");
+  regular_top_level_message = build_string ("Back to top level");
   staticpro (&regular_top_level_message);
 #ifdef HAVE_STACK_OVERFLOW_HANDLING
   recover_top_level_message
-    = build_pure_c_string ("Re-entering top level after C stack overflow");
+    = build_string ("Re-entering top level after C stack overflow");
   staticpro (&recover_top_level_message);
 #endif
   DEFVAR_LISP ("internal--top-level-message", Vinternal__top_level_message,
diff --git a/src/keymap.c b/src/keymap.c
index 6762915f70..bcc48b9520 100644
--- a/src/keymap.c
+++ b/src/keymap.c
@@ -50,7 +50,6 @@
 #include "keyboard.h"
 #include "termhooks.h"
 #include "blockinput.h"
-#include "puresize.h"
 #include "intervals.h"
 #include "keymap.h"
 #include "window.h"
@@ -138,8 +137,6 @@ DEFUN ("make-sparse-keymap", Fmake_sparse_keymap, Smake_sparse_keymap, 0, 1, 0,
 {
   if (!NILP (string))
     {
-      if (!NILP (Vpurify_flag))
-	string = Fpurecopy (string);
       return list2 (Qkeymap, string);
     }
   return list1 (Qkeymap);
@@ -336,7 +333,6 @@ DEFUN ("set-keymap-parent", Fset_keymap_parent, Sset_keymap_parent, 2, 2, 0,
 	 If we came to the end, add the parent in PREV.  */
       if (!CONSP (list) || KEYMAPP (list))
 	{
-	  CHECK_IMPURE (prev, XCONS (prev));
 	  XSETCDR (prev, parent);
 	  return parent;
 	}
@@ -757,7 +753,7 @@ store_in_keymap (Lisp_Object keymap, register Lisp_Object idx, Lisp_Object def)
 
   /* If we are preparing to dump, and DEF is a menu element
      with a menu item indicator, copy it to ensure it is not pure.  */
-  if (CONSP (def) && PURE_P (XCONS (def))
+  if (CONSP (def)
       && (EQ (XCAR (def), Qmenu_item) || STRINGP (XCAR (def))))
     def = Fcons (XCAR (def), XCDR (def));
 
@@ -805,7 +801,6 @@ store_in_keymap (Lisp_Object keymap, register Lisp_Object idx, Lisp_Object def)
 	  {
 	    if (FIXNATP (idx) && XFIXNAT (idx) < ASIZE (elt))
 	      {
-		CHECK_IMPURE (elt, XVECTOR (elt));
 		ASET (elt, XFIXNAT (idx), def);
 		return def;
 	      }
@@ -858,7 +853,6 @@ store_in_keymap (Lisp_Object keymap, register Lisp_Object idx, Lisp_Object def)
 	      }
 	    else if (EQ (idx, XCAR (elt)))
 	      {
-		CHECK_IMPURE (elt, XCONS (elt));
 		XSETCDR (elt, def);
 		return def;
 	      }
@@ -904,7 +898,6 @@ store_in_keymap (Lisp_Object keymap, register Lisp_Object idx, Lisp_Object def)
 	}
       else
 	elt = Fcons (idx, def);
-      CHECK_IMPURE (insertion_point, XCONS (insertion_point));
       XSETCDR (insertion_point, Fcons (elt, XCDR (insertion_point)));
     }
   }
@@ -3604,12 +3597,12 @@ syms_of_keymap (void)
   Fset (intern_c_string ("ctl-x-map"), control_x_map);
   Ffset (intern_c_string ("Control-X-prefix"), control_x_map);
 
-  exclude_keys = pure_list
-    (pure_cons (build_pure_c_string ("DEL"), build_pure_c_string ("\\d")),
-     pure_cons (build_pure_c_string ("TAB"), build_pure_c_string ("\\t")),
-     pure_cons (build_pure_c_string ("RET"), build_pure_c_string ("\\r")),
-     pure_cons (build_pure_c_string ("ESC"), build_pure_c_string ("\\e")),
-     pure_cons (build_pure_c_string ("SPC"), build_pure_c_string (" ")));
+  exclude_keys = list
+    (Fcons (build_string ("DEL"), build_string ("\\d")),
+     Fcons (build_string ("TAB"), build_string ("\\t")),
+     Fcons (build_string ("RET"), build_string ("\\r")),
+     Fcons (build_string ("ESC"), build_string ("\\e")),
+     Fcons (build_string ("SPC"), build_string (" ")));
   staticpro (&exclude_keys);
 
   DEFVAR_LISP ("define-key-rebound-commands", Vdefine_key_rebound_commands,
@@ -3665,12 +3658,12 @@ syms_of_keymap (void)
   DEFSYM (Qmode_line, "mode-line");
 
   staticpro (&Vmouse_events);
-  Vmouse_events = pure_list (Qmenu_bar, Qtool_bar, Qheader_line, Qmode_line,
-			     intern_c_string ("mouse-1"),
-			     intern_c_string ("mouse-2"),
-			     intern_c_string ("mouse-3"),
-			     intern_c_string ("mouse-4"),
-			     intern_c_string ("mouse-5"));
+  Vmouse_events = list (Qmenu_bar, Qtool_bar, Qheader_line, Qmode_line,
+			intern_c_string ("mouse-1"),
+			intern_c_string ("mouse-2"),
+			intern_c_string ("mouse-3"),
+			intern_c_string ("mouse-4"),
+			intern_c_string ("mouse-5"));
 
   /* Keymap used for minibuffers when doing completion.  */
   /* Keymap used for minibuffers when doing completion and require a match.  */
diff --git a/src/lisp.h b/src/lisp.h
index 6d101fed90..8fb6f493b3 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -821,9 +821,6 @@ #define XUNTAG(a, type, ctype) ((ctype *) \
 	 special (with `defvar' etc), and shouldn't be lexically bound.  */
       bool_bf declared_special : 1;
 
-      /* True if pointed to from purespace and hence can't be GC'd.  */
-      bool_bf pinned : 1;
-
       /* The symbol's name, as a Lisp string.  */
       Lisp_Object name;
 
@@ -1513,20 +1510,14 @@ #define STRING_BYTES_BOUND  \
 /* Mark STR as a unibyte string.  */
 #define STRING_SET_UNIBYTE(STR)				\
   do {							\
-    if (XSTRING (STR)->u.s.size == 0)			\
-      (STR) = empty_unibyte_string;			\
-    else						\
-      XSTRING (STR)->u.s.size_byte = -1;		\
+    XSTRING (STR)->u.s.size_byte = -1;			\
   } while (false)
 
 /* Mark STR as a multibyte string.  Assure that STR contains only
    ASCII characters in advance.  */
-#define STRING_SET_MULTIBYTE(STR)			\
-  do {							\
-    if (XSTRING (STR)->u.s.size == 0)			\
-      (STR) = empty_multibyte_string;			\
-    else						\
-      XSTRING (STR)->u.s.size_byte = XSTRING (STR)->u.s.size; \
+#define STRING_SET_MULTIBYTE(STR)				\
+  do {								\
+    XSTRING (STR)->u.s.size_byte = XSTRING (STR)->u.s.size;	\
   } while (false)
 
 /* Convenience functions for dealing with Lisp strings.  */
@@ -2287,12 +2278,8 @@ #define DEFSYM(sym, name) /* empty */
   /* Index of first free entry in free list, or -1 if none.  */
   ptrdiff_t next_free;
 
-  /* True if the table can be purecopied.  The table cannot be
-     changed afterwards.  */
-  bool purecopy;
-
   /* True if the table is mutable.  Ordinarily tables are mutable, but
-     pure tables are not, and while a table is being mutated it is
+     some tables are not, and while a table is being mutated it is
      immutable for recursive attempts to mutate it.  */
   bool mutable;
 
@@ -3601,7 +3588,7 @@ #define CONS_TO_INTEGER(cons, type, var)				\
 Lisp_Object hashfn_eql (Lisp_Object, struct Lisp_Hash_Table *);
 Lisp_Object hashfn_equal (Lisp_Object, struct Lisp_Hash_Table *);
 Lisp_Object make_hash_table (struct hash_table_test, EMACS_INT, float, float,
-                             Lisp_Object, bool);
+                             Lisp_Object);
 ptrdiff_t hash_lookup (struct Lisp_Hash_Table *, Lisp_Object, Lisp_Object *);
 ptrdiff_t hash_put (struct Lisp_Hash_Table *, Lisp_Object, Lisp_Object,
 		    Lisp_Object);
@@ -3752,7 +3739,6 @@ #define CONS_TO_INTEGER(cons, type, var)				\
 
 /* Defined in alloc.c.  */
 extern void *my_heap_start (void);
-extern void check_pure_size (void);
 extern void allocate_string_data (struct Lisp_String *, EMACS_INT, EMACS_INT);
 extern void malloc_warning (const char *);
 extern AVOID memory_full (size_t);
@@ -3783,11 +3769,8 @@ #define OBJECT_CT_MAX INTPTR_MAX
 extern Lisp_Object list5 (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object,
 			  Lisp_Object);
 extern Lisp_Object listn (ptrdiff_t, Lisp_Object, ...);
-extern Lisp_Object pure_listn (ptrdiff_t, Lisp_Object, ...);
 #define list(...) \
   listn (ARRAYELTS (((Lisp_Object []) {__VA_ARGS__})), __VA_ARGS__)
-#define pure_list(...) \
-  pure_listn (ARRAYELTS (((Lisp_Object []) {__VA_ARGS__})), __VA_ARGS__)
 
 enum gc_root_type
 {
@@ -3861,17 +3844,6 @@ build_unibyte_string (const char *str)
 extern Lisp_Object make_string_from_bytes (const char *, ptrdiff_t, ptrdiff_t);
 extern Lisp_Object make_specified_string (const char *,
 					  ptrdiff_t, ptrdiff_t, bool);
-extern Lisp_Object make_pure_string (const char *, ptrdiff_t, ptrdiff_t, bool);
-extern Lisp_Object make_pure_c_string (const char *, ptrdiff_t);
-
-/* Make a string allocated in pure space, use STR as string data.  */
-
-INLINE Lisp_Object
-build_pure_c_string (const char *str)
-{
-  return make_pure_c_string (str, strlen (str));
-}
-
 /* Make a string from the data at STR, treating it as multibyte if the
    data warrants.  */
 
@@ -3881,7 +3853,6 @@ build_string (const char *str)
   return make_string (str, strlen (str));
 }
 
-extern Lisp_Object pure_cons (Lisp_Object, Lisp_Object);
 extern Lisp_Object make_vector (ptrdiff_t, Lisp_Object);
 extern void make_byte_code (struct Lisp_Vector *);
 extern struct Lisp_Vector *allocate_vector (ptrdiff_t);
diff --git a/src/lread.c b/src/lread.c
index eecb5e141d..4ff7808527 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -2043,13 +2043,13 @@ readevalloop (Lisp_Object readcharfun,
 	read_objects_map
 	  = make_hash_table (hashtest_eq, DEFAULT_HASH_SIZE,
 			     DEFAULT_REHASH_SIZE, DEFAULT_REHASH_THRESHOLD,
-			     Qnil, false);
+			     Qnil);
       if (! HASH_TABLE_P (read_objects_completed)
 	  || XHASH_TABLE (read_objects_completed)->count)
 	read_objects_completed
 	  = make_hash_table (hashtest_eq, DEFAULT_HASH_SIZE,
 			     DEFAULT_REHASH_SIZE, DEFAULT_REHASH_THRESHOLD,
-			     Qnil, false);
+			     Qnil);
       if (!NILP (Vpurify_flag) && c == '(')
 	{
 	  val = read_list (0, readcharfun);
@@ -2261,12 +2261,12 @@ read_internal_start (Lisp_Object stream, Lisp_Object start, Lisp_Object end)
       || XHASH_TABLE (read_objects_map)->count)
     read_objects_map
       = make_hash_table (hashtest_eq, DEFAULT_HASH_SIZE, DEFAULT_REHASH_SIZE,
-			 DEFAULT_REHASH_THRESHOLD, Qnil, false);
+			 DEFAULT_REHASH_THRESHOLD, Qnil);
   if (! HASH_TABLE_P (read_objects_completed)
       || XHASH_TABLE (read_objects_completed)->count)
     read_objects_completed
       = make_hash_table (hashtest_eq, DEFAULT_HASH_SIZE, DEFAULT_REHASH_SIZE,
-			 DEFAULT_REHASH_THRESHOLD, Qnil, false);
+			 DEFAULT_REHASH_THRESHOLD, Qnil);
   if (EQ (Vread_with_symbol_positions, Qt)
       || EQ (Vread_with_symbol_positions, stream))
     Vread_symbol_positions_list = Qnil;
@@ -2835,11 +2835,6 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list)
 	      if (!NILP (params[param_count + 1]))
 		param_count += 2;
 
-              params[param_count] = QCpurecopy;
-              params[param_count + 1] = Fplist_get (tmp, Qpurecopy);
-              if (!NILP (params[param_count + 1]))
-                param_count += 2;
-
 	      /* This is the hash table data.  */
 	      data = Fplist_get (tmp, Qdata);
 
@@ -3109,13 +3104,13 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list)
 	      /* No symbol character follows, this is the empty
 		 symbol.  */
 	      UNREAD (c);
-	      return Fmake_symbol (empty_unibyte_string);
+	      return Fmake_symbol (build_string (""));
 	    }
 	  goto read_symbol;
 	}
       /* ## is the empty symbol.  */
       if (c == '#')
-	return Fintern (empty_unibyte_string, Qnil);
+	return Fintern (build_string (""), Qnil);
 
       if (c >= '0' && c <= '9')
 	{
@@ -3566,9 +3561,8 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list)
 	  if (uninterned_symbol)
 	    {
 	      Lisp_Object name
-		= ((! NILP (Vpurify_flag)
-		    ? make_pure_string : make_specified_string)
-		   (read_buffer, nchars, nbytes, multibyte));
+		= make_specified_string (read_buffer, nchars, nbytes,
+					 multibyte);
 	      result = Fmake_symbol (name);
 	    }
 	  else
@@ -4153,10 +4147,8 @@ intern_c_string_1 (const char *str, ptrdiff_t len)
 
   if (!SYMBOLP (tem))
     {
-      /* Creating a non-pure string from a string literal not implemented yet.
-	 We could just use make_string here and live with the extra copy.  */
       eassert (!NILP (Vpurify_flag));
-      tem = intern_driver (make_pure_c_string (str, len), obarray, tem);
+      tem = intern_driver (make_string (str, len), obarray, tem);
     }
   return tem;
 }
@@ -4165,7 +4157,7 @@ intern_c_string_1 (const char *str, ptrdiff_t len)
 define_symbol (Lisp_Object sym, char const *str)
 {
   ptrdiff_t len = strlen (str);
-  Lisp_Object string = make_pure_c_string (str, len);
+  Lisp_Object string = make_string (str, len);
   init_symbol (sym, string);
 
   /* Qunbound is uninterned, so that it's not confused with any symbol
@@ -4192,8 +4184,7 @@ DEFUN ("intern", Fintern, Sintern, 1, 2, 0,
 
   tem = oblookup (obarray, SSDATA (string), SCHARS (string), SBYTES (string));
   if (!SYMBOLP (tem))
-    tem = intern_driver (NILP (Vpurify_flag) ? string : Fpurecopy (string),
-			 obarray, tem);
+    tem = intern_driver (string, obarray, tem);
   return tem;
 }
 
@@ -4843,17 +4834,17 @@ syms_of_lread (void)
 `load' and related functions try to append these suffixes, in order,
 to the specified file name if a suffix is allowed or required.  */);
 #ifdef HAVE_MODULES
-  Vload_suffixes = list3 (build_pure_c_string (".elc"),
-			  build_pure_c_string (".el"),
-			  build_pure_c_string (MODULES_SUFFIX));
+  Vload_suffixes = list3 (build_string (".elc"),
+			  build_string (".el"),
+			  build_string (MODULES_SUFFIX));
 #else
-  Vload_suffixes = list2 (build_pure_c_string (".elc"),
-			  build_pure_c_string (".el"));
+  Vload_suffixes = list2 (build_string (".elc"),
+			  build_string (".el"));
 #endif
   DEFVAR_LISP ("module-file-suffix", Vmodule_file_suffix,
 	       doc: /* Suffix of loadable module file, or nil if modules are not supported.  */);
 #ifdef HAVE_MODULES
-  Vmodule_file_suffix = build_pure_c_string (MODULES_SUFFIX);
+  Vmodule_file_suffix = build_string (MODULES_SUFFIX);
 #else
   Vmodule_file_suffix = Qnil;
 #endif
@@ -4996,7 +4987,7 @@ syms_of_lread (void)
 When the regular expression matches, the file is considered to be safe
 to load.  See also `load-dangerous-libraries'.  */);
   Vbytecomp_version_regexp
-    = build_pure_c_string ("^;;;.\\(in Emacs version\\|bytecomp version FSF\\)");
+    = build_string ("^;;;.\\(in Emacs version\\|bytecomp version FSF\\)");
 
   DEFSYM (Qlexical_binding, "lexical-binding");
   DEFVAR_LISP ("lexical-binding", Vlexical_binding,
diff --git a/src/pdumper.c b/src/pdumper.c
index 2abac80a37..efebe8e57c 100644
--- a/src/pdumper.c
+++ b/src/pdumper.c
@@ -2471,7 +2471,6 @@ dump_symbol (struct dump_context *ctx,
   DUMP_FIELD_COPY (&out, symbol, u.s.trapped_write);
   DUMP_FIELD_COPY (&out, symbol, u.s.interned);
   DUMP_FIELD_COPY (&out, symbol, u.s.declared_special);
-  DUMP_FIELD_COPY (&out, symbol, u.s.pinned);
   dump_field_lv (ctx, &out, symbol, &symbol->u.s.name, WEIGHT_STRONG);
   switch (symbol->u.s.redirect)
     {
@@ -2741,7 +2740,6 @@ dump_hash_table (struct dump_context *ctx,
      them as close to the hash table as possible.  */
   DUMP_FIELD_COPY (out, hash, count);
   DUMP_FIELD_COPY (out, hash, next_free);
-  DUMP_FIELD_COPY (out, hash, purecopy);
   DUMP_FIELD_COPY (out, hash, mutable);
   DUMP_FIELD_COPY (out, hash, rehash_threshold);
   DUMP_FIELD_COPY (out, hash, rehash_size);
diff --git a/src/print.c b/src/print.c
index cb34090514..534fc168fb 100644
--- a/src/print.c
+++ b/src/print.c
@@ -1575,12 +1575,6 @@ print_vectorlike (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag,
 	print_object (Fhash_table_rehash_threshold (obj),
 		      printcharfun, escapeflag);
 
-	if (h->purecopy)
-	  {
-	    print_c_string (" purecopy ", printcharfun);
-	    print_object (h->purecopy ? Qt : Qnil, printcharfun, escapeflag);
-	  }
-
 	print_c_string (" data ", printcharfun);
 
 	/* Print the data here as a plist. */
diff --git a/src/process.c b/src/process.c
index abadabe77e..1600f9d45e 100644
--- a/src/process.c
+++ b/src/process.c
@@ -8368,7 +8368,7 @@ syms_of_process (void)
    const struct socket_options *sopt;
 
 #define ADD_SUBFEATURE(key, val) \
-  subfeatures = pure_cons (pure_cons (key, pure_cons (val, Qnil)), subfeatures)
+  subfeatures = Fcons (Fcons (key, Fcons (val, Qnil)), subfeatures)
 
    ADD_SUBFEATURE (QCnowait, Qt);
 #ifdef DATAGRAM_SOCKETS
@@ -8390,7 +8390,7 @@ #define ADD_SUBFEATURE(key, val) \
    ADD_SUBFEATURE (QCserver, Qt);
 
    for (sopt = socket_options; sopt->name; sopt++)
-     subfeatures = pure_cons (intern_c_string (sopt->name), subfeatures);
+     subfeatures = Fcons (intern_c_string (sopt->name), subfeatures);
 
    Fprovide (intern_c_string ("make-network-process"), subfeatures);
  }
diff --git a/src/profiler.c b/src/profiler.c
index ed0e9ddd88..3838f9c836 100644
--- a/src/profiler.c
+++ b/src/profiler.c
@@ -63,7 +63,7 @@ make_log (void)
   Lisp_Object log = make_hash_table (hashtest_profiler, heap_size,
 				     DEFAULT_REHASH_SIZE,
 				     DEFAULT_REHASH_THRESHOLD,
-				     Qnil, false);
+				     Qnil);
   struct Lisp_Hash_Table *h = XHASH_TABLE (log);
 
   /* What is special about our hash-tables is that the keys are pre-filled
diff --git a/src/puresize.h b/src/puresize.h
index f5fad8b42b..e69de29bb2 100644
--- a/src/puresize.h
+++ b/src/puresize.h
@@ -1,115 +0,0 @@
-/* How much read-only Lisp storage a dumped Emacs needs.
-   Copyright (C) 1993, 2001-2019 Free Software Foundation, Inc.
-
-This file is part of GNU Emacs.
-
-GNU Emacs is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or (at
-your option) any later version.
-
-GNU Emacs is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.  */
-
-#ifndef EMACS_PURESIZE_H
-#define EMACS_PURESIZE_H
-
-#include "lisp.h"
-
-INLINE_HEADER_BEGIN
-
-/* Define PURESIZE, the number of bytes of pure Lisp code to leave space for.
-
-   At one point, this was defined in config.h, meaning that changing
-   PURESIZE would make Make recompile all of Emacs.  But only a few
-   files actually use PURESIZE, so we split it out to its own .h file.
-
-   Make sure to include this file after config.h, since that tells us
-   whether we are running X windows, which tells us how much pure
-   storage to allocate.  */
-
-/* First define a measure of the amount of data we have.  */
-
-/* A system configuration file may set this to request a certain extra
-   amount of storage.  This is a lot more update-robust that defining
-   BASE_PURESIZE or even PURESIZE directly.  */
-#ifndef SYSTEM_PURESIZE_EXTRA
-#define SYSTEM_PURESIZE_EXTRA 0
-#endif
-
-#ifndef SITELOAD_PURESIZE_EXTRA
-#define SITELOAD_PURESIZE_EXTRA 0
-#endif
-
-#ifndef BASE_PURESIZE
-#define BASE_PURESIZE (2000000 + SYSTEM_PURESIZE_EXTRA + SITELOAD_PURESIZE_EXTRA)
-#endif
-
-/* Increase BASE_PURESIZE by a ratio depending on the machine's word size.  */
-#ifndef PURESIZE_RATIO
-#if EMACS_INT_MAX >> 31 != 0
-#if PTRDIFF_MAX >> 31 != 0
-#define PURESIZE_RATIO 10 / 6	/* Don't surround with `()'.  */
-#else
-#define PURESIZE_RATIO 8 / 6	/* Don't surround with `()'.  */
-#endif
-#else
-#define PURESIZE_RATIO 1
-#endif
-#endif
-
-#ifdef ENABLE_CHECKING
-/* ENABLE_CHECKING somehow increases the purespace used, probably because
-   it tends to cause some macro arguments to be evaluated twice.  This is
-   a bug, but it's difficult to track it down.  */
-#define PURESIZE_CHECKING_RATIO 12 / 10	/* Don't surround with `()'.  */
-#else
-#define PURESIZE_CHECKING_RATIO 1
-#endif
-
-/* This is the actual size in bytes to allocate.  */
-#ifndef PURESIZE
-#define PURESIZE  (BASE_PURESIZE * PURESIZE_RATIO * PURESIZE_CHECKING_RATIO)
-#endif
-
-extern AVOID pure_write_error (Lisp_Object);
-
-extern EMACS_INT pure[];
-
-/* The puresize_h_* macros are private to this include file.  */
-
-/* True if PTR is pure.  */
-
-#define puresize_h_PURE_P(ptr) \
-  ((uintptr_t) (ptr) - (uintptr_t) pure <= PURESIZE)
-
-INLINE bool
-PURE_P (void *ptr)
-{
-  return puresize_h_PURE_P (ptr);
-}
-
-/* Signal an error if OBJ is pure.  PTR is OBJ untagged.  */
-
-#define puresize_h_CHECK_IMPURE(obj, ptr) \
-  (PURE_P (ptr) ? pure_write_error (obj) : (void) 0)
-
-INLINE void
-CHECK_IMPURE (Lisp_Object obj, void *ptr)
-{
-  puresize_h_CHECK_IMPURE (obj, ptr);
-}
-
-#if DEFINE_KEY_OPS_AS_MACROS
-# define PURE_P(ptr) puresize_h_PURE_P (ptr)
-# define CHECK_IMPURE(obj, ptr) puresize_h_CHECK_IMPURE (obj, ptr)
-#endif
-
-INLINE_HEADER_END
-
-#endif /* EMACS_PURESIZE_H */
diff --git a/src/search.c b/src/search.c
index fa574959fb..49c2a29e19 100644
--- a/src/search.c
+++ b/src/search.c
@@ -3368,19 +3368,19 @@ syms_of_search (void)
   DEFSYM (Qinvalid_regexp, "invalid-regexp");
 
   Fput (Qsearch_failed, Qerror_conditions,
-	pure_list (Qsearch_failed, Qerror));
+	list (Qsearch_failed, Qerror));
   Fput (Qsearch_failed, Qerror_message,
-	build_pure_c_string ("Search failed"));
+	build_string ("Search failed"));
 
   Fput (Quser_search_failed, Qerror_conditions,
-	pure_list (Quser_search_failed, Quser_error, Qsearch_failed, Qerror));
+	list (Quser_search_failed, Quser_error, Qsearch_failed, Qerror));
   Fput (Quser_search_failed, Qerror_message,
-        build_pure_c_string ("Search failed"));
+        build_string ("Search failed"));
 
   Fput (Qinvalid_regexp, Qerror_conditions,
-	pure_list (Qinvalid_regexp, Qerror));
+	list (Qinvalid_regexp, Qerror));
   Fput (Qinvalid_regexp, Qerror_message,
-	build_pure_c_string ("Invalid regexp"));
+	build_string ("Invalid regexp"));
 
   re_match_object = Qnil;
   staticpro (&re_match_object);
diff --git a/src/syntax.c b/src/syntax.c
index edfdae2259..15bfba9024 100644
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -3716,9 +3716,9 @@ syms_of_syntax (void)
 
   DEFSYM (Qscan_error, "scan-error");
   Fput (Qscan_error, Qerror_conditions,
-	pure_list (Qscan_error, Qerror));
+	list (Qscan_error, Qerror));
   Fput (Qscan_error, Qerror_message,
-	build_pure_c_string ("Scan error"));
+	build_string ("Scan error"));
 
   DEFVAR_BOOL ("parse-sexp-ignore-comments", parse_sexp_ignore_comments,
 	       doc: /* Non-nil means `forward-sexp', etc., should treat comments as whitespace.  */);
diff --git a/src/w32fns.c b/src/w32fns.c
index acd9c80528..ed3b0b3a2d 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -10259,9 +10259,9 @@ syms_of_w32fns (void)
   DEFSYM (Qjson, "json");
 
   Fput (Qundefined_color, Qerror_conditions,
-	pure_list (Qundefined_color, Qerror));
+	list (Qundefined_color, Qerror));
   Fput (Qundefined_color, Qerror_message,
-	build_pure_c_string ("Undefined color"));
+	build_string ("Undefined color"));
 
   staticpro (&w32_grabbed_keys);
   w32_grabbed_keys = Qnil;
diff --git a/src/xdisp.c b/src/xdisp.c
index 50f6443f6b..1781774148 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -32985,7 +32985,7 @@ syms_of_xdisp (void)
   staticpro (&echo_area_buffer[0]);
   staticpro (&echo_area_buffer[1]);
 
-  Vmessages_buffer_name = build_pure_c_string ("*Messages*");
+  Vmessages_buffer_name = build_string ("*Messages*");
   staticpro (&Vmessages_buffer_name);
 
   mode_line_proptrans_alist = Qnil;
@@ -33068,7 +33068,7 @@ syms_of_xdisp (void)
   DEFVAR_LISP ("overlay-arrow-string", Voverlay_arrow_string,
     doc: /* String to display as an arrow in non-window frames.
 See also `overlay-arrow-position'.  */);
-  Voverlay_arrow_string = build_pure_c_string ("=>");
+  Voverlay_arrow_string = build_string ("=>");
 
   DEFVAR_LISP ("overlay-arrow-variable-list", Voverlay_arrow_variable_list,
     doc: /* List of variables (symbols) which hold markers for overlay arrows.
@@ -33176,18 +33176,18 @@ syms_of_xdisp (void)
 This variable has the same structure as `mode-line-format' (which see),
 and is used only on frames for which no explicit name has been set
 \(see `modify-frame-parameters').  */);
-  /* Do not nest calls to pure_list.  This works around a bug in
+  /* Do not nest calls to list.  This works around a bug in
      Oracle Developer Studio 12.6.  */
   Lisp_Object icon_title_name_format
-    = pure_list (empty_unibyte_string,
-		 intern_c_string ("invocation-name"),
-		 build_pure_c_string ("@"),
-		 intern_c_string ("system-name"));
+    = list (empty_unibyte_string,
+	    intern_c_string ("invocation-name"),
+	    build_string ("@"),
+	    intern_c_string ("system-name"));
   Vicon_title_format
     = Vframe_title_format
-    = pure_list (intern_c_string ("multiple-frames"),
-		 build_pure_c_string ("%b"),
-		 icon_title_name_format);
+    = list (intern_c_string ("multiple-frames"),
+	    build_string ("%b"),
+	    icon_title_name_format);
 
   DEFVAR_LISP ("message-log-max", Vmessage_log_max,
     doc: /* Maximum number of lines to keep in the message log buffer.
diff --git a/src/xfaces.c b/src/xfaces.c
index c3cae7e2a6..41e02f2a80 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -6659,7 +6659,7 @@ syms_of_xfaces (void)
 This stipple pattern is used on monochrome displays
 instead of shades of gray for a face background color.
 See `set-face-stipple' for possible values for this variable.  */);
-  Vface_default_stipple = build_pure_c_string ("gray3");
+  Vface_default_stipple = build_string ("gray3");
 
   DEFVAR_LISP ("tty-defined-color-alist", Vtty_defined_color_alist,
    doc: /* An alist of defined terminal colors and their RGB values.
diff --git a/src/xfns.c b/src/xfns.c
index b8a1914186..aee20630a3 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -7680,9 +7680,9 @@ syms_of_xfns (void)
 #endif
 
   Fput (Qundefined_color, Qerror_conditions,
-	pure_list (Qundefined_color, Qerror));
+	list (Qundefined_color, Qerror));
   Fput (Qundefined_color, Qerror_message,
-	build_pure_c_string ("Undefined color"));
+	build_string ("Undefined color"));
 
   DEFVAR_LISP ("x-pointer-shape", Vx_pointer_shape,
     doc: /* The shape of the pointer when over text.
@@ -7871,7 +7871,7 @@ syms_of_xfns (void)
     char gtk_version[sizeof ".." + 3 * INT_STRLEN_BOUND (int)];
     int len = sprintf (gtk_version, "%d.%d.%d",
 		       GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION);
-    Vgtk_version_string = make_pure_string (gtk_version, len, len, false);
+    Vgtk_version_string = make_specified_string (gtk_version, len, len, false);
   }
 #endif /* USE_GTK */
 
@@ -7885,7 +7885,8 @@ syms_of_xfns (void)
     int len = sprintf (cairo_version, "%d.%d.%d",
 		       CAIRO_VERSION_MAJOR, CAIRO_VERSION_MINOR,
                        CAIRO_VERSION_MICRO);
-    Vcairo_version_string = make_pure_string (cairo_version, len, len, false);
+    Vcairo_version_string = make_specified_string (cairo_version, len, len,
+						   false);
   }
 #endif
 
diff --git a/src/xterm.c b/src/xterm.c
index c96aa74a7a..964c588e05 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -13498,7 +13498,7 @@ syms_of_xterm (void)
   DEFSYM (Qlatin_1, "latin-1");
 
 #ifdef USE_GTK
-  xg_default_icon_file = build_pure_c_string ("icons/hicolor/scalable/apps/emacs.svg");
+  xg_default_icon_file = build_string ("icons/hicolor/scalable/apps/emacs.svg");
   staticpro (&xg_default_icon_file);
 
   DEFSYM (Qx_gtk_map_stock, "x-gtk-map-stock");
@@ -13619,7 +13619,7 @@ syms_of_xterm (void)
   Vx_keysym_table = make_hash_table (hashtest_eql, 900,
 				     DEFAULT_REHASH_SIZE,
 				     DEFAULT_REHASH_THRESHOLD,
-				     Qnil, false);
+				     Qnil);
 
   DEFVAR_BOOL ("x-frame-normalize-before-maximize",
 	       x_frame_normalize_before_maximize,
-- 
2.22.0


  reply	other threads:[~2019-07-21 12:53 UTC|newest]

Thread overview: 125+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-07-14 14:26 bug#36649: 27.0.50; pure space and pdumper Pip Cet
2019-07-21  7:28 ` Paul Eggert
2019-07-21 12:53   ` Pip Cet [this message]
2019-07-21 13:44     ` Robert Pluim
2019-07-21 14:36       ` Pip Cet
2019-07-21 15:06         ` Robert Pluim
2019-07-21 17:43           ` Pip Cet
2019-07-21 17:56             ` Robert Pluim
2019-07-21 18:07               ` Pip Cet
2019-07-21 19:12                 ` Robert Pluim
2019-07-21 19:35                   ` Pip Cet
2019-07-21 20:20                     ` Robert Pluim
2019-07-22  3:58                       ` Pip Cet
2019-07-22  8:14                         ` Robert Pluim
2019-07-22 14:30                           ` Eli Zaretskii
2019-07-22 15:46                             ` Robert Pluim
2019-07-22 15:03                           ` Pip Cet
2019-07-22 18:45                             ` Robert Pluim
2020-08-21 12:51                               ` Lars Ingebrigtsen
2020-08-21 13:04                                 ` Pip Cet
2020-08-21 13:47                                   ` Eli Zaretskii
2020-08-21 15:26                                     ` Andreas Schwab
2020-08-21 21:41                                     ` Paul Eggert
2020-08-22  3:51                                     ` Richard Stallman
2020-08-22  8:55                                     ` Pip Cet
2020-08-22  9:59                                       ` Andreas Schwab
2020-08-28 12:32                                         ` Pip Cet
2020-08-28 14:24                                           ` Andrea Corallo via Bug reports for GNU Emacs, the Swiss army knife of text editors
2020-11-15 15:19                                           ` Stefan Kangas
2021-03-03 15:34                                             ` Pip Cet
2021-03-04 12:55                                               ` Pip Cet
2021-03-04 14:56                                                 ` Robert Pluim
2021-03-04 15:49                                                   ` Eli Zaretskii
2021-03-04 16:42                                                     ` Robert Pluim
2021-03-04 17:07                                                       ` Eli Zaretskii
2021-03-04 17:18                                                         ` Robert Pluim
2021-03-04 16:53                                                     ` martin rudalics
2021-03-04 17:45                                                     ` Andy Moreton
2021-03-04 21:52                                                   ` Paul Eggert
2021-03-05  3:00                                                     ` Pip Cet
2021-03-05  7:20                                                       ` Eli Zaretskii
2021-03-14 22:19                                                       ` Stefan Monnier
2021-05-12 14:50                                                         ` Lars Ingebrigtsen
2021-05-12 15:01                                                           ` Eli Zaretskii
2021-05-12 17:03                                                             ` Lars Ingebrigtsen
2021-05-12 17:06                                                               ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2021-05-12 17:11                                                                 ` Lars Ingebrigtsen
2021-05-12 17:28                                                                   ` Eli Zaretskii
2021-05-12 17:32                                                                     ` Lars Ingebrigtsen
2021-05-12 17:42                                                                       ` Eli Zaretskii
2021-05-12 17:58                                                                         ` Lars Ingebrigtsen
2021-05-12 18:25                                                                           ` Lars Ingebrigtsen
2021-05-12 18:37                                                                             ` Eli Zaretskii
2021-05-12 18:48                                                                               ` Lars Ingebrigtsen
2021-05-12 18:52                                                                                 ` Eli Zaretskii
2021-05-12 19:07                                                                                   ` Lars Ingebrigtsen
2021-05-12 19:12                                                                                     ` Eli Zaretskii
2021-05-12 19:44                                                                                       ` Lars Ingebrigtsen
2021-05-13 14:44                                                                                         ` Pip Cet
2021-05-13 21:23                                                                                           ` Andrea Corallo via Bug reports for GNU Emacs, the Swiss army knife of text editors
2021-05-14  6:26                                                                                             ` Eli Zaretskii
2021-05-14  6:35                                                                                               ` Andrea Corallo via Bug reports for GNU Emacs, the Swiss army knife of text editors
2021-05-14  7:07                                                                                                 ` Eli Zaretskii
2021-05-16 13:46                                                                                             ` Lars Ingebrigtsen
2021-05-13 14:08                                                                                   ` Eli Zaretskii
2021-05-16 13:38                                                                                     ` Lars Ingebrigtsen
2021-05-17  8:43                                                                                       ` Paul Eggert
2021-05-17 10:25                                                                                         ` Eli Zaretskii
2021-05-17 14:15                                                                                           ` Lars Ingebrigtsen
2021-05-17 14:23                                                                                             ` Eli Zaretskii
2021-05-19 15:11                                                                                               ` Eli Zaretskii
2021-05-19 17:29                                                                                                 ` Paul Eggert
2021-05-19 17:38                                                                                                   ` Eli Zaretskii
2021-05-19 17:43                                                                                                     ` Paul Eggert
2021-05-20  8:46                                                                                                       ` Eli Zaretskii
2021-05-19 18:55                                                                                                 ` Lars Ingebrigtsen
2021-05-17 14:32                                                                                             ` Andreas Schwab
2021-05-18 13:33                                                                                               ` Lars Ingebrigtsen
2021-10-20 17:41                                                                                           ` Stefan Kangas
2021-10-20 18:18                                                                                             ` Eli Zaretskii
2021-05-17 14:13                                                                                         ` Lars Ingebrigtsen
2021-05-12 19:12                                                                           ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2021-05-12 18:02                                                                       ` Paul Eggert
2021-05-12 17:37                                                                     ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2021-05-12 17:44                                                                       ` Eli Zaretskii
2021-05-12 19:07                                                                         ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2021-05-12 19:17                                                                           ` Eli Zaretskii
2021-05-12 17:19                                                                 ` Eli Zaretskii
2021-05-12 17:10                                                               ` Eli Zaretskii
2021-05-12 17:24                                                                 ` Lars Ingebrigtsen
2020-08-22 17:36                                       ` Paul Eggert
2019-07-21 18:14               ` Eli Zaretskii
2022-07-01 13:46 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-07-01 15:51   ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-07-01 16:03     ` Eli Zaretskii
2022-07-01 16:33       ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-07-01 18:12         ` Eli Zaretskii
2022-07-01 18:58           ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-07-02  8:55             ` Pip Cet
2022-07-02  9:06               ` Eli Zaretskii
2022-07-02  9:16                 ` Lars Ingebrigtsen
2022-07-02  9:22                   ` Eli Zaretskii
2022-07-02 10:30                     ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-07-02 10:41                       ` Eli Zaretskii
2022-07-02 10:51                         ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-07-02 12:07                           ` Lars Ingebrigtsen
2022-07-02 12:22                             ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-07-02 12:41                               ` Lars Ingebrigtsen
2022-07-02 12:45                                 ` Eli Zaretskii
2022-07-02 17:23                                   ` Lars Ingebrigtsen
2022-07-02 17:31                                     ` Eli Zaretskii
2022-07-02 16:57                     ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-07-02 17:11                       ` Eli Zaretskii
2022-07-02 18:03                         ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-07-02 18:32                           ` Eli Zaretskii
2022-07-02 10:28                   ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-07-02 10:32                     ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-07-02 10:40                     ` Eli Zaretskii
2022-07-02 10:55                       ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-07-03  7:14 ` Gerd Möllmann
2022-07-03  7:42   ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-07-03  8:21     ` Gerd Möllmann
2022-07-03  9:38       ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-07-03  9:42         ` Gerd Möllmann
2022-07-03 10:01           ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAOqdjBdF0JgDJj1H5hc=XBnOxJc=dyCMb=+OhbVh1Tb6fiVnCQ@mail.gmail.com' \
    --to=pipcet@gmail.com \
    --cc=36649@debbugs.gnu.org \
    --cc=eggert@cs.ucla.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).