area_roots.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. /*
  2. * Part of Scheme 48 1.9. See file COPYING for notices and license.
  3. *
  4. * Authors: David Frese
  5. */
  6. /* Implements area_roots.h */
  7. #include <stdlib.h>
  8. #include "scheme48.h"
  9. #include "area_roots.h"
  10. #include "areas.h"
  11. #include "memory.h"
  12. #include "memory_map.h"
  13. #include "utils.h"
  14. #include "data.h"
  15. #include "measure.h"
  16. #include "generation_gc.h"
  17. #include "gc_config.h"
  18. #if (S48_USE_REMEMBERED_SETS)
  19. #include "remset.h"
  20. #endif
  21. /* initializes the dirty vector of AREA */
  22. void s48_init_dirty_vector(Area* area) {
  23. #if S48_DIRTY_VECTOR_METHOD==S48_ADDRESS_DIRTY_VECTORS
  24. Dirty_vector* dv = &area->dirty_vector;
  25. unsigned long area_size = area->end - area->start;
  26. unsigned long number_of_cards = area_size >> S48_LOG_CARD_SIZE ;
  27. dv->length = number_of_cards;
  28. /* A vector of pointers */
  29. dv->items = (s48_address*)calloc(sizeof(s48_address), number_of_cards);
  30. #endif
  31. }
  32. /* deinitializes the dirty vector of AREA. (should free the memory
  33. allocated in init_dirty_vector */
  34. void s48_deinit_dirty_vector(Area* area) {
  35. #if S48_DIRTY_VECTOR_METHOD==S48_ADDRESS_DIRTY_VECTORS
  36. free(area->dirty_vector.items);
  37. #endif
  38. }
  39. #if (MEASURE_GC)
  40. static unsigned long areas_visited = 0;
  41. static unsigned long areas_passed = 0;
  42. #endif
  43. inline static void call_trace_locationsB(Area* area,
  44. s48_address start_address,
  45. s48_address end_address) {
  46. #if (MEASURE_GC)
  47. areas_passed += (end_address - start_address);
  48. #endif
  49. s48_internal_trace_locationsB(area, TRUE, start_address, end_address,
  50. "s48_trace_areas_roots");
  51. }
  52. /* trace (all possible) pointers to collected generations, in the
  53. old/uncollected area AREA */
  54. void trace_area_roots(Area* area)
  55. {
  56. /* the tracing can always be stopped at the trace pointer, because
  57. the part behind that (objects added the the area during the
  58. collection) will be traced later anyway. And the cards behind
  59. that will not be marked either. */
  60. #if (MEASURE_GC)
  61. areas_visited += areas->frontier - areas->start;
  62. #endif
  63. #if S48_DIRTY_VECTOR_METHOD==S48_NO_DIRTY_VECTORS
  64. /* Without a dirty vector, we trace everything to be sure to catch
  65. all intergenerational pointers. */
  66. call_trace_locationsB(area, area->start, area->trace);
  67. #endif
  68. #if S48_DIRTY_VECTOR_METHOD==S48_ADDRESS_DIRTY_VECTORS
  69. /* This method stores the first location of an intergenerational
  70. pointer within a card (a fixed-sized part of the area). */
  71. Dirty_vector* dirty_vector = &area->dirty_vector;
  72. s48_address card_start_address = area->start;
  73. int i;
  74. for (i = 0;
  75. (i < dirty_vector->length) && (card_start_address < area->trace);
  76. i++, card_start_address += S48_CARD_SIZE) {
  77. s48_address start_address = dirty_vector->items[i];
  78. if (start_address != NULL) {
  79. s48_address end_address = card_start_address + S48_CARD_SIZE;
  80. /* no need to trace behind trace pointer */
  81. if (end_address > area->trace) end_address = area->trace;
  82. /* checks */
  83. if (start_address < card_start_address)
  84. s48_gc_error("s48_trace_areas_roots: dirty address too small.");
  85. if (start_address >= end_address)
  86. s48_gc_error("s48_trace_areas_roots: dirty address too big.");
  87. /* reset */
  88. dirty_vector->items[i] = NULL;
  89. /* trace */
  90. call_trace_locationsB(area, start_address, end_address);
  91. }
  92. } // for loop over dirty vector
  93. #endif
  94. }
  95. /* FPage 9 */
  96. /* passes all dirty regions in all areas in the linked list starting
  97. with AREAS, to trace_locationsB */
  98. void s48_trace_areas_roots(Area* areas) {
  99. while(areas != NULL) {
  100. trace_area_roots(areas);
  101. areas = areas->next;
  102. }
  103. #if (MEASURE_GC)
  104. measure_areas_roots(areas_visited, areas_passed);
  105. areas_visited = 0;
  106. areas_passed = 0;
  107. #endif
  108. }
  109. void s48_set_dirty_vector(Area* area, s48_address addr, long stob,
  110. Area* maybe_to_area) {
  111. s48_set_dirty_vector_inline(area, addr, stob, maybe_to_area);
  112. }
  113. void s48_write_barrier(long stob, s48_address address, long value) {
  114. s48_write_barrier_inline(stob, address, value);
  115. }