Skip to content

Commit

Permalink
8339307: jhsdb jstack could not trace FFM upcall frame
Browse files Browse the repository at this point in the history
Reviewed-by: cjplummer, jvernee
  • Loading branch information
YaSuenag committed Sep 7, 2024
1 parent fbe2629 commit deeb09a
Show file tree
Hide file tree
Showing 12 changed files with 447 additions and 10 deletions.
1 change: 1 addition & 0 deletions src/hotspot/share/code/codeBlob.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -595,6 +595,7 @@ class UpcallLinker;

// A (Panama) upcall stub. Not used by JNI.
class UpcallStub: public RuntimeBlob {
friend class VMStructs;
friend class UpcallLinker;
private:
jobject _receiver;
Expand Down
13 changes: 12 additions & 1 deletion src/hotspot/share/runtime/vmStructs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,12 @@
\
nonstatic_field(DeoptimizationBlob, _unpack_offset, int) \
\
/*****************************************************/ \
/* UpcallStubs (NOTE: incomplete, but only a little) */ \
/*****************************************************/ \
\
nonstatic_field(UpcallStub, _frame_data_offset, ByteSize) \
\
/**************************************************/ \
/* NMethods (NOTE: incomplete, but only a little) */ \
/**************************************************/ \
Expand Down Expand Up @@ -1012,7 +1018,9 @@
nonstatic_field(AccessFlags, _flags, jint) \
nonstatic_field(elapsedTimer, _counter, jlong) \
nonstatic_field(elapsedTimer, _active, bool) \
nonstatic_field(InvocationCounter, _counter, unsigned int)
nonstatic_field(InvocationCounter, _counter, unsigned int) \
\
nonstatic_field(UpcallStub::FrameData, jfa, JavaFrameAnchor)

//--------------------------------------------------------------------------------
// VM_TYPES
Expand Down Expand Up @@ -1306,6 +1314,7 @@
declare_type(nmethod, CodeBlob) \
declare_type(RuntimeStub, RuntimeBlob) \
declare_type(SingletonBlob, RuntimeBlob) \
declare_type(UpcallStub, RuntimeBlob) \
declare_type(SafepointBlob, SingletonBlob) \
declare_type(DeoptimizationBlob, SingletonBlob) \
declare_c2_type(ExceptionBlob, SingletonBlob) \
Expand Down Expand Up @@ -1900,6 +1909,7 @@
declare_integer_type(BasicType) /* FIXME: wrong type (not integer) */ \
\
declare_integer_type(CompLevel) \
declare_integer_type(ByteSize) \
JVMTI_ONLY(declare_toplevel_type(BreakpointInfo)) \
JVMTI_ONLY(declare_toplevel_type(BreakpointInfo*)) \
declare_toplevel_type(CodeBlob*) \
Expand Down Expand Up @@ -1948,6 +1958,7 @@
declare_type(FileMapInfo, CHeapObj<mtInternal>) \
declare_toplevel_type(FileMapHeader) \
declare_toplevel_type(CDSFileMapRegion) \
declare_toplevel_type(UpcallStub::FrameData) \
\
/************/ \
/* GC types */ \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,8 @@ public ImmutableOopMapSet getOopMaps() {

public boolean isRuntimeStub() { return false; }

public boolean isUpcallStub() { return false; }

public boolean isDeoptimizationStub() { return false; }

public boolean isUncommonTrapStub() { return false; }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 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
Expand Down Expand Up @@ -60,6 +60,7 @@ private static synchronized void initialize(TypeDataBase db) {
virtualConstructor.addMapping("AdapterBlob", AdapterBlob.class);
virtualConstructor.addMapping("MethodHandlesAdapterBlob", MethodHandlesAdapterBlob.class);
virtualConstructor.addMapping("VtableBlob", VtableBlob.class);
virtualConstructor.addMapping("UpcallStub", UpcallStub.class);
virtualConstructor.addMapping("SafepointBlob", SafepointBlob.class);
virtualConstructor.addMapping("DeoptimizationBlob", DeoptimizationBlob.class);
if (VM.getVM().isServerCompiler()) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
/*
* Copyright (c) 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.
*
*/

package sun.jvm.hotspot.code;

import java.util.*;
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.runtime.*;
import sun.jvm.hotspot.types.*;
import sun.jvm.hotspot.utilities.Observable;
import sun.jvm.hotspot.utilities.Observer;

public class UpcallStub extends RuntimeBlob {

private static CIntegerField frameDataOffsetField;
private static AddressField lastJavaFPField;
private static AddressField lastJavaSPField;
private static AddressField lastJavaPCField;

static {
VM.registerVMInitializedObserver(new Observer() {
public void update(Observable o, Object data) {
initialize(VM.getVM().getTypeDataBase());
}
});
}

private static void initialize(TypeDataBase db) {
Type type = db.lookupType("UpcallStub");
frameDataOffsetField = type.getCIntegerField("_frame_data_offset");

Type anchorType = db.lookupType("JavaFrameAnchor");
lastJavaSPField = anchorType.getAddressField("_last_Java_sp");
lastJavaPCField = anchorType.getAddressField("_last_Java_pc");

try {
lastJavaFPField = anchorType.getAddressField("_last_Java_fp");
} catch (Exception e) {
// Some platforms (e.g. PPC64) does not have this field.
lastJavaFPField = null;
}
}

public UpcallStub(Address addr) {
super(addr);
}

protected Address getJavaFrameAnchor(Frame frame) {
var frameDataOffset = frameDataOffsetField.getValue(addr);
var frameDataAddr = frame.getUnextendedSP().addOffsetTo(frameDataOffset);
var frameData = VMObjectFactory.newObject(FrameData.class, frameDataAddr);
return frameData.getJavaFrameAnchor();
}

public Address getLastJavaSP(Frame frame) {
return lastJavaSPField.getValue(getJavaFrameAnchor(frame));
}

public Address getLastJavaFP(Frame frame) {
return lastJavaFPField == null ? null : lastJavaFPField.getValue(getJavaFrameAnchor(frame));
}

public Address getLastJavaPC(Frame frame) {
return lastJavaPCField.getValue(getJavaFrameAnchor(frame));
}

public boolean isUpcallStub() {
return true;
}

public static class FrameData extends VMObject {

private static AddressField jfaField;

static {
VM.registerVMInitializedObserver(new Observer() {
public void update(Observable o, Object data) {
initialize(VM.getVM().getTypeDataBase());
}
});
}

private static void initialize(TypeDataBase db) {
Type type = db.lookupType("UpcallStub::FrameData");
jfaField = type.getAddressField("jfa");
}

public FrameData(Address addr) {
super(addr);
}

public Address getJavaFrameAnchor() {
return addr.addOffsetTo(jfaField.getOffset());
}

}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2019, Red Hat Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
Expand Down Expand Up @@ -292,7 +292,7 @@ public Frame sender(RegisterMap regMap, CodeBlob cb) {
}

if (cb != null) {
return senderForCompiledFrame(map, cb);
return cb.isUpcallStub() ? senderForUpcallStub(map, (UpcallStub)cb) : senderForCompiledFrame(map, cb);
}

// Must be native-compiled frame, i.e. the marshaling code for native
Expand Down Expand Up @@ -327,6 +327,34 @@ private Frame senderForEntryFrame(AARCH64RegisterMap map) {
return fr;
}

private Frame senderForUpcallStub(AARCH64RegisterMap map, UpcallStub stub) {
if (DEBUG) {
System.out.println("senderForUpcallStub");
}
if (Assert.ASSERTS_ENABLED) {
Assert.that(map != null, "map must be set");
}

var lastJavaFP = stub.getLastJavaFP(this);
var lastJavaSP = stub.getLastJavaSP(this);
var lastJavaPC = stub.getLastJavaPC(this);

if (Assert.ASSERTS_ENABLED) {
Assert.that(lastJavaSP.greaterThan(getSP()), "must be above this frame on stack");
}
AARCH64Frame fr;
if (lastJavaPC != null) {
fr = new AARCH64Frame(lastJavaSP, lastJavaFP, lastJavaPC);
} else {
fr = new AARCH64Frame(lastJavaSP, lastJavaFP);
}
map.clear();
if (Assert.ASSERTS_ENABLED) {
Assert.that(map.getIncludeArgumentOops(), "should be set by clear");
}
return fr;
}

//------------------------------------------------------------------------------
// frame::adjust_unextended_sp
private void adjustUnextendedSP() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 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
Expand Down Expand Up @@ -279,7 +279,7 @@ public Frame sender(RegisterMap regMap, CodeBlob cb) {
}

if (cb != null) {
return senderForCompiledFrame(map, cb);
return cb.isUpcallStub() ? senderForUpcallStub(map, (UpcallStub)cb) : senderForCompiledFrame(map, cb);
}

// Must be native-compiled frame, i.e. the marshaling code for native
Expand Down Expand Up @@ -314,6 +314,34 @@ private Frame senderForEntryFrame(PPC64RegisterMap map) {
return fr;
}

private Frame senderForUpcallStub(PPC64RegisterMap map, UpcallStub stub) {
if (DEBUG) {
System.out.println("senderForUpcallStub");
}
if (Assert.ASSERTS_ENABLED) {
Assert.that(map != null, "map must be set");
}

var lastJavaFP = stub.getLastJavaFP(this); // This will be null
var lastJavaSP = stub.getLastJavaSP(this);
var lastJavaPC = stub.getLastJavaPC(this);

if (Assert.ASSERTS_ENABLED) {
Assert.that(lastJavaSP.greaterThan(getSP()), "must be above this frame on stack");
}
PPC64Frame fr;
if (lastJavaPC != null) {
fr = new PPC64Frame(lastJavaSP, lastJavaFP, lastJavaPC);
} else {
fr = new PPC64Frame(lastJavaSP, lastJavaFP);
}
map.clear();
if (Assert.ASSERTS_ENABLED) {
Assert.that(map.getIncludeArgumentOops(), "should be set by clear");
}
return fr;
}

//------------------------------------------------------------------------------
// frame::adjust_unextended_sp
private void adjustUnextendedSP() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2019, Red Hat Inc.
* Copyright (c) 2021, 2023, Huawei Technologies Co., Ltd. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
Expand Down Expand Up @@ -284,7 +284,7 @@ public Frame sender(RegisterMap regMap, CodeBlob cb) {
}

if (cb != null) {
return senderForCompiledFrame(map, cb);
return cb.isUpcallStub() ? senderForUpcallStub(map, (UpcallStub)cb) : senderForCompiledFrame(map, cb);
}

// Must be native-compiled frame, i.e. the marshaling code for native
Expand Down Expand Up @@ -319,6 +319,34 @@ private Frame senderForEntryFrame(RISCV64RegisterMap map) {
return fr;
}

private Frame senderForUpcallStub(RISCV64RegisterMap map, UpcallStub stub) {
if (DEBUG) {
System.out.println("senderForUpcallStub");
}
if (Assert.ASSERTS_ENABLED) {
Assert.that(map != null, "map must be set");
}

var lastJavaFP = stub.getLastJavaFP(this);
var lastJavaSP = stub.getLastJavaSP(this);
var lastJavaPC = stub.getLastJavaPC(this);

if (Assert.ASSERTS_ENABLED) {
Assert.that(lastJavaSP.greaterThan(getSP()), "must be above this frame on stack");
}
RISCV64Frame fr;
if (lastJavaPC != null) {
fr = new RISCV64Frame(lastJavaSP, lastJavaFP, lastJavaPC);
} else {
fr = new RISCV64Frame(lastJavaSP, lastJavaFP);
}
map.clear();
if (Assert.ASSERTS_ENABLED) {
Assert.that(map.getIncludeArgumentOops(), "should be set by clear");
}
return fr;
}

//------------------------------------------------------------------------------
// frame::adjust_unextended_sp
private void adjustUnextendedSP() {
Expand Down
Loading

0 comments on commit deeb09a

Please sign in to comment.