diff options
| author | Dmitry Antipov | 2012-07-06 09:07:44 +0400 |
|---|---|---|
| committer | Dmitry Antipov | 2012-07-06 09:07:44 +0400 |
| commit | 657924ff58fc22a6e57dc8366a20dadf97324c63 (patch) | |
| tree | 94e256617a34f005119bcf7481bbbaa41c19a63f /src | |
| parent | 6edc3d285d0495d69888018758371abfa4752327 (diff) | |
| download | emacs-657924ff58fc22a6e57dc8366a20dadf97324c63.tar.gz emacs-657924ff58fc22a6e57dc8366a20dadf97324c63.zip | |
Introduce fast path for the widely used marker operation.
* alloc.c (build_marker): New function.
* lisp.h (build_marker): New prototype.
* buffer.c (clone_per_buffer_values, Fmake_indirect_buffer): Use it.
* composite.c (autocmp_chars): Likewise.
* editfns.c (buildmark): Remove.
(Fpoint_marker, Fpoint_min_marker, Fpoint_max_marker)
(save_restriction_save): Use build_marker.
* marker.c (buf_charpos_to_bytepos, buf_bytepos_to_charpos): Likewise.
* window.c (save_window_save): Likewise.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 13 | ||||
| -rw-r--r-- | src/alloc.c | 27 | ||||
| -rw-r--r-- | src/buffer.c | 35 | ||||
| -rw-r--r-- | src/composite.c | 7 | ||||
| -rw-r--r-- | src/editfns.c | 19 | ||||
| -rw-r--r-- | src/lisp.h | 1 | ||||
| -rw-r--r-- | src/marker.c | 28 | ||||
| -rw-r--r-- | src/window.c | 9 |
8 files changed, 67 insertions, 72 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index c8a9b3f8b0c..460bdaa198c 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,5 +1,18 @@ | |||
| 1 | 2012-07-06 Dmitry Antipov <dmantipov@yandex.ru> | 1 | 2012-07-06 Dmitry Antipov <dmantipov@yandex.ru> |
| 2 | 2 | ||
| 3 | Introduce fast path for the widely used marker operation. | ||
| 4 | * alloc.c (build_marker): New function. | ||
| 5 | * lisp.h (build_marker): New prototype. | ||
| 6 | * buffer.c (clone_per_buffer_values, Fmake_indirect_buffer): Use it. | ||
| 7 | * composite.c (autocmp_chars): Likewise. | ||
| 8 | * editfns.c (buildmark): Remove. | ||
| 9 | (Fpoint_marker, Fpoint_min_marker, Fpoint_max_marker) | ||
| 10 | (save_restriction_save): Use build_marker. | ||
| 11 | * marker.c (buf_charpos_to_bytepos, buf_bytepos_to_charpos): Likewise. | ||
| 12 | * window.c (save_window_save): Likewise. | ||
| 13 | |||
| 14 | 2012-07-06 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 15 | |||
| 3 | Do not use Fdelete_overlay in delete_all_overlays | 16 | Do not use Fdelete_overlay in delete_all_overlays |
| 4 | to avoid redundant calls to unchain_overlay. | 17 | to avoid redundant calls to unchain_overlay. |
| 5 | * buffer.c (drop_overlay): New function. | 18 | * buffer.c (drop_overlay): New function. |
diff --git a/src/alloc.c b/src/alloc.c index 695d71c6c94..88f96c41a15 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -3641,6 +3641,33 @@ DEFUN ("make-marker", Fmake_marker, Smake_marker, 0, 0, 0, | |||
| 3641 | return val; | 3641 | return val; |
| 3642 | } | 3642 | } |
| 3643 | 3643 | ||
| 3644 | /* Return a newly allocated marker which points into BUF | ||
| 3645 | at character position CHARPOS and byte position BYTEPOS. */ | ||
| 3646 | |||
| 3647 | Lisp_Object | ||
| 3648 | build_marker (struct buffer *buf, ptrdiff_t charpos, ptrdiff_t bytepos) | ||
| 3649 | { | ||
| 3650 | Lisp_Object obj; | ||
| 3651 | struct Lisp_Marker *m; | ||
| 3652 | |||
| 3653 | /* No dead buffers here. */ | ||
| 3654 | eassert (!NILP (BVAR (buf, name))); | ||
| 3655 | |||
| 3656 | /* Every character is at least one byte. */ | ||
| 3657 | eassert (charpos <= bytepos); | ||
| 3658 | |||
| 3659 | obj = allocate_misc (); | ||
| 3660 | XMISCTYPE (obj) = Lisp_Misc_Marker; | ||
| 3661 | m = XMARKER (obj); | ||
| 3662 | m->buffer = buf; | ||
| 3663 | m->charpos = charpos; | ||
| 3664 | m->bytepos = bytepos; | ||
| 3665 | m->insertion_type = 0; | ||
| 3666 | m->next = BUF_MARKERS (buf); | ||
| 3667 | BUF_MARKERS (buf) = m; | ||
| 3668 | return obj; | ||
| 3669 | } | ||
| 3670 | |||
| 3644 | /* Put MARKER back on the free list after using it temporarily. */ | 3671 | /* Put MARKER back on the free list after using it temporarily. */ |
| 3645 | 3672 | ||
| 3646 | void | 3673 | void |
diff --git a/src/buffer.c b/src/buffer.c index f73d2d07537..a37a61c0fc8 100644 --- a/src/buffer.c +++ b/src/buffer.c | |||
| @@ -458,11 +458,8 @@ copy_overlays (struct buffer *b, struct Lisp_Overlay *list) | |||
| 458 | static void | 458 | static void |
| 459 | clone_per_buffer_values (struct buffer *from, struct buffer *to) | 459 | clone_per_buffer_values (struct buffer *from, struct buffer *to) |
| 460 | { | 460 | { |
| 461 | Lisp_Object to_buffer; | ||
| 462 | int offset; | 461 | int offset; |
| 463 | 462 | ||
| 464 | XSETBUFFER (to_buffer, to); | ||
| 465 | |||
| 466 | for_each_per_buffer_object_at (offset) | 463 | for_each_per_buffer_object_at (offset) |
| 467 | { | 464 | { |
| 468 | Lisp_Object obj; | 465 | Lisp_Object obj; |
| @@ -475,9 +472,9 @@ clone_per_buffer_values (struct buffer *from, struct buffer *to) | |||
| 475 | if (MARKERP (obj) && XMARKER (obj)->buffer == from) | 472 | if (MARKERP (obj) && XMARKER (obj)->buffer == from) |
| 476 | { | 473 | { |
| 477 | struct Lisp_Marker *m = XMARKER (obj); | 474 | struct Lisp_Marker *m = XMARKER (obj); |
| 478 | obj = Fmake_marker (); | 475 | |
| 476 | obj = build_marker (to, m->charpos, m->bytepos); | ||
| 479 | XMARKER (obj)->insertion_type = m->insertion_type; | 477 | XMARKER (obj)->insertion_type = m->insertion_type; |
| 480 | set_marker_both (obj, to_buffer, m->charpos, m->bytepos); | ||
| 481 | } | 478 | } |
| 482 | 479 | ||
| 483 | PER_BUFFER_VALUE (to, offset) = obj; | 480 | PER_BUFFER_VALUE (to, offset) = obj; |
| @@ -615,32 +612,24 @@ CLONE nil means the indirect buffer's state is reset to default values. */) | |||
| 615 | eassert (NILP (BVAR (b->base_buffer, begv_marker))); | 612 | eassert (NILP (BVAR (b->base_buffer, begv_marker))); |
| 616 | eassert (NILP (BVAR (b->base_buffer, zv_marker))); | 613 | eassert (NILP (BVAR (b->base_buffer, zv_marker))); |
| 617 | 614 | ||
| 618 | BVAR (b->base_buffer, pt_marker) = Fmake_marker (); | 615 | BVAR (b->base_buffer, pt_marker) |
| 619 | set_marker_both (BVAR (b->base_buffer, pt_marker), base_buffer, | 616 | = build_marker (b->base_buffer, b->base_buffer->pt, b->base_buffer->pt_byte); |
| 620 | b->base_buffer->pt, | 617 | |
| 621 | b->base_buffer->pt_byte); | 618 | BVAR (b->base_buffer, begv_marker) |
| 619 | = build_marker (b->base_buffer, b->base_buffer->begv, b->base_buffer->begv_byte); | ||
| 622 | 620 | ||
| 623 | BVAR (b->base_buffer, begv_marker) = Fmake_marker (); | 621 | BVAR (b->base_buffer, zv_marker) |
| 624 | set_marker_both (BVAR (b->base_buffer, begv_marker), base_buffer, | 622 | = build_marker (b->base_buffer, b->base_buffer->zv, b->base_buffer->zv_byte); |
| 625 | b->base_buffer->begv, | ||
| 626 | b->base_buffer->begv_byte); | ||
| 627 | 623 | ||
| 628 | BVAR (b->base_buffer, zv_marker) = Fmake_marker (); | ||
| 629 | set_marker_both (BVAR (b->base_buffer, zv_marker), base_buffer, | ||
| 630 | b->base_buffer->zv, | ||
| 631 | b->base_buffer->zv_byte); | ||
| 632 | XMARKER (BVAR (b->base_buffer, zv_marker))->insertion_type = 1; | 624 | XMARKER (BVAR (b->base_buffer, zv_marker))->insertion_type = 1; |
| 633 | } | 625 | } |
| 634 | 626 | ||
| 635 | if (NILP (clone)) | 627 | if (NILP (clone)) |
| 636 | { | 628 | { |
| 637 | /* Give the indirect buffer markers for its narrowing. */ | 629 | /* Give the indirect buffer markers for its narrowing. */ |
| 638 | BVAR (b, pt_marker) = Fmake_marker (); | 630 | BVAR (b, pt_marker) = build_marker (b, b->pt, b->pt_byte); |
| 639 | set_marker_both (BVAR (b, pt_marker), buf, b->pt, b->pt_byte); | 631 | BVAR (b, begv_marker) = build_marker (b, b->begv, b->begv_byte); |
| 640 | BVAR (b, begv_marker) = Fmake_marker (); | 632 | BVAR (b, zv_marker) = build_marker (b, b->zv, b->zv_byte); |
| 641 | set_marker_both (BVAR (b, begv_marker), buf, b->begv, b->begv_byte); | ||
| 642 | BVAR (b, zv_marker) = Fmake_marker (); | ||
| 643 | set_marker_both (BVAR (b, zv_marker), buf, b->zv, b->zv_byte); | ||
| 644 | XMARKER (BVAR (b, zv_marker))->insertion_type = 1; | 633 | XMARKER (BVAR (b, zv_marker))->insertion_type = 1; |
| 645 | } | 634 | } |
| 646 | else | 635 | else |
diff --git a/src/composite.c b/src/composite.c index 87fad6fa18f..bfc8093a87f 100644 --- a/src/composite.c +++ b/src/composite.c | |||
| @@ -951,11 +951,8 @@ autocmp_chars (Lisp_Object rule, ptrdiff_t charpos, ptrdiff_t bytepos, ptrdiff_t | |||
| 951 | 951 | ||
| 952 | /* Save point as marker before calling out to lisp. */ | 952 | /* Save point as marker before calling out to lisp. */ |
| 953 | if (NILP (string)) | 953 | if (NILP (string)) |
| 954 | { | 954 | record_unwind_protect (restore_point_unwind, |
| 955 | Lisp_Object m = Fmake_marker (); | 955 | build_marker (current_buffer, pt, pt_byte)); |
| 956 | set_marker_both (m, Qnil, pt, pt_byte); | ||
| 957 | record_unwind_protect (restore_point_unwind, m); | ||
| 958 | } | ||
| 959 | 956 | ||
| 960 | args[0] = Vauto_composition_function; | 957 | args[0] = Vauto_composition_function; |
| 961 | args[1] = AREF (rule, 2); | 958 | args[1] = AREF (rule, 2); |
diff --git a/src/editfns.c b/src/editfns.c index d4146cefb92..e40bea44e9c 100644 --- a/src/editfns.c +++ b/src/editfns.c | |||
| @@ -205,15 +205,6 @@ DEFUN ("string-to-char", Fstring_to_char, Sstring_to_char, 1, 1, 0, | |||
| 205 | XSETFASTINT (val, 0); | 205 | XSETFASTINT (val, 0); |
| 206 | return val; | 206 | return val; |
| 207 | } | 207 | } |
| 208 | |||
| 209 | static Lisp_Object | ||
| 210 | buildmark (ptrdiff_t charpos, ptrdiff_t bytepos) | ||
| 211 | { | ||
| 212 | register Lisp_Object mark; | ||
| 213 | mark = Fmake_marker (); | ||
| 214 | set_marker_both (mark, Qnil, charpos, bytepos); | ||
| 215 | return mark; | ||
| 216 | } | ||
| 217 | 208 | ||
| 218 | DEFUN ("point", Fpoint, Spoint, 0, 0, 0, | 209 | DEFUN ("point", Fpoint, Spoint, 0, 0, 0, |
| 219 | doc: /* Return value of point, as an integer. | 210 | doc: /* Return value of point, as an integer. |
| @@ -229,7 +220,7 @@ DEFUN ("point-marker", Fpoint_marker, Spoint_marker, 0, 0, 0, | |||
| 229 | doc: /* Return value of point, as a marker object. */) | 220 | doc: /* Return value of point, as a marker object. */) |
| 230 | (void) | 221 | (void) |
| 231 | { | 222 | { |
| 232 | return buildmark (PT, PT_BYTE); | 223 | return build_marker (current_buffer, PT, PT_BYTE); |
| 233 | } | 224 | } |
| 234 | 225 | ||
| 235 | DEFUN ("goto-char", Fgoto_char, Sgoto_char, 1, 1, "NGoto char: ", | 226 | DEFUN ("goto-char", Fgoto_char, Sgoto_char, 1, 1, "NGoto char: ", |
| @@ -1003,7 +994,7 @@ DEFUN ("point-min-marker", Fpoint_min_marker, Spoint_min_marker, 0, 0, 0, | |||
| 1003 | This is the beginning, unless narrowing (a buffer restriction) is in effect. */) | 994 | This is the beginning, unless narrowing (a buffer restriction) is in effect. */) |
| 1004 | (void) | 995 | (void) |
| 1005 | { | 996 | { |
| 1006 | return buildmark (BEGV, BEGV_BYTE); | 997 | return build_marker (current_buffer, BEGV, BEGV_BYTE); |
| 1007 | } | 998 | } |
| 1008 | 999 | ||
| 1009 | DEFUN ("point-max", Fpoint_max, Spoint_max, 0, 0, 0, | 1000 | DEFUN ("point-max", Fpoint_max, Spoint_max, 0, 0, 0, |
| @@ -1023,7 +1014,7 @@ This is (1+ (buffer-size)), unless narrowing (a buffer restriction) | |||
| 1023 | is in effect, in which case it is less. */) | 1014 | is in effect, in which case it is less. */) |
| 1024 | (void) | 1015 | (void) |
| 1025 | { | 1016 | { |
| 1026 | return buildmark (ZV, ZV_BYTE); | 1017 | return build_marker (current_buffer, ZV, ZV_BYTE); |
| 1027 | } | 1018 | } |
| 1028 | 1019 | ||
| 1029 | DEFUN ("gap-position", Fgap_position, Sgap_position, 0, 0, 0, | 1020 | DEFUN ("gap-position", Fgap_position, Sgap_position, 0, 0, 0, |
| @@ -3289,8 +3280,8 @@ save_restriction_save (void) | |||
| 3289 | { | 3280 | { |
| 3290 | Lisp_Object beg, end; | 3281 | Lisp_Object beg, end; |
| 3291 | 3282 | ||
| 3292 | beg = buildmark (BEGV, BEGV_BYTE); | 3283 | beg = build_marker (current_buffer, BEGV, BEGV_BYTE); |
| 3293 | end = buildmark (ZV, ZV_BYTE); | 3284 | end = build_marker (current_buffer, ZV, ZV_BYTE); |
| 3294 | 3285 | ||
| 3295 | /* END must move forward if text is inserted at its exact location. */ | 3286 | /* END must move forward if text is inserted at its exact location. */ |
| 3296 | XMARKER (end)->insertion_type = 1; | 3287 | XMARKER (end)->insertion_type = 1; |
diff --git a/src/lisp.h b/src/lisp.h index 332ac298ce3..53a15545794 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -2853,6 +2853,7 @@ extern Lisp_Object set_marker_restricted (Lisp_Object, Lisp_Object, Lisp_Object) | |||
| 2853 | extern Lisp_Object set_marker_both (Lisp_Object, Lisp_Object, ptrdiff_t, ptrdiff_t); | 2853 | extern Lisp_Object set_marker_both (Lisp_Object, Lisp_Object, ptrdiff_t, ptrdiff_t); |
| 2854 | extern Lisp_Object set_marker_restricted_both (Lisp_Object, Lisp_Object, | 2854 | extern Lisp_Object set_marker_restricted_both (Lisp_Object, Lisp_Object, |
| 2855 | ptrdiff_t, ptrdiff_t); | 2855 | ptrdiff_t, ptrdiff_t); |
| 2856 | extern Lisp_Object build_marker (struct buffer *, ptrdiff_t, ptrdiff_t); | ||
| 2856 | extern void syms_of_marker (void); | 2857 | extern void syms_of_marker (void); |
| 2857 | 2858 | ||
| 2858 | /* Defined in fileio.c */ | 2859 | /* Defined in fileio.c */ |
diff --git a/src/marker.c b/src/marker.c index a059987aa51..3b0adc7de8d 100644 --- a/src/marker.c +++ b/src/marker.c | |||
| @@ -187,12 +187,7 @@ buf_charpos_to_bytepos (struct buffer *b, ptrdiff_t charpos) | |||
| 187 | cache the correspondence by creating a marker here. | 187 | cache the correspondence by creating a marker here. |
| 188 | It will last until the next GC. */ | 188 | It will last until the next GC. */ |
| 189 | if (record) | 189 | if (record) |
| 190 | { | 190 | build_marker (b, best_below, best_below_byte); |
| 191 | Lisp_Object marker, buffer; | ||
| 192 | marker = Fmake_marker (); | ||
| 193 | XSETBUFFER (buffer, b); | ||
| 194 | set_marker_both (marker, buffer, best_below, best_below_byte); | ||
| 195 | } | ||
| 196 | 191 | ||
| 197 | if (byte_debug_flag) | 192 | if (byte_debug_flag) |
| 198 | byte_char_debug_check (b, charpos, best_below_byte); | 193 | byte_char_debug_check (b, charpos, best_below_byte); |
| @@ -218,12 +213,7 @@ buf_charpos_to_bytepos (struct buffer *b, ptrdiff_t charpos) | |||
| 218 | cache the correspondence by creating a marker here. | 213 | cache the correspondence by creating a marker here. |
| 219 | It will last until the next GC. */ | 214 | It will last until the next GC. */ |
| 220 | if (record) | 215 | if (record) |
| 221 | { | 216 | build_marker (b, best_above, best_above_byte); |
| 222 | Lisp_Object marker, buffer; | ||
| 223 | marker = Fmake_marker (); | ||
| 224 | XSETBUFFER (buffer, b); | ||
| 225 | set_marker_both (marker, buffer, best_above, best_above_byte); | ||
| 226 | } | ||
| 227 | 217 | ||
| 228 | if (byte_debug_flag) | 218 | if (byte_debug_flag) |
| 229 | byte_char_debug_check (b, charpos, best_above_byte); | 219 | byte_char_debug_check (b, charpos, best_above_byte); |
| @@ -365,12 +355,7 @@ buf_bytepos_to_charpos (struct buffer *b, ptrdiff_t bytepos) | |||
| 365 | But don't do it if BUF_MARKERS is nil; | 355 | But don't do it if BUF_MARKERS is nil; |
| 366 | that is a signal from Fset_buffer_multibyte. */ | 356 | that is a signal from Fset_buffer_multibyte. */ |
| 367 | if (record && BUF_MARKERS (b)) | 357 | if (record && BUF_MARKERS (b)) |
| 368 | { | 358 | build_marker (b, best_below, best_below_byte); |
| 369 | Lisp_Object marker, buffer; | ||
| 370 | marker = Fmake_marker (); | ||
| 371 | XSETBUFFER (buffer, b); | ||
| 372 | set_marker_both (marker, buffer, best_below, best_below_byte); | ||
| 373 | } | ||
| 374 | 359 | ||
| 375 | if (byte_debug_flag) | 360 | if (byte_debug_flag) |
| 376 | byte_char_debug_check (b, best_below, bytepos); | 361 | byte_char_debug_check (b, best_below, bytepos); |
| @@ -398,12 +383,7 @@ buf_bytepos_to_charpos (struct buffer *b, ptrdiff_t bytepos) | |||
| 398 | But don't do it if BUF_MARKERS is nil; | 383 | But don't do it if BUF_MARKERS is nil; |
| 399 | that is a signal from Fset_buffer_multibyte. */ | 384 | that is a signal from Fset_buffer_multibyte. */ |
| 400 | if (record && BUF_MARKERS (b)) | 385 | if (record && BUF_MARKERS (b)) |
| 401 | { | 386 | build_marker (b, best_above, best_above_byte); |
| 402 | Lisp_Object marker, buffer; | ||
| 403 | marker = Fmake_marker (); | ||
| 404 | XSETBUFFER (buffer, b); | ||
| 405 | set_marker_both (marker, buffer, best_above, best_above_byte); | ||
| 406 | } | ||
| 407 | 387 | ||
| 408 | if (byte_debug_flag) | 388 | if (byte_debug_flag) |
| 409 | byte_char_debug_check (b, best_above, bytepos); | 389 | byte_char_debug_check (b, best_above, bytepos); |
diff --git a/src/window.c b/src/window.c index 0f88cbaece9..721b4d98477 100644 --- a/src/window.c +++ b/src/window.c | |||
| @@ -5911,12 +5911,9 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, int i) | |||
| 5911 | is the selected window, then get the value of point from | 5911 | is the selected window, then get the value of point from |
| 5912 | the buffer; pointm is garbage in the selected window. */ | 5912 | the buffer; pointm is garbage in the selected window. */ |
| 5913 | if (EQ (window, selected_window)) | 5913 | if (EQ (window, selected_window)) |
| 5914 | { | 5914 | p->pointm = build_marker (XBUFFER (w->buffer), |
| 5915 | p->pointm = Fmake_marker (); | 5915 | BUF_PT (XBUFFER (w->buffer)), |
| 5916 | set_marker_both (p->pointm, w->buffer, | 5916 | BUF_PT_BYTE (XBUFFER (w->buffer))); |
| 5917 | BUF_PT (XBUFFER (w->buffer)), | ||
| 5918 | BUF_PT_BYTE (XBUFFER (w->buffer))); | ||
| 5919 | } | ||
| 5920 | else | 5917 | else |
| 5921 | p->pointm = Fcopy_marker (w->pointm, Qnil); | 5918 | p->pointm = Fcopy_marker (w->pointm, Qnil); |
| 5922 | XMARKER (p->pointm)->insertion_type | 5919 | XMARKER (p->pointm)->insertion_type |