Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[GR-62501] Revert refactor of Method vs. MethodVersion to fix isObsolete(). #10949

Merged
merged 1 commit into from
Apr 1, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public final class CallFrame {

private final byte typeTag;
private final long classId;
private final MethodRef method;
private final MethodVersionRef methodVersion;
private final long methodId;
private final long codeIndex;
private final long threadId;
Expand All @@ -55,14 +55,14 @@ public final class CallFrame {
private Object scope;
private final TruffleLogger logger;

public CallFrame(long threadId, byte typeTag, long classId, MethodRef method, long methodId, long codeIndex, Frame frame, Node currentNode, RootNode rootNode,
public CallFrame(long threadId, byte typeTag, long classId, MethodVersionRef methodVersion, long methodId, long codeIndex, Frame frame, Node currentNode, RootNode rootNode,
DebugStackFrame debugStackFrame, JDWPContext context, TruffleLogger logger) {
this.threadId = threadId;
this.typeTag = typeTag;
this.classId = classId;
this.method = method;
this.methodVersion = methodVersion;
this.methodId = methodId;
this.codeIndex = method != null && method.isObsolete() ? -1 : codeIndex;
this.codeIndex = methodVersion != null && methodVersion.isObsolete() ? -1 : codeIndex;
this.frame = frame;
this.currentNode = currentNode;
this.rootNode = rootNode;
Expand All @@ -85,15 +85,22 @@ public long getClassId() {
return classId;
}

public MethodVersionRef getMethodVersion() {
return methodVersion;
}

public MethodRef getMethod() {
return method;
if (methodVersion != null) {
return methodVersion.getMethod();
}
return null;
}

public long getMethodId() {
if (method == null) {
if (methodVersion == null) {
return methodId;
}
return method.isObsolete() ? 0 : methodId;
return methodVersion.isObsolete() ? 0 : methodId;
}

public long getCodeIndex() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2025, 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 @@ -172,31 +172,6 @@ private synchronized long generateUniqueId(T object) {
return id;
}

public void replaceObject(T original, T replacement) {
int id = (int) getIdAsLong(original);
objects[id] = new WeakReference<>(replacement);
log(() -> "Replaced ID: " + id);
}

@SuppressWarnings({"unchecked", "rawtypes"})
public void updateId(KlassRef klass) {
// remove existing ID
removeId(klass);
Long theId = innerClassIDMap.get(klass.getNameAsString());
if (theId != null) {
// then inject klass under the new ID
objects[(int) (long) theId] = new WeakReference(klass);
}
}

@SuppressWarnings({"unchecked", "rawtypes"})
private void removeId(KlassRef klass) {
int id = (int) getId(klass);
if (id > 0) {
objects[id] = new WeakReference<>(null);
}
}

public boolean checkRemoved(long refTypeId) {
return innerClassIDMap.containsValue(refTypeId);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public interface JDWPContext {
* @param root the Truffle root node object
* @return the declaring method of the root node
*/
MethodRef getMethodFromRootNode(RootNode root);
MethodVersionRef getMethodFromRootNode(RootNode root);

/**
* @return guest language array of all active threads
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,14 +175,6 @@ public interface MethodRef {
*/
boolean hasSourceFileAttribute();

/**
* Determines if the code index is located in the source file on the last line of this method.
*
* @param codeIndex
* @return true if last line, false otherwise
*/
boolean isLastLine(long codeIndex);

/**
* Returns the klass that declares this method.
*
Expand Down Expand Up @@ -234,16 +226,6 @@ public interface MethodRef {

void disposeHooks();

/**
* Determine if this method is obsolete. A method is obsolete if it has been replaced by a
* non-equivalent method using the RedefineClasses command. The original and redefined methods
* are considered equivalent if their bytecodes are the same except for indices into the
* constant pool and the referenced constants are equal.
*
* @return true if the method is obsolete
*/
boolean isObsolete();

/**
* Returns the last bci of the method.
*
Expand All @@ -264,4 +246,11 @@ public interface MethodRef {
* @return true if the method is a static initializer
*/
boolean isClassInitializer();

/**
* Determines if this method was removed by redefinition.
*
* @return true if removed
*/
boolean isRemovedByRedefinition();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright (c) 2025, 2025, 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 com.oracle.truffle.espresso.jdwp.api;

public interface MethodVersionRef {
/**
* Returns the MethodRef corresponding to this method version.
*
* @return the MethodRef
*/
MethodRef getMethod();

/**
* Determine if this method is obsolete. A method is obsolete if it has been replaced by a
* non-equivalent method using the RedefineClasses command. The original and redefined methods
* are considered equivalent if their bytecodes are the same except for indices into the
* constant pool and the referenced constants are equal.
*
* @return true if the method is obsolete
*/
boolean isObsolete();
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2029, 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 @@ -96,7 +96,7 @@ public interface VMListener {
* This method should be called when when the monitor wait(timeout) method is invoked in the
* guest VM. A monitor wait event will then be sent through JDWP, if there was a request for the
* current thread.
*
*
* @param monitor the monitor object
* @param timeout the timeout in ms before the wait will time out
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
import com.oracle.truffle.espresso.jdwp.api.JDWPOptions;
import com.oracle.truffle.espresso.jdwp.api.KlassRef;
import com.oracle.truffle.espresso.jdwp.api.MethodRef;
import com.oracle.truffle.espresso.jdwp.api.MethodVersionRef;
import com.oracle.truffle.espresso.jdwp.api.VMEventListener;

public final class DebuggerController implements ContextsListener {
Expand Down Expand Up @@ -415,10 +416,10 @@ private void doStepOut(SuspendedInfo susp) {
SteppingInfo steppingInfo = commandRequestIds.get(susp.getThread());
if (steppingInfo != null && stepOutBCI != -1) {
// record the location that we'll land on after the step out completes
MethodRef method = context.getMethodFromRootNode(callerRoot);
MethodVersionRef method = context.getMethodFromRootNode(callerRoot);
if (method != null) {
KlassRef klass = method.getDeclaringKlassRef();
steppingInfo.setStepOutBCI(context.getIds().getIdAsLong(klass), context.getIds().getIdAsLong(method), stepOutBCI);
KlassRef klass = method.getMethod().getDeclaringKlassRef();
steppingInfo.setStepOutBCI(context.getIds().getIdAsLong(klass), context.getIds().getIdAsLong(method.getMethod()), stepOutBCI);
}
}
}
Expand Down Expand Up @@ -869,16 +870,17 @@ public CallFrame[] getCallFrames(Object guestThread) {
List<CallFrame> callFrames = new ArrayList<>();
Truffle.getRuntime().iterateFrames(frameInstance -> {
KlassRef klass;
MethodRef method;
MethodVersionRef methodVersion;
RootNode root = getRootNode(frameInstance);
if (root == null) {
return null;
}
method = getContext().getMethodFromRootNode(root);
if (method == null) {
methodVersion = getContext().getMethodFromRootNode(root);
if (methodVersion == null) {
return null;
}

MethodRef method = methodVersion.getMethod();
klass = method.getDeclaringKlassRef();
long klassId = ids.getIdAsLong(klass);
long methodId = ids.getIdAsLong(method);
Expand Down Expand Up @@ -914,7 +916,7 @@ public CallFrame[] getCallFrames(Object guestThread) {
if (currentNode instanceof RootNode) {
currentNode = context.getInstrumentableNode((RootNode) currentNode);
}
callFrames.add(new CallFrame(context.getIds().getIdAsLong(guestThread), typeTag, klassId, method, methodId, codeIndex, frame, currentNode, root, null, context, jdwpLogger));
callFrames.add(new CallFrame(context.getIds().getIdAsLong(guestThread), typeTag, klassId, methodVersion, methodId, codeIndex, frame, currentNode, root, null, context, jdwpLogger));
return null;
});
return callFrames.toArray(new CallFrame[0]);
Expand Down Expand Up @@ -1227,11 +1229,11 @@ private CallFrame[] createCallFrames(long threadId, Iterable<DebugStackFrame> st
}

Frame rawFrame = frame.getRawFrame(context.getLanguageClass(), FrameInstance.FrameAccess.READ_WRITE);
MethodRef method = context.getMethodFromRootNode(root);
KlassRef klass = method.getDeclaringKlassRef();
MethodVersionRef methodVersion = context.getMethodFromRootNode(root);
KlassRef klass = methodVersion.getMethod().getDeclaringKlassRef();

klassId = ids.getIdAsLong(klass);
methodId = ids.getIdAsLong(method);
methodId = ids.getIdAsLong(methodVersion.getMethod());
typeTag = TypeTag.getKind(klass);

// check if we have a dedicated step out code index on the top frame
Expand All @@ -1241,7 +1243,7 @@ private CallFrame[] createCallFrames(long threadId, Iterable<DebugStackFrame> st
codeIndex = context.getBCI(rawNode, rawFrame);
}

list.addLast(new CallFrame(threadId, typeTag, klassId, method, methodId, codeIndex, rawFrame, rawNode, root, frame, context, jdwpLogger));
list.addLast(new CallFrame(threadId, typeTag, klassId, methodVersion, methodId, codeIndex, rawFrame, rawNode, root, frame, context, jdwpLogger));
frameCount++;
if (frameLimit != -1 && frameCount >= frameLimit) {
return list.toArray(new CallFrame[0]);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2025, 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 @@ -1518,7 +1518,8 @@ static CommandResult createReply(Packet packet, JDWPContext context) {
if (method == null) {
return new CommandResult(reply);
}
reply.writeBoolean(method.isObsolete());
// only condition to check here is if removed by redefinition
reply.writeBoolean(method.isRemovedByRedefinition());
}
return new CommandResult(reply);
}
Expand Down Expand Up @@ -2154,7 +2155,7 @@ static CommandResult createReply(Packet packet, DebuggerController controller) {
reply.writeLong(controller.getContext().getIds().getIdAsLong(frame));
reply.writeByte(frame.getTypeTag());
reply.writeLong(frame.getClassId());
reply.writeLong(frame.getMethod().isObsolete() ? 0 : controller.getContext().getIds().getIdAsLong(frame.getMethod()));
reply.writeLong(frame.getMethodVersion().isObsolete() ? 0 : controller.getContext().getIds().getIdAsLong(frame.getMethod()));
reply.writeLong(frame.getCodeIndex());
}
return new CommandResult(reply);
Expand Down
Loading
Loading