Skip to content

Commit c9c7ab7

Browse files
[GR-41670] JDWP & Class loading fixes.
PullRequest: graal/12904
2 parents ad3a5c6 + 89d9433 commit c9c7ab7

File tree

8 files changed

+71
-24
lines changed

8 files changed

+71
-24
lines changed

espresso/src/com.oracle.truffle.espresso.launcher/src/com/oracle/truffle/espresso/launcher/EspressoLauncher.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@ protected List<String> preprocessArguments(List<String> arguments, Map<String, S
208208
versionAction = VersionAction.PrintAndExit;
209209
break;
210210
case "-showversion":
211+
case "--show-version":
211212
versionAction = VersionAction.PrintAndContinue;
212213
break;
213214

@@ -583,6 +584,7 @@ protected void collectArguments(Set<String> options) {
583584
options.add("-classpath");
584585
options.add("-version");
585586
options.add("-showversion");
587+
options.add("--show-version");
586588
options.add("-ea");
587589
options.add("-enableassertions");
588590
options.add("-esa");

espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/classfile/ClassfileParser.java

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,6 @@
5555
import java.util.Objects;
5656
import java.util.Set;
5757

58-
import com.oracle.truffle.espresso.impl.ClassLoadingEnv;
59-
import com.oracle.truffle.espresso.verifier.MethodVerifier;
6058
import org.graalvm.collections.EconomicMap;
6159

6260
import com.oracle.truffle.espresso.classfile.ConstantPool.Tag;
@@ -86,6 +84,7 @@
8684
import com.oracle.truffle.espresso.descriptors.Symbol.Signature;
8785
import com.oracle.truffle.espresso.descriptors.Symbol.Type;
8886
import com.oracle.truffle.espresso.descriptors.Types;
87+
import com.oracle.truffle.espresso.impl.ClassLoadingEnv;
8988
import com.oracle.truffle.espresso.impl.ClassRegistry;
9089
import com.oracle.truffle.espresso.impl.ParserField;
9190
import com.oracle.truffle.espresso.impl.ParserKlass;
@@ -101,6 +100,7 @@
101100
import com.oracle.truffle.espresso.runtime.EspressoContext;
102101
import com.oracle.truffle.espresso.runtime.EspressoException;
103102
import com.oracle.truffle.espresso.runtime.StaticObject;
103+
import com.oracle.truffle.espresso.verifier.MethodVerifier;
104104

105105
@SuppressWarnings("try")
106106
public final class ClassfileParser {
@@ -176,22 +176,22 @@ public final class ClassfileParser {
176176
private int maxBootstrapMethodAttrIndex = -1;
177177
private Tag badConstantSeen;
178178

179-
StaticObject loader;
179+
boolean verifiable;
180180

181181
private ConstantPool pool;
182182

183-
private ClassfileParser(ClassLoadingEnv env, ClassfileStream stream, StaticObject loader, Symbol<Type> requestedClassType, ClassRegistry.ClassDefinitionInfo info) {
183+
private ClassfileParser(ClassLoadingEnv env, ClassfileStream stream, boolean verifiable, Symbol<Type> requestedClassType, ClassRegistry.ClassDefinitionInfo info) {
184184
this.requestedClassType = requestedClassType;
185185
this.env = env;
186186
this.classfile = null;
187187
this.stream = Objects.requireNonNull(stream);
188-
this.loader = loader;
188+
this.verifiable = verifiable;
189189
this.classDefinitionInfo = info;
190190
}
191191

192192
// Note: only used for reading the class name from class bytes
193193
private ClassfileParser(ClassLoadingEnv env, ClassfileStream stream) {
194-
this(env, stream, null, null, ClassRegistry.ClassDefinitionInfo.EMPTY);
194+
this(env, stream, false, null, ClassRegistry.ClassDefinitionInfo.EMPTY);
195195
}
196196

197197
void handleBadConstant(Tag tag, ClassfileStream s) {
@@ -224,11 +224,16 @@ void checkDynamicConstantSupport(Tag tag) {
224224
}
225225

226226
public static ParserKlass parse(ClassLoadingEnv env, ClassfileStream stream, StaticObject loader, Symbol<Type> requestedClassName) {
227-
return parse(env, stream, loader, requestedClassName, ClassRegistry.ClassDefinitionInfo.EMPTY);
227+
boolean verifiable = MethodVerifier.needsVerify(env.getLanguage(), loader);
228+
return parse(env, stream, verifiable, requestedClassName, ClassRegistry.ClassDefinitionInfo.EMPTY);
229+
}
230+
231+
public static ParserKlass parse(ClassLoadingEnv env, ClassfileStream stream, boolean verifiable, Symbol<Type> requestedClassName) {
232+
return parse(env, stream, verifiable, requestedClassName, ClassRegistry.ClassDefinitionInfo.EMPTY);
228233
}
229234

230-
public static ParserKlass parse(ClassLoadingEnv env, ClassfileStream stream, StaticObject loader, Symbol<Type> requestedClassType, ClassRegistry.ClassDefinitionInfo info) {
231-
return new ClassfileParser(env, stream, loader, requestedClassType, info).parseClass();
235+
public static ParserKlass parse(ClassLoadingEnv env, ClassfileStream stream, boolean verifiable, Symbol<Type> requestedClassType, ClassRegistry.ClassDefinitionInfo info) {
236+
return new ClassfileParser(env, stream, verifiable, requestedClassType, info).parseClass();
232237
}
233238

234239
private ParserKlass parseClass() {
@@ -1307,7 +1312,7 @@ boolean hasCycles(InnerClassesAttribute.Entry[] entries) {
13071312
}
13081313

13091314
private StackMapTableAttribute parseStackMapTableAttribute(Symbol<Name> attributeName, int attributeSize) {
1310-
if (MethodVerifier.needsVerify(env.getLanguage(), loader)) {
1315+
if (verifiable) {
13111316
return new StackMapTableAttribute(attributeName, stream.readByteArray(attributeSize));
13121317
}
13131318
stream.skip(attributeSize);

espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/impl/ClassLoadingEnv.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
*/
2323
package com.oracle.truffle.espresso.impl;
2424

25+
import java.util.concurrent.atomic.AtomicLong;
26+
2527
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
2628
import com.oracle.truffle.api.TruffleLogger;
2729
import com.oracle.truffle.espresso.EspressoLanguage;
@@ -30,8 +32,6 @@
3032
import com.oracle.truffle.espresso.perf.TimerCollection;
3133
import com.oracle.truffle.espresso.runtime.StaticObject;
3234

33-
import java.util.concurrent.atomic.AtomicLong;
34-
3535
public class ClassLoadingEnv implements LanguageAccess {
3636
private final AtomicLong klassIdProvider = new AtomicLong();
3737
private final AtomicLong loaderIdProvider = new AtomicLong();

espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/impl/ClassRegistry.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ private ClassDefinitionInfo(StaticObject protectionDomain,
9797
this.classData = classData;
9898
this.isHidden = isHidden;
9999
this.isStrongHidden = isStrongHidden;
100+
assert isAnonymousClass() || patches == null;
100101
}
101102

102103
public final StaticObject protectionDomain;

espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/EspressoRootNode.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,7 @@ public boolean usesMonitors() {
251251

252252
final void initMonitorStack(VirtualFrame frame, MonitorStack monitorStack) {
253253
initMonitorSlot(frame);
254+
assert monitorStack != null;
254255
frame.setAuxiliarySlot(monitorSlot, monitorStack);
255256
}
256257

@@ -281,9 +282,7 @@ private void registerMonitor(VirtualFrame frame, StaticObject monitor) {
281282

282283
protected MonitorStack getMonitorStack(Frame frame) {
283284
assert monitorSlot >= 0;
284-
Object frameResult = frame.getAuxiliarySlot(monitorSlot);
285-
assert frameResult instanceof MonitorStack;
286-
return (MonitorStack) frameResult;
285+
return (MonitorStack) frame.getAuxiliarySlot(monitorSlot);
287286
}
288287

289288
public final StaticObject[] getMonitorsOnFrame(Frame frame) {
@@ -335,10 +334,10 @@ public Object execute(VirtualFrame frame) {
335334
}
336335

337336
private void enterSynchronized(VirtualFrame frame, StaticObject monitor) {
338-
InterpreterToVM.monitorEnter(monitor, getMeta());
339337
MonitorStack monitorStack = new MonitorStack();
340338
monitorStack.synchronizedMethodMonitor = monitor;
341339
initMonitorStack(frame, monitorStack);
340+
InterpreterToVM.monitorEnter(monitor, getMeta());
342341
}
343342
}
344343

espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/MethodWithBytecodeNode.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,17 @@
2222
*/
2323
package com.oracle.truffle.espresso.nodes;
2424

25+
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
2526
import com.oracle.truffle.api.frame.Frame;
27+
import com.oracle.truffle.api.frame.MaterializedFrame;
2628
import com.oracle.truffle.api.frame.VirtualFrame;
2729
import com.oracle.truffle.api.instrumentation.StandardTags;
2830
import com.oracle.truffle.api.instrumentation.StandardTags.RootBodyTag;
2931
import com.oracle.truffle.api.instrumentation.StandardTags.RootTag;
3032
import com.oracle.truffle.api.instrumentation.Tag;
33+
import com.oracle.truffle.api.interop.NodeLibrary;
34+
import com.oracle.truffle.api.library.ExportLibrary;
35+
import com.oracle.truffle.api.library.ExportMessage;
3136
import com.oracle.truffle.espresso.impl.SuppressFBWarnings;
3237

3338
/**
@@ -37,6 +42,7 @@
3742
* This class exists to conform to the Truffle instrumentation APIs, namely {@link RootTag} and
3843
* {@link RootBodyTag} in order to support proper unwind and re-enter.
3944
*/
45+
@ExportLibrary(NodeLibrary.class)
4046
final class MethodWithBytecodeNode extends EspressoInstrumentableRootNodeImpl {
4147

4248
@Child AbstractInstrumentableBytecodeNode bytecodeNode;
@@ -71,4 +77,20 @@ public boolean hasTag(Class<? extends Tag> tag) {
7177
}
7278
return false;
7379
}
80+
81+
@ExportMessage
82+
@SuppressWarnings("static-method")
83+
public boolean hasScope(@SuppressWarnings("unused") Frame frame) {
84+
return true;
85+
}
86+
87+
@ExportMessage
88+
public Object getScope(Frame frame, boolean nodeEnter) {
89+
return getScopeSlowPath(frame != null ? frame.materialize() : null, nodeEnter);
90+
}
91+
92+
@TruffleBoundary
93+
private Object getScopeSlowPath(MaterializedFrame frame, boolean nodeEnter) {
94+
return bytecodeNode.getScope(frame, nodeEnter);
95+
}
7496
}

espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/preinit/CachedParserKlassProvider.java

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import com.oracle.truffle.espresso.impl.ClassRegistry;
3333
import com.oracle.truffle.espresso.impl.ParserKlass;
3434
import com.oracle.truffle.espresso.runtime.StaticObject;
35+
import com.oracle.truffle.espresso.verifier.MethodVerifier;
3536

3637
public final class CachedParserKlassProvider extends AbstractCachedKlassProvider implements ParserKlassProvider {
3738
private final ParserKlassProvider fallbackProvider;
@@ -45,10 +46,9 @@ public CachedParserKlassProvider(TruffleLogger logger, ParserKlassProvider fallb
4546

4647
@Override
4748
public ParserKlass getParserKlass(ClassLoadingEnv env, StaticObject loader, Symbol<Symbol.Type> typeOrNull, byte[] bytes, ClassRegistry.ClassDefinitionInfo info) {
48-
assert (info.isAnonymousClass() && typeOrNull == null) || (!info.isAnonymousClass() && typeOrNull != null);
49-
if (shouldCacheClass(info)) {
49+
if (shouldCacheClass(info) && typeOrNull != null) {
5050
ParserKlassCacheKey key = null;
51-
ParserKlass parserKlass = null;
51+
ParserKlass parserKlass;
5252

5353
boolean loaderIsBootOrPlatform = env.loaderIsBootOrPlatform(loader);
5454

@@ -57,7 +57,9 @@ public ParserKlass getParserKlass(ClassLoadingEnv env, StaticObject loader, Symb
5757
parserKlass = bootParserKlassCache.get(typeOrNull);
5858
} else {
5959
// For other class loaders, query the application cache
60-
key = new ParserKlassCacheKey(bytes);
60+
boolean verifiable = MethodVerifier.needsVerify(env.getLanguage(), loader);
61+
assert !info.isAnonymousClass() && !info.isHidden() && info.patches == null;
62+
key = new ParserKlassCacheKey(bytes, typeOrNull, verifiable);
6163
parserKlass = appParserKlassCache.get(key);
6264
}
6365

@@ -88,10 +90,21 @@ public int getCachedParserKlassCount() {
8890
private static final class ParserKlassCacheKey {
8991
private final byte[] bytes;
9092
private final int hash;
93+
private final Symbol<Symbol.Type> type;
94+
private final boolean verifiable;
9195

92-
ParserKlassCacheKey(byte[] bytes) {
96+
ParserKlassCacheKey(byte[] bytes, Symbol<Symbol.Type> type, boolean verifiable) {
9397
this.bytes = bytes;
94-
this.hash = Arrays.hashCode(bytes);
98+
this.type = type;
99+
this.verifiable = verifiable;
100+
this.hash = computeHash(bytes, type, verifiable);
101+
}
102+
103+
private static int computeHash(byte[] bytes, Symbol<Symbol.Type> typeOrNull, boolean verifiable) {
104+
int result = Arrays.hashCode(bytes);
105+
result = 31 * result + typeOrNull.hashCode();
106+
result = 31 * result + Boolean.hashCode(verifiable);
107+
return result;
95108
}
96109

97110
@Override
@@ -103,7 +116,10 @@ public boolean equals(Object o) {
103116
return false;
104117
}
105118
ParserKlassCacheKey other = (ParserKlassCacheKey) o;
106-
return this.hash == other.hash && Arrays.equals(this.bytes, other.bytes);
119+
if (this.hash != other.hash) {
120+
return false;
121+
}
122+
return Arrays.equals(this.bytes, other.bytes) && this.type.equals(other.type) && this.verifiable == other.verifiable;
107123
}
108124

109125
@Override

espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/preinit/DefaultParserKlassProvider.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,12 @@
2929
import com.oracle.truffle.espresso.impl.ClassRegistry;
3030
import com.oracle.truffle.espresso.impl.ParserKlass;
3131
import com.oracle.truffle.espresso.runtime.StaticObject;
32+
import com.oracle.truffle.espresso.verifier.MethodVerifier;
3233

3334
public final class DefaultParserKlassProvider implements ParserKlassProvider {
3435
@Override
3536
public ParserKlass getParserKlass(ClassLoadingEnv env, StaticObject loader, Symbol<Symbol.Type> typeOrNull, byte[] bytes, ClassRegistry.ClassDefinitionInfo info) {
36-
return ClassfileParser.parse(env, new ClassfileStream(bytes, null), loader, typeOrNull, info);
37+
boolean verifiable = MethodVerifier.needsVerify(env.getLanguage(), loader);
38+
return ClassfileParser.parse(env, new ClassfileStream(bytes, null), verifiable, typeOrNull, info);
3739
}
3840
}

0 commit comments

Comments
 (0)