Mercurial > hg > xemacs-beta
comparison src/mc-alloc.c @ 3303:619edf713d55
[xemacs-hg @ 2006-03-26 14:05:29 by crestani]
2006-03-21 Marcus Crestani <crestani@xemacs.org>
* mc-alloc.c (visit_all_used_page_headers):
* mc-alloc.c (finalize_page_for_disksave):
* mc-alloc.c (mc_finalize_for_disksave):
* mc-alloc.c (sweep_page):
* mc-alloc.c (mc_sweep):
* mc-alloc.c (protect_heap_page):
* mc-alloc.c (protect_heap_pages):
* mc-alloc.c (unprotect_heap_page):
* mc-alloc.c (unprotect_heap_pages):
* mc-alloc.h: Return number of pages processed.
* vdb.c (vdb_start_dirty_bits_recording): Adjust size of
page_fault_table to its upper bound (= number of pages that
contain BLACK objects) in advance, to avoid malloc in the signal
handler.
author | crestani |
---|---|
date | Sun, 26 Mar 2006 14:05:30 +0000 |
parents | d674024a8674 |
children | 1043bbfa24cf |
comparison
equal
deleted
inserted
replaced
3302:3d54e5f2dfb0 | 3303:619edf713d55 |
---|---|
428 } | 428 } |
429 #endif /* ERROR_CHECK_GC */ | 429 #endif /* ERROR_CHECK_GC */ |
430 | 430 |
431 /* Visits all pages (page_headers) hooked into the used heap pages | 431 /* Visits all pages (page_headers) hooked into the used heap pages |
432 list and executes f with the current page header as | 432 list and executes f with the current page header as |
433 argument. Needed for sweep. */ | 433 argument. Needed for sweep. Returns number of processed pages. */ |
434 static void | 434 static EMACS_INT |
435 visit_all_used_page_headers (void (*f) (page_header *ph)) | 435 visit_all_used_page_headers (EMACS_INT (*f) (page_header *ph)) |
436 { | 436 { |
437 EMACS_INT number_of_pages_processed = 0; | |
437 EMACS_INT i; | 438 EMACS_INT i; |
438 for (i = 0; i < N_USED_PAGE_LISTS; i++) | 439 for (i = 0; i < N_USED_PAGE_LISTS; i++) |
439 if (PLH_FIRST (USED_HEAP_PAGES (i))) | 440 if (PLH_FIRST (USED_HEAP_PAGES (i))) |
440 { | 441 { |
441 page_header *ph = PLH_FIRST (USED_HEAP_PAGES (i)); | 442 page_header *ph = PLH_FIRST (USED_HEAP_PAGES (i)); |
442 while (PH_NEXT (ph)) | 443 while (PH_NEXT (ph)) |
443 { | 444 { |
444 page_header *next = PH_NEXT (ph); /* in case f removes the page */ | 445 page_header *next = PH_NEXT (ph); /* in case f removes the page */ |
445 f (ph); | 446 number_of_pages_processed += f (ph); |
446 ph = next; | 447 ph = next; |
447 } | 448 } |
448 f (ph); | 449 number_of_pages_processed += f (ph); |
449 } | 450 } |
451 return number_of_pages_processed; | |
450 } | 452 } |
451 | 453 |
452 | 454 |
453 | 455 |
454 | 456 |
1483 /* Finalize a page for disksave. XEmacs calls this routine before it | 1485 /* Finalize a page for disksave. XEmacs calls this routine before it |
1484 dumps the heap image. You have to tell mc-alloc how to call your | 1486 dumps the heap image. You have to tell mc-alloc how to call your |
1485 object's finalizer for disksave. Therefore, you have to define the | 1487 object's finalizer for disksave. Therefore, you have to define the |
1486 macro MC_ALLOC_CALL_FINALIZER_FOR_DISKSAVE(ptr). This macro should | 1488 macro MC_ALLOC_CALL_FINALIZER_FOR_DISKSAVE(ptr). This macro should |
1487 do nothing else then test if there is a finalizer and call it on | 1489 do nothing else then test if there is a finalizer and call it on |
1488 the given argument, which is the heap address of the object. */ | 1490 the given argument, which is the heap address of the object. |
1489 static void | 1491 Returns number of processed pages. */ |
1492 static EMACS_INT | |
1490 finalize_page_for_disksave (page_header *ph) | 1493 finalize_page_for_disksave (page_header *ph) |
1491 { | 1494 { |
1492 EMACS_INT heap_space = (EMACS_INT) PH_HEAP_SPACE (ph); | 1495 EMACS_INT heap_space = (EMACS_INT) PH_HEAP_SPACE (ph); |
1493 EMACS_INT heap_space_step = PH_CELL_SIZE (ph); | 1496 EMACS_INT heap_space_step = PH_CELL_SIZE (ph); |
1494 EMACS_INT mark_bit = 0; | 1497 EMACS_INT mark_bit = 0; |
1497 for (mark_bit = 0; mark_bit < mark_bit_max_index; mark_bit++) | 1500 for (mark_bit = 0; mark_bit < mark_bit_max_index; mark_bit++) |
1498 { | 1501 { |
1499 EMACS_INT ptr = (heap_space + (heap_space_step * mark_bit)); | 1502 EMACS_INT ptr = (heap_space + (heap_space_step * mark_bit)); |
1500 MC_ALLOC_CALL_FINALIZER_FOR_DISKSAVE ((void *) ptr); | 1503 MC_ALLOC_CALL_FINALIZER_FOR_DISKSAVE ((void *) ptr); |
1501 } | 1504 } |
1502 } | 1505 return 1; |
1503 | 1506 } |
1504 | 1507 |
1505 /* Finalizes the heap for disksave. */ | 1508 |
1506 void | 1509 /* Finalizes the heap for disksave. Returns number of processed |
1510 pages. */ | |
1511 EMACS_INT | |
1507 mc_finalize_for_disksave (void) | 1512 mc_finalize_for_disksave (void) |
1508 { | 1513 { |
1509 visit_all_used_page_headers (finalize_page_for_disksave); | 1514 return visit_all_used_page_headers (finalize_page_for_disksave); |
1510 } | 1515 } |
1511 | 1516 |
1512 | 1517 |
1513 /* Sweeps a page: all the non-marked cells are freed. If the page is empty | 1518 /* Sweeps a page: all the non-marked cells are freed. If the page is |
1514 in the end, it is removed. If some cells are free, it is moved to the | 1519 empty in the end, it is removed. If some cells are free, it is |
1515 front of its page header list. Full pages stay where they are. */ | 1520 moved to the front of its page header list. Full pages stay where |
1516 static void | 1521 they are. Returns number of processed pages.*/ |
1522 static EMACS_INT | |
1517 sweep_page (page_header *ph) | 1523 sweep_page (page_header *ph) |
1518 { | 1524 { |
1519 Rawbyte *heap_space = (Rawbyte *) PH_HEAP_SPACE (ph); | 1525 Rawbyte *heap_space = (Rawbyte *) PH_HEAP_SPACE (ph); |
1520 EMACS_INT heap_space_step = PH_CELL_SIZE (ph); | 1526 EMACS_INT heap_space_step = PH_CELL_SIZE (ph); |
1521 EMACS_INT mark_bit = 0; | 1527 EMACS_INT mark_bit = 0; |
1531 GET_BIT (bit, ph, mark_bit * N_MARK_BITS); | 1537 GET_BIT (bit, ph, mark_bit * N_MARK_BITS); |
1532 if (bit) | 1538 if (bit) |
1533 { | 1539 { |
1534 zero_mark_bits (ph); | 1540 zero_mark_bits (ph); |
1535 PH_BLACK_BIT (ph) = 0; | 1541 PH_BLACK_BIT (ph) = 0; |
1536 return; | 1542 return 1; |
1537 } | 1543 } |
1538 } | 1544 } |
1539 | 1545 |
1540 for (mark_bit = 0; mark_bit < mark_bit_max_index; mark_bit++) | 1546 for (mark_bit = 0; mark_bit < mark_bit_max_index; mark_bit++) |
1541 { | 1547 { |
1550 PH_BLACK_BIT (ph) = 0; | 1556 PH_BLACK_BIT (ph) = 0; |
1551 if (PH_CELLS_USED (ph) == 0) | 1557 if (PH_CELLS_USED (ph) == 0) |
1552 remove_page_from_used_list (ph); | 1558 remove_page_from_used_list (ph); |
1553 else if (PH_CELLS_USED (ph) < PH_CELLS_ON_PAGE (ph)) | 1559 else if (PH_CELLS_USED (ph) < PH_CELLS_ON_PAGE (ph)) |
1554 move_page_header_to_front (ph); | 1560 move_page_header_to_front (ph); |
1555 } | 1561 |
1556 | 1562 return 1; |
1557 | 1563 } |
1558 /* Sweeps the heap. */ | 1564 |
1559 void | 1565 |
1566 /* Sweeps the heap. Returns number of processed pages. */ | |
1567 EMACS_INT | |
1560 mc_sweep (void) | 1568 mc_sweep (void) |
1561 { | 1569 { |
1562 visit_all_used_page_headers (sweep_page); | 1570 return visit_all_used_page_headers (sweep_page); |
1563 } | 1571 } |
1564 | 1572 |
1565 | 1573 |
1566 /* Frees the cell pointed to by ptr. */ | 1574 /* Frees the cell pointed to by ptr. */ |
1567 void | 1575 void |
1858 && (PH_PROTECTION_BIT (ph) == 1)); | 1866 && (PH_PROTECTION_BIT (ph) == 1)); |
1859 } | 1867 } |
1860 | 1868 |
1861 | 1869 |
1862 /* Protect the heap page of given page header ph if black objects are | 1870 /* Protect the heap page of given page header ph if black objects are |
1863 on the page. */ | 1871 on the page. Returns number of processed pages. */ |
1864 static void | 1872 static EMACS_INT |
1865 protect_heap_page (page_header *ph) | 1873 protect_heap_page (page_header *ph) |
1866 { | 1874 { |
1867 if (PH_BLACK_BIT (ph)) | 1875 if (PH_BLACK_BIT (ph)) |
1868 { | 1876 { |
1869 void *heap_space = PH_HEAP_SPACE (ph); | 1877 void *heap_space = PH_HEAP_SPACE (ph); |
1870 EMACS_INT heap_space_size = PH_N_PAGES (ph) * PAGE_SIZE; | 1878 EMACS_INT heap_space_size = PH_N_PAGES (ph) * PAGE_SIZE; |
1871 vdb_protect ((void *) heap_space, heap_space_size); | 1879 vdb_protect ((void *) heap_space, heap_space_size); |
1872 PH_PROTECTION_BIT (ph) = 1; | 1880 PH_PROTECTION_BIT (ph) = 1; |
1873 } | 1881 return 1; |
1874 } | 1882 } |
1875 | 1883 return 0; |
1876 /* Protect all heap pages with black objects. */ | 1884 } |
1877 void | 1885 |
1886 /* Protect all heap pages with black objects. Returns number of | |
1887 processed pages.*/ | |
1888 EMACS_INT | |
1878 protect_heap_pages (void) | 1889 protect_heap_pages (void) |
1879 { | 1890 { |
1880 visit_all_used_page_headers (protect_heap_page); | 1891 return visit_all_used_page_headers (protect_heap_page); |
1881 } | 1892 } |
1882 | 1893 |
1883 | 1894 |
1884 /* Remove protection (if there) of heap page of given page header | 1895 /* Remove protection (if there) of heap page of given page header |
1885 ph. */ | 1896 ph. Returns number of processed pages. */ |
1886 static void | 1897 static EMACS_INT |
1887 unprotect_heap_page (page_header *ph) | 1898 unprotect_heap_page (page_header *ph) |
1888 { | 1899 { |
1889 if (PH_PROTECTION_BIT (ph)) | 1900 if (PH_PROTECTION_BIT (ph)) |
1890 { | 1901 { |
1891 void *heap_space = PH_HEAP_SPACE (ph); | 1902 void *heap_space = PH_HEAP_SPACE (ph); |
1892 EMACS_INT heap_space_size = PH_N_PAGES (ph) * PAGE_SIZE; | 1903 EMACS_INT heap_space_size = PH_N_PAGES (ph) * PAGE_SIZE; |
1893 vdb_unprotect (heap_space, heap_space_size); | 1904 vdb_unprotect (heap_space, heap_space_size); |
1894 PH_PROTECTION_BIT (ph) = 0; | 1905 PH_PROTECTION_BIT (ph) = 0; |
1895 } | 1906 return 1; |
1896 } | 1907 } |
1897 | 1908 return 0; |
1898 /* Remove protection for all heap pages which are protected. */ | 1909 } |
1899 void | 1910 |
1911 /* Remove protection for all heap pages which are protected. Returns | |
1912 number of processed pages. */ | |
1913 EMACS_INT | |
1900 unprotect_heap_pages (void) | 1914 unprotect_heap_pages (void) |
1901 { | 1915 { |
1902 visit_all_used_page_headers (unprotect_heap_page); | 1916 return visit_all_used_page_headers (unprotect_heap_page); |
1903 } | 1917 } |
1904 | 1918 |
1905 /* Remove protection and mark page dirty. */ | 1919 /* Remove protection and mark page dirty. */ |
1906 void | 1920 void |
1907 unprotect_page_and_mark_dirty (void *ptr) | 1921 unprotect_page_and_mark_dirty (void *ptr) |