Mercurial > hg > xemacs-beta
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 { |