use of com.oracle.truffle.espresso.descriptors.Symbol.Type in project graal by oracle.
the class VM method JVM_LookupDefineClass.
@VmImpl(isJni = true)
@TruffleBoundary
@JavaType(Class.class)
public StaticObject JVM_LookupDefineClass(@JavaType(Class.class) StaticObject lookup, @Pointer TruffleObject namePtr, @Pointer TruffleObject bufPtr, int len, @JavaType(ProtectionDomain.class) StaticObject pd, boolean initialize, int flags, @JavaType(Object.class) StaticObject classData) {
if (StaticObject.isNull(lookup)) {
throw getMeta().throwExceptionWithMessage(getMeta().java_lang_InternalError, "Lookup class is null");
}
assert !getUncached().isNull(bufPtr);
assert lookup.getMirrorKlass() instanceof ObjectKlass;
boolean isNestMate = (flags & NESTMATE_CLASS) == NESTMATE_CLASS;
boolean isHidden = (flags & HIDDEN_CLASS) == HIDDEN_CLASS;
boolean isStrong = (flags & STRONG_LOADER_LINK) == STRONG_LOADER_LINK;
boolean vmAnnotations = (flags & ACCESS_VM_ANNOTATIONS) == ACCESS_VM_ANNOTATIONS;
ObjectKlass nest = null;
if (isNestMate) {
nest = (ObjectKlass) lookup.getMirrorKlass().nest();
}
if (!isHidden) {
if (!StaticObject.isNull(classData)) {
throw getMeta().throwExceptionWithMessage(getMeta().java_lang_IllegalArgumentException, "classData is only applicable for hidden classes");
}
if (isNestMate) {
throw getMeta().throwExceptionWithMessage(getMeta().java_lang_IllegalArgumentException, "dynamic nestmate is only applicable for hidden classes");
}
if (!isStrong) {
throw getMeta().throwExceptionWithMessage(getMeta().java_lang_IllegalArgumentException, "an ordinary class must be strongly referenced by its defining loader");
}
if (vmAnnotations) {
throw getMeta().throwExceptionWithMessage(getMeta().java_lang_IllegalArgumentException, "vm annotations only allowed for hidden classes");
}
if (flags != STRONG_LOADER_LINK) {
throw getMeta().throwExceptionWithMessage(getMeta().java_lang_IllegalArgumentException, String.format("invalid flag 0x%x", flags));
}
}
ByteBuffer buf = NativeUtils.directByteBuffer(bufPtr, len, JavaKind.Byte);
final byte[] bytes = new byte[len];
buf.get(bytes);
// can be null
Symbol<Type> type = namePtrToInternal(namePtr);
StaticObject loader = lookup.getMirrorKlass().getDefiningClassLoader();
ObjectKlass k;
if (isHidden) {
// Special handling
k = getRegistries().defineKlass(type, bytes, loader, new ClassRegistry.ClassDefinitionInfo(pd, nest, classData, isStrong));
} else {
k = getRegistries().defineKlass(type, bytes, loader, new ClassRegistry.ClassDefinitionInfo(pd));
}
if (initialize) {
k.safeInitialize();
} else {
k.ensureLinked();
}
return k.mirror();
}
use of com.oracle.truffle.espresso.descriptors.Symbol.Type in project graal by oracle.
the class MethodVerifier method verifyInvokeInterface.
private void verifyInvokeInterface(int bci, OperandStack stack) {
// Check padding.
verifyGuarantee(code.readUByte(bci + 4) == 0, "4th byte after INVOKEINTERFACE must be 0.");
// Check CP validity
MethodRefConstant mrc = getMethodRefConstant(bci);
// Checks versioning
Symbol<Name> calledMethodName = mrc.getName(pool);
// Check guest is not invoking <clinit>
verifyGuarantee(!isClassInit(calledMethodName), "Invocation of class initializer!");
// Only INVOKESPECIAL can call <init>
verifyGuarantee(!isInstanceInit(calledMethodName), "Invocation of instance initializer with opcode other than INVOKESPECIAL");
Symbol<Signature> calledMethodSignature = mrc.getSignature(pool);
Operand[] parsedSig = getOperandSig(calledMethodSignature);
// Check signature is well formed.
assert parsedSig.length > 0 : "Method ref with no return value !";
// Pop arguments
// Check signature conforms with count argument
int count = code.readUByte(bci + 3);
verifyGuarantee(count > 0, "Invalid count argument for INVOKEINTERFACE: " + count);
// Has a receiver.
int descCount = 1;
for (int i = parsedSig.length - 2; i >= 0; i--) {
descCount++;
if (isType2(parsedSig[i])) {
descCount++;
}
stack.pop(parsedSig[i]);
}
verifyGuarantee(count == descCount, "Inconsistent redundant argument count for INVOKEINTERFACE.");
assert Validation.validClassNameEntry(mrc.getHolderKlassName(pool));
Symbol<Type> methodHolder = getTypes().fromName(mrc.getHolderKlassName(pool));
Operand methodHolderOp = kindToOperand(methodHolder);
checkInit(stack.popRef(methodHolderOp));
Operand returnOp = parsedSig[parsedSig.length - 1];
if (!(returnOp == Void)) {
stack.push(returnOp);
}
}
use of com.oracle.truffle.espresso.descriptors.Symbol.Type in project graal by oracle.
the class MethodVerifier method verifyInvokeSpecial.
private void verifyInvokeSpecial(int bci, OperandStack stack, Locals locals) {
// Check CP validity
MethodRefConstant mrc = getMethodRefConstant(bci);
// Checks versioning
if (version51OrEarlier()) {
verifyGuarantee(mrc.tag() != INTERFACE_METHOD_REF, "invokeSpecial refers to an interface method with classfile version " + majorVersion);
}
Symbol<Name> calledMethodName = mrc.getName(pool);
// Check guest is not invoking <clinit>
verifyGuarantee(!isClassInit(calledMethodName), "Invocation of class initializer!");
Operand returnOp = popSignatureGetReturnOP(stack, mrc);
assert Validation.validClassNameEntry(mrc.getHolderKlassName(pool));
Symbol<Type> methodHolder = getTypes().fromName(mrc.getHolderKlassName(pool));
Operand methodHolderOp = kindToOperand(methodHolder);
if (isInstanceInit(calledMethodName)) {
UninitReferenceOperand toInit = (UninitReferenceOperand) stack.popUninitRef(methodHolderOp);
if (toInit.isUninitThis()) {
verifyGuarantee(Name._init_.equals(methodName), "Encountered UninitializedThis outside of Constructor: " + toInit);
boolean isValidInitThis = toInit.getType() == methodHolder || // have been handled by the previous check.
toInit.getKlass().getSuperKlass().getType() == methodHolder;
verifyGuarantee(isValidInitThis, "<init> method must call this.<init> or super.<init>");
calledConstructor = true;
} else {
verifyGuarantee(code.opcode(toInit.newBCI) == NEW, "There is no NEW bytecode at bci: " + toInit.newBCI);
// according to JCK's "vm/classfmt/ins/instr_03608m1" :
//
// Calling parent's initializer of uninitialized new object is
// illegal, but serialization does just that.
//
// In particular, it generates a class whose method executes NEW
// j.l.Number (an abstract class), then calls j.l.Object.<init> on
// it.
//
// A workaround would be to check if the underlying class is
// abstract/interface, but that would feel really silly...
verifyGuarantee(toInit.getType() == methodHolder, "Calling wrong initializer for a new object.");
}
Operand stackOp = stack.initUninit(toInit);
locals.initUninit(toInit, stackOp);
checkProtectedMember(stackOp, methodHolder, mrc, true);
} else {
verifyGuarantee(checkMethodSpecialAccess(methodHolderOp), "invokespecial must specify a method in this class or a super class");
Operand stackOp = checkInit(stack.popRef(methodHolderOp));
/**
* 4.10.1.9.invokespecial:
*
* invokespecial, for other than an instance initialization method, must name a method
* in the current class/interface or a superclass / superinterface.
*/
verifyGuarantee(checkReceiverSpecialAccess(stackOp), "Invalid use of INVOKESPECIAL");
}
if (!(returnOp == Void)) {
stack.push(returnOp);
}
}
use of com.oracle.truffle.espresso.descriptors.Symbol.Type in project graal by oracle.
the class ClassInfo method create.
public static HotSwapClassInfo create(ObjectKlass klass, Symbol<Name> name, byte[] bytes, StaticObject definingLoader, EspressoContext context) {
Symbol<Type> type = context.getTypes().fromName(name);
ParserKlass parserKlass = ClassfileParser.parse(new ClassfileStream(bytes, null), definingLoader, type, context);
StringBuilder hierarchy = new StringBuilder();
StringBuilder methods = new StringBuilder();
StringBuilder fields = new StringBuilder();
StringBuilder enclosing = new StringBuilder();
Matcher matcher = InnerClassRedefiner.ANON_INNER_CLASS_PATTERN.matcher(name.toString());
if (matcher.matches()) {
// fingerprints are only relevant for inner classes
hierarchy.append(parserKlass.getSuperKlass().toString()).append(";");
for (Symbol<Type> itf : parserKlass.getSuperInterfaces()) {
hierarchy.append(itf.toString()).append(";");
}
for (ParserMethod method : parserKlass.getMethods()) {
methods.append(method.getName().toString()).append(";");
methods.append(method.getSignature().toString()).append(";");
}
for (ParserField field : parserKlass.getFields()) {
fields.append(field.getType().toString()).append(";");
fields.append(field.getName().toString()).append(";");
}
ConstantPool pool = parserKlass.getConstantPool();
EnclosingMethodAttribute attr = (EnclosingMethodAttribute) parserKlass.getAttribute(EnclosingMethodAttribute.NAME);
NameAndTypeConstant nmt = pool.nameAndTypeAt(attr.getMethodIndex());
enclosing.append(nmt.getName(pool)).append(";").append(nmt.getDescriptor(pool));
}
return new HotSwapClassInfo(klass, name, definingLoader, hierarchy.toString(), methods.toString(), fields.toString(), enclosing.toString(), new ArrayList<>(1), bytes);
}
use of com.oracle.truffle.espresso.descriptors.Symbol.Type in project graal by oracle.
the class EspressoContext method spawnVM.
@SuppressWarnings("try")
private void spawnVM() {
try (DebugCloseable spawn = SPAWN_VM.scope(timers)) {
long initStartTimeNanos = System.nanoTime();
this.nativeAccess = spawnNativeAccess();
initVmProperties();
// Spawn JNI first, then the VM.
try (DebugCloseable vmInit = VM_INIT.scope(timers)) {
// Mokapot is loaded
this.vm = VM.create(getJNI());
vm.attachThread(Thread.currentThread());
}
if (getJavaVersion().modulesEnabled()) {
registries.initJavaBaseModule();
registries.getBootClassRegistry().initUnnamedModule(StaticObject.NULL);
}
// TODO: link libjimage
initializeAgents();
try (DebugCloseable metaInit = META_INIT.scope(timers)) {
this.meta = new Meta(this);
}
this.metaInitialized = true;
this.threads = new ThreadsAccess(meta);
this.blockingSupport = BlockingSupport.create(threads);
this.interpreterToVM = new InterpreterToVM(this);
try (DebugCloseable knownClassInit = KNOWN_CLASS_INIT.scope(timers)) {
initializeKnownClass(Type.java_lang_Object);
for (Symbol<Type> type : Arrays.asList(Type.java_lang_String, Type.java_lang_System, // JDK-8069005
Type.java_lang_Class, Type.java_lang_ThreadGroup, Type.java_lang_Thread)) {
initializeKnownClass(type);
}
}
if (meta.jdk_internal_misc_UnsafeConstants != null) {
initializeKnownClass(Type.jdk_internal_misc_UnsafeConstants);
UnsafeAccess.initializeGuestUnsafeConstants(meta);
}
// Create main thread as soon as Thread class is initialized.
threadRegistry.createMainThread(meta);
try (DebugCloseable knownClassInit = KNOWN_CLASS_INIT.scope(timers)) {
initializeKnownClass(Type.java_lang_Object);
for (Symbol<Type> type : Arrays.asList(Type.java_lang_reflect_Method, Type.java_lang_ref_Finalizer)) {
initializeKnownClass(type);
}
}
referenceDrainer.initReferenceDrain();
try (DebugCloseable systemInit = SYSTEM_INIT.scope(timers)) {
// Call guest initialization
if (getJavaVersion().java8OrEarlier()) {
meta.java_lang_System_initializeSystemClass.invokeDirect(null);
} else {
assert getJavaVersion().java9OrLater();
meta.java_lang_System_initPhase1.invokeDirect(null);
int e = (int) meta.java_lang_System_initPhase2.invokeDirect(null, false, false);
if (e != 0) {
throw EspressoError.shouldNotReachHere();
}
getVM().getJvmti().postVmStart();
modulesInitialized = true;
meta.java_lang_System_initPhase3.invokeDirect(null);
}
}
getVM().getJvmti().postVmInit();
meta.postSystemInit();
try (DebugCloseable knownClassInit = KNOWN_CLASS_INIT.scope(timers)) {
// System exceptions.
for (Symbol<Type> type : Arrays.asList(Type.java_lang_OutOfMemoryError, Type.java_lang_NullPointerException, Type.java_lang_ClassCastException, Type.java_lang_ArrayStoreException, Type.java_lang_ArithmeticException, Type.java_lang_StackOverflowError, Type.java_lang_IllegalMonitorStateException, Type.java_lang_IllegalArgumentException)) {
initializeKnownClass(type);
}
}
// Init memoryError instances
StaticObject stackOverflowErrorInstance = meta.java_lang_StackOverflowError.allocateInstance();
StaticObject outOfMemoryErrorInstance = meta.java_lang_OutOfMemoryError.allocateInstance();
// Preemptively set stack trace.
meta.HIDDEN_FRAMES.setHiddenObject(stackOverflowErrorInstance, VM.StackTrace.EMPTY_STACK_TRACE);
meta.java_lang_Throwable_backtrace.setObject(stackOverflowErrorInstance, stackOverflowErrorInstance);
meta.HIDDEN_FRAMES.setHiddenObject(outOfMemoryErrorInstance, VM.StackTrace.EMPTY_STACK_TRACE);
meta.java_lang_Throwable_backtrace.setObject(outOfMemoryErrorInstance, outOfMemoryErrorInstance);
this.stackOverflow = EspressoException.wrap(stackOverflowErrorInstance, meta);
this.outOfMemory = EspressoException.wrap(outOfMemoryErrorInstance, meta);
meta.java_lang_StackOverflowError.lookupDeclaredMethod(Name._init_, Signature._void_String).invokeDirect(stackOverflowErrorInstance, meta.toGuestString("VM StackOverFlow"));
meta.java_lang_OutOfMemoryError.lookupDeclaredMethod(Name._init_, Signature._void_String).invokeDirect(outOfMemoryErrorInstance, meta.toGuestString("VM OutOfMemory"));
// Create application (system) class loader.
StaticObject systemClassLoader = null;
try (DebugCloseable systemLoader = SYSTEM_CLASSLOADER.scope(timers)) {
systemClassLoader = (StaticObject) meta.java_lang_ClassLoader_getSystemClassLoader.invokeDirect(null);
}
topBindings = new EspressoBindings(systemClassLoader, getEnv().getOptions().get(EspressoOptions.ExposeNativeJavaVM));
initDoneTimeNanos = System.nanoTime();
long elapsedNanos = initDoneTimeNanos - initStartTimeNanos;
getLogger().log(Level.FINE, "VM booted in {0} ms", TimeUnit.NANOSECONDS.toMillis(elapsedNanos));
}
}
Aggregations