147 assert_at_safepoint();
148
149 HeapWord* invisible_root = ShenandoahThreadLocalData::get_invisible_root(t);
150 if (invisible_root == nullptr) {
151 return;
152 }
153 size_t invisible_root_word_size = ShenandoahThreadLocalData::get_invisible_root_word_size(t);
154
155 ShenandoahHeap* const heap = ShenandoahHeap::heap();
156 ShenandoahMarkingContext* const marking_context = heap->marking_context();
157 // Mark the invisible root if it is not marked.
158 if (!marking_context->is_marked(invisible_root)) {
159 bool was_upgraded = false;
160 if (!marking_context->mark_strong(cast_to_oop(invisible_root), was_upgraded)) {
161 return;
162 }
163
164 // Update region liveness data
165 ShenandoahHeapRegion* region = heap->heap_region_containing(invisible_root);
166 if (region->is_regular_or_regular_pinned()) {
167 assert(!ShenandoahHeapRegion::requires_humongous(invisible_root_word_size), "Must not be humongous.");
168 region->increase_live_data_alloc_words(invisible_root_word_size);
169 } else if (region->is_humongous_start()) {
170 DEBUG_ONLY(size_t total_live_words = 0;)
171 do {
172 size_t current = region->get_live_data_words();
173 size_t region_used_words = region->used() >> LogHeapWordSize;
174 DEBUG_ONLY(total_live_words += region_used_words;)
175 assert(current == 0 || current == region_used_words, "Must be");
176 if (current == 0) {
177 region->increase_live_data_alloc_words(region_used_words);
178 }
179 region = heap->get_region(region->index() + 1);
180 } while (region != nullptr && region->is_humongous_continuation());
181 assert(total_live_words == invisible_root_word_size, "Must be");
182 }
183 }
184 }
185 };
186
187 // The rationale for selecting the roots to scan is as follows:
|
147 assert_at_safepoint();
148
149 HeapWord* invisible_root = ShenandoahThreadLocalData::get_invisible_root(t);
150 if (invisible_root == nullptr) {
151 return;
152 }
153 size_t invisible_root_word_size = ShenandoahThreadLocalData::get_invisible_root_word_size(t);
154
155 ShenandoahHeap* const heap = ShenandoahHeap::heap();
156 ShenandoahMarkingContext* const marking_context = heap->marking_context();
157 // Mark the invisible root if it is not marked.
158 if (!marking_context->is_marked(invisible_root)) {
159 bool was_upgraded = false;
160 if (!marking_context->mark_strong(cast_to_oop(invisible_root), was_upgraded)) {
161 return;
162 }
163
164 // Update region liveness data
165 ShenandoahHeapRegion* region = heap->heap_region_containing(invisible_root);
166 if (region->is_regular_or_regular_pinned()) {
167 // The invisible root is a freshly allocated, not-yet-hashed mutator object
168 // array (see ShenandoahObjArrayAllocator), so it is classified for the
169 // humongous path with hash-expansion headroom, just like its allocation.
170 assert(!ShenandoahHeapRegion::requires_humongous(invisible_root_word_size, true /* may_expand_for_hash */), "Must not be humongous.");
171 region->increase_live_data_alloc_words(invisible_root_word_size);
172 } else if (region->is_humongous_start()) {
173 DEBUG_ONLY(size_t total_live_words = 0;)
174 do {
175 size_t current = region->get_live_data_words();
176 size_t region_used_words = region->used() >> LogHeapWordSize;
177 DEBUG_ONLY(total_live_words += region_used_words;)
178 assert(current == 0 || current == region_used_words, "Must be");
179 if (current == 0) {
180 region->increase_live_data_alloc_words(region_used_words);
181 }
182 region = heap->get_region(region->index() + 1);
183 } while (region != nullptr && region->is_humongous_continuation());
184 assert(total_live_words == invisible_root_word_size, "Must be");
185 }
186 }
187 }
188 };
189
190 // The rationale for selecting the roots to scan is as follows:
|