comparison src/window.c @ 5178:97eb4942aec8

merge
author Ben Wing <ben@xemacs.org>
date Mon, 29 Mar 2010 21:28:13 -0500
parents 8b2f75cecb89 be6e5ea38dda
children 71ee43b8a74d
comparison
equal deleted inserted replaced
5177:b785049378e3 5178:97eb4942aec8
53 53
54 Lisp_Object Qwindowp, Qwindow_live_p; 54 Lisp_Object Qwindowp, Qwindow_live_p;
55 Lisp_Object Qdisplay_buffer; 55 Lisp_Object Qdisplay_buffer;
56 56
57 #ifdef MEMORY_USAGE_STATS 57 #ifdef MEMORY_USAGE_STATS
58 Lisp_Object Qface_cache, Qglyph_cache, Qline_start_cache, Qother_redisplay; 58 Lisp_Object Qface_cache, Qglyph_cache, Qline_start_cache, Qredisplay_structs;
59 #ifdef HAVE_SCROLLBARS 59 #ifdef HAVE_SCROLLBARS
60 Lisp_Object Qscrollbar_instances; 60 Lisp_Object Qscrollbar_instances;
61 #endif 61 #endif
62 #endif 62 #endif
63 63
180 { XD_LISP_OBJECT, offsetof (face_cachel, background_pixmap) }, 180 { XD_LISP_OBJECT, offsetof (face_cachel, background_pixmap) },
181 { XD_END } 181 { XD_END }
182 }; 182 };
183 183
184 #ifdef NEW_GC 184 #ifdef NEW_GC
185 DEFINE_LRECORD_IMPLEMENTATION ("face-cachel", face_cachel, 185 DEFINE_DUMPABLE_INTERNAL_LISP_OBJECT ("face-cachel", face_cachel,
186 1, /*dumpable-flag*/ 186 0, face_cachel_description_1,
187 0, 0, 0, 0, 0, 187 Lisp_Face_Cachel);
188 face_cachel_description_1,
189 Lisp_Face_Cachel);
190 #endif /* NEW_GC */ 188 #endif /* NEW_GC */
191 189
192 static const struct sized_memory_description face_cachel_description = { 190 static const struct sized_memory_description face_cachel_description = {
193 sizeof (face_cachel), 191 sizeof (face_cachel),
194 face_cachel_description_1 192 face_cachel_description_1
202 #endif /* not NEW_GC */ 200 #endif /* not NEW_GC */
203 { XD_END } 201 { XD_END }
204 }; 202 };
205 203
206 #ifdef NEW_GC 204 #ifdef NEW_GC
207 DEFINE_LRECORD_IMPLEMENTATION ("face-cachel-dynarr", face_cachel_dynarr, 205 DEFINE_DUMPABLE_INTERNAL_LISP_OBJECT ("face-cachel-dynarr", face_cachel_dynarr,
208 1, /*dumpable-flag*/ 206 0, face_cachel_dynarr_description_1,
209 0, 0, 0, 0, 0, 207 face_cachel_dynarr);
210 face_cachel_dynarr_description_1,
211 face_cachel_dynarr);
212 #else /* not NEW_GC */ 208 #else /* not NEW_GC */
213 static const struct sized_memory_description face_cachel_dynarr_description = { 209 static const struct sized_memory_description face_cachel_dynarr_description = {
214 sizeof (face_cachel_dynarr), 210 sizeof (face_cachel_dynarr),
215 face_cachel_dynarr_description_1 211 face_cachel_dynarr_description_1
216 }; 212 };
220 { XD_LISP_OBJECT, offsetof (glyph_cachel, glyph) }, 216 { XD_LISP_OBJECT, offsetof (glyph_cachel, glyph) },
221 { XD_END } 217 { XD_END }
222 }; 218 };
223 219
224 #ifdef NEW_GC 220 #ifdef NEW_GC
225 DEFINE_LRECORD_IMPLEMENTATION ("glyph-cachel", glyph_cachel, 221 DEFINE_DUMPABLE_INTERNAL_LISP_OBJECT ("glyph-cachel", glyph_cachel,
226 1, /*dumpable-flag*/ 222 0, glyph_cachel_description_1,
227 0, 0, 0, 0, 0, 223 Lisp_Glyph_Cachel);
228 glyph_cachel_description_1,
229 Lisp_Glyph_Cachel);
230 #endif /* NEW_GC */ 224 #endif /* NEW_GC */
231 225
232 static const struct sized_memory_description glyph_cachel_description = { 226 static const struct sized_memory_description glyph_cachel_description = {
233 sizeof (glyph_cachel), 227 sizeof (glyph_cachel),
234 glyph_cachel_description_1 228 glyph_cachel_description_1
242 #endif /* not NEW_GC */ 236 #endif /* not NEW_GC */
243 { XD_END } 237 { XD_END }
244 }; 238 };
245 239
246 #ifdef NEW_GC 240 #ifdef NEW_GC
247 DEFINE_LRECORD_IMPLEMENTATION ("glyph-cachel-dynarr", glyph_cachel_dynarr, 241 DEFINE_DUMPABLE_INTERNAL_LISP_OBJECT ("glyph-cachel-dynarr",
248 1, /*dumpable-flag*/ 242 glyph_cachel_dynarr, 0,
249 0, 0, 0, 0, 0, 243 glyph_cachel_dynarr_description_1,
250 glyph_cachel_dynarr_description_1, 244 glyph_cachel_dynarr);
251 glyph_cachel_dynarr);
252 #else /* not NEW_GC */ 245 #else /* not NEW_GC */
253 static const struct sized_memory_description glyph_cachel_dynarr_description = { 246 static const struct sized_memory_description glyph_cachel_dynarr_description = {
254 sizeof (glyph_cachel_dynarr), 247 sizeof (glyph_cachel_dynarr),
255 glyph_cachel_dynarr_description_1 248 glyph_cachel_dynarr_description_1
256 }; 249 };
314 int UNUSED (escapeflag)) 307 int UNUSED (escapeflag))
315 { 308 {
316 Lisp_Object buf; 309 Lisp_Object buf;
317 310
318 if (print_readably) 311 if (print_readably)
319 printing_unreadable_lcrecord (obj, 0); 312 printing_unreadable_lisp_object (obj, 0);
320 313
321 write_ascstring (printcharfun, "#<window"); 314 write_ascstring (printcharfun, "#<window");
322 buf = XWINDOW_BUFFER (obj); 315 buf = XWINDOW_BUFFER (obj);
323 if (EQ (buf, Qt)) 316 if (EQ (buf, Qt))
324 write_ascstring (printcharfun, " during creation"); 317 write_ascstring (printcharfun, " during creation");
326 { 319 {
327 320
328 Lisp_Object name = XBUFFER (buf)->name; 321 Lisp_Object name = XBUFFER (buf)->name;
329 write_fmt_string_lisp (printcharfun, " on %S", 1, name); 322 write_fmt_string_lisp (printcharfun, " on %S", 1, name);
330 } 323 }
331 write_fmt_string (printcharfun, " 0x%x>", XWINDOW (obj)->header.uid); 324 write_fmt_string (printcharfun, " 0x%x>", LISP_OBJECT_UID (obj));
332 } 325 }
333 326
334 static void 327 static void
335 finalize_window (void *header, int UNUSED (for_disksave)) 328 finalize_window (Lisp_Object obj)
336 { 329 {
337 struct window *w = (struct window *) header; 330 struct window *w = XWINDOW (obj);
338 331
339 if (w->line_start_cache) 332 if (w->line_start_cache)
340 { 333 {
341 Dynarr_free (w->line_start_cache); 334 Dynarr_free (w->line_start_cache);
342 w->line_start_cache = 0; 335 w->line_start_cache = 0;
373 make_saved_buffer_point_cache (void) 366 make_saved_buffer_point_cache (void)
374 { 367 {
375 return make_lisp_hash_table (20, HASH_TABLE_KEY_WEAK, HASH_TABLE_EQ); 368 return make_lisp_hash_table (20, HASH_TABLE_KEY_WEAK, HASH_TABLE_EQ);
376 } 369 }
377 370
378 DEFINE_LRECORD_IMPLEMENTATION ("window", window, 371 DEFINE_NODUMP_LISP_OBJECT ("window", window,
379 0, /*dumpable-flag*/ 372 mark_window, print_window, finalize_window,
380 mark_window, print_window, finalize_window, 373 0, 0, window_description, struct window);
381 0, 0, window_description, struct window);
382 374
383 #define INIT_DISP_VARIABLE(field, initialization) \ 375 #define INIT_DISP_VARIABLE(field, initialization) \
384 p->field[CURRENT_DISP] = initialization; \ 376 p->field[CURRENT_DISP] = initialization; \
385 p->field[DESIRED_DISP] = initialization; \ 377 p->field[DESIRED_DISP] = initialization; \
386 p->field[CMOTION_DISP] = initialization; 378 p->field[CMOTION_DISP] = initialization;
395 here because the window must have its frame pointer set or 387 here because the window must have its frame pointer set or
396 reset_face_cachels will fail. */ 388 reset_face_cachels will fail. */
397 Lisp_Object 389 Lisp_Object
398 allocate_window (void) 390 allocate_window (void)
399 { 391 {
400 struct window *p = ALLOC_LCRECORD_TYPE (struct window, &lrecord_window); 392 Lisp_Object obj = ALLOC_NORMAL_LISP_OBJECT (window);
401 Lisp_Object val = wrap_window (p); 393 struct window *p = XWINDOW (obj);
402 394
403 #define WINDOW_SLOT(slot) p->slot = Qnil; 395 #define WINDOW_SLOT(slot) p->slot = Qnil;
404 #include "winslots.h" 396 #include "winslots.h"
405 397
406 INIT_DISP_VARIABLE (start, Fmake_marker ()); 398 INIT_DISP_VARIABLE (start, Fmake_marker ());
430 p->line_cache_last_updated = Qzero; 422 p->line_cache_last_updated = Qzero;
431 423
432 p->windows_changed = 1; 424 p->windows_changed = 1;
433 p->shadow_thickness_changed = 1; 425 p->shadow_thickness_changed = 1;
434 426
435 return val; 427 return obj;
436 } 428 }
437 #undef INIT_DISP_VARIABLE 429 #undef INIT_DISP_VARIABLE
438 430
439 /************************************************************************/ 431 /************************************************************************/
440 /* Window mirror structure */ 432 /* Window mirror structure */
529 return wrap_window_mirror (mir->next); 521 return wrap_window_mirror (mir->next);
530 else 522 else
531 return Qnil; 523 return Qnil;
532 } 524 }
533 525
534 DEFINE_LRECORD_IMPLEMENTATION ("window-mirror", window_mirror, 526 DEFINE_NODUMP_INTERNAL_LISP_OBJECT ("window-mirror", window_mirror,
535 0, /*dumpable-flag*/ 527 mark_window_mirror,
536 mark_window_mirror, internal_object_printer, 528 window_mirror_description,
537 0, 0, 0, window_mirror_description, 529 struct window_mirror);
538 struct window_mirror);
539 530
540 /* Create a new window mirror structure and associated redisplay 531 /* Create a new window mirror structure and associated redisplay
541 structs. */ 532 structs. */
542 static struct window_mirror * 533 static struct window_mirror *
543 new_window_mirror (struct frame *f) 534 new_window_mirror (struct frame *f)
544 { 535 {
545 struct window_mirror *t = 536 Lisp_Object obj = ALLOC_NORMAL_LISP_OBJECT (window_mirror);
546 ALLOC_LCRECORD_TYPE (struct window_mirror, &lrecord_window_mirror); 537 struct window_mirror *t = XWINDOW_MIRROR (obj);
547 538
548 t->frame = f; 539 t->frame = f;
549 t->current_display_lines = Dynarr_new (display_line); 540 t->current_display_lines = Dynarr_new (display_line);
550 t->desired_display_lines = Dynarr_new (display_line); 541 t->desired_display_lines = Dynarr_new (display_line);
551 542
634 redisplay structures. */ 625 redisplay structures. */
635 static struct window_mirror * 626 static struct window_mirror *
636 find_window_mirror_internal (Lisp_Object win, struct window_mirror *rmir, 627 find_window_mirror_internal (Lisp_Object win, struct window_mirror *rmir,
637 struct window *w) 628 struct window *w)
638 { 629 {
639 for (; !NILP (win); win = XWINDOW (win)->next, rmir = rmir->next) 630 for (; !NILP (win) && rmir; win = XWINDOW (win)->next, rmir = rmir->next)
640 { 631 {
641 if (w == XWINDOW (win)) 632 if (w == XWINDOW (win))
642 return rmir; 633 return rmir;
643 634
644 if (!NILP (XWINDOW (win)->vchild)) 635 if (!NILP (XWINDOW (win)->vchild))
685 #ifdef HAVE_SCROLLBARS 676 #ifdef HAVE_SCROLLBARS
686 release_window_mirror_scrollbars (mir); 677 release_window_mirror_scrollbars (mir);
687 #endif 678 #endif
688 free_display_structs (mir); 679 free_display_structs (mir);
689 mir = mir->next; 680 mir = mir->next;
690 /* not worth calling free_managed_lcrecord() -- window mirrors 681 /* not worth calling free_normal_lisp_object() -- window mirrors
691 are not created that frequently and it's dangerous. we don't 682 are not created that frequently and it's dangerous. we don't
692 know for sure that there aren't other pointers around -- e.g. 683 know for sure that there aren't other pointers around -- e.g.
693 in a scrollbar instance. */ 684 in a scrollbar instance. */
694 } 685 }
695 } 686 }
713 find_window_mirror (struct window *w) 704 find_window_mirror (struct window *w)
714 { 705 {
715 struct frame *f = XFRAME (w->frame); 706 struct frame *f = XFRAME (w->frame);
716 if (f->mirror_dirty) 707 if (f->mirror_dirty)
717 update_frame_window_mirror (f); 708 update_frame_window_mirror (f);
709 return find_window_mirror_internal (f->root_window,
710 XWINDOW_MIRROR (f->root_mirror), w);
711 }
712
713 /* Given a real window, return its mirror structure, if it exists.
714 Don't do any updating. */
715 static struct window_mirror *
716 find_window_mirror_maybe (struct window *w)
717 {
718 struct frame *f = XFRAME (w->frame);
719 if (!WINDOW_MIRRORP (f->root_mirror))
720 return 0;
718 return find_window_mirror_internal (f->root_window, 721 return find_window_mirror_internal (f->root_window,
719 XWINDOW_MIRROR (f->root_mirror), w); 722 XWINDOW_MIRROR (f->root_mirror), w);
720 } 723 }
721 724
722 /***************************************************************************** 725 /*****************************************************************************
759 display_line_dynarr * 762 display_line_dynarr *
760 window_display_lines (struct window *w, int which) 763 window_display_lines (struct window *w, int which)
761 { 764 {
762 struct window_mirror *t; 765 struct window_mirror *t;
763 766
764 if (XFRAME (w->frame)->mirror_dirty)
765 update_frame_window_mirror (XFRAME (w->frame));
766 t = find_window_mirror (w); 767 t = find_window_mirror (w);
767 assert (t); 768 assert (t);
768 769
769 if (which == CURRENT_DISP) 770 if (which == CURRENT_DISP)
770 return t->current_display_lines; 771 return t->current_display_lines;
782 struct buffer * 783 struct buffer *
783 window_display_buffer (struct window *w) 784 window_display_buffer (struct window *w)
784 { 785 {
785 struct window_mirror *t; 786 struct window_mirror *t;
786 787
787 if (XFRAME (w->frame)->mirror_dirty)
788 update_frame_window_mirror (XFRAME (w->frame));
789 t = find_window_mirror (w); 788 t = find_window_mirror (w);
790 assert (t); 789 assert (t);
791 790
792 return t->buffer; 791 return t->buffer;
793 } 792 }
795 void 794 void
796 set_window_display_buffer (struct window *w, struct buffer *b) 795 set_window_display_buffer (struct window *w, struct buffer *b)
797 { 796 {
798 struct window_mirror *t; 797 struct window_mirror *t;
799 798
800 if (XFRAME (w->frame)->mirror_dirty)
801 update_frame_window_mirror (XFRAME (w->frame));
802 t = find_window_mirror (w); 799 t = find_window_mirror (w);
803 assert (t); 800 assert (t);
804 801
805 t->buffer = b; 802 t->buffer = b;
806 } 803 }
1811 (window)) 1808 (window))
1812 { 1809 {
1813 struct window *w = decode_window (window); 1810 struct window *w = decode_window (window);
1814 struct frame *f = XFRAME (w->frame); 1811 struct frame *f = XFRAME (w->frame);
1815 1812
1816 int left = 1813 int left = w->pixel_left - FRAME_PANED_LEFT_EDGE (f);
1817 w->pixel_left - FRAME_LEFT_BORDER_END (f) - FRAME_LEFT_GUTTER_BOUNDS (f); 1814 int top = w->pixel_top - FRAME_PANED_TOP_EDGE (f);
1818 int top =
1819 w->pixel_top - FRAME_TOP_BORDER_END (f) - FRAME_TOP_GUTTER_BOUNDS (f);
1820 1815
1821 return list4 (make_int (left), 1816 return list4 (make_int (left),
1822 make_int (top), 1817 make_int (top),
1823 make_int (left + w->pixel_width), 1818 make_int (left + w->pixel_width),
1824 make_int (top + w->pixel_height)); 1819 make_int (top + w->pixel_height));
2144 window_unmap_subwindows (w); 2139 window_unmap_subwindows (w);
2145 2140
2146 /* Free the extra data structures attached to windows immediately so 2141 /* Free the extra data structures attached to windows immediately so
2147 they don't sit around consuming excess space. They will be 2142 they don't sit around consuming excess space. They will be
2148 reinitialized by the window-configuration code as necessary. */ 2143 reinitialized by the window-configuration code as necessary. */
2149 finalize_window ((void *) w, 0); 2144 finalize_window (wrap_window (w));
2150 2145
2151 /* Nobody should be accessing anything in this object any more, 2146 /* Nobody should be accessing anything in this object any more,
2152 and making them Qnil allows for better GC'ing in case a pointer 2147 and making them Qnil allows for better GC'ing in case a pointer
2153 to the dead window continues to hang around. Zero all other 2148 to the dead window continues to hang around. Zero all other
2154 structs in case someone tries to access something through them. 2149 structs in case someone tries to access something through them.
3872 } 3867 }
3873 3868
3874 static void 3869 static void
3875 make_dummy_parent (Lisp_Object window) 3870 make_dummy_parent (Lisp_Object window)
3876 { 3871 {
3877 Lisp_Object new_;
3878 struct window *o = XWINDOW (window); 3872 struct window *o = XWINDOW (window);
3879 struct window *p = ALLOC_LCRECORD_TYPE (struct window, &lrecord_window); 3873 Lisp_Object obj = ALLOC_NORMAL_LISP_OBJECT (window);
3880 3874 struct window *p = XWINDOW (obj);
3881 new_ = wrap_window (p); 3875
3882 COPY_LCRECORD (p, o); 3876 copy_lisp_object (obj, window);
3883 3877
3884 /* Don't copy the pointers to the line start cache or the face 3878 /* Don't copy the pointers to the line start cache or the face
3885 instances. */ 3879 instances. */
3886 p->line_start_cache = Dynarr_new (line_start_cache); 3880 p->line_start_cache = Dynarr_new (line_start_cache);
3887 #ifdef NEW_GC 3881 #ifdef NEW_GC
3897 #endif /* not NEW_GC */ 3891 #endif /* not NEW_GC */
3898 p->subwindow_instance_cache = 3892 p->subwindow_instance_cache =
3899 make_image_instance_cache_hash_table (); 3893 make_image_instance_cache_hash_table ();
3900 3894
3901 /* Put new into window structure in place of window */ 3895 /* Put new into window structure in place of window */
3902 replace_window (window, new_); 3896 replace_window (window, obj);
3903 3897
3904 o->next = Qnil; 3898 o->next = Qnil;
3905 o->prev = Qnil; 3899 o->prev = Qnil;
3906 o->vchild = Qnil; 3900 o->vchild = Qnil;
3907 o->hchild = Qnil; 3901 o->hchild = Qnil;
3908 o->parent = new_; 3902 o->parent = obj;
3909 3903
3910 p->start[CURRENT_DISP] = Qnil; 3904 p->start[CURRENT_DISP] = Qnil;
3911 p->start[DESIRED_DISP] = Qnil; 3905 p->start[DESIRED_DISP] = Qnil;
3912 p->start[CMOTION_DISP] = Qnil; 3906 p->start[CMOTION_DISP] = Qnil;
3913 p->pointm[CURRENT_DISP] = Qnil; 3907 p->pointm[CURRENT_DISP] = Qnil;
5166 MARK_WINDOWS_CHANGED (w); 5160 MARK_WINDOWS_CHANGED (w);
5167 } 5161 }
5168 5162
5169 #ifdef MEMORY_USAGE_STATS 5163 #ifdef MEMORY_USAGE_STATS
5170 5164
5165 struct window_mirror_stats
5166 {
5167 struct usage_stats u;
5168 /* Ancilliary non-lisp */
5169 Bytecount redisplay_structs;
5170 #ifdef HAVE_SCROLLBARS
5171 /* Ancilliary Lisp */
5172 Bytecount scrollbar;
5173 #endif
5174 };
5175
5171 struct window_stats 5176 struct window_stats
5172 { 5177 {
5173 int face; 5178 struct usage_stats u;
5174 int glyph; 5179 /* Ancillary non-Lisp */
5180 Bytecount line_start;
5181 /* The next two: ancillary non-Lisp under old-GC, ancillary Lisp under
5182 NEW_GC */
5183 Bytecount face;
5184 Bytecount glyph;
5185 /* The next two are copied out of the window mirror, which is an ancillary
5186 Lisp structure; the first is non-Lisp, the second Lisp, but from our
5187 perspective, they are both counted as Lisp */
5188 Bytecount redisplay_structs;
5175 #ifdef HAVE_SCROLLBARS 5189 #ifdef HAVE_SCROLLBARS
5176 int scrollbar; 5190 Bytecount scrollbar;
5177 #endif 5191 #endif
5178 int line_start; 5192 /* Remaining memory associated with window mirror (ancillary Lisp) */
5179 int other_redisplay; 5193 Bytecount window_mirror;
5180 int other;
5181 }; 5194 };
5182 5195
5183 static void 5196 static void
5184 compute_window_mirror_usage (struct window_mirror *mir, 5197 compute_window_mirror_usage (struct window_mirror *mir,
5185 struct window_stats *stats, 5198 struct window_mirror_stats *stats)
5186 struct overhead_stats *ovstats) 5199 {
5187 { 5200 stats->redisplay_structs =
5188 if (!mir) 5201 compute_display_line_dynarr_usage (mir->current_display_lines, &stats->u)
5189 return; 5202 +
5190 stats->other += LISPOBJ_STORAGE_SIZE (mir, sizeof (*mir), ovstats); 5203 compute_display_line_dynarr_usage (mir->desired_display_lines, &stats->u);
5191 #ifdef HAVE_SCROLLBARS 5204 #ifdef HAVE_SCROLLBARS
5192 { 5205 stats->scrollbar =
5193 struct device *d = XDEVICE (FRAME_DEVICE (mir->frame)); 5206 compute_all_scrollbar_instance_usage (mir->scrollbar_vertical_instance) +
5194 5207 compute_all_scrollbar_instance_usage (mir->scrollbar_horizontal_instance);
5195 stats->scrollbar +=
5196 compute_scrollbar_instance_usage (d, mir->scrollbar_vertical_instance,
5197 ovstats);
5198 stats->scrollbar +=
5199 compute_scrollbar_instance_usage (d, mir->scrollbar_horizontal_instance,
5200 ovstats);
5201 }
5202 #endif /* HAVE_SCROLLBARS */ 5208 #endif /* HAVE_SCROLLBARS */
5203 stats->other_redisplay += 5209 }
5204 compute_display_line_dynarr_usage (mir->current_display_lines, ovstats); 5210
5205 stats->other_redisplay += 5211
5206 compute_display_line_dynarr_usage (mir->desired_display_lines, ovstats); 5212 static void
5213 window_mirror_memory_usage (Lisp_Object window_mirror,
5214 struct generic_usage_stats *gustats)
5215 {
5216 struct window_mirror_stats *stats = (struct window_mirror_stats *) gustats;
5217
5218 compute_window_mirror_usage (XWINDOW_MIRROR (window_mirror), stats);
5207 } 5219 }
5208 5220
5209 static void 5221 static void
5210 compute_window_usage (struct window *w, struct window_stats *stats, 5222 compute_window_usage (struct window *w, struct window_stats *stats,
5211 struct overhead_stats *ovstats) 5223 struct usage_stats *ustats)
5212 { 5224 {
5213 xzero (*stats); 5225 stats->line_start =
5214 stats->other += LISPOBJ_STORAGE_SIZE (w, sizeof (*w), ovstats); 5226 compute_line_start_cache_dynarr_usage (w->line_start_cache, ustats);
5215 stats->face += compute_face_cachel_usage (w->face_cachels, ovstats); 5227 stats->face = compute_face_cachel_usage (w->face_cachels,
5216 stats->glyph += compute_glyph_cachel_usage (w->glyph_cachels, ovstats); 5228 IF_OLD_GC (ustats));
5217 stats->line_start += 5229 stats->glyph = compute_glyph_cachel_usage (w->glyph_cachels,
5218 compute_line_start_cache_dynarr_usage (w->line_start_cache, ovstats); 5230 IF_OLD_GC (ustats));
5219 compute_window_mirror_usage (find_window_mirror (w), stats, ovstats); 5231 {
5220 } 5232 struct window_mirror *wm;
5221 5233
5222 DEFUN ("window-memory-usage", Fwindow_memory_usage, 1, 1, 0, /* 5234 wm = find_window_mirror_maybe (w);
5223 Return stats about the memory usage of window WINDOW. 5235 if (wm)
5224 The values returned are in the form of an alist of usage types and byte 5236 {
5225 counts. The byte counts attempt to encompass all the memory used 5237 struct generic_usage_stats gustats;
5226 by the window (separate from the memory logically associated with a 5238 struct window_mirror_stats *wmstats;
5227 buffer or frame), including internal structures and any malloc() 5239 Bytecount total;
5228 overhead associated with them. In practice, the byte counts are 5240 total = lisp_object_memory_usage_full (wrap_window_mirror (wm),
5229 underestimated because certain memory usage is very hard to determine 5241 NULL, NULL, NULL, &gustats);
5230 \(e.g. the amount of memory used inside the Xt library or inside the 5242 wmstats = (struct window_mirror_stats *) &gustats;
5231 X server) and because there is other stuff that might logically 5243 stats->redisplay_structs = wmstats->redisplay_structs;
5232 be associated with a window, buffer, or frame (e.g. window configurations, 5244 total -= stats->redisplay_structs;
5233 glyphs) but should not obviously be included in the usage counts.
5234
5235 Multiple slices of the total memory usage may be returned, separated
5236 by a nil. Each slice represents a particular view of the memory, a
5237 particular way of partitioning it into groups. Within a slice, there
5238 is no overlap between the groups of memory, and each slice collectively
5239 represents all the memory concerned.
5240 */
5241 (window))
5242 {
5243 struct window_stats stats;
5244 struct overhead_stats ovstats;
5245 Lisp_Object val = Qnil;
5246
5247 CHECK_WINDOW (window); /* dead windows should be allowed, no? */
5248 xzero (ovstats);
5249 compute_window_usage (XWINDOW (window), &stats, &ovstats);
5250
5251 val = acons (Qface_cache, make_int (stats.face), val);
5252 val = acons (Qglyph_cache, make_int (stats.glyph), val);
5253 #ifdef HAVE_SCROLLBARS 5245 #ifdef HAVE_SCROLLBARS
5254 val = acons (Qscrollbar_instances, make_int (stats.scrollbar), val); 5246 stats->scrollbar = wmstats->scrollbar;
5247 total -= stats->scrollbar;
5255 #endif 5248 #endif
5256 val = acons (Qline_start_cache, make_int (stats.line_start), val); 5249 stats->window_mirror = total;
5257 val = acons (Qother_redisplay, make_int (stats.other_redisplay), val); 5250 }
5258 val = acons (Qother, make_int (stats.other), val); 5251 }
5259 val = Fcons (Qnil, val); 5252 }
5260 val = acons (Qactually_requested, make_int (ovstats.was_requested), val); 5253
5261 val = acons (Qmalloc_overhead, make_int (ovstats.malloc_overhead), val); 5254 static void
5262 val = acons (Qdynarr_overhead, make_int (ovstats.dynarr_overhead), val); 5255 window_memory_usage (Lisp_Object window, struct generic_usage_stats *gustats)
5263 5256 {
5264 return Fnreverse (val); 5257 struct window_stats *stats = (struct window_stats *) gustats;
5258
5259 compute_window_usage (XWINDOW (window), stats, &stats->u);
5265 } 5260 }
5266 5261
5267 #endif /* MEMORY_USAGE_STATS */ 5262 #endif /* MEMORY_USAGE_STATS */
5263
5264
5268 5265
5269 /* Mark all subwindows of a window as deleted. The argument 5266 /* Mark all subwindows of a window as deleted. The argument
5270 W is actually the subwindow tree of the window in question. */ 5267 W is actually the subwindow tree of the window in question. */
5271 5268
5272 void 5269 void
5416 { 5413 {
5417 Lisp_Object buffer = XWINDOW (window)->buffer; 5414 Lisp_Object buffer = XWINDOW (window)->buffer;
5418 if (!NILP (buffer) && BUFFERP (buffer)) 5415 if (!NILP (buffer) && BUFFERP (buffer))
5419 stderr_out (" on %s", XSTRING_DATA (XBUFFER (buffer)->name)); 5416 stderr_out (" on %s", XSTRING_DATA (XBUFFER (buffer)->name));
5420 } 5417 }
5421 stderr_out (" 0x%x>", XWINDOW (window)->header.uid); 5418 stderr_out (" 0x%x>", LISP_OBJECT_UID (window));
5422 5419
5423 while (!NILP (child)) 5420 while (!NILP (child))
5424 { 5421 {
5425 debug_print_window (child, level + 1); 5422 debug_print_window (child, level + 1);
5426 child = Fwindow_next_child (child); 5423 child = Fwindow_next_child (child);
5440 /************************************************************************/ 5437 /************************************************************************/
5441 /* initialization */ 5438 /* initialization */
5442 /************************************************************************/ 5439 /************************************************************************/
5443 5440
5444 void 5441 void
5442 window_objects_create (void)
5443 {
5444 #ifdef MEMORY_USAGE_STATS
5445 OBJECT_HAS_METHOD (window, memory_usage);
5446 OBJECT_HAS_METHOD (window_mirror, memory_usage);
5447 #endif
5448 }
5449
5450 void
5445 syms_of_window (void) 5451 syms_of_window (void)
5446 { 5452 {
5447 INIT_LRECORD_IMPLEMENTATION (window); 5453 INIT_LISP_OBJECT (window);
5448 INIT_LRECORD_IMPLEMENTATION (window_mirror); 5454 INIT_LISP_OBJECT (window_mirror);
5449 #ifdef NEW_GC 5455 #ifdef NEW_GC
5450 INIT_LRECORD_IMPLEMENTATION (face_cachel); 5456 INIT_LISP_OBJECT (face_cachel);
5451 INIT_LRECORD_IMPLEMENTATION (face_cachel_dynarr); 5457 INIT_LISP_OBJECT (face_cachel_dynarr);
5452 INIT_LRECORD_IMPLEMENTATION (glyph_cachel); 5458 INIT_LISP_OBJECT (glyph_cachel);
5453 INIT_LRECORD_IMPLEMENTATION (glyph_cachel_dynarr); 5459 INIT_LISP_OBJECT (glyph_cachel_dynarr);
5454 #endif /* NEW_GC */ 5460 #endif /* NEW_GC */
5455 5461
5456 DEFSYMBOL (Qwindowp); 5462 DEFSYMBOL (Qwindowp);
5457 DEFSYMBOL (Qwindow_live_p); 5463 DEFSYMBOL (Qwindow_live_p);
5458 DEFSYMBOL (Qdisplay_buffer); 5464 DEFSYMBOL (Qdisplay_buffer);
5462 DEFSYMBOL (Qglyph_cache); 5468 DEFSYMBOL (Qglyph_cache);
5463 DEFSYMBOL (Qline_start_cache); 5469 DEFSYMBOL (Qline_start_cache);
5464 #ifdef HAVE_SCROLLBARS 5470 #ifdef HAVE_SCROLLBARS
5465 DEFSYMBOL (Qscrollbar_instances); 5471 DEFSYMBOL (Qscrollbar_instances);
5466 #endif 5472 #endif
5467 DEFSYMBOL (Qother_redisplay); 5473 DEFSYMBOL (Qredisplay_structs);
5468 /* Qother in general.c */
5469 #endif 5474 #endif
5470 5475
5471 DEFSYMBOL (Qtruncate_partial_width_windows); 5476 DEFSYMBOL (Qtruncate_partial_width_windows);
5472 DEFSYMBOL (Qcurrent_window_configuration); 5477 DEFSYMBOL (Qcurrent_window_configuration);
5473 DEFSYMBOL (Qset_window_configuration); 5478 DEFSYMBOL (Qset_window_configuration);
5541 DEFSUBR (Fscroll_right); 5546 DEFSUBR (Fscroll_right);
5542 DEFSUBR (Fother_window_for_scrolling); 5547 DEFSUBR (Fother_window_for_scrolling);
5543 DEFSUBR (Fscroll_other_window); 5548 DEFSUBR (Fscroll_other_window);
5544 DEFSUBR (Fcenter_to_window_line); 5549 DEFSUBR (Fcenter_to_window_line);
5545 DEFSUBR (Fmove_to_window_line); 5550 DEFSUBR (Fmove_to_window_line);
5546 #ifdef MEMORY_USAGE_STATS
5547 DEFSUBR (Fwindow_memory_usage);
5548 #endif
5549 DEFSUBR (Fcurrent_pixel_column); 5551 DEFSUBR (Fcurrent_pixel_column);
5550 DEFSUBR (Fcurrent_pixel_row); 5552 DEFSUBR (Fcurrent_pixel_row);
5551 } 5553 }
5552 5554
5553 void 5555 void
5559 } 5561 }
5560 5562
5561 void 5563 void
5562 vars_of_window (void) 5564 vars_of_window (void)
5563 { 5565 {
5566 #ifdef MEMORY_USAGE_STATS
5567 Lisp_Object l;
5568
5569 l = listu (Qline_start_cache,
5570 #ifdef NEW_GC
5571 Qt,
5572 #endif
5573 Qface_cache, Qglyph_cache,
5574 #ifndef NEW_GC
5575 Qt,
5576 #endif
5577 Qredisplay_structs,
5578 #ifdef HAVE_SCROLLBARS
5579 Qscrollbar_instances,
5580 #endif
5581 intern ("window-mirror"),
5582 Qunbound);
5583
5584 OBJECT_HAS_PROPERTY (window, memusage_stats_list, l);
5585
5586 l = listu (Qredisplay_structs,
5587 #ifdef HAVE_SCROLLBARS
5588 Qt, Qscrollbar_instances,
5589 #endif
5590 Qunbound);
5591 OBJECT_HAS_PROPERTY (window_mirror, memusage_stats_list, l);
5592 #endif /* MEMORY_USAGE_STATS */
5593
5564 DEFVAR_BOOL ("scroll-on-clipped-lines", &scroll_on_clipped_lines /* 5594 DEFVAR_BOOL ("scroll-on-clipped-lines", &scroll_on_clipped_lines /*
5565 *Non-nil means to scroll if point lands on a line which is clipped. 5595 *Non-nil means to scroll if point lands on a line which is clipped.
5566 */ ); 5596 */ );
5567 scroll_on_clipped_lines = 1; 5597 scroll_on_clipped_lines = 1;
5568 5598