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 #include "gc/shared/gcLogPrecious.hpp"
25 #include "gc/z/zAddress.inline.hpp"
26 #include "gc/z/zCollectedHeap.hpp"
27 #include "gc/z/zForwarding.inline.hpp"
28 #include "gc/z/zPage.inline.hpp"
29 #include "gc/z/zStat.hpp"
30 #include "gc/z/zUtils.inline.hpp"
31 #include "logging/log.hpp"
32 #include "utilities/align.hpp"
33
34 //
35 // Reference count states:
36 //
37 // * If the reference count is zero, it will never change again.
38 //
39 // * If the reference count is positive, it can be both retained
40 // (increased) and released (decreased).
41 //
42 // * If the reference count is negative, is can only be released
43 // (increased). A negative reference count means that one or more
355 // Previous YC already handled the remembered fields
356 assert(res == ZPublishState::reject, "Unexpected value");
357 }
358
359 bool ZForwarding::relocated_remembered_fields_published_contains(volatile zpointer* p) {
360 for (volatile zpointer* const elem : _relocated_remembered_fields_array) {
361 if (elem == p) {
362 return true;
363 }
364 }
365
366 return false;
367 }
368
369 void ZForwarding::verify() const {
370 guarantee(_ref_count.load_relaxed() != 0, "Invalid reference count");
371 guarantee(_page != nullptr, "Invalid page");
372
373 uint32_t live_objects = 0;
374 size_t live_bytes = 0;
375
376 for (ZForwardingCursor i = 0; i < _entries.length(); i++) {
377 const ZForwardingEntry entry = at(&i);
378 if (!entry.populated()) {
379 // Skip empty entries
380 continue;
381 }
382
383 // Check from index
384 guarantee(entry.from_index() < _page->object_max_count(), "Invalid from index");
385
386 // Check for duplicates
387 for (ZForwardingCursor j = i + 1; j < _entries.length(); j++) {
388 const ZForwardingEntry other = at(&j);
389 if (!other.populated()) {
390 // Skip empty entries
391 continue;
392 }
393
394 guarantee(entry.from_index() != other.from_index(), "Duplicate from");
395 guarantee(entry.to_offset() != other.to_offset(), "Duplicate to");
396 }
397
398 const zaddress to_addr = ZOffset::address(to_zoffset(entry.to_offset()));
399 const size_t size = ZUtils::object_size(to_addr);
400 const size_t aligned_size = align_up(size, _page->object_alignment());
401 live_bytes += aligned_size;
402 live_objects++;
403 }
404
405 // Verify number of live objects and bytes
406 _page->verify_live(live_objects, live_bytes, _in_place);
407 }
|
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 #include "gc/shared/gc_globals.hpp"
25 #include "gc/shared/gcLogPrecious.hpp"
26 #include "gc/z/zAddress.inline.hpp"
27 #include "gc/z/zCollectedHeap.hpp"
28 #include "gc/z/zForwarding.inline.hpp"
29 #include "gc/z/zPage.inline.hpp"
30 #include "gc/z/zStat.hpp"
31 #include "gc/z/zUtils.inline.hpp"
32 #include "logging/log.hpp"
33 #include "utilities/align.hpp"
34
35 //
36 // Reference count states:
37 //
38 // * If the reference count is zero, it will never change again.
39 //
40 // * If the reference count is positive, it can be both retained
41 // (increased) and released (decreased).
42 //
43 // * If the reference count is negative, is can only be released
44 // (increased). A negative reference count means that one or more
356 // Previous YC already handled the remembered fields
357 assert(res == ZPublishState::reject, "Unexpected value");
358 }
359
360 bool ZForwarding::relocated_remembered_fields_published_contains(volatile zpointer* p) {
361 for (volatile zpointer* const elem : _relocated_remembered_fields_array) {
362 if (elem == p) {
363 return true;
364 }
365 }
366
367 return false;
368 }
369
370 void ZForwarding::verify() const {
371 guarantee(_ref_count.load_relaxed() != 0, "Invalid reference count");
372 guarantee(_page != nullptr, "Invalid page");
373
374 uint32_t live_objects = 0;
375 size_t live_bytes = 0;
376 uint32_t no_move_expand_count = 0;
377
378 for (ZForwardingCursor i = 0; i < _entries.length(); i++) {
379 const ZForwardingEntry entry = at(&i);
380 if (!entry.populated()) {
381 // Skip empty entries
382 continue;
383 }
384
385 // Check from index
386 guarantee(entry.from_index() < _page->object_max_count(), "Invalid from index");
387
388 // Check for duplicates
389 for (ZForwardingCursor j = i + 1; j < _entries.length(); j++) {
390 const ZForwardingEntry other = at(&j);
391 if (!other.populated()) {
392 // Skip empty entries
393 continue;
394 }
395
396 guarantee(entry.from_index() != other.from_index(), "Duplicate from");
397 guarantee(entry.to_offset() != other.to_offset(), "Duplicate to");
398 }
399
400 // Read size from the TO object — always safe after relocation.
401 const zaddress to_addr = ZOffset::address(to_zoffset(entry.to_offset()));
402 const size_t size = ZUtils::object_size(to_addr);
403 const size_t aligned_size = align_up(size, _page->object_alignment());
404 live_bytes += aligned_size;
405 live_objects++;
406
407 // Detect non-moving in-place objects (from_offset == to_offset): they are counted in
408 // will_expand_objects if they had is_hashed_not_expanded() at mark time, but they did not
409 // actually expand during relocation (size = old_size). Track these so verify_live() can
410 // subtract them from the expected live_bytes adjustment.
411 if (_in_place && UseCompactObjectHeaders) {
412 const zoffset from_offset = start() + (entry.from_index() << object_alignment_shift());
413 if (to_zoffset(entry.to_offset()) == from_offset) {
414 const oop to_obj = to_oop(to_addr);
415 if (to_obj->mark().is_hashed_not_expanded() && to_obj->klass()->expand_for_hash(to_obj, to_obj->mark())) {
416 no_move_expand_count++;
417 }
418 }
419 }
420 }
421
422 // Verify number of live objects and bytes. live_bytes is computed from TO-space sizes;
423 // verify_live() adjusts for compact hash expansion using the will_expand and no_move counts.
424 _page->verify_live(live_objects, live_bytes, no_move_expand_count, _in_place);
425 }
|