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)