Skip to content

Commit

Permalink
[GR-61430] Espresso 24.2 backports.
Browse files Browse the repository at this point in the history
PullRequest: graal/19816
  • Loading branch information
gilles-duboscq authored and ansalond committed Jan 23, 2025
2 parents 0869146 + ee9fd30 commit 826d284
Show file tree
Hide file tree
Showing 33 changed files with 806 additions and 625 deletions.
2 changes: 1 addition & 1 deletion espresso/mx.espresso/mx_espresso.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ def _run_espresso(args=None, cwd=None, nonZeroIsFatal=True, out=None, err=None,

def _run_espresso_meta(args, nonZeroIsFatal=True, timeout=None):
"""Run Espresso (standalone) on Espresso (launcher)"""
return _run_espresso_launcher([
return _run_espresso([
'--vm.Xss4m',
] + _espresso_standalone_command(args, allow_jacoco=False), nonZeroIsFatal=nonZeroIsFatal, timeout=timeout)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -667,7 +667,7 @@ private ParserMethod[] parseMethods(boolean isInterface) throws ValidationExcept
* Classes in general have lots of methods: use a hash set rather than array lookup for dup
* check.
*/
final HashSet<MethodKey> dup = HashSet.newHashSet(methodCount);
final HashSet<MethodKey> dup = new HashSet<>(methodCount);
for (int i = 0; i < methodCount; ++i) {
ParserMethod method;
try (DebugCloseable closeable = PARSE_SINGLE_METHOD.scope(parsingContext.getTimers())) {
Expand Down Expand Up @@ -1940,7 +1940,7 @@ private Symbol<Type>[] parseInterfaces() {
interfaces[i] = interfaceType;
}
// Check for duplicate interfaces in the interface array.
Set<Symbol<Type>> present = HashSet.newHashSet(interfaces.length);
Set<Symbol<Type>> present = new HashSet<>(interfaces.length);
for (Symbol<Type> t : interfaces) {
if (!present.add(t)) {
throw classFormatError("Duplicate interface name in classfile: " + t);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ public final class ErrorCodes {
public static final int ABSENT_INFORMATION = 101;
public static final int INVALID_EVENT_TYPE = 102;
public static final int INTERNAL = 113;
public static final int INVALID_INDEX = 503;
public static final int INVALID_LENGTH = 504;
public static final int INVALID_STRING = 506;
public static final int INVALID_CLASS_LOADER = 507;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,4 +114,6 @@ public interface FieldRef {
* @return true if this field has any breakpoints, false otherwise
*/
boolean hasActiveBreakpoint();

void disposeFieldBreakpoint();
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import com.oracle.truffle.api.frame.Frame;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.nodes.RootNode;
import com.oracle.truffle.espresso.jdwp.impl.DebuggerController;

/**
* Interface that defines required methods for a guest language when implementing JDWP.
Expand Down Expand Up @@ -500,4 +501,6 @@ public interface JDWPContext {
Object allocateInstance(KlassRef klass);

void steppingInProgress(Thread t, boolean value);

void replaceController(DebuggerController newController);
}
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,8 @@ public interface MethodRef {
*/
boolean hasActiveHook();

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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ public void activate(Object mainThread, DebuggerController control, JDWPContext
this.ids = context.getIds();
}

public void replaceController(DebuggerController newController) {
this.debuggerController = newController;
}

@Override
public void onDetach() {
// free up request, to avoid attempting to send anything further
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,8 @@ public interface BreakpointInfo {
void addSuspendPolicy(byte suspendPolicy);

byte getSuspendPolicy();

default void dispose() {
// do nothing by default
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ public void reInitialize() {
DebuggerController newController = new DebuggerController(jdwpLogger);
newController.truffleContext = truffleContext;
newController.initialize(debugger, options, context, initialThread, eventListener);
context.replaceController(newController);
assert newController.setupState != null;

if (newController.setupState.fatalConnectionError) {
Expand Down Expand Up @@ -186,6 +187,10 @@ public void reset(boolean prepareForReconnect) {
// existence state.
resetting.lockInterruptibly();

// end the current debugger session to avoid hitting any further breakpoints
// when resuming all threads
endSession();

currentReceiverThread = receiverThread;

// Close the server socket used to listen for transport dt_socket.
Expand All @@ -207,16 +212,14 @@ public void reset(boolean prepareForReconnect) {
// re-enable GC for all objects
getGCPrevention().clearAll();

// end the current debugger session to avoid hitting any further breakpoints
// when resuming all threads
endSession();

// resume all threads
forceResumeAll();
eventFilters.clearAll();

// Now, close the socket, which will force the receiver thread to complete eventually.
// Note that we might run this code in the receiver thread, so we can't simply join.
closeSocket();

// resume all threads
forceResumeAll();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
Expand Down Expand Up @@ -700,6 +703,9 @@ public void leaveTruffleContext(Object previous) {

@Override
public void onLanguageContextInitialized(TruffleContext con, @SuppressWarnings("unused") LanguageInfo language) {
if (!"java".equals(language.getId())) {
return;
}
truffleContext = con;

// With the Espresso context initialized, we can now complete the JDWP setup and establish
Expand Down Expand Up @@ -819,8 +825,8 @@ private void lockThread(Object thread, boolean forceSuspend, List<Callable<Void>
while (!Thread.currentThread().isInterrupted()) {
try {
synchronized (lock) {
if (!lock.isLocked()) {
// released from other thread, so break loop
if (!lock.isLocked() || !connection.isOpen()) {
// released from other thread or session ended, so break loop
break;
}
// no reason to hold a hard suspension status, since now
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,20 @@ public RequestFilter getRequestFilter(int requestId) {
readLock.unlock();
}
}

public void clearAll() {
try {
lock.writeLock().lock();
// traverse all filters and clear all registered breakpoint information
for (RequestFilter requestFilter : requestFilters) {
BreakpointInfo breakpointInfo = requestFilter.getBreakpointInfo();
if (breakpointInfo != null) {
breakpointInfo.dispose();
}
}
requestFilters = new RequestFilter[0];
} finally {
lock.writeLock().unlock();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,9 @@ public boolean isModificationBreakpoint() {
public boolean isAccessBreakpoint() {
return accessBreakpoint;
}

@Override
public void dispose() {
field.disposeFieldBreakpoint();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2111,8 +2111,7 @@ static CommandResult createReply(Packet packet, DebuggerController controller) {
}

int startFrame = input.readInt();
int length = input.readInt();
final int requestedLength = length;
int requestedLength = input.readInt();

controller.fine(() -> "requesting frames for thread: " + controller.getContext().getThreadName(thread));
controller.fine(() -> "startFrame requested: " + startFrame);
Expand All @@ -2127,13 +2126,21 @@ static CommandResult createReply(Packet packet, DebuggerController controller) {
}

CallFrame[] frames = suspendedInfo.getStackFrames();

if (length == -1 || length > frames.length) {
length = frames.length;
if (startFrame < 0 || startFrame >= frames.length) {
reply.errorCode(ErrorCodes.INVALID_INDEX);
return new CommandResult(reply);
}
int length;
if (requestedLength == -1) {
length = frames.length - startFrame;
} else if (requestedLength < 0 || startFrame + requestedLength > frames.length) {
reply.errorCode(ErrorCodes.INVALID_LENGTH);
return new CommandResult(reply);
} else {
length = requestedLength;
}
reply.writeInt(length);
final int finalLength = length;
controller.fine(() -> "returning " + finalLength + " frames for thread: " + controller.getContext().getThreadName(thread));
controller.fine(() -> "returning " + length + " frames for thread: " + controller.getContext().getThreadName(thread));

for (int i = startFrame; i < startFrame + length; i++) {
CallFrame frame = frames[i];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,11 @@ public boolean onMethodEnter(@SuppressWarnings("unused") MethodRef method, @Supp
public boolean onMethodExit(@SuppressWarnings("unused") MethodRef method, @SuppressWarnings("unused") Object returnValue) {
return isMethodExit;
}

@Override
public void dispose() {
for (MethodRef method : methods) {
method.disposeHooks();
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
Expand Down Expand Up @@ -40,6 +40,23 @@
*/
package com.oracle.truffle.espresso.polyglot;

/**
* This interface must be implemented by a custom defined type converter that is declared as context
* builder input using the 'java.PolyglotTypeConverters' option. If a polyglot object that is passed
* into Espresso has a declared meta name that matches the declaration used for the GuestConversion,
* the toGuest method is invoked. This invocation is responsible for returning a guest object
* matching the parameterized type.
* </p>
* Note that, in the case where the target type, e.g. a method parameter type in the guest, is not
* assignable from the returned instance of the toGuest method, the converted value is ignored.
* Hence, other custom or internal type mappings might be attempted in sequence in response to such
* incompatible conversion. For example, the built-in collection type mappings
* (java.BuiltInPolyglotCollections) might be compatible for the incoming polyglot object, or there
* might be custom interface mapping (java.PolyglotInterfaceMappings).
*
* @param <T> the guest type this converter is converting an interop meta name-mapped polyglot
* instance to.
*/
public interface GuestTypeConversion<T> {
T toGuest(Object polyglotInstance);
}
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,17 @@ private int lookup(int targetBCI) {
throw EspressoError.shouldNotReachHere();
}

/**
* Lookup the index of the largest element which is smaller or equal to {@code targetBCI}.
*/
public int lookupBucket(int targetBCI) {
int res = slowLookup(targetBCI, 0, length);
if (res >= 0) {
return res;
}
return -res - 1;
}

public int lookup(int curIndex, int curBCI, int targetBCI) {
int res;
int start;
Expand All @@ -117,7 +128,7 @@ public int lookup(int curIndex, int curBCI, int targetBCI) {
if (res >= 0) {
return res;
}
return -res - 2;
return -res - 1;
}

public int checkNext(int curIndex, int targetBCI) {
Expand All @@ -128,20 +139,20 @@ public int checkNext(int curIndex, int targetBCI) {
}

/**
* inlined binary search. No bounds checks.
* Inlined binary search. No bounds checks.
*
* @see Arrays#binarySearch(int[], int, int, int)
* @return either the index of the element that is equal to {@code targetBCI} or a negative
* number {@code -(i + 1)} where i is the index of the largest element which is smaller
* than {@code targetBCI}.
*/
@ExplodeLoop(kind = ExplodeLoop.LoopExplosionKind.FULL_EXPLODE)
private int slowLookup(int targetBCI, int start, int end) {
// Our usage should not see an out of bounds
int low = start;
int high = end - 1;

while (low <= high) {
int mid = (low + high) >>> 1;
int midVal = bcis[mid];

if (midVal < targetBCI) {
low = mid + 1;
} else if (midVal > targetBCI) {
Expand All @@ -150,7 +161,7 @@ private int slowLookup(int targetBCI, int start, int end) {
return mid;
}
}
return -(low + 1); // key not found.
return -low;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -199,10 +199,13 @@ public MethodRefConstant resolvedMethodRefAt(ObjectKlass accessingKlass, int ind
return (MethodRefConstant) resolved;
}

public Method resolvedMethodAtNoCache(ObjectKlass accessingKlass, int index) {
public Method resolveMethodAndUpdate(ObjectKlass accessingKlass, int index) {
CompilerAsserts.neverPartOfCompilation();
Resolvable.ResolvedConstant resolved = resolvedAtNoCache(accessingKlass, index, "method");
return (Method) resolved.value();
synchronized (this) {
resolvedConstants[index] = resolved;
}
return ((Method) resolved.value());
}

public StaticObject resolvedMethodHandleAt(ObjectKlass accessingKlass, int index) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -926,11 +926,16 @@ public final void removeFieldBreakpointInfo(int requestId) {
// remove index 1, but keep info at index 0
temp[0] = infos[0];
infos = temp;
return;
}
}
}

@Override
public void disposeFieldBreakpoint() {
hasActiveBreakpoints.set(false);
infos = null;
}

public void setCompatibleField(@SuppressWarnings("unused") Field field) {
// only applicable to RedefineAddedFields
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1104,6 +1104,11 @@ public synchronized void removeActiveHook(MethodHook hook) {
}
}

public synchronized void disposeHooks() {
hasActiveHook.set(false);
hooks = MethodHook.EMPTY;
}

public SharedRedefinitionContent redefine(ObjectKlass.KlassVersion klassVersion, ParserMethod newMethod, ParserKlass newKlass, Ids<Object> ids) {
// install the new method version immediately
LinkedMethod newLinkedMethod = new LinkedMethod(newMethod);
Expand Down Expand Up @@ -1848,6 +1853,11 @@ public void removedMethodHook(MethodHook hook) {
getMethod().removeActiveHook(hook);
}

@Override
public void disposeHooks() {
getMethod().disposeHooks();
}

@Override
public boolean hasActiveHook() {
return getMethod().hasActiveHook();
Expand Down
Loading

0 comments on commit 826d284

Please sign in to comment.