Skip to content

Commit fe9c585

Browse files
[GR-67997] Espresso: Add EnableAdvancedRedefinition option.
PullRequest: graal/21585
2 parents 4d8a68e + f75c657 commit fe9c585

File tree

13 files changed

+254
-123
lines changed

13 files changed

+254
-123
lines changed

espresso/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
* Added experimentation support for `-javaagent`. It can also be enabled from the polyglot API with `java.JavaAgent.$i` option set to `/path/to/jar=agent-options` where `$i` starts at 0 and increments by 1 for each extra java agent.
77
* Added the `org.graalvm.continuations.IdentityHashCodes` class, providing utilities for restoring identity hashcodes. This may be used for more properly deserializing continuations.
88
* Added support for guest Java version 25.
9+
* Introduce a `EnableAdvancedRedefinition` option that controls whether things like method or field addition/removal and class hierarchy changes are enabled.
10+
It controls the access to such features both for JDWP and java agents.
11+
Previously, this was enabled by default for JDWP, in this release it must be explicitly turned on.
912

1013
## Version 24.2.0
1114
### User-visible changes

espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/api/ErrorCodes.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ public final class ErrorCodes {
3737
public static final int INVALID_SLOT = 35;
3838
public static final int INVALID_MODULE = 42;
3939
public static final int INVALID_CLASS_FORMAT = 60;
40+
public static final int CIRCULAR_CLASS_DEFINITION = 61;
4041
public static final int FAILS_VERIFICATION = 62;
4142
public static final int ADD_METHOD_NOT_IMPLEMENTED = 63;
4243
public static final int SCHEMA_CHANGE_NOT_IMPLEMENTED = 64;
@@ -46,6 +47,7 @@ public final class ErrorCodes {
4647
public static final int NAMES_DONT_MATCH = 69;
4748
public static final int CLASS_MODIFIERS_CHANGE_NOT_IMPLEMENTED = 70;
4849
public static final int METHOD_MODIFIERS_CHANGE_NOT_IMPLEMENTED = 71;
50+
public static final int CLASS_ATTRIBUTE_CHANGE_NOT_IMPLEMENTED = 72;
4951
public static final int NOT_IMPLEMENTED = 99;
5052
public static final int ABSENT_INFORMATION = 101;
5153
public static final int INVALID_EVENT_TYPE = 102;

espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/EspressoOptions.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -763,6 +763,12 @@ public enum MemoryAccessOption {
763763
usageSyntax = "allow|warn|debug|deny") //
764764
public static final OptionKey<MemoryAccessOption> SunMiscUnsafeMemoryAccess = new OptionKey<>(MemoryAccessOption.defaultValue);
765765

766+
@Option(help = "Enable advanced class redefinition.", //
767+
category = OptionCategory.EXPERT, //
768+
stability = OptionStability.EXPERIMENTAL, //
769+
usageSyntax = "false|true") //
770+
public static final OptionKey<Boolean> EnableAdvancedRedefinition = new OptionKey<>(false);
771+
766772
/**
767773
* Property used to force liveness analysis to also be applied by the interpreter. For testing
768774
* purpose only. Use a host property rather than an option. An option would slow interpreter

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

Lines changed: 38 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -47,39 +47,49 @@ default int getCachedParserKlassCount() {
4747
return 0;
4848
}
4949

50-
static ParserKlass parseKlass(ClassRegistry.ClassDefinitionInfo info, ClassLoadingEnv env, StaticObject loader, Symbol<Type> typeOrNull, byte[] bytes) {
50+
/**
51+
* Like {@link #parseKlass} but throws host exceptions that must be caught an handled by the
52+
* called.
53+
*
54+
* @throws ValidationException a descriptor validation caused a class format error.
55+
* @throws ParserException various exceptions, see subclasses.
56+
*/
57+
static ParserKlass parseKlassWithHostErrors(ClassRegistry.ClassDefinitionInfo info, ClassLoadingEnv env, StaticObject loader, Symbol<Type> typeOrNull, byte[] bytes) throws ValidationException {
5158
boolean verifiable = EspressoVerifier.needsVerify(env.getLanguage(), loader);
5259
boolean loaderIsBootOrPlatform = env.loaderIsBootOrPlatform(loader);
53-
Meta meta = env.getMeta();
54-
try {
55-
// Classes from trusted class loaders can create strongly referenced symbols directly
56-
// during parsing.
57-
boolean ensureStrongSymbols = env.loaderIsBootOrPlatform(loader) || env.loaderIsAppLoader(loader);
58-
ParsingContext parsingContext = ClassLoadingEnv.createParsingContext(env, ensureStrongSymbols);
60+
// Classes from trusted class loaders can create strongly referenced symbols directly
61+
// during parsing.
62+
boolean ensureStrongSymbols = env.loaderIsBootOrPlatform(loader) || env.loaderIsAppLoader(loader);
63+
ParsingContext parsingContext = ClassLoadingEnv.createParsingContext(env, ensureStrongSymbols);
5964

60-
// Trusted classes do not need validation/verification.
61-
boolean validate = verifiable;
62-
ParserKlass parserKlass = ClassfileParser.parse(parsingContext, new ClassfileStream(bytes, null), verifiable, loaderIsBootOrPlatform, typeOrNull, info.isHidden,
63-
info.forceAllowVMAnnotations, validate);
64-
if (info.isHidden) {
65-
Symbol<Type> requestedClassType = typeOrNull;
66-
assert requestedClassType != null;
67-
long hiddenKlassId = env.getNewKlassId();
68-
Symbol<Name> thisKlassName = parsingContext.getOrCreateName(TypeSymbols.hiddenClassName(requestedClassType, hiddenKlassId));
69-
Symbol<Type> thisKlassType = parsingContext.getOrCreateTypeFromName(thisKlassName);
70-
var pool = parserKlass.getConstantPool().patchForHiddenClass(parserKlass.getThisKlassIndex(), thisKlassName);
71-
var classFlags = parserKlass.getFlags() | Constants.ACC_IS_HIDDEN_CLASS;
72-
return new ParserKlass(pool, classFlags, thisKlassName, thisKlassType,
73-
parserKlass.getSuperKlass(), parserKlass.getSuperInterfaces(),
74-
parserKlass.getMethods(), parserKlass.getFields(),
75-
parserKlass.getAttributes(),
76-
parserKlass.getThisKlassIndex(),
77-
parserKlass.getMajorVersion(), parserKlass.getMinorVersion(),
78-
parserKlass.getHiddenKlassId());
79-
}
65+
// Trusted classes do not need validation/verification.
66+
boolean validate = verifiable;
67+
ParserKlass parserKlass = ClassfileParser.parse(parsingContext, new ClassfileStream(bytes, null), verifiable, loaderIsBootOrPlatform, typeOrNull, info.isHidden,
68+
info.forceAllowVMAnnotations, validate);
69+
if (info.isHidden) {
70+
Symbol<Type> requestedClassType = typeOrNull;
71+
assert requestedClassType != null;
72+
long hiddenKlassId = env.getNewKlassId();
73+
Symbol<Name> thisKlassName = parsingContext.getOrCreateName(TypeSymbols.hiddenClassName(requestedClassType, hiddenKlassId));
74+
Symbol<Type> thisKlassType = parsingContext.getOrCreateTypeFromName(thisKlassName);
75+
var pool = parserKlass.getConstantPool().patchForHiddenClass(parserKlass.getThisKlassIndex(), thisKlassName);
76+
var classFlags = parserKlass.getFlags() | Constants.ACC_IS_HIDDEN_CLASS;
77+
return new ParserKlass(pool, classFlags, thisKlassName, thisKlassType,
78+
parserKlass.getSuperKlass(), parserKlass.getSuperInterfaces(),
79+
parserKlass.getMethods(), parserKlass.getFields(),
80+
parserKlass.getAttributes(),
81+
parserKlass.getThisKlassIndex(),
82+
parserKlass.getMajorVersion(), parserKlass.getMinorVersion(),
83+
parserKlass.getHiddenKlassId());
84+
}
8085

81-
return parserKlass;
86+
return parserKlass;
87+
}
8288

89+
static ParserKlass parseKlass(ClassRegistry.ClassDefinitionInfo info, ClassLoadingEnv env, StaticObject loader, Symbol<Type> typeOrNull, byte[] bytes) {
90+
Meta meta = env.getMeta();
91+
try {
92+
return parseKlassWithHostErrors(info, env, loader, typeOrNull, bytes);
8393
} catch (ValidationException | ParserException.ClassFormatError validationOrBadFormat) {
8494
throw meta.throwExceptionWithMessage(meta.java_lang_ClassFormatError, validationOrBadFormat.getMessage());
8595
} catch (ParserException.UnsupportedClassVersionError unsupportedClassVersionError) {

0 commit comments

Comments
 (0)