Mercurial > hg > xemacs-beta
comparison src/opaque.c @ 380:8626e4521993 r21-2-5
Import from CVS: tag r21-2-5
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:07:10 +0200 |
parents | cc15677e0335 |
children | 6719134a07c2 |
comparison
equal
deleted
inserted
replaced
379:76b7d63099ad | 380:8626e4521993 |
---|---|
40 */ | 40 */ |
41 | 41 |
42 #include <config.h> | 42 #include <config.h> |
43 #include "lisp.h" | 43 #include "lisp.h" |
44 #include "opaque.h" | 44 #include "opaque.h" |
45 #include <stddef.h> | |
45 | 46 |
46 Lisp_Object Qopaquep; | 47 Lisp_Object Qopaquep; |
47 | 48 |
48 static int in_opaque_list_marking; | 49 static int in_opaque_list_marking; |
49 | 50 |
53 Lisp_Object Vopaque_ptr_free_list; | 54 Lisp_Object Vopaque_ptr_free_list; |
54 | 55 |
55 static Lisp_Object | 56 static Lisp_Object |
56 mark_opaque (Lisp_Object obj, void (*markobj) (Lisp_Object)) | 57 mark_opaque (Lisp_Object obj, void (*markobj) (Lisp_Object)) |
57 { | 58 { |
59 Lisp_Opaque *p = XOPAQUE (obj); | |
60 Lisp_Object size_or_chain = p->size_or_chain; | |
58 #ifdef ERROR_CHECK_GC | 61 #ifdef ERROR_CHECK_GC |
59 if (!in_opaque_list_marking) | 62 if (!in_opaque_list_marking) |
60 /* size is non-int for objects on an opaque free list. We sure | 63 /* size is non-int for objects on an opaque free list. We sure |
61 as hell better not be marking any of these objects unless | 64 as hell better not be marking any of these objects unless |
62 we're marking an opaque list. */ | 65 we're marking an opaque list. */ |
63 assert (INTP (XOPAQUE (obj)->size_or_chain)); | 66 assert (GC_INTP (size_or_chain)); |
64 else | 67 else |
65 /* marking an opaque on the free list doesn't do any recursive | 68 /* marking an opaque on the free list doesn't do any recursive |
66 markings, so we better not have non-freed opaques on a free | 69 markings, so we better not have non-freed opaques on a free |
67 list. */ | 70 list. */ |
68 assert (!INTP (XOPAQUE (obj)->size_or_chain)); | 71 assert (!GC_INTP (size_or_chain)); |
69 #endif | 72 #endif |
70 if (INTP (XOPAQUE (obj)->size_or_chain) && XOPAQUE_MARKFUN (obj)) | 73 if (GC_INTP (size_or_chain) && OPAQUE_MARKFUN (p)) |
71 return XOPAQUE_MARKFUN (obj) (obj, markobj); | 74 return OPAQUE_MARKFUN (p) (obj, markobj); |
72 else | 75 else |
73 return XOPAQUE (obj)->size_or_chain; | 76 return size_or_chain; |
74 } | 77 } |
75 | 78 |
76 /* Should never, ever be called. (except by an external debugger) */ | 79 /* Should never, ever be called. (except by an external debugger) */ |
77 static void | 80 static void |
78 print_opaque (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag) | 81 print_opaque (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag) |
79 { | 82 { |
83 CONST Lisp_Opaque *p = XOPAQUE (obj); | |
80 char buf[200]; | 84 char buf[200]; |
81 if (INTP (XOPAQUE (obj)->size_or_chain)) | 85 char size_buf[50]; |
82 sprintf (buf, "#<INTERNAL EMACS BUG (opaque, size=%ld) 0x%lx>", | 86 |
83 (long) XOPAQUE_SIZE (obj), (unsigned long) XPNTR (obj)); | 87 if (INTP (p->size_or_chain)) |
84 else | 88 sprintf (size_buf, "size=%lu", (unsigned long) OPAQUE_SIZE (p)); |
85 sprintf (buf, "#<INTERNAL EMACS BUG (opaque, freed) 0x%lx>", | 89 else |
86 (unsigned long) XPNTR (obj)); | 90 sprintf (size_buf, "freed"); |
91 | |
92 sprintf (buf, "#<INTERNAL OBJECT (XEmacs bug?) (opaque, %s) 0x%lx>", | |
93 size_buf, (unsigned long) p); | |
87 write_c_string (buf, printcharfun); | 94 write_c_string (buf, printcharfun); |
88 } | 95 } |
89 | 96 |
90 static size_t | 97 static size_t |
91 sizeof_opaque (CONST void *header) | 98 sizeof_opaque (CONST void *header) |
92 { | 99 { |
93 CONST struct Lisp_Opaque *p = (CONST struct Lisp_Opaque *) header; | 100 CONST Lisp_Opaque *p = (CONST Lisp_Opaque *) header; |
94 if (!INTP (p->size_or_chain)) | 101 return offsetof (Lisp_Opaque, data) |
95 return sizeof (*p); | 102 + (GC_INTP (p->size_or_chain) ? XINT (p->size_or_chain) : 0); |
96 return sizeof (*p) + XINT (p->size_or_chain) - sizeof (int); | 103 } |
97 } | 104 |
98 | 105 /* Return an opaque object of size SIZE. |
99 Lisp_Object | 106 If DATA is OPAQUE_CLEAR, the object's data is memset to '\0' bytes. |
100 make_opaque (int size, CONST void *data) | 107 If DATA is OPAQUE_UNINIT, the object's data is uninitialized. |
101 { | 108 Else the object's data is initialized by copying from DATA. */ |
102 struct Lisp_Opaque *p = (struct Lisp_Opaque *) | 109 Lisp_Object |
103 alloc_lcrecord (sizeof (*p) + size - sizeof (int), lrecord_opaque); | 110 make_opaque (size_t size, CONST void *data) |
104 Lisp_Object val; | 111 { |
105 | 112 Lisp_Opaque *p = (Lisp_Opaque *) |
113 alloc_lcrecord (offsetof (Lisp_Opaque, data) + size, lrecord_opaque); | |
106 p->markfun = 0; | 114 p->markfun = 0; |
107 p->size_or_chain = make_int (size); | 115 p->size_or_chain = make_int (size); |
108 if (data) | 116 |
117 if (data == OPAQUE_CLEAR) | |
118 memset (p->data, '\0', size); | |
119 else if (data == OPAQUE_UNINIT) | |
120 DO_NOTHING; | |
121 else | |
109 memcpy (p->data, data, size); | 122 memcpy (p->data, data, size); |
110 else | 123 |
111 memset (p->data, 0, size); | 124 { |
112 XSETOPAQUE (val, p); | 125 Lisp_Object val; |
113 return val; | 126 XSETOPAQUE (val, p); |
127 return val; | |
128 } | |
114 } | 129 } |
115 | 130 |
116 /* This will not work correctly for opaques with subobjects! */ | 131 /* This will not work correctly for opaques with subobjects! */ |
117 | 132 |
118 static int | 133 static int |
119 equal_opaque (Lisp_Object obj1, Lisp_Object obj2, int depth) | 134 equal_opaque (Lisp_Object obj1, Lisp_Object obj2, int depth) |
120 { | 135 { |
136 size_t size; | |
121 #ifdef DEBUG_XEMACS | 137 #ifdef DEBUG_XEMACS |
122 assert (!XOPAQUE_MARKFUN (obj1) && !XOPAQUE_MARKFUN (obj2)); | 138 assert (!XOPAQUE_MARKFUN (obj1) && !XOPAQUE_MARKFUN (obj2)); |
123 assert (INTP (XOPAQUE(obj1)->size_or_chain)); | 139 assert (INTP (XOPAQUE (obj1)->size_or_chain)); |
124 assert (INTP (XOPAQUE(obj2)->size_or_chain)); | 140 assert (INTP (XOPAQUE (obj2)->size_or_chain)); |
125 #endif | 141 #endif |
126 if (XOPAQUE_SIZE(obj1) != XOPAQUE_SIZE(obj2)) | 142 return ((size = XOPAQUE_SIZE (obj1)) == XOPAQUE_SIZE (obj2) && |
127 return 0; | 143 !memcmp (XOPAQUE_DATA (obj1), XOPAQUE_DATA (obj2), size)); |
128 return (XOPAQUE_SIZE(obj1) == sizeof(*XOPAQUE_DATA(obj1)) | |
129 ? *XOPAQUE_DATA(obj1) == *XOPAQUE_DATA(obj2) | |
130 : memcmp (XOPAQUE_DATA(obj1), XOPAQUE_DATA(obj2), | |
131 XOPAQUE_SIZE(obj1)) == 0); | |
132 } | 144 } |
133 | 145 |
134 /* This will not work correctly for opaques with subobjects! */ | 146 /* This will not work correctly for opaques with subobjects! */ |
135 | 147 |
136 static unsigned long | 148 static unsigned long |
137 hash_opaque (Lisp_Object obj, int depth) | 149 hash_opaque (Lisp_Object obj, int depth) |
138 { | 150 { |
139 #ifdef DEBUG_XEMACS | 151 #ifdef DEBUG_XEMACS |
140 assert (!XOPAQUE_MARKFUN (obj)); | 152 assert (!XOPAQUE_MARKFUN (obj)); |
141 assert (INTP (XOPAQUE(obj)->size_or_chain)); | 153 assert (INTP (XOPAQUE (obj)->size_or_chain)); |
142 #endif | 154 #endif |
143 if (XOPAQUE_SIZE(obj) == sizeof (unsigned long)) | 155 if (XOPAQUE_SIZE (obj) == sizeof (unsigned long)) |
144 return (unsigned int) *XOPAQUE_DATA(obj); | 156 return *((unsigned long *) XOPAQUE_DATA(obj)); |
145 else | 157 else |
146 return memory_hash (XOPAQUE_DATA(obj), XOPAQUE_SIZE(obj)); | 158 return memory_hash (XOPAQUE_DATA (obj), XOPAQUE_SIZE (obj)); |
147 } | 159 } |
148 | 160 |
149 DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION ("opaque", opaque, | 161 DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION ("opaque", opaque, |
150 mark_opaque, print_opaque, 0, | 162 mark_opaque, print_opaque, 0, |
151 equal_opaque, hash_opaque, | 163 equal_opaque, hash_opaque, |
152 sizeof_opaque, struct Lisp_Opaque); | 164 sizeof_opaque, Lisp_Opaque); |
153 | 165 |
154 static Lisp_Object | 166 static Lisp_Object |
155 mark_opaque_list (Lisp_Object obj, void (*markobj) (Lisp_Object)) | 167 mark_opaque_list (Lisp_Object obj, void (*markobj) (Lisp_Object)) |
156 { | 168 { |
157 in_opaque_list_marking++; | 169 in_opaque_list_marking++; |
158 (markobj) (XOPAQUE_LIST (obj)->free); | 170 markobj (XOPAQUE_LIST (obj)->free); |
159 in_opaque_list_marking--; | 171 in_opaque_list_marking--; |
160 return Qnil; | 172 return Qnil; |
161 } | 173 } |
162 | 174 |
163 Lisp_Object | 175 Lisp_Object |
164 make_opaque_list (int size, | 176 make_opaque_list (size_t size, |
165 Lisp_Object (*markfun) (Lisp_Object obj, | 177 Lisp_Object (*markfun) (Lisp_Object obj, |
166 void (*markobj) (Lisp_Object))) | 178 void (*markobj) (Lisp_Object))) |
167 { | 179 { |
168 Lisp_Object val; | 180 Lisp_Object val; |
169 struct Lisp_Opaque_List *p = | 181 Lisp_Opaque_List *p = |
170 alloc_lcrecord_type (struct Lisp_Opaque_List, lrecord_opaque_list); | 182 alloc_lcrecord_type (Lisp_Opaque_List, lrecord_opaque_list); |
171 | 183 |
172 p->markfun = markfun; | 184 p->markfun = markfun; |
173 p->size = size; | 185 p->size = size; |
174 p->free = Qnil; | 186 p->free = Qnil; |
175 XSETOPAQUE_LIST (val, p); | 187 XSETOPAQUE_LIST (val, p); |
176 return val; | 188 return val; |
177 } | 189 } |
178 | 190 |
179 DEFINE_LRECORD_IMPLEMENTATION ("opaque-list", opaque_list, | 191 DEFINE_LRECORD_IMPLEMENTATION ("opaque-list", opaque_list, |
180 mark_opaque_list, internal_object_printer, | 192 mark_opaque_list, internal_object_printer, |
181 0, 0, 0, struct Lisp_Opaque_List); | 193 0, 0, 0, Lisp_Opaque_List); |
182 | 194 |
183 Lisp_Object | 195 Lisp_Object |
184 allocate_managed_opaque (Lisp_Object opaque_list, CONST void *data) | 196 allocate_managed_opaque (Lisp_Object opaque_list, CONST void *data) |
185 { | 197 { |
186 struct Lisp_Opaque_List *li = XOPAQUE_LIST (opaque_list); | 198 Lisp_Opaque_List *li = XOPAQUE_LIST (opaque_list); |
187 Lisp_Object val; | 199 Lisp_Object val; |
188 | 200 |
189 if (!NILP (li->free)) | 201 if (!NILP (li->free)) |
190 { | 202 { |
191 val = li->free; | 203 val = li->free; |
206 } | 218 } |
207 | 219 |
208 void | 220 void |
209 free_managed_opaque (Lisp_Object opaque_list, Lisp_Object opaque) | 221 free_managed_opaque (Lisp_Object opaque_list, Lisp_Object opaque) |
210 { | 222 { |
211 struct Lisp_Opaque_List *li = XOPAQUE_LIST (opaque_list); | 223 Lisp_Opaque_List *li = XOPAQUE_LIST (opaque_list); |
212 | 224 |
213 #ifdef ERROR_CHECK_GC | 225 #ifdef ERROR_CHECK_GC |
214 assert (INTP (XOPAQUE (opaque)->size_or_chain)); | 226 assert (INTP (XOPAQUE (opaque)->size_or_chain)); |
215 #endif | 227 #endif |
216 XOPAQUE (opaque)->size_or_chain = li->free; | 228 XOPAQUE (opaque)->size_or_chain = li->free; |
224 { | 236 { |
225 return allocate_managed_opaque (Vopaque_ptr_free_list, | 237 return allocate_managed_opaque (Vopaque_ptr_free_list, |
226 (CONST void *) &val); | 238 (CONST void *) &val); |
227 } | 239 } |
228 | 240 |
229 /* Be wery wery careful with this. Same admonitions as with | 241 /* Be very very careful with this. Same admonitions as with |
230 free_cons() apply. */ | 242 free_cons() apply. */ |
231 | 243 |
232 void | 244 void |
233 free_opaque_ptr (Lisp_Object ptr) | 245 free_opaque_ptr (Lisp_Object ptr) |
234 { | 246 { |