1/*
2 * Copyright (c) 2018, Red Hat, Inc. All rights reserved.
3 *
4 * This code is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 only, as
6 * published by the Free Software Foundation.
7 *
8 * This code is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11 * version 2 for more details (a copy is included in the LICENSE file that
12 * accompanied this code).
13 *
14 * You should have received a copy of the GNU General Public License version
15 * 2 along with this work; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
19 * or visit www.oracle.com if you need additional information or have any
20 * questions.
21 *
22 */
23
24#ifndef SHARE_GC_SHENANDOAH_SHENANDOAHTRAVERSALGC_INLINE_HPP
25#define SHARE_GC_SHENANDOAH_SHENANDOAHTRAVERSALGC_INLINE_HPP
26
27#include "gc/shenandoah/shenandoahAsserts.hpp"
28#include "gc/shenandoah/shenandoahBarrierSet.inline.hpp"
29#include "gc/shenandoah/shenandoahHeap.inline.hpp"
30#include "gc/shenandoah/shenandoahMarkingContext.inline.hpp"
31#include "gc/shenandoah/shenandoahStringDedup.hpp"
32#include "gc/shenandoah/shenandoahTraversalGC.hpp"
33#include "gc/shenandoah/shenandoahTaskqueue.hpp"
34#include "gc/shenandoah/shenandoahTaskqueue.inline.hpp"
35#include "oops/compressedOops.inline.hpp"
36#include "oops/oop.inline.hpp"
37
38template <class T, bool STRING_DEDUP, bool DEGEN>
39void ShenandoahTraversalGC::process_oop(T* p, Thread* thread, ShenandoahObjToScanQueue* queue, ShenandoahMarkingContext* const mark_context) {
40 T o = RawAccess<>::oop_load(p);
41 if (!CompressedOops::is_null(o)) {
42 oop obj = CompressedOops::decode_not_null(o);
43 if (DEGEN) {
44 oop forw = ShenandoahBarrierSet::resolve_forwarded_not_null(obj);
45 if (!oopDesc::equals_raw(obj, forw)) {
46 // Update reference.
47 RawAccess<IS_NOT_NULL>::oop_store(p, forw);
48 }
49 obj = forw;
50 } else if (_heap->in_collection_set(obj)) {
51 oop forw = ShenandoahBarrierSet::resolve_forwarded_not_null(obj);
52 if (oopDesc::equals_raw(obj, forw)) {
53 forw = _heap->evacuate_object(obj, thread);
54 }
55 shenandoah_assert_forwarded_except(p, obj, _heap->cancelled_gc());
56 // Update reference.
57 ShenandoahHeap::cas_oop(forw, p, obj);
58 obj = forw;
59 }
60
61 shenandoah_assert_not_forwarded(p, obj);
62 shenandoah_assert_not_in_cset_except(p, obj, _heap->cancelled_gc());
63
64 if (mark_context->mark(obj)) {
65 bool succeeded = queue->push(ShenandoahMarkTask(obj));
66 assert(succeeded, "must succeed to push to task queue");
67
68 if (STRING_DEDUP && ShenandoahStringDedup::is_candidate(obj) && !_heap->cancelled_gc()) {
69 assert(ShenandoahStringDedup::is_enabled(), "Must be enabled");
70 // Only dealing with to-space string, so that we can avoid evac-oom protocol, which is costly here.
71 shenandoah_assert_not_in_cset(p, obj);
72 ShenandoahStringDedup::enqueue_candidate(obj);
73 }
74 }
75 }
76}
77
78#endif // SHARE_GC_SHENANDOAH_SHENANDOAHTRAVERSALGC_INLINE_HPP
79