mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-01 05:58:29 +00:00
Co-authored-by: Patricio Chilano Mateo <pchilanomate@openjdk.org> Co-authored-by: Alan Bateman <alanb@openjdk.org> Co-authored-by: Andrew Haley <aph@openjdk.org> Co-authored-by: Fei Yang <fyang@openjdk.org> Co-authored-by: Coleen Phillimore <coleenp@openjdk.org> Co-authored-by: Richard Reingruber <rrich@openjdk.org> Co-authored-by: Martin Doerr <mdoerr@openjdk.org> Reviewed-by: aboldtch, dholmes, coleenp, fbredberg, dlong, sspitsyn
225 lines
7.7 KiB
C++
225 lines
7.7 KiB
C++
/*
|
|
* Copyright (c) 2022, 2024, 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_VM_RUNTIME_CONTINUATIONHELPER_INLINE_HPP
|
|
#define SHARE_VM_RUNTIME_CONTINUATIONHELPER_INLINE_HPP
|
|
|
|
#include "runtime/continuationHelper.hpp"
|
|
|
|
#include "code/scopeDesc.hpp"
|
|
#include "compiler/oopMap.hpp"
|
|
#include "compiler/oopMap.inline.hpp"
|
|
#include "interpreter/oopMapCache.hpp"
|
|
#include "runtime/frame.inline.hpp"
|
|
#include "runtime/objectMonitor.hpp"
|
|
#include "runtime/stackValue.hpp"
|
|
#include "runtime/synchronizer.hpp"
|
|
#include "utilities/macros.hpp"
|
|
|
|
#include CPU_HEADER_INLINE(continuationHelper)
|
|
|
|
#ifndef CPU_OVERRIDES_RETURN_ADDRESS_ACCESSORS
|
|
inline address ContinuationHelper::return_address_at(intptr_t* sp) {
|
|
return *(address*)sp;
|
|
}
|
|
|
|
inline void ContinuationHelper::patch_return_address_at(intptr_t* sp,
|
|
address pc) {
|
|
*(address*)sp = pc;
|
|
}
|
|
#endif // !CPU_OVERRIDES_RETURN_ADDRESS_ACCESSORS
|
|
|
|
inline bool ContinuationHelper::NonInterpretedUnknownFrame::is_instance(const frame& f) {
|
|
return !f.is_interpreted_frame();
|
|
}
|
|
|
|
inline bool ContinuationHelper::Frame::is_stub(CodeBlob* cb) {
|
|
return cb != nullptr && cb->is_runtime_stub();
|
|
}
|
|
|
|
inline Method* ContinuationHelper::Frame::frame_method(const frame& f) {
|
|
return f.is_interpreted_frame() ? f.interpreter_frame_method() : f.cb()->as_nmethod()->method();
|
|
}
|
|
|
|
inline address ContinuationHelper::Frame::return_pc(const frame& f) {
|
|
return return_address_at((intptr_t *)return_pc_address(f));
|
|
}
|
|
|
|
#ifdef ASSERT
|
|
inline intptr_t* ContinuationHelper::Frame::frame_top(const frame &f) {
|
|
if (f.is_interpreted_frame()) {
|
|
ResourceMark rm;
|
|
InterpreterOopMap mask;
|
|
f.interpreted_frame_oop_map(&mask);
|
|
return InterpretedFrame::frame_top(f, &mask);
|
|
} else {
|
|
return CompiledFrame::frame_top(f);
|
|
}
|
|
}
|
|
|
|
inline bool ContinuationHelper::Frame::is_deopt_return(address pc, const frame& sender) {
|
|
if (sender.is_interpreted_frame()) return false;
|
|
|
|
nmethod* nm = sender.cb()->as_nmethod();
|
|
return nm->is_deopt_pc(pc);
|
|
}
|
|
|
|
#endif
|
|
|
|
inline bool ContinuationHelper::InterpretedFrame::is_instance(const frame& f) {
|
|
return f.is_interpreted_frame();
|
|
}
|
|
|
|
inline address ContinuationHelper::InterpretedFrame::return_pc(const frame& f) {
|
|
return return_address_at((intptr_t *)return_pc_address(f));
|
|
}
|
|
|
|
inline int ContinuationHelper::InterpretedFrame::size(const frame&f) {
|
|
return pointer_delta_as_int(InterpretedFrame::frame_bottom(f), InterpretedFrame::frame_top(f));
|
|
}
|
|
|
|
inline int ContinuationHelper::InterpretedFrame::stack_argsize(const frame& f) {
|
|
return f.interpreter_frame_method()->size_of_parameters();
|
|
}
|
|
|
|
inline int ContinuationHelper::InterpretedFrame::expression_stack_size(const frame &f, InterpreterOopMap* mask) {
|
|
int size = mask->expression_stack_size();
|
|
assert(size <= f.interpreter_frame_expression_stack_size(), "size1: %d size2: %d", size, f.interpreter_frame_expression_stack_size());
|
|
return size;
|
|
}
|
|
|
|
#ifdef ASSERT
|
|
inline bool ContinuationHelper::InterpretedFrame::is_owning_locks(const frame& f) {
|
|
assert(f.interpreter_frame_monitor_end() <= f.interpreter_frame_monitor_begin(), "must be");
|
|
if (f.interpreter_frame_monitor_end() == f.interpreter_frame_monitor_begin()) {
|
|
return false;
|
|
}
|
|
|
|
for (BasicObjectLock* current = f.previous_monitor_in_interpreter_frame(f.interpreter_frame_monitor_begin());
|
|
current >= f.interpreter_frame_monitor_end();
|
|
current = f.previous_monitor_in_interpreter_frame(current)) {
|
|
|
|
oop obj = current->obj();
|
|
if (obj != nullptr) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
#endif
|
|
|
|
inline intptr_t* ContinuationHelper::InterpretedFrame::frame_top(const frame& f) { // inclusive; this will be copied with the frame
|
|
return f.unextended_sp();
|
|
}
|
|
|
|
inline intptr_t* ContinuationHelper::NonInterpretedFrame::frame_top(const frame& f, int callee_argsize, bool callee_interpreted) {
|
|
return f.unextended_sp() + (callee_interpreted ? 0 : callee_argsize);
|
|
}
|
|
|
|
inline intptr_t* ContinuationHelper::NonInterpretedFrame::frame_top(const frame& f) { // inclusive; this will be copied with the frame
|
|
return f.unextended_sp();
|
|
}
|
|
|
|
inline intptr_t* ContinuationHelper::NonInterpretedFrame::frame_bottom(const frame& f) { // exclusive; this will not be copied with the frame
|
|
return f.unextended_sp() + f.cb()->frame_size();
|
|
}
|
|
|
|
inline int ContinuationHelper::NonInterpretedFrame::size(const frame& f) {
|
|
assert(!f.is_interpreted_frame(), "");
|
|
return f.cb()->frame_size();
|
|
}
|
|
|
|
inline int ContinuationHelper::NonInterpretedFrame::stack_argsize(const frame& f) {
|
|
return f.compiled_frame_stack_argsize();
|
|
}
|
|
|
|
inline bool ContinuationHelper::CompiledFrame::is_instance(const frame& f) {
|
|
return f.is_compiled_frame();
|
|
}
|
|
|
|
#ifdef ASSERT
|
|
template<typename RegisterMapT>
|
|
bool ContinuationHelper::CompiledFrame::is_owning_locks(JavaThread* thread, RegisterMapT* map, const frame& f) {
|
|
assert(!f.is_interpreted_frame(), "");
|
|
assert(CompiledFrame::is_instance(f), "");
|
|
|
|
nmethod* nm = f.cb()->as_nmethod();
|
|
assert(!nm->is_native_method(), ""); // See compiledVFrame::compiledVFrame(...) in vframe_hp.cpp
|
|
|
|
if (!nm->has_monitors()) {
|
|
return false;
|
|
}
|
|
|
|
frame::update_map_with_saved_link(map, Frame::callee_link_address(f)); // the monitor object could be stored in the link register
|
|
ResourceMark rm;
|
|
for (ScopeDesc* scope = nm->scope_desc_at(f.pc()); scope != nullptr; scope = scope->sender()) {
|
|
GrowableArray<MonitorValue*>* mons = scope->monitors();
|
|
if (mons == nullptr || mons->is_empty()) {
|
|
continue;
|
|
}
|
|
|
|
for (int index = (mons->length()-1); index >= 0; index--) { // see compiledVFrame::monitors()
|
|
MonitorValue* mon = mons->at(index);
|
|
if (mon->eliminated()) {
|
|
continue; // we ignore scalar-replaced monitors
|
|
}
|
|
ScopeValue* ov = mon->owner();
|
|
StackValue* owner_sv = StackValue::create_stack_value(&f, map, ov); // it is an oop
|
|
oop owner = owner_sv->get_obj()();
|
|
if (owner != nullptr) {
|
|
//assert(nm->has_monitors(), "");
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
#endif
|
|
|
|
inline bool ContinuationHelper::NativeFrame::is_instance(const frame& f) {
|
|
return f.is_native_frame();
|
|
}
|
|
|
|
#ifdef ASSERT
|
|
inline bool ContinuationHelper::NativeFrame::is_owning_locks(JavaThread* thread, const frame& f) {
|
|
assert(NativeFrame::is_instance(f), "");
|
|
|
|
Method* method = f.cb()->as_nmethod()->method();
|
|
if (!method->is_synchronized()) {
|
|
return false;
|
|
} else {
|
|
// Just verify we are actually the owner
|
|
oop synced_obj = f.get_native_receiver();
|
|
assert(ObjectSynchronizer::current_thread_holds_lock(thread, Handle(thread, synced_obj)), "must be owner");
|
|
return true;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
inline bool ContinuationHelper::StubFrame::is_instance(const frame& f) {
|
|
return !f.is_interpreted_frame() && is_stub(f.cb());
|
|
}
|
|
|
|
#endif // SHARE_VM_RUNTIME_CONTINUATIONHELPER_INLINE_HPP
|