comparison src/vdb.c @ 3092:141c2920ea48

[xemacs-hg @ 2005-11-25 01:41:31 by crestani] Incremental Garbage Collector
author crestani
date Fri, 25 Nov 2005 01:42:08 +0000
parents
children 619edf713d55
comparison
equal deleted inserted replaced
3091:c22d8984148c 3092:141c2920ea48
1 /* Virtual diry bit implementation (platform independent) for XEmacs.
2 Copyright (C) 2005 Marcus Crestani.
3
4 This file is part of XEmacs.
5
6 XEmacs is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
9 later version.
10
11 XEmacs is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with XEmacs; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
20
21 /* Synched up with: Not in FSF. */
22
23 #include <config.h>
24 #include "lisp.h"
25 #include "gc.h"
26 #include "mc-alloc.h"
27 #include "vdb.h"
28
29
30 typedef struct
31 {
32 Dynarr_declare (void *);
33 } void_ptr_dynarr;
34
35 void_ptr_dynarr *page_fault_table;
36
37 /* Init page fault table and protect heap. */
38 void
39 vdb_start_dirty_bits_recording (void)
40 {
41 page_fault_table = Dynarr_new2 (void_ptr_dynarr, void *);
42 protect_heap_pages ();
43 }
44
45 /* Remove heap protection. */
46 void
47 vdb_stop_dirty_bits_recording (void)
48 {
49 unprotect_heap_pages ();
50 }
51
52 /* Read page fault table and pass page faults to garbage collector. */
53 int
54 vdb_read_dirty_bits (void)
55 {
56 int repushed_objects = 0;
57 Elemcount count;
58 for (count = Dynarr_length (page_fault_table); count; count--)
59 repushed_objects +=
60 repush_all_objects_on_page (Dynarr_at (page_fault_table, count - 1));
61 Dynarr_free (page_fault_table);
62 page_fault_table = 0;
63 return repushed_objects;
64 }
65
66 /* Called by the page fault handler: add address to page fault table. */
67 void
68 vdb_designate_modified (void *addr)
69 {
70 Dynarr_add (page_fault_table, addr);
71 }
72
73
74 /* For testing and debugging... */
75
76 DEFUN ("test-vdb", Ftest_vdb, 0, 0, "", /*
77 Test virtual dirty bit implementation. Prints results to stderr.
78 */
79 ())
80 {
81 Rawbyte *p;
82 char c;
83 Elemcount count;
84
85 /* Wrap up gc (if currently running). */
86 gc_full ();
87
88 /* Allocate a buffer; it will have the default
89 protection of PROT_READ|PROT_WRITE. */
90 p = (Rawbyte *) mc_alloc (mc_get_page_size());
91 set_lheader_implementation ((struct lrecord_header *) p, &lrecord_cons);
92 fprintf (stderr, "Allocate p: [%x ... %x], length %d\n",
93 (int) p, (int) (p + mc_get_page_size ()),
94 (int) mc_get_page_size ());
95
96 /* Test read. */
97 fprintf (stderr, "Attempt to read p[666]... ");
98 c = p[666];
99 fprintf (stderr, "read ok.\n");
100
101 /* Test write. */
102 fprintf (stderr, "Attempt to write 42 to p[666]... ");
103 p[666] = 42;
104 fprintf (stderr, "write ok, p[666] = %d\n", p[666]);
105
106 /* Mark the buffer read-only and set environemnt for write-barrier. */
107 fprintf (stderr, "Write-protect the page.\n");
108 MARK_BLACK (p);
109 vdb_start_dirty_bits_recording ();
110 write_barrier_enabled = 1;
111
112 /* Test write-barrier read. */
113 fprintf (stderr, "Attempt to read p[666]... ");
114 c = p[666];
115 fprintf (stderr, "read ok.\n");
116
117 /* Test write-barrier write, program receives SIGSEGV. */
118 fprintf (stderr, "Attempt to write 23 to p[666]... ");
119 p[666] = 23;
120 fprintf (stderr, "Written p[666] = %d\n", p[666]);
121
122 /* Stop write-barrier mode. */
123 write_barrier_enabled = 0;
124 MARK_WHITE (p);
125 vdb_unprotect (p, mc_get_page_size ());
126 for (count = Dynarr_length (page_fault_table); count; count--)
127 if (Dynarr_at (page_fault_table, count - 1) == &p[666])
128 fprintf (stderr, "VALID page fault at %x\n",
129 (int) Dynarr_at (page_fault_table, count - 1));
130 else
131 fprintf (stderr, "WRONG page fault at %x\n",
132 (int) Dynarr_at (page_fault_table, count - 1));
133 Dynarr_free (page_fault_table);
134 mc_free (p);
135 return Qnil;
136 }
137
138 DEFUN ("test-segfault", Ftest_segfault, 0, 0, "", /*
139 Test virtual dirty bit implementation: provoke a segfault on purpose.
140 WARNING: this function causes a SEGFAULT on purpose and thus crashes
141 XEmacs! This is only used for debbugging, e.g. for testing how the
142 debugger behaves when XEmacs segfaults and the write barrier is
143 enabled.
144 */
145 ())
146 {
147 Rawbyte *q = 0;
148 q[0] = 23;
149 return Qnil;
150 }
151
152 void
153 syms_of_vdb (void)
154 {
155 DEFSUBR (Ftest_vdb);
156 DEFSUBR (Ftest_segfault);
157 }