summaryrefslogtreecommitdiff
path: root/src/buffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/buffer.c')
-rw-r--r--src/buffer.c68
1 files changed, 52 insertions, 16 deletions
diff --git a/src/buffer.c b/src/buffer.c
index cc0899676de..a12c80ec0b0 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -44,6 +44,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include "keymap.h"
#include "frame.h"
#include "xwidget.h"
+#include "pdumper.h"
#ifdef WINDOWSNT
#include "w32heap.h" /* for mmap_* */
@@ -529,6 +530,8 @@ even if it is dead. The return value is never nil. */)
/* No one shows us now. */
b->window_count = 0;
+ memset (&b->local_flags, 0, sizeof (b->local_flags));
+
BUF_GAP_SIZE (b) = 20;
block_input ();
/* We allocate extra 1-byte at the tail and keep it always '\0' for
@@ -781,6 +784,8 @@ CLONE nil means the indirect buffer's state is reset to default values. */)
/* Always -1 for an indirect buffer. */
b->window_count = -1;
+ memset (&b->local_flags, 0, sizeof (b->local_flags));
+
b->pt = b->base_buffer->pt;
b->begv = b->base_buffer->begv;
b->zv = b->base_buffer->zv;
@@ -5001,24 +5006,37 @@ alloc_buffer_text (struct buffer *b, ptrdiff_t nbytes)
void
enlarge_buffer_text (struct buffer *b, ptrdiff_t delta)
{
- void *p;
- ptrdiff_t nbytes = (BUF_Z_BYTE (b) - BUF_BEG_BYTE (b) + BUF_GAP_SIZE (b) + 1
- + delta);
block_input ();
+ void *p;
+ unsigned char *old_beg = b->text->beg;
+ ptrdiff_t old_nbytes =
+ BUF_Z_BYTE (b) - BUF_BEG_BYTE (b) + BUF_GAP_SIZE (b) + 1;
+ ptrdiff_t new_nbytes = old_nbytes + delta;
+
+ if (pdumper_object_p (old_beg))
+ b->text->beg = NULL;
+ else
+ old_beg = NULL;
+
#if defined USE_MMAP_FOR_BUFFERS
- p = mmap_realloc ((void **) &b->text->beg, nbytes);
+ p = mmap_realloc ((void **) &b->text->beg, new_nbytes);
#elif defined REL_ALLOC
- p = r_re_alloc ((void **) &b->text->beg, nbytes);
+ p = r_re_alloc ((void **) &b->text->beg, new_nbytes);
#else
- p = xrealloc (b->text->beg, nbytes);
+ p = xrealloc (b->text->beg, new_nbytes);
#endif
if (p == NULL)
{
+ if (old_beg)
+ b->text->beg = old_beg;
unblock_input ();
- memory_full (nbytes);
+ memory_full (new_nbytes);
}
+ if (old_beg)
+ memcpy (p, old_beg, min (old_nbytes, new_nbytes));
+
BUF_BEG_ADDR (b) = p;
unblock_input ();
}
@@ -5031,13 +5049,16 @@ free_buffer_text (struct buffer *b)
{
block_input ();
+ if (!pdumper_object_p (b->text->beg))
+ {
#if defined USE_MMAP_FOR_BUFFERS
- mmap_free ((void **) &b->text->beg);
+ mmap_free ((void **) &b->text->beg);
#elif defined REL_ALLOC
- r_alloc_free ((void **) &b->text->beg);
+ r_alloc_free ((void **) &b->text->beg);
#else
- xfree (b->text->beg);
+ xfree (b->text->beg);
#endif
+ }
BUF_BEG_ADDR (b) = NULL;
unblock_input ();
@@ -5048,14 +5069,25 @@ free_buffer_text (struct buffer *b)
/***********************************************************************
Initialization
***********************************************************************/
-
void
init_buffer_once (void)
{
+ /* TODO: clean up the buffer-local machinery. Right now,
+ we have:
+
+ buffer_defaults: default values of buffer-locals
+ buffer_local_flags: metadata
+ buffer_permanent_local_flags: metadata
+ buffer_local_symbols: metadata
+
+ There must be a simpler way to store the metadata.
+ */
+
int idx;
/* Items flagged permanent get an explicit permanent-local property
added in bindings.el, for clarity. */
+ PDUMPER_REMEMBER_SCALAR (buffer_permanent_local_flags);
memset (buffer_permanent_local_flags, 0, sizeof buffer_permanent_local_flags);
/* 0 means not a lisp var, -1 means always local, else mask. */
@@ -5144,10 +5176,15 @@ init_buffer_once (void)
XSETFASTINT (BVAR (&buffer_local_flags, extra_line_spacing), idx); ++idx;
XSETFASTINT (BVAR (&buffer_local_flags, cursor_in_non_selected_windows), idx); ++idx;
+ /* buffer_local_flags contains no pointers, so it's safe to treat it
+ as a blob for pdumper. */
+ PDUMPER_REMEMBER_SCALAR (buffer_local_flags);
+
/* Need more room? */
if (idx >= MAX_PER_BUFFER_VARS)
emacs_abort ();
last_per_buffer_idx = idx;
+ PDUMPER_REMEMBER_SCALAR (last_per_buffer_idx);
/* Make sure all markable slots in buffer_defaults
are initialized reasonably, so mark_buffer won't choke. */
@@ -5242,7 +5279,9 @@ init_buffer_once (void)
Vbuffer_alist = Qnil;
current_buffer = 0;
+ pdumper_remember_lv_ptr_raw (&current_buffer, Lisp_Vectorlike);
all_buffers = 0;
+ pdumper_remember_lv_ptr_raw (&all_buffers, Lisp_Vectorlike);
QSFundamental = build_pure_c_string ("Fundamental");
@@ -5266,12 +5305,12 @@ init_buffer_once (void)
}
void
-init_buffer (int initialized)
+init_buffer (void)
{
Lisp_Object temp;
#ifdef USE_MMAP_FOR_BUFFERS
- if (initialized)
+ if (dumped_with_unexec_p ())
{
struct buffer *b;
@@ -5312,9 +5351,6 @@ init_buffer (int initialized)
eassert (b->text->beg != NULL);
}
}
-#else /* not USE_MMAP_FOR_BUFFERS */
- /* Avoid compiler warnings. */
- (void) initialized;
#endif /* USE_MMAP_FOR_BUFFERS */
AUTO_STRING (scratch, "*scratch*");