Mercurial > hg > xemacs-beta
view src/vdb.c @ 5776:65d65b52d608
Pass character count from coding systems to buffer insertion code.
src/ChangeLog addition:
2014-01-16 Aidan Kehoe <kehoea@parhasard.net>
Pass character count information from the no-conversion and
unicode coding systems to the buffer insertion code, making
#'find-file on large buffers a little snappier (if
ERROR_CHECK_TEXT is not defined).
* file-coding.c:
* file-coding.c (coding_character_tell): New.
* file-coding.c (conversion_coding_stream_description): New.
* file-coding.c (no_conversion_convert):
Update characters_seen when decoding.
* file-coding.c (no_conversion_character_tell): New.
* file-coding.c (lstream_type_create_file_coding): Create the
no_conversion type with data.
* file-coding.c (coding_system_type_create):
Make the character_tell method available here.
* file-coding.h:
* file-coding.h (struct coding_system_methods):
Add a new character_tell() method, passing charcount information
from the coding systems to the buffer code, avoiding duplicate
bytecount-to-charcount work especially with large buffers.
* fileio.c (Finsert_file_contents_internal):
Update this to pass charcount information to
buffer_insert_string_1(), if that is available from the lstream code.
* insdel.c:
* insdel.c (buffer_insert_string_1):
Add a new CCLEN argument, giving the character count of the string
to insert. It can be -1 to indicate that te function should work
it out itself using bytecount_to_charcount(), as it used to.
* insdel.c (buffer_insert_raw_string_1):
* insdel.c (buffer_insert_lisp_string_1):
* insdel.c (buffer_insert_ascstring_1):
* insdel.c (buffer_insert_emacs_char_1):
* insdel.c (buffer_insert_from_buffer_1):
* insdel.c (buffer_replace_char):
Update these functions to use the new calling convention.
* insdel.h:
* insdel.h (buffer_insert_string):
Update this header to reflect the new buffer_insert_string_1()
argument.
* lstream.c (Lstream_character_tell): New.
Return the number of characters *read* and seen by the consumer so
far, taking into account the unget buffer, and buffered reading.
* lstream.c (Lstream_unread):
Update unget_character_count here as appropriate.
* lstream.c (Lstream_rewind):
Reset unget_character_count here too.
* lstream.h:
* lstream.h (struct lstream):
Provide the character_tell method, add a new field,
unget_character_count, giving the number of characters ever passed
to Lstream_unread().
Declare Lstream_character_tell().
Make Lstream_ungetc(), which happens to be unused, an inline
function rather than a macro, in the course of updating it to
modify unget_character_count.
* print.c (output_string):
Use the new argument to buffer_insert_string_1().
* tests.c:
* tests.c (Ftest_character_tell):
New test function.
* tests.c (syms_of_tests):
Make it available.
* unicode.c:
* unicode.c (struct unicode_coding_stream):
* unicode.c (unicode_character_tell):
New method.
* unicode.c (unicode_convert):
Update the character counter as appropriate.
* unicode.c (coding_system_type_create_unicode):
Make the character_tell method available.
author | Aidan Kehoe <kehoea@parhasard.net> |
---|---|
date | Thu, 16 Jan 2014 16:27:52 +0000 |
parents | 308d34e9f07d |
children |
line wrap: on
line source
/* Virtual diry bit implementation (platform independent) for XEmacs. Copyright (C) 2005 Marcus Crestani. Copyright (C) 2010 Ben Wing. This file is part of XEmacs. XEmacs 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. XEmacs 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 XEmacs. If not, see <http://www.gnu.org/licenses/>. */ /* Synched up with: Not in FSF. */ #include <config.h> #include "lisp.h" #include "gc.h" #include "mc-alloc.h" #include "vdb.h" typedef struct { Dynarr_declare (void *); } void_ptr_dynarr; void_ptr_dynarr *page_fault_table; /* Init page fault table and protect heap. */ void vdb_start_dirty_bits_recording (void) { Elemcount protected_pages = (Elemcount) protect_heap_pages (); page_fault_table = Dynarr_new2 (void_ptr_dynarr, void *); Dynarr_resize (page_fault_table, protected_pages); } /* Remove heap protection. */ void vdb_stop_dirty_bits_recording (void) { unprotect_heap_pages (); } /* Read page fault table and pass page faults to garbage collector. */ int vdb_read_dirty_bits (void) { int repushed_objects = 0; Elemcount count; for (count = Dynarr_length (page_fault_table); count; count--) repushed_objects += repush_all_objects_on_page (Dynarr_at (page_fault_table, count - 1)); Dynarr_free (page_fault_table); page_fault_table = 0; return repushed_objects; } /* Called by the page fault handler: add address to page fault table. */ void vdb_designate_modified (void *addr) { Dynarr_add (page_fault_table, addr); } /* For testing and debugging... */ #ifdef DEBUG_XEMACS DEFUN ("test-vdb", Ftest_vdb, 0, 0, "", /* Test virtual dirty bit implementation. Prints results to stderr. */ ()) { Rawbyte *p; char c; Elemcount count; /* Wrap up gc (if currently running). */ gc_full (); /* Allocate a buffer; it will have the default protection of PROT_READ|PROT_WRITE. */ p = (Rawbyte *) mc_alloc (mc_get_page_size()); set_lheader_implementation ((struct lrecord_header *) p, &lrecord_cons); fprintf (stderr, "Allocate p: [%p ... %p], length %d\n", p, p + mc_get_page_size (), (int) mc_get_page_size ()); /* Test read. */ fprintf (stderr, "Attempt to read p[666]... "); c = p[666]; fprintf (stderr, "read ok.\n"); /* Test write. */ fprintf (stderr, "Attempt to write 42 to p[666]... "); p[666] = 42; fprintf (stderr, "write ok, p[666] = %d\n", p[666]); /* Mark the buffer read-only and set environemnt for write-barrier. */ fprintf (stderr, "Write-protect the page.\n"); MARK_BLACK (p); vdb_start_dirty_bits_recording (); write_barrier_enabled = 1; /* Test write-barrier read. */ fprintf (stderr, "Attempt to read p[666]... "); c = p[666]; fprintf (stderr, "read ok.\n"); /* Test write-barrier write, program receives SIGSEGV. */ fprintf (stderr, "Attempt to write 23 to p[666]... "); p[666] = 23; fprintf (stderr, "Written p[666] = %d\n", p[666]); /* Stop write-barrier mode. */ write_barrier_enabled = 0; MARK_WHITE (p); vdb_unprotect (p, mc_get_page_size ()); for (count = Dynarr_length (page_fault_table); count; count--) if (Dynarr_at (page_fault_table, count - 1) == &p[666]) fprintf (stderr, "VALID page fault at %p\n", Dynarr_at (page_fault_table, count - 1)); else fprintf (stderr, "WRONG page fault at %p\n", Dynarr_at (page_fault_table, count - 1)); Dynarr_free (page_fault_table); return Qnil; } DEFUN ("test-segfault", Ftest_segfault, 0, 0, "", /* Test virtual dirty bit implementation: provoke a segfault on purpose. WARNING: this function causes a SEGFAULT on purpose and thus crashes XEmacs! This is only used for debbugging, e.g. for testing how the debugger behaves when XEmacs segfaults and the write barrier is enabled. */ ()) { Rawbyte *q = 0; q[0] = 23; return Qnil; } #endif /* DEBUG_XEMACS */ void syms_of_vdb (void) { #ifdef DEBUG_XEMACS DEFSUBR (Ftest_vdb); DEFSUBR (Ftest_segfault); #endif /* DEBUG_XEMACS */ }