blob: 38aab2c78a78df76d024e78c9db1c88f0addf0bb [file] [log] [blame]
/* 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