1 /*
 2  * Copyright (c) 2021, Red Hat, Inc. All rights reserved.
 3  * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
 4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 5  *
 6  * This code is free software; you can redistribute it and/or modify it
 7  * under the terms of the GNU General Public License version 2 only, as
 8  * published by the Free Software Foundation.
 9  *
10  * This code is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13  * version 2 for more details (a copy is included in the LICENSE file that
14  * accompanied this code).
15  *
16  * You should have received a copy of the GNU General Public License version
17  * 2 along with this work; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19  *
20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21  * or visit www.oracle.com if you need additional information or have any
22  * questions.
23  *
24  */
25 
26 #include "precompiled.hpp"
27 
28 #include "gc/shenandoah/shenandoahHeap.inline.hpp"
29 #include "gc/shenandoah/shenandoahHeapRegion.hpp"
30 #include "gc/shenandoah/shenandoahMarkClosures.hpp"
31 #include "gc/shenandoah/shenandoahMarkingContext.hpp"
32 #include "gc/shenandoah/shenandoahSharedVariables.hpp"
33 
34 
35 ShenandoahFinalMarkUpdateRegionStateClosure::ShenandoahFinalMarkUpdateRegionStateClosure(
36   ShenandoahMarkingContext *ctx) :
37   _ctx(ctx), _lock(ShenandoahHeap::heap()->lock()) {}
38 
39 void ShenandoahFinalMarkUpdateRegionStateClosure::heap_region_do(ShenandoahHeapRegion* r) {
40   if (r->is_active()) {
41     if (_ctx != nullptr) {
42       // _ctx may be null when this closure is used to sync only the pin status
43       // update the watermark of old regions. For old regions we cannot reset
44       // the TAMS because we rely on that to keep promoted objects alive after
45       // old marking is complete.
46 
47       // All allocations past TAMS are implicitly live, adjust the region data.
48       // Bitmaps/TAMS are swapped at this point, so we need to poll complete bitmap.
49       HeapWord *tams = _ctx->top_at_mark_start(r);
50       HeapWord *top = r->top();
51       if (top > tams) {
52         r->increase_live_data_alloc_words(pointer_delta(top, tams));
53       }
54     }
55 
56     // We are about to select the collection set, make sure it knows about
57     // current pinning status. Also, this allows trashing more regions that
58     // now have their pinning status dropped.
59     if (r->is_pinned()) {
60       if (r->pin_count() == 0) {
61         ShenandoahHeapLocker locker(_lock);
62         r->make_unpinned();
63       }
64     } else {
65       if (r->pin_count() > 0) {
66         ShenandoahHeapLocker locker(_lock);
67         r->make_pinned();
68       }
69     }
70 
71     // Remember limit for updating refs. It's guaranteed that we get no
72     // from-space-refs written from here on.
73     r->set_update_watermark_at_safepoint(r->top());
74   } else {
75     assert(!r->has_live(), "Region " SIZE_FORMAT " should have no live data", r->index());
76     assert(_ctx == nullptr || _ctx->top_at_mark_start(r) == r->top(),
77              "Region " SIZE_FORMAT " should have correct TAMS", r->index());
78   }
79 }
80 
81 
82 ShenandoahUpdateCensusZeroCohortClosure::ShenandoahUpdateCensusZeroCohortClosure(
83   ShenandoahMarkingContext *ctx) :
84   _ctx(ctx), _age0_pop(0), _total_pop(0) {}
85 
86 void ShenandoahUpdateCensusZeroCohortClosure::heap_region_do(ShenandoahHeapRegion* r) {
87   if (_ctx != nullptr && r->is_active()) {
88     assert(r->is_young(), "Young regions only");
89     HeapWord* tams = _ctx->top_at_mark_start(r);
90     HeapWord* top  = r->top();
91     if (top > tams) {
92       _age0_pop += pointer_delta(top, tams);
93     }
94     // TODO: check significance of _ctx != nullptr above, can that
95     // spoof _total_pop in some corner cases?
96     NOT_PRODUCT(_total_pop += r->get_live_data_words();)
97   }
98 }