mirror of
https://github.com/openjdk/jdk.git
synced 2026-05-11 05:59:52 +00:00
Co-authored-by: Stefan Karlsson <stefank@openjdk.org> Co-authored-by: Axel Boldt-Christmas <aboldtch@openjdk.org> Reviewed-by: stefank, rrich, pchilanomate
165 lines
6.5 KiB
C++
165 lines
6.5 KiB
C++
/* Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
*
|
|
* This code is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License version 2 only, as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
* version 2 for more details (a copy is included in the LICENSE file that
|
|
* accompanied this code).
|
|
*
|
|
* You should have received a copy of the GNU General Public License version
|
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*
|
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
* or visit www.oracle.com if you need additional information or have any
|
|
* questions.
|
|
*
|
|
*/
|
|
|
|
#ifndef SHARE_OOPS_INSTANCESTACKCHUNKKLASS_INLINE_HPP
|
|
#define SHARE_OOPS_INSTANCESTACKCHUNKKLASS_INLINE_HPP
|
|
|
|
#include "oops/instanceStackChunkKlass.hpp"
|
|
|
|
#include "oops/oop.inline.hpp"
|
|
#include "oops/stackChunkOop.inline.hpp"
|
|
#include "runtime/continuationJavaClasses.hpp"
|
|
#include "runtime/frame.inline.hpp"
|
|
#include "runtime/handles.inline.hpp"
|
|
#include "utilities/bitMap.inline.hpp"
|
|
#include "utilities/debug.hpp"
|
|
#include "utilities/devirtualizer.inline.hpp"
|
|
#include "utilities/globalDefinitions.hpp"
|
|
#include "utilities/macros.hpp"
|
|
|
|
inline size_t InstanceStackChunkKlass::instance_size(size_t stack_size_in_words) const {
|
|
return align_object_size(size_helper() + stack_size_in_words + gc_data_size(stack_size_in_words));
|
|
}
|
|
|
|
inline size_t InstanceStackChunkKlass::bitmap_size_in_bits(size_t stack_size_in_words) {
|
|
// Need one bit per potential narrowOop* or oop* address.
|
|
size_t size_in_bits = stack_size_in_words << (LogBitsPerWord - LogBitsPerHeapOop);
|
|
|
|
return align_up(size_in_bits, BitsPerWord);
|
|
}
|
|
|
|
inline size_t InstanceStackChunkKlass::gc_data_size(size_t stack_size_in_words) {
|
|
// At the moment all GCs are okay with GC data big enough to fit a bit map
|
|
return bitmap_size(stack_size_in_words);
|
|
}
|
|
|
|
inline size_t InstanceStackChunkKlass::bitmap_size(size_t stack_size_in_words) {
|
|
return bitmap_size_in_bits(stack_size_in_words) >> LogBitsPerWord;
|
|
}
|
|
|
|
template <typename T, class OopClosureType>
|
|
void InstanceStackChunkKlass::oop_oop_iterate(oop obj, OopClosureType* closure) {
|
|
stackChunkOop chunk = stackChunkOopDesc::cast(obj);
|
|
if (Devirtualizer::do_metadata(closure)) {
|
|
Devirtualizer::do_klass(closure, this);
|
|
}
|
|
oop_oop_iterate_stack<T>(chunk, closure);
|
|
oop_oop_iterate_header<T>(chunk, closure);
|
|
}
|
|
|
|
template <typename T, class OopClosureType>
|
|
void InstanceStackChunkKlass::oop_oop_iterate_reverse(oop obj, OopClosureType* closure) {
|
|
assert(!Devirtualizer::do_metadata(closure), "Code to handle metadata is not implemented");
|
|
stackChunkOop chunk = stackChunkOopDesc::cast(obj);
|
|
oop_oop_iterate_stack<T>(chunk, closure);
|
|
oop_oop_iterate_header<T>(chunk, closure);
|
|
}
|
|
|
|
template <typename T, class OopClosureType>
|
|
void InstanceStackChunkKlass::oop_oop_iterate_bounded(oop obj, OopClosureType* closure, MemRegion mr) {
|
|
stackChunkOop chunk = stackChunkOopDesc::cast(obj);
|
|
if (Devirtualizer::do_metadata(closure)) {
|
|
if (mr.contains(obj)) {
|
|
Devirtualizer::do_klass(closure, this);
|
|
}
|
|
}
|
|
oop_oop_iterate_stack_bounded<T>(chunk, closure, mr);
|
|
oop_oop_iterate_header_bounded<T>(chunk, closure, mr);
|
|
}
|
|
|
|
template <typename T, class OopClosureType>
|
|
void InstanceStackChunkKlass::oop_oop_iterate_header(stackChunkOop chunk, OopClosureType* closure) {
|
|
T* parent_addr = chunk->field_addr<T>(jdk_internal_vm_StackChunk::parent_offset());
|
|
T* cont_addr = chunk->field_addr<T>(jdk_internal_vm_StackChunk::cont_offset());
|
|
Devirtualizer::do_oop(closure, parent_addr);
|
|
Devirtualizer::do_oop(closure, cont_addr);
|
|
}
|
|
|
|
template <typename T, class OopClosureType>
|
|
void InstanceStackChunkKlass::oop_oop_iterate_header_bounded(stackChunkOop chunk, OopClosureType* closure, MemRegion mr) {
|
|
T* parent_addr = chunk->field_addr<T>(jdk_internal_vm_StackChunk::parent_offset());
|
|
T* cont_addr = chunk->field_addr<T>(jdk_internal_vm_StackChunk::cont_offset());
|
|
if (mr.contains(parent_addr)) {
|
|
Devirtualizer::do_oop(closure, parent_addr);
|
|
}
|
|
if (mr.contains(cont_addr)) {
|
|
Devirtualizer::do_oop(closure, cont_addr);
|
|
}
|
|
}
|
|
|
|
template <typename T, class OopClosureType>
|
|
void InstanceStackChunkKlass::oop_oop_iterate_stack_bounded(stackChunkOop chunk, OopClosureType* closure, MemRegion mr) {
|
|
if (chunk->has_bitmap()) {
|
|
intptr_t* start = chunk->sp_address() - frame::metadata_words_at_bottom;
|
|
intptr_t* end = chunk->end_address();
|
|
// mr.end() can actually be less than start. In that case, we only walk the metadata
|
|
if ((intptr_t*)mr.start() > start) {
|
|
start = (intptr_t*)mr.start();
|
|
}
|
|
if ((intptr_t*)mr.end() < end) {
|
|
end = (intptr_t*)mr.end();
|
|
}
|
|
oop_oop_iterate_stack_with_bitmap<T>(chunk, closure, start, end);
|
|
} else {
|
|
oop_oop_iterate_stack_slow(chunk, closure, mr);
|
|
}
|
|
}
|
|
|
|
template <typename T, class OopClosureType>
|
|
void InstanceStackChunkKlass::oop_oop_iterate_stack(stackChunkOop chunk, OopClosureType* closure) {
|
|
if (chunk->has_bitmap()) {
|
|
oop_oop_iterate_stack_with_bitmap<T>(chunk, closure, chunk->sp_address() - frame::metadata_words_at_bottom, chunk->end_address());
|
|
} else {
|
|
oop_oop_iterate_stack_slow(chunk, closure, chunk->range());
|
|
}
|
|
}
|
|
|
|
template <typename T, class OopClosureType>
|
|
class StackChunkOopIterateBitmapClosure {
|
|
stackChunkOop _chunk;
|
|
OopClosureType* const _closure;
|
|
|
|
public:
|
|
StackChunkOopIterateBitmapClosure(stackChunkOop chunk, OopClosureType* closure) : _chunk(chunk), _closure(closure) {}
|
|
|
|
bool do_bit(BitMap::idx_t index) {
|
|
Devirtualizer::do_oop(_closure, _chunk->address_for_bit<T>(index));
|
|
return true;
|
|
}
|
|
};
|
|
|
|
template <typename T, class OopClosureType>
|
|
void InstanceStackChunkKlass::oop_oop_iterate_stack_with_bitmap(stackChunkOop chunk, OopClosureType* closure,
|
|
intptr_t* start, intptr_t* end) {
|
|
if (Devirtualizer::do_metadata(closure)) {
|
|
do_methods(chunk, closure);
|
|
}
|
|
|
|
if (end > start) {
|
|
StackChunkOopIterateBitmapClosure<T, OopClosureType> bitmap_closure(chunk, closure);
|
|
chunk->bitmap().iterate(&bitmap_closure, chunk->bit_index_for((T*)start), chunk->bit_index_for((T*)end));
|
|
}
|
|
}
|
|
|
|
#endif // SHARE_OOPS_INSTANCESTACKCHUNKKLASS_INLINE_HPP
|