Bug Summary

File:jdk/src/hotspot/share/gc/shenandoah/shenandoahMark.inline.hpp
Warning:line 144, column 19
The result of the left shift is undefined because the right operand is negative

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name shenandoahMark.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mthread-model posix -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -fno-rounding-math -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64 -dwarf-column-info -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib/llvm-10/lib/clang/10.0.0 -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/hotspot/variant-server/libjvm/objs/precompiled -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -D __STDC_CONSTANT_MACROS -D _GNU_SOURCE -D _REENTRANT -D LIBC=gnu -D LINUX -D VM_LITTLE_ENDIAN -D _LP64=1 -D ASSERT -D CHECK_UNHANDLED_OOPS -D TARGET_ARCH_x86 -D INCLUDE_SUFFIX_OS=_linux -D INCLUDE_SUFFIX_CPU=_x86 -D INCLUDE_SUFFIX_COMPILER=_gcc -D TARGET_COMPILER_gcc -D AMD64 -D HOTSPOT_LIB_ARCH="amd64" -D COMPILER1 -D COMPILER2 -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/hotspot/variant-server/gensrc/adfiles -I /home/daniel/Projects/java/jdk/src/hotspot/share -I /home/daniel/Projects/java/jdk/src/hotspot/os/linux -I /home/daniel/Projects/java/jdk/src/hotspot/os/posix -I /home/daniel/Projects/java/jdk/src/hotspot/cpu/x86 -I /home/daniel/Projects/java/jdk/src/hotspot/os_cpu/linux_x86 -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/hotspot/variant-server/gensrc -I /home/daniel/Projects/java/jdk/src/hotspot/share/precompiled -I /home/daniel/Projects/java/jdk/src/hotspot/share/include -I /home/daniel/Projects/java/jdk/src/hotspot/os/posix/include -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/support/modules_include/java.base -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/support/modules_include/java.base/linux -I /home/daniel/Projects/java/jdk/src/java.base/share/native/libjimage -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/hotspot/variant-server/gensrc/adfiles -I /home/daniel/Projects/java/jdk/src/hotspot/share -I /home/daniel/Projects/java/jdk/src/hotspot/os/linux -I /home/daniel/Projects/java/jdk/src/hotspot/os/posix -I /home/daniel/Projects/java/jdk/src/hotspot/cpu/x86 -I /home/daniel/Projects/java/jdk/src/hotspot/os_cpu/linux_x86 -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/hotspot/variant-server/gensrc -D _FORTIFY_SOURCE=2 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/c++/7.5.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/x86_64-linux-gnu/c++/7.5.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/x86_64-linux-gnu/c++/7.5.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/c++/7.5.0/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-10/lib/clang/10.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O3 -Wno-format-zero-length -Wno-unused-parameter -Wno-unused -Wno-parentheses -Wno-comment -Wno-unknown-pragmas -Wno-address -Wno-delete-non-virtual-dtor -Wno-char-subscripts -Wno-array-bounds -Wno-int-in-bool-context -Wno-ignored-qualifiers -Wno-missing-field-initializers -Wno-implicit-fallthrough -Wno-empty-body -Wno-strict-overflow -Wno-sequence-point -Wno-maybe-uninitialized -Wno-misleading-indentation -Wno-cast-function-type -Wno-shift-negative-value -std=c++14 -fdeprecated-macro -fdebug-compilation-dir /home/daniel/Projects/java/jdk/make/hotspot -ferror-limit 19 -fmessage-length 0 -fvisibility hidden -stack-protector 1 -fno-rtti -fgnuc-version=4.2.1 -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -o /home/daniel/Projects/java/scan/2021-12-21-193737-8510-1 -x c++ /home/daniel/Projects/java/jdk/src/hotspot/share/gc/shenandoah/shenandoahMark.cpp

/home/daniel/Projects/java/jdk/src/hotspot/share/gc/shenandoah/shenandoahMark.cpp

1/*
2 * Copyright (c) 2021, Red Hat, Inc. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25
26#include "precompiled.hpp"
27
28#include "gc/shenandoah/shenandoahBarrierSet.hpp"
29#include "gc/shenandoah/shenandoahClosures.inline.hpp"
30#include "gc/shenandoah/shenandoahMark.inline.hpp"
31#include "gc/shenandoah/shenandoahOopClosures.inline.hpp"
32#include "gc/shenandoah/shenandoahReferenceProcessor.hpp"
33#include "gc/shenandoah/shenandoahTaskqueue.inline.hpp"
34#include "gc/shenandoah/shenandoahUtils.hpp"
35#include "gc/shenandoah/shenandoahVerifier.hpp"
36
37ShenandoahMarkRefsSuperClosure::ShenandoahMarkRefsSuperClosure(ShenandoahObjToScanQueue* q, ShenandoahReferenceProcessor* rp) :
38 MetadataVisitingOopIterateClosure(rp),
39 _queue(q),
40 _mark_context(ShenandoahHeap::heap()->marking_context()),
41 _weak(false)
42{ }
43
44ShenandoahMark::ShenandoahMark() :
45 _task_queues(ShenandoahHeap::heap()->marking_context()->task_queues()) {
46}
47
48void ShenandoahMark::clear() {
49 // Clean up marking stacks.
50 ShenandoahObjToScanQueueSet* queues = ShenandoahHeap::heap()->marking_context()->task_queues();
51 queues->clear();
52
53 // Cancel SATB buffers.
54 ShenandoahBarrierSet::satb_mark_queue_set().abandon_partial_marking();
55}
56
57template <bool CANCELLABLE, StringDedupMode STRING_DEDUP>
58void ShenandoahMark::mark_loop_prework(uint w, TaskTerminator *t, ShenandoahReferenceProcessor *rp, StringDedup::Requests* const req) {
59 ShenandoahObjToScanQueue* q = get_queue(w);
60
61 ShenandoahHeap* const heap = ShenandoahHeap::heap();
62 ShenandoahLiveData* ld = heap->get_liveness_cache(w);
63
64 // TODO: We can clean up this if we figure out how to do templated oop closures that
65 // play nice with specialized_oop_iterators.
66 if (heap->unload_classes()) {
67 if (heap->has_forwarded_objects()) {
68 using Closure = ShenandoahMarkUpdateRefsMetadataClosure;
69 Closure cl(q, rp);
70 mark_loop_work<Closure, CANCELLABLE, STRING_DEDUP>(&cl, ld, w, t, req);
71 } else {
72 using Closure = ShenandoahMarkRefsMetadataClosure;
73 Closure cl(q, rp);
74 mark_loop_work<Closure, CANCELLABLE, STRING_DEDUP>(&cl, ld, w, t, req);
75 }
76 } else {
77 if (heap->has_forwarded_objects()) {
78 using Closure = ShenandoahMarkUpdateRefsClosure;
79 Closure cl(q, rp);
80 mark_loop_work<Closure, CANCELLABLE, STRING_DEDUP>(&cl, ld, w, t, req);
81 } else {
82 using Closure = ShenandoahMarkRefsClosure;
83 Closure cl(q, rp);
84 mark_loop_work<Closure, CANCELLABLE, STRING_DEDUP>(&cl, ld, w, t, req);
85 }
86 }
87
88 heap->flush_liveness_cache(w);
89}
90
91void ShenandoahMark::mark_loop(uint worker_id, TaskTerminator* terminator, ShenandoahReferenceProcessor *rp,
92 bool cancellable, StringDedupMode dedup_mode, StringDedup::Requests* const req) {
93 if (cancellable) {
94 switch(dedup_mode) {
95 case NO_DEDUP:
96 mark_loop_prework<true, NO_DEDUP>(worker_id, terminator, rp, req);
97 break;
98 case ENQUEUE_DEDUP:
99 mark_loop_prework<true, ENQUEUE_DEDUP>(worker_id, terminator, rp, req);
100 break;
101 case ALWAYS_DEDUP:
102 mark_loop_prework<true, ALWAYS_DEDUP>(worker_id, terminator, rp, req);
103 break;
104 }
105 } else {
106 switch(dedup_mode) {
107 case NO_DEDUP:
108 mark_loop_prework<false, NO_DEDUP>(worker_id, terminator, rp, req);
109 break;
110 case ENQUEUE_DEDUP:
111 mark_loop_prework<false, ENQUEUE_DEDUP>(worker_id, terminator, rp, req);
112 break;
113 case ALWAYS_DEDUP:
114 mark_loop_prework<false, ALWAYS_DEDUP>(worker_id, terminator, rp, req);
115 break;
116 }
117 }
118}
119
120template <class T, bool CANCELLABLE, StringDedupMode STRING_DEDUP>
121void ShenandoahMark::mark_loop_work(T* cl, ShenandoahLiveData* live_data, uint worker_id, TaskTerminator *terminator, StringDedup::Requests* const req) {
122 uintx stride = ShenandoahMarkLoopStride;
123
124 ShenandoahHeap* heap = ShenandoahHeap::heap();
125 ShenandoahObjToScanQueueSet* queues = task_queues();
126 ShenandoahObjToScanQueue* q;
127 ShenandoahMarkTask t;
128
129 heap->ref_processor()->set_mark_closure(worker_id, cl);
130
131 /*
132 * Process outstanding queues, if any.
133 *
134 * There can be more queues than workers. To deal with the imbalance, we claim
135 * extra queues first. Since marking can push new tasks into the queue associated
136 * with this worker id, we come back to process this queue in the normal loop.
137 */
138 assert(queues->get_reserved() == heap->workers()->active_workers(),do { if (!(queues->get_reserved() == heap->workers()->
active_workers())) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/shenandoah/shenandoahMark.cpp"
, 139, "assert(" "queues->get_reserved() == heap->workers()->active_workers()"
") failed", "Need to reserve proper number of queues: reserved: %u, active: %u"
, queues->get_reserved(), heap->workers()->active_workers
()); ::breakpoint(); } } while (0)
1
Assuming the condition is true
2
Taking false branch
3
Loop condition is false. Exiting loop
139 "Need to reserve proper number of queues: reserved: %u, active: %u", queues->get_reserved(), heap->workers()->active_workers())do { if (!(queues->get_reserved() == heap->workers()->
active_workers())) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/shenandoah/shenandoahMark.cpp"
, 139, "assert(" "queues->get_reserved() == heap->workers()->active_workers()"
") failed", "Need to reserve proper number of queues: reserved: %u, active: %u"
, queues->get_reserved(), heap->workers()->active_workers
()); ::breakpoint(); } } while (0)
;
140
141 q = queues->claim_next();
142 while (q != NULL__null) {
4
Assuming 'q' is not equal to NULL
5
Loop condition is true. Entering loop body
143 if (CANCELLABLE && heap->check_cancelled_gc_and_yield()) {
144 return;
145 }
146
147 for (uint i = 0; i < stride; i++) {
6
Assuming 'i' is < 'stride'
7
Loop condition is true. Entering loop body
148 if (q->pop(t)) {
8
Taking true branch
149 do_task<T, STRING_DEDUP>(q, cl, live_data, req, &t);
9
Calling 'ShenandoahMark::do_task'
150 } else {
151 assert(q->is_empty(), "Must be empty")do { if (!(q->is_empty())) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/shenandoah/shenandoahMark.cpp"
, 151, "assert(" "q->is_empty()" ") failed", "Must be empty"
); ::breakpoint(); } } while (0)
;
152 q = queues->claim_next();
153 break;
154 }
155 }
156 }
157 q = get_queue(worker_id);
158
159 ShenandoahSATBBufferClosure drain_satb(q);
160 SATBMarkQueueSet& satb_mq_set = ShenandoahBarrierSet::satb_mark_queue_set();
161
162 /*
163 * Normal marking loop:
164 */
165 while (true) {
166 if (CANCELLABLE && heap->check_cancelled_gc_and_yield()) {
167 return;
168 }
169
170 while (satb_mq_set.completed_buffers_num() > 0) {
171 satb_mq_set.apply_closure_to_completed_buffer(&drain_satb);
172 }
173
174 uint work = 0;
175 for (uint i = 0; i < stride; i++) {
176 if (q->pop(t) ||
177 queues->steal(worker_id, t)) {
178 do_task<T, STRING_DEDUP>(q, cl, live_data, req, &t);
179 work++;
180 } else {
181 break;
182 }
183 }
184
185 if (work == 0) {
186 // No work encountered in current stride, try to terminate.
187 // Need to leave the STS here otherwise it might block safepoints.
188 ShenandoahSuspendibleThreadSetLeaver stsl(CANCELLABLE && ShenandoahSuspendibleWorkers);
189 ShenandoahTerminatorTerminator tt(heap);
190 if (terminator->offer_termination(&tt)) return;
191 }
192 }
193}

/home/daniel/Projects/java/jdk/src/hotspot/share/gc/shenandoah/shenandoahMark.inline.hpp

1/*
2 * Copyright (c) 2015, 2021, Red Hat, Inc. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25#ifndef SHARE_GC_SHENANDOAH_SHENANDOAHMARK_INLINE_HPP
26#define SHARE_GC_SHENANDOAH_SHENANDOAHMARK_INLINE_HPP
27
28#include "gc/shenandoah/shenandoahMark.hpp"
29
30#include "gc/shenandoah/shenandoahAsserts.hpp"
31#include "gc/shenandoah/shenandoahBarrierSet.inline.hpp"
32#include "gc/shenandoah/shenandoahHeap.inline.hpp"
33#include "gc/shenandoah/shenandoahMarkingContext.inline.hpp"
34#include "gc/shenandoah/shenandoahStringDedup.inline.hpp"
35#include "gc/shenandoah/shenandoahTaskqueue.inline.hpp"
36#include "gc/shenandoah/shenandoahUtils.hpp"
37#include "memory/iterator.inline.hpp"
38#include "oops/compressedOops.inline.hpp"
39#include "oops/oop.inline.hpp"
40#include "runtime/prefetch.inline.hpp"
41#include "utilities/powerOfTwo.hpp"
42
43template <StringDedupMode STRING_DEDUP>
44void ShenandoahMark::dedup_string(oop obj, StringDedup::Requests* const req) {
45 if (STRING_DEDUP == ENQUEUE_DEDUP) {
46 if (ShenandoahStringDedup::is_candidate(obj)) {
47 req->add(obj);
48 }
49 } else if (STRING_DEDUP == ALWAYS_DEDUP) {
50 if (ShenandoahStringDedup::is_string_candidate(obj) &&
51 !ShenandoahStringDedup::dedup_requested(obj)) {
52 req->add(obj);
53 }
54 }
55}
56
57template <class T, StringDedupMode STRING_DEDUP>
58void ShenandoahMark::do_task(ShenandoahObjToScanQueue* q, T* cl, ShenandoahLiveData* live_data, StringDedup::Requests* const req, ShenandoahMarkTask* task) {
59 oop obj = task->obj();
60
61 shenandoah_assert_not_forwarded(NULL, obj)ShenandoahAsserts::assert_not_forwarded(__null, obj, "/home/daniel/Projects/java/jdk/src/hotspot/share/gc/shenandoah/shenandoahMark.inline.hpp"
, 61)
;
62 shenandoah_assert_marked(NULL, obj)ShenandoahAsserts::assert_marked(__null, obj, "/home/daniel/Projects/java/jdk/src/hotspot/share/gc/shenandoah/shenandoahMark.inline.hpp"
, 62)
;
63 shenandoah_assert_not_in_cset_except(NULL, obj, ShenandoahHeap::heap()->cancelled_gc())if (!(ShenandoahHeap::heap()->cancelled_gc())) ShenandoahAsserts
::assert_not_in_cset(__null, obj, "/home/daniel/Projects/java/jdk/src/hotspot/share/gc/shenandoah/shenandoahMark.inline.hpp"
, 63)
;
10
Taking true branch
64
65 // Are we in weak subgraph scan?
66 bool weak = task->is_weak();
67 cl->set_weak(weak);
68
69 if (task->is_not_chunked()) {
11
Taking true branch
70 if (obj->is_instance()) {
12
Taking false branch
71 // Case 1: Normal oop, process as usual.
72 obj->oop_iterate(cl);
73 dedup_string<STRING_DEDUP>(obj, req);
74 } else if (obj->is_objArray()) {
13
Taking true branch
75 // Case 2: Object array instance and no chunk is set. Must be the first
76 // time we visit it, start the chunked processing.
77 do_chunked_array_start<T>(q, cl, obj, weak);
14
Calling 'ShenandoahMark::do_chunked_array_start'
78 } else {
79 // Case 3: Primitive array. Do nothing, no oops there. We use the same
80 // performance tweak TypeArrayKlass::oop_oop_iterate_impl is using:
81 // We skip iterating over the klass pointer since we know that
82 // Universe::TypeArrayKlass never moves.
83 assert (obj->is_typeArray(), "should be type array")do { if (!(obj->is_typeArray())) { (*g_assert_poison) = 'X'
;; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/shenandoah/shenandoahMark.inline.hpp"
, 83, "assert(" "obj->is_typeArray()" ") failed", "should be type array"
); ::breakpoint(); } } while (0)
;
84 }
85 // Count liveness the last: push the outstanding work to the queues first
86 // Avoid double-counting objects that are visited twice due to upgrade
87 // from final- to strong mark.
88 if (task->count_liveness()) {
89 count_liveness(live_data, obj);
90 }
91 } else {
92 // Case 4: Array chunk, has sensible chunk id. Process it.
93 do_chunked_array<T>(q, cl, obj, task->chunk(), task->pow(), weak);
94 }
95}
96
97inline void ShenandoahMark::count_liveness(ShenandoahLiveData* live_data, oop obj) {
98 ShenandoahHeap* const heap = ShenandoahHeap::heap();
99 size_t region_idx = heap->heap_region_index_containing(obj);
100 ShenandoahHeapRegion* region = heap->get_region(region_idx);
101 size_t size = obj->size();
102
103 if (!region->is_humongous_start()) {
104 assert(!region->is_humongous(), "Cannot have continuations here")do { if (!(!region->is_humongous())) { (*g_assert_poison) =
'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/shenandoah/shenandoahMark.inline.hpp"
, 104, "assert(" "!region->is_humongous()" ") failed", "Cannot have continuations here"
); ::breakpoint(); } } while (0)
;
105 ShenandoahLiveData cur = live_data[region_idx];
106 size_t new_val = size + cur;
107 if (new_val >= SHENANDOAH_LIVEDATA_MAX((ShenandoahLiveData)-1)) {
108 // overflow, flush to region data
109 region->increase_live_data_gc_words(new_val);
110 live_data[region_idx] = 0;
111 } else {
112 // still good, remember in locals
113 live_data[region_idx] = (ShenandoahLiveData) new_val;
114 }
115 } else {
116 shenandoah_assert_in_correct_region(NULL, obj)ShenandoahAsserts::assert_in_correct_region(__null, obj, "/home/daniel/Projects/java/jdk/src/hotspot/share/gc/shenandoah/shenandoahMark.inline.hpp"
, 116)
;
117 size_t num_regions = ShenandoahHeapRegion::required_regions(size * HeapWordSize);
118
119 for (size_t i = region_idx; i < region_idx + num_regions; i++) {
120 ShenandoahHeapRegion* chain_reg = heap->get_region(i);
121 assert(chain_reg->is_humongous(), "Expecting a humongous region")do { if (!(chain_reg->is_humongous())) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/shenandoah/shenandoahMark.inline.hpp"
, 121, "assert(" "chain_reg->is_humongous()" ") failed", "Expecting a humongous region"
); ::breakpoint(); } } while (0)
;
122 chain_reg->increase_live_data_gc_words(chain_reg->used() >> LogHeapWordSize);
123 }
124 }
125}
126
127template <class T>
128inline void ShenandoahMark::do_chunked_array_start(ShenandoahObjToScanQueue* q, T* cl, oop obj, bool weak) {
129 assert(obj->is_objArray(), "expect object array")do { if (!(obj->is_objArray())) { (*g_assert_poison) = 'X'
;; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/shenandoah/shenandoahMark.inline.hpp"
, 129, "assert(" "obj->is_objArray()" ") failed", "expect object array"
); ::breakpoint(); } } while (0)
;
15
Taking false branch
16
Loop condition is false. Exiting loop
130 objArrayOop array = objArrayOop(obj);
131 int len = array->length();
132
133 // Mark objArray klass metadata
134 if (Devirtualizer::do_metadata(cl)) {
17
Taking false branch
135 Devirtualizer::do_klass(cl, array->klass());
136 }
137
138 if (len <= (int) ObjArrayMarkingStride*2) {
18
Assuming the condition is false
19
Taking false branch
139 // A few slices only, process directly
140 array->oop_iterate_range(cl, 0, len);
141 } else {
142 int bits = log2i_graceful(len);
20
Calling 'log2i_graceful<int, 0>'
24
Returning from 'log2i_graceful<int, 0>'
25
'bits' initialized to -1
143 // Compensate for non-power-of-two arrays, cover the array in excess:
144 if (len != (1 << bits)) bits++;
26
The result of the left shift is undefined because the right operand is negative
145
146 // Only allow full chunks on the queue. This frees do_chunked_array() from checking from/to
147 // boundaries against array->length(), touching the array header on every chunk.
148 //
149 // To do this, we cut the prefix in full-sized chunks, and submit them on the queue.
150 // If the array is not divided in chunk sizes, then there would be an irregular tail,
151 // which we will process separately.
152
153 int last_idx = 0;
154
155 int chunk = 1;
156 int pow = bits;
157
158 // Handle overflow
159 if (pow >= 31) {
160 assert (pow == 31, "sanity")do { if (!(pow == 31)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/shenandoah/shenandoahMark.inline.hpp"
, 160, "assert(" "pow == 31" ") failed", "sanity"); ::breakpoint
(); } } while (0)
;
161 pow--;
162 chunk = 2;
163 last_idx = (1 << pow);
164 bool pushed = q->push(ShenandoahMarkTask(array, true, weak, 1, pow));
165 assert(pushed, "overflow queue should always succeed pushing")do { if (!(pushed)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/shenandoah/shenandoahMark.inline.hpp"
, 165, "assert(" "pushed" ") failed", "overflow queue should always succeed pushing"
); ::breakpoint(); } } while (0)
;
166 }
167
168 // Split out tasks, as suggested in ShenandoahMarkTask docs. Record the last
169 // successful right boundary to figure out the irregular tail.
170 while ((1 << pow) > (int)ObjArrayMarkingStride &&
171 (chunk*2 < ShenandoahMarkTask::chunk_size())) {
172 pow--;
173 int left_chunk = chunk*2 - 1;
174 int right_chunk = chunk*2;
175 int left_chunk_end = left_chunk * (1 << pow);
176 if (left_chunk_end < len) {
177 bool pushed = q->push(ShenandoahMarkTask(array, true, weak, left_chunk, pow));
178 assert(pushed, "overflow queue should always succeed pushing")do { if (!(pushed)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/shenandoah/shenandoahMark.inline.hpp"
, 178, "assert(" "pushed" ") failed", "overflow queue should always succeed pushing"
); ::breakpoint(); } } while (0)
;
179 chunk = right_chunk;
180 last_idx = left_chunk_end;
181 } else {
182 chunk = left_chunk;
183 }
184 }
185
186 // Process the irregular tail, if present
187 int from = last_idx;
188 if (from < len) {
189 array->oop_iterate_range(cl, from, len);
190 }
191 }
192}
193
194template <class T>
195inline void ShenandoahMark::do_chunked_array(ShenandoahObjToScanQueue* q, T* cl, oop obj, int chunk, int pow, bool weak) {
196 assert(obj->is_objArray(), "expect object array")do { if (!(obj->is_objArray())) { (*g_assert_poison) = 'X'
;; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/shenandoah/shenandoahMark.inline.hpp"
, 196, "assert(" "obj->is_objArray()" ") failed", "expect object array"
); ::breakpoint(); } } while (0)
;
197 objArrayOop array = objArrayOop(obj);
198
199 assert (ObjArrayMarkingStride > 0, "sanity")do { if (!(ObjArrayMarkingStride > 0)) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/shenandoah/shenandoahMark.inline.hpp"
, 199, "assert(" "ObjArrayMarkingStride > 0" ") failed", "sanity"
); ::breakpoint(); } } while (0)
;
200
201 // Split out tasks, as suggested in ShenandoahMarkTask docs. Avoid pushing tasks that
202 // are known to start beyond the array.
203 while ((1 << pow) > (int)ObjArrayMarkingStride && (chunk*2 < ShenandoahMarkTask::chunk_size())) {
204 pow--;
205 chunk *= 2;
206 bool pushed = q->push(ShenandoahMarkTask(array, true, weak, chunk - 1, pow));
207 assert(pushed, "overflow queue should always succeed pushing")do { if (!(pushed)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/shenandoah/shenandoahMark.inline.hpp"
, 207, "assert(" "pushed" ") failed", "overflow queue should always succeed pushing"
); ::breakpoint(); } } while (0)
;
208 }
209
210 int chunk_size = 1 << pow;
211
212 int from = (chunk - 1) * chunk_size;
213 int to = chunk * chunk_size;
214
215#ifdef ASSERT1
216 int len = array->length();
217 assert (0 <= from && from < len, "from is sane: %d/%d", from, len)do { if (!(0 <= from && from < len)) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/shenandoah/shenandoahMark.inline.hpp"
, 217, "assert(" "0 <= from && from < len" ") failed"
, "from is sane: %d/%d", from, len); ::breakpoint(); } } while
(0)
;
218 assert (0 < to && to <= len, "to is sane: %d/%d", to, len)do { if (!(0 < to && to <= len)) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/shenandoah/shenandoahMark.inline.hpp"
, 218, "assert(" "0 < to && to <= len" ") failed"
, "to is sane: %d/%d", to, len); ::breakpoint(); } } while (0
)
;
219#endif
220
221 array->oop_iterate_range(cl, from, to);
222}
223
224class ShenandoahSATBBufferClosure : public SATBBufferClosure {
225private:
226 ShenandoahObjToScanQueue* _queue;
227 ShenandoahHeap* _heap;
228 ShenandoahMarkingContext* const _mark_context;
229public:
230 ShenandoahSATBBufferClosure(ShenandoahObjToScanQueue* q) :
231 _queue(q),
232 _heap(ShenandoahHeap::heap()),
233 _mark_context(_heap->marking_context())
234 {
235 }
236
237 void do_buffer(void **buffer, size_t size) {
238 assert(size == 0 || !_heap->has_forwarded_objects(), "Forwarded objects are not expected here")do { if (!(size == 0 || !_heap->has_forwarded_objects())) {
(*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/shenandoah/shenandoahMark.inline.hpp"
, 238, "assert(" "size == 0 || !_heap->has_forwarded_objects()"
") failed", "Forwarded objects are not expected here"); ::breakpoint
(); } } while (0)
;
239 for (size_t i = 0; i < size; ++i) {
240 oop *p = (oop *) &buffer[i];
241 ShenandoahMark::mark_through_ref<oop>(p, _queue, _mark_context, false);
242 }
243 }
244};
245
246template<class T>
247inline void ShenandoahMark::mark_through_ref(T* p, ShenandoahObjToScanQueue* q, ShenandoahMarkingContext* const mark_context, bool weak) {
248 T o = RawAccess<>::oop_load(p);
249 if (!CompressedOops::is_null(o)) {
250 oop obj = CompressedOops::decode_not_null(o);
251
252 shenandoah_assert_not_forwarded(p, obj)ShenandoahAsserts::assert_not_forwarded(p, obj, "/home/daniel/Projects/java/jdk/src/hotspot/share/gc/shenandoah/shenandoahMark.inline.hpp"
, 252)
;
253 shenandoah_assert_not_in_cset_except(p, obj, ShenandoahHeap::heap()->cancelled_gc())if (!(ShenandoahHeap::heap()->cancelled_gc())) ShenandoahAsserts
::assert_not_in_cset(p, obj, "/home/daniel/Projects/java/jdk/src/hotspot/share/gc/shenandoah/shenandoahMark.inline.hpp"
, 253)
;
254
255 bool skip_live = false;
256 bool marked;
257 if (weak) {
258 marked = mark_context->mark_weak(obj);
259 } else {
260 marked = mark_context->mark_strong(obj, /* was_upgraded = */ skip_live);
261 }
262 if (marked) {
263 bool pushed = q->push(ShenandoahMarkTask(obj, skip_live, weak));
264 assert(pushed, "overflow queue should always succeed pushing")do { if (!(pushed)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/gc/shenandoah/shenandoahMark.inline.hpp"
, 264, "assert(" "pushed" ") failed", "overflow queue should always succeed pushing"
); ::breakpoint(); } } while (0)
;
265 }
266
267 shenandoah_assert_marked(p, obj)ShenandoahAsserts::assert_marked(p, obj, "/home/daniel/Projects/java/jdk/src/hotspot/share/gc/shenandoah/shenandoahMark.inline.hpp"
, 267)
;
268 }
269}
270
271ShenandoahObjToScanQueueSet* ShenandoahMark::task_queues() const {
272 return _task_queues;
273}
274
275ShenandoahObjToScanQueue* ShenandoahMark::get_queue(uint index) const {
276 return _task_queues->queue(index);
277}
278#endif // SHARE_GC_SHENANDOAH_SHENANDOAHMARK_INLINE_HPP

/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/powerOfTwo.hpp

1/*
2 * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25#ifndef SHARE_UTILITIES_POWEROFTWO_HPP
26#define SHARE_UTILITIES_POWEROFTWO_HPP
27
28#include "metaprogramming/enableIf.hpp"
29#include "utilities/count_leading_zeros.hpp"
30#include "utilities/count_trailing_zeros.hpp"
31#include "utilities/debug.hpp"
32#include "utilities/globalDefinitions.hpp"
33#include <limits>
34#include <type_traits>
35
36// Power of two convenience library.
37
38template <typename T, ENABLE_IF(std::is_integral<T>::value)std::enable_if_t<bool(std::is_integral<T>::value), int
> = 0
>
39constexpr T max_power_of_2() {
40 T max_val = std::numeric_limits<T>::max();
41 return max_val - (max_val >> 1);
42}
43
44// Returns true iff there exists integer i such that (T(1) << i) == value.
45template <typename T, ENABLE_IF(std::is_integral<T>::value)std::enable_if_t<bool(std::is_integral<T>::value), int
> = 0
>
46constexpr bool is_power_of_2(T value) {
47 return (value > T(0)) && ((value & (value - 1)) == T(0));
48}
49
50// Log2 of a positive, integral value, i.e., largest i such that 2^i <= value
51// Precondition: value > 0
52template<typename T, ENABLE_IF(std::is_integral<T>::value)std::enable_if_t<bool(std::is_integral<T>::value), int
> = 0
>
53inline int log2i(T value) {
54 assert(value > T(0), "value must be > 0")do { if (!(value > T(0))) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/powerOfTwo.hpp"
, 54, "assert(" "value > T(0)" ") failed", "value must be > 0"
); ::breakpoint(); } } while (0)
;
55 const int bits = sizeof(value) * BitsPerByte;
56 return bits - count_leading_zeros(value) - 1;
57}
58
59// Log2 of positive, integral value, i.e., largest i such that 2^i <= value
60// Returns -1 if value is zero
61// For negative values this will return 63 for 64-bit types, 31 for
62// 32-bit types, and so on.
63template<typename T, ENABLE_IF(std::is_integral<T>::value)std::enable_if_t<bool(std::is_integral<T>::value), int
> = 0
>
64inline int log2i_graceful(T value) {
65 if (value == 0) {
21
Assuming 'value' is equal to 0
22
Taking true branch
66 return -1;
23
Returning the value -1
67 }
68 const int bits = sizeof(value) * BitsPerByte;
69 return bits - count_leading_zeros(value) - 1;
70}
71
72// Log2 of a power of 2, i.e., i such that 2^i == value
73// Preconditions: value > 0, value is a power of two
74template<typename T, ENABLE_IF(std::is_integral<T>::value)std::enable_if_t<bool(std::is_integral<T>::value), int
> = 0
>
75inline int log2i_exact(T value) {
76 assert(is_power_of_2(value),do { if (!(is_power_of_2(value))) { (*g_assert_poison) = 'X';
; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/powerOfTwo.hpp"
, 78, "assert(" "is_power_of_2(value)" ") failed", "value must be a power of 2: "
"%" "l" "x", static_cast<uint64_t>(value)); ::breakpoint
(); } } while (0)
77 "value must be a power of 2: " UINT64_FORMAT_X,do { if (!(is_power_of_2(value))) { (*g_assert_poison) = 'X';
; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/powerOfTwo.hpp"
, 78, "assert(" "is_power_of_2(value)" ") failed", "value must be a power of 2: "
"%" "l" "x", static_cast<uint64_t>(value)); ::breakpoint
(); } } while (0)
78 static_cast<uint64_t>(value))do { if (!(is_power_of_2(value))) { (*g_assert_poison) = 'X';
; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/powerOfTwo.hpp"
, 78, "assert(" "is_power_of_2(value)" ") failed", "value must be a power of 2: "
"%" "l" "x", static_cast<uint64_t>(value)); ::breakpoint
(); } } while (0)
;
79 return count_trailing_zeros(value);
80}
81
82// Preconditions: value != 0, and the unsigned representation of value is a power of two
83inline int exact_log2(intptr_t value) {
84 return log2i_exact((uintptr_t)value);
85}
86
87// Preconditions: value != 0, and the unsigned representation of value is a power of two
88inline int exact_log2_long(jlong value) {
89 return log2i_exact((julong)value);
90}
91
92// Round down to the closest power of two less than or equal to the given value.
93// precondition: value > 0.
94template<typename T, ENABLE_IF(std::is_integral<T>::value)std::enable_if_t<bool(std::is_integral<T>::value), int
> = 0
>
95inline T round_down_power_of_2(T value) {
96 assert(value > 0, "Invalid value")do { if (!(value > 0)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/powerOfTwo.hpp"
, 96, "assert(" "value > 0" ") failed", "Invalid value"); ::
breakpoint(); } } while (0)
;
97 return T(1) << log2i(value);
98}
99
100// Round up to the closest power of two greater to or equal to the given value.
101// precondition: value > 0.
102// precondition: value <= maximum power of two representable by T.
103template<typename T, ENABLE_IF(std::is_integral<T>::value)std::enable_if_t<bool(std::is_integral<T>::value), int
> = 0
>
104inline T round_up_power_of_2(T value) {
105 assert(value > 0, "Invalid value")do { if (!(value > 0)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/powerOfTwo.hpp"
, 105, "assert(" "value > 0" ") failed", "Invalid value");
::breakpoint(); } } while (0)
;
106 assert(value <= max_power_of_2<T>(), "Overflow")do { if (!(value <= max_power_of_2<T>())) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/powerOfTwo.hpp"
, 106, "assert(" "value <= max_power_of_2<T>()" ") failed"
, "Overflow"); ::breakpoint(); } } while (0)
;
107 if (is_power_of_2(value)) {
108 return value;
109 }
110 return T(1) << (log2i(value) + 1);
111}
112
113// Calculate the next power of two greater than the given value.
114// precondition: if signed, value >= 0.
115// precondition: value < maximum power of two representable by T.
116template <typename T, ENABLE_IF(std::is_integral<T>::value)std::enable_if_t<bool(std::is_integral<T>::value), int
> = 0
>
117inline T next_power_of_2(T value) {
118 assert(value < std::numeric_limits<T>::max(), "Overflow")do { if (!(value < std::numeric_limits<T>::max())) {
(*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/utilities/powerOfTwo.hpp"
, 118, "assert(" "value < std::numeric_limits<T>::max()"
") failed", "Overflow"); ::breakpoint(); } } while (0)
;
119 return round_up_power_of_2(value + 1);
120}
121
122#endif // SHARE_UTILITIES_POWEROFTWO_HPP