comparison src/alloc.c @ 452:3d3049ae1304 r21-2-41

Import from CVS: tag r21-2-41
author cvs
date Mon, 13 Aug 2007 11:40:21 +0200
parents 98528da0b7fc
children d7a9135ec789
comparison
equal deleted inserted replaced
451:8ad70c5cd5d7 452:3d3049ae1304
40 */ 40 */
41 41
42 #include <config.h> 42 #include <config.h>
43 #include "lisp.h" 43 #include "lisp.h"
44 44
45 #include "alloc.h"
46 #include "backtrace.h" 45 #include "backtrace.h"
47 #include "buffer.h" 46 #include "buffer.h"
48 #include "bytecode.h" 47 #include "bytecode.h"
49 #include "chartab.h" 48 #include "chartab.h"
50 #include "device.h" 49 #include "device.h"
777 You have some weird system and need to supply a reasonable value here. 776 You have some weird system and need to supply a reasonable value here.
778 #endif 777 #endif
779 778
780 /* The construct (* (void **) (ptr)) would cause aliasing problems 779 /* The construct (* (void **) (ptr)) would cause aliasing problems
781 with modern optimizing compilers like `gcc -O3 -fstrict-aliasing'. 780 with modern optimizing compilers like `gcc -O3 -fstrict-aliasing'.
782 But `char *' can legally alias any pointer. Hence this union trick. */ 781 But `char *' can legally alias any pointer. Hence this union trick...
782
783 It turned out that the union trick was not good enough for xlC -O3;
784 and it is questionable whether it really complies with the C standard.
785 so we use memset instead, which should be safe from optimizations. */
783 typedef union { char c; void *p; } *aliasing_voidpp; 786 typedef union { char c; void *p; } *aliasing_voidpp;
784 #define ALIASING_VOIDPP_DEREFERENCE(ptr) \ 787 #define ALIASING_VOIDPP_DEREFERENCE(ptr) \
785 (((aliasing_voidpp) (ptr))->p) 788 (((aliasing_voidpp) (ptr))->p)
786 #define FREE_STRUCT_P(ptr) \ 789 #define FREE_STRUCT_P(ptr) \
787 (ALIASING_VOIDPP_DEREFERENCE (ptr) == (void *) INVALID_POINTER_VALUE) 790 (ALIASING_VOIDPP_DEREFERENCE (ptr) == (void *) INVALID_POINTER_VALUE)
788 #define MARK_STRUCT_AS_FREE(ptr) \ 791 #define MARK_STRUCT_AS_FREE(ptr) memset (ptr, 0xff, sizeof (void *))
789 (ALIASING_VOIDPP_DEREFERENCE (ptr) = (void *) INVALID_POINTER_VALUE) 792 #define MARK_STRUCT_AS_NOT_FREE(ptr) memset (ptr, 0x00, sizeof (void *))
790 #define MARK_STRUCT_AS_NOT_FREE(ptr) \
791 (ALIASING_VOIDPP_DEREFERENCE (ptr) = 0)
792 793
793 #ifdef ERROR_CHECK_GC 794 #ifdef ERROR_CHECK_GC
794 795
795 #define PUT_FIXED_TYPE_ON_FREE_LIST(type, structtype, ptr) \ 796 #define PUT_FIXED_TYPE_ON_FREE_LIST(type, structtype, ptr) \
796 do { if (type##_free_list_tail) \ 797 do { if (type##_free_list_tail) \
2345 This hack speeds up (garbage-collect) by about 5%. */ 2346 This hack speeds up (garbage-collect) by about 5%. */
2346 Lisp_Object (*lrecord_markers[countof (lrecord_implementations_table)]) (Lisp_Object); 2347 Lisp_Object (*lrecord_markers[countof (lrecord_implementations_table)]) (Lisp_Object);
2347 2348
2348 struct gcpro *gcprolist; 2349 struct gcpro *gcprolist;
2349 2350
2350 /* 415 used Mly 29-Jun-93 */ 2351 /* We want the staticpros relocated, but not the pointers found therein.
2351 /* 1327 used slb 28-Feb-98 */ 2352 Hence we use a trivial description, as for pointerless objects. */
2352 /* 1328 used og 03-Oct-99 (moving slowly, heh?) */ 2353 static const struct lrecord_description staticpro_description_1[] = {
2353 #ifdef HAVE_SHLIB 2354 { XD_END }
2354 #define NSTATICS 4000 2355 };
2355 #else 2356
2356 #define NSTATICS 2000 2357 static const struct struct_description staticpro_description = {
2357 #endif 2358 sizeof (Lisp_Object *),
2358 2359 staticpro_description_1
2359 /* Not "static" because used by dumper.c */ 2360 };
2360 Lisp_Object *staticvec[NSTATICS]; 2361
2361 int staticidx; 2362 static const struct lrecord_description staticpros_description_1[] = {
2362 2363 XD_DYNARR_DESC (Lisp_Object_ptr_dynarr, &staticpro_description),
2363 /* Put an entry in staticvec, pointing at the variable whose address is given 2364 { XD_END }
2364 */ 2365 };
2366
2367 static const struct struct_description staticpros_description = {
2368 sizeof (Lisp_Object_ptr_dynarr),
2369 staticpros_description_1
2370 };
2371
2372 Lisp_Object_ptr_dynarr *staticpros;
2373
2374 /* Mark the Lisp_Object at non-heap VARADDRESS as a root object for
2375 garbage collection, and for dumping. */
2365 void 2376 void
2366 staticpro (Lisp_Object *varaddress) 2377 staticpro (Lisp_Object *varaddress)
2367 { 2378 {
2368 /* #### This is now a dubious assert() since this routine may be called */ 2379 Dynarr_add (staticpros, varaddress);
2369 /* by Lisp attempting to load a DLL. */ 2380 dump_add_root_object (varaddress);
2370 assert (staticidx < countof (staticvec)); 2381 }
2371 staticvec[staticidx++] = varaddress; 2382
2372 } 2383
2373 2384 Lisp_Object_ptr_dynarr *staticpros_nodump;
2374 2385
2375 Lisp_Object *staticvec_nodump[200]; 2386 /* Mark the Lisp_Object at non-heap VARADDRESS as a root object for
2376 int staticidx_nodump; 2387 garbage collection, but not for dumping. */
2377
2378 /* Put an entry in staticvec_nodump, pointing at the variable whose address is given
2379 */
2380 void 2388 void
2381 staticpro_nodump (Lisp_Object *varaddress) 2389 staticpro_nodump (Lisp_Object *varaddress)
2382 { 2390 {
2383 /* #### This is now a dubious assert() since this routine may be called */ 2391 Dynarr_add (staticpros_nodump, varaddress);
2384 /* by Lisp attempting to load a DLL. */
2385 assert (staticidx_nodump < countof (staticvec_nodump));
2386 staticvec_nodump[staticidx_nodump++] = varaddress;
2387 }
2388
2389
2390 struct pdump_dumpstructinfo dumpstructvec[200];
2391 int dumpstructidx;
2392
2393 /* Put an entry in dumpstructvec, pointing at the variable whose address is given
2394 */
2395 void
2396 dumpstruct (void *varaddress, const struct struct_description *desc)
2397 {
2398 assert (dumpstructidx < countof (dumpstructvec));
2399 dumpstructvec[dumpstructidx].data = varaddress;
2400 dumpstructvec[dumpstructidx].desc = desc;
2401 dumpstructidx++;
2402 }
2403
2404 struct pdump_dumpopaqueinfo dumpopaquevec[250];
2405 int dumpopaqueidx;
2406
2407 /* Put an entry in dumpopaquevec, pointing at the variable whose address is given
2408 */
2409 void
2410 dumpopaque (void *varaddress, size_t size)
2411 {
2412 assert (dumpopaqueidx < countof (dumpopaquevec));
2413
2414 dumpopaquevec[dumpopaqueidx].data = varaddress;
2415 dumpopaquevec[dumpopaqueidx].size = size;
2416 dumpopaqueidx++;
2417 }
2418
2419 Lisp_Object *pdump_wirevec[50];
2420 int pdump_wireidx;
2421
2422 /* Put an entry in pdump_wirevec, pointing at the variable whose address is given
2423 */
2424 void
2425 pdump_wire (Lisp_Object *varaddress)
2426 {
2427 assert (pdump_wireidx < countof (pdump_wirevec));
2428 pdump_wirevec[pdump_wireidx++] = varaddress;
2429 }
2430
2431
2432 Lisp_Object *pdump_wirevec_list[50];
2433 int pdump_wireidx_list;
2434
2435 /* Put an entry in pdump_wirevec_list, pointing at the variable whose address is given
2436 */
2437 void
2438 pdump_wire_list (Lisp_Object *varaddress)
2439 {
2440 assert (pdump_wireidx_list < countof (pdump_wirevec_list));
2441 pdump_wirevec_list[pdump_wireidx_list++] = varaddress;
2442 } 2392 }
2443 2393
2444 #ifdef ERROR_CHECK_GC 2394 #ifdef ERROR_CHECK_GC
2445 #define GC_CHECK_LHEADER_INVARIANTS(lheader) do { \ 2395 #define GC_CHECK_LHEADER_INVARIANTS(lheader) do { \
2446 struct lrecord_header * GCLI_lh = (lheader); \ 2396 struct lrecord_header * GCLI_lh = (lheader); \
3427 cleanup_specifiers (); 3377 cleanup_specifiers ();
3428 3378
3429 /* Mark all the special slots that serve as the roots of accessibility. */ 3379 /* Mark all the special slots that serve as the roots of accessibility. */
3430 3380
3431 { /* staticpro() */ 3381 { /* staticpro() */
3432 int i; 3382 Lisp_Object **p = Dynarr_begin (staticpros);
3433 for (i = 0; i < staticidx; i++) 3383 size_t count;
3434 mark_object (*(staticvec[i])); 3384 for (count = Dynarr_length (staticpros); count; count--)
3435 for (i = 0; i < staticidx_nodump; i++) 3385 mark_object (**p++);
3436 mark_object (*(staticvec_nodump[i])); 3386 }
3387
3388 { /* staticpro_nodump() */
3389 Lisp_Object **p = Dynarr_begin (staticpros_nodump);
3390 size_t count;
3391 for (count = Dynarr_length (staticpros_nodump); count; count--)
3392 mark_object (**p++);
3437 } 3393 }
3438 3394
3439 { /* GCPRO() */ 3395 { /* GCPRO() */
3440 struct gcpro *tail; 3396 struct gcpro *tail;
3441 int i; 3397 int i;
3468 { 3424 {
3469 int nargs = backlist->nargs; 3425 int nargs = backlist->nargs;
3470 int i; 3426 int i;
3471 3427
3472 mark_object (*backlist->function); 3428 mark_object (*backlist->function);
3473 if (nargs == UNEVALLED || nargs == MANY) 3429 if (nargs < 0 /* nargs == UNEVALLED || nargs == MANY */)
3474 mark_object (backlist->args[0]); 3430 mark_object (backlist->args[0]);
3475 else 3431 else
3476 for (i = 0; i < nargs; i++) 3432 for (i = 0; i < nargs; i++)
3477 mark_object (backlist->args[i]); 3433 mark_object (backlist->args[i]);
3478 } 3434 }
3895 init_extent_alloc (); 3851 init_extent_alloc ();
3896 init_event_alloc (); 3852 init_event_alloc ();
3897 3853
3898 ignore_malloc_warnings = 0; 3854 ignore_malloc_warnings = 0;
3899 3855
3900 staticidx_nodump = 0; 3856 if (staticpros_nodump)
3901 dumpstructidx = 0; 3857 Dynarr_free (staticpros_nodump);
3902 pdump_wireidx = 0; 3858 staticpros_nodump = Dynarr_new2 (Lisp_Object_ptr_dynarr, Lisp_Object *);
3859 Dynarr_resize (staticpros_nodump, 100); /* merely a small optimization */
3903 3860
3904 consing_since_gc = 0; 3861 consing_since_gc = 0;
3905 #if 1 3862 #if 1
3906 gc_cons_threshold = 500000; /* XEmacs change */ 3863 gc_cons_threshold = 500000; /* XEmacs change */
3907 #else 3864 #else
3939 INIT_LRECORD_IMPLEMENTATION (cons); 3896 INIT_LRECORD_IMPLEMENTATION (cons);
3940 INIT_LRECORD_IMPLEMENTATION (vector); 3897 INIT_LRECORD_IMPLEMENTATION (vector);
3941 INIT_LRECORD_IMPLEMENTATION (string); 3898 INIT_LRECORD_IMPLEMENTATION (string);
3942 INIT_LRECORD_IMPLEMENTATION (lcrecord_list); 3899 INIT_LRECORD_IMPLEMENTATION (lcrecord_list);
3943 3900
3944 staticidx = 0; 3901 staticpros = Dynarr_new2 (Lisp_Object_ptr_dynarr, Lisp_Object *);
3902 Dynarr_resize (staticpros, 1410); /* merely a small optimization */
3903 dump_add_root_struct_ptr (&staticpros, &staticpros_description);
3945 } 3904 }
3946 3905
3947 void 3906 void
3948 reinit_alloc (void) 3907 reinit_alloc (void)
3949 { 3908 {