use of com.oracle.truffle.espresso.perf.DebugCloseable 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));
}
}
use of com.oracle.truffle.espresso.perf.DebugCloseable in project graal by oracle.
the class ClassRegistry method createKlass.
@SuppressWarnings("try")
private ObjectKlass createKlass(Meta meta, ParserKlass parserKlass, Symbol<Type> type, Symbol<Type> superKlassType, ClassDefinitionInfo info) {
EspressoThreadLocalState threadLocalState = meta.getContext().getLanguage().getThreadLocalState();
TypeStack chain = threadLocalState.getTypeStack();
ObjectKlass superKlass = null;
ObjectKlass[] superInterfaces = null;
LinkedKlass[] linkedInterfaces = null;
chain.push(type);
try {
if (superKlassType != null) {
if (chain.contains(superKlassType)) {
throw meta.throwException(meta.java_lang_ClassCircularityError);
}
superKlass = loadKlassRecursively(meta, superKlassType, true);
}
final Symbol<Type>[] superInterfacesTypes = parserKlass.getSuperInterfaces();
linkedInterfaces = superInterfacesTypes.length == 0 ? LinkedKlass.EMPTY_ARRAY : new LinkedKlass[superInterfacesTypes.length];
superInterfaces = superInterfacesTypes.length == 0 ? ObjectKlass.EMPTY_ARRAY : new ObjectKlass[superInterfacesTypes.length];
for (int i = 0; i < superInterfacesTypes.length; ++i) {
if (chain.contains(superInterfacesTypes[i])) {
throw meta.throwException(meta.java_lang_ClassCircularityError);
}
ObjectKlass interf = loadKlassRecursively(meta, superInterfacesTypes[i], false);
superInterfaces[i] = interf;
linkedInterfaces[i] = interf.getLinkedKlass();
}
} finally {
chain.pop();
}
if (getContext().getJavaVersion().java16OrLater() && superKlass != null) {
if (superKlass.isFinalFlagSet()) {
throw meta.throwExceptionWithMessage(meta.java_lang_IncompatibleClassChangeError, "class " + type + " is a subclass of final class " + superKlassType);
}
}
ObjectKlass klass;
try (DebugCloseable define = KLASS_DEFINE.scope(context.getTimers())) {
// FIXME(peterssen): Do NOT create a LinkedKlass every time, use a global cache.
ContextDescription description = new ContextDescription(context.getLanguage(), context.getJavaVersion());
LinkedKlass linkedKlass = LinkedKlass.create(description, parserKlass, superKlass == null ? null : superKlass.getLinkedKlass(), linkedInterfaces);
klass = new ObjectKlass(context, linkedKlass, superKlass, superInterfaces, getClassLoader(), info);
}
if (superKlass != null) {
if (!Klass.checkAccess(superKlass, klass)) {
throw meta.throwExceptionWithMessage(meta.java_lang_IllegalAccessError, "class " + type + " cannot access its superclass " + superKlassType);
}
if (!superKlass.permittedSubclassCheck(klass)) {
throw meta.throwExceptionWithMessage(meta.java_lang_IncompatibleClassChangeError, "class " + type + " is not a permitted subclass of class " + superKlassType);
}
}
for (ObjectKlass interf : superInterfaces) {
if (interf != null) {
if (!Klass.checkAccess(interf, klass)) {
throw meta.throwExceptionWithMessage(meta.java_lang_IllegalAccessError, "class " + type + " cannot access its superinterface " + interf.getType());
}
if (!interf.permittedSubclassCheck(klass)) {
throw meta.throwExceptionWithMessage(meta.java_lang_IncompatibleClassChangeError, "class " + type + " is not a permitted subclass of interface " + superKlassType);
}
}
}
return klass;
}
use of com.oracle.truffle.espresso.perf.DebugCloseable in project graal by oracle.
the class ClassRegistry method defineKlass.
@SuppressWarnings("try")
public ObjectKlass defineKlass(Symbol<Type> typeOrNull, final byte[] bytes, ClassDefinitionInfo info) {
Meta meta = getMeta();
ParserKlass parserKlass;
try (DebugCloseable parse = KLASS_PARSE.scope(getContext().getTimers())) {
parserKlass = getParserKlass(bytes, typeOrNull, info);
}
Symbol<Type> type = typeOrNull == null ? parserKlass.getType() : typeOrNull;
if (info.addedToRegistry()) {
Klass maybeLoaded = findLoadedKlass(type);
if (maybeLoaded != null) {
throw meta.throwExceptionWithMessage(meta.java_lang_LinkageError, "Class " + type + " already defined");
}
}
Symbol<Type> superKlassType = parserKlass.getSuperKlass();
ObjectKlass klass = createKlass(meta, parserKlass, type, superKlassType, info);
if (info.addedToRegistry()) {
registerKlass(klass, type);
} else if (info.isStrongHidden()) {
registerStrongHiddenClass(klass);
}
return klass;
}
use of com.oracle.truffle.espresso.perf.DebugCloseable in project graal by oracle.
the class ClassfileParser method parseMethod.
private ParserMethod parseMethod(boolean isInterface) {
int methodFlags = stream.readU2();
int nameIndex = stream.readU2();
int signatureIndex = stream.readU2();
final Symbol<Name> name;
final Symbol<Signature> signature;
int attributeCount;
Attribute[] methodAttributes;
int extraFlags = methodFlags;
boolean isClinit = false;
boolean isInit = false;
try (DebugCloseable closeable = METHOD_INIT.scope(context.getTimers())) {
try (DebugCloseable nameCheck = NAME_CHECK.scope(context.getTimers())) {
pool.utf8At(nameIndex).validateMethodName(true);
name = pool.symbolAt(nameIndex, "method name");
if (name.equals(Name._clinit_)) {
// ACC_STRICT flag.
if (majorVersion < JAVA_7_VERSION) {
// Backwards compatibility.
methodFlags = ACC_STATIC;
} else if ((methodFlags & ACC_STATIC) == ACC_STATIC) {
methodFlags &= (ACC_STRICT | ACC_STATIC);
} else if (context.getJavaVersion().java9OrLater()) {
throw ConstantPool.classFormatError("Method <clinit> is not static.");
}
// extraFlags = INITIALIZER | methodFlags;
isClinit = true;
} else if (name.equals(Name._init_)) {
if (isInterface) {
throw ConstantPool.classFormatError("Method <init> is not valid in an interface.");
}
isInit = true;
}
}
final boolean isStatic = Modifier.isStatic(extraFlags);
verifyMethodFlags(methodFlags, isInterface, isInit, isClinit, majorVersion);
/*
* A method is a class or interface initialization method if all of the following are
* true:
*
* It has the special name <clinit>.
*
* It is void (4.3.3). (checked earlier)
*
* In a class file whose version number is 51.0 or above, the method has its ACC_STATIC
* flag set and takes no arguments (4.6).
*/
try (DebugCloseable signatureCheck = SIGNATURE_CHECK.scope(context.getTimers())) {
// Checks for void method if init or clinit.
/*
* Obtain slot number for the signature. Forces a validation, but better in startup
* than going twice through the sequence, once for validation, once for slots.
*/
int slots = pool.utf8At(signatureIndex).validateSignatureGetSlots(isInit || isClinit);
signature = Signatures.check(pool.symbolAt(signatureIndex, "method descriptor"));
if (isClinit && majorVersion >= JAVA_7_VERSION) {
// Checks clinit takes no arguments.
if (!signature.equals(Signature._void)) {
throw ConstantPool.classFormatError("Method <clinit> has invalid signature: " + signature);
}
}
if (slots + (isStatic ? 0 : 1) > 255) {
throw ConstantPool.classFormatError("Too many arguments in method signature: " + signature);
}
if (name.equals(Name.finalize) && signature.equals(Signature._void) && !Modifier.isStatic(methodFlags) && !Type.java_lang_Object.equals(classType)) {
// This class has a finalizer method implementation (ignore for
// java.lang.Object).
classFlags |= ACC_FINALIZER;
}
}
attributeCount = stream.readU2();
methodAttributes = spawnAttributesArray(attributeCount);
}
CodeAttribute codeAttribute = null;
Attribute checkedExceptions = null;
Attribute runtimeVisibleAnnotations = null;
CommonAttributeParser commonAttributeParser = new CommonAttributeParser(InfoType.Method);
MethodParametersAttribute methodParameters = null;
for (int i = 0; i < attributeCount; ++i) {
final int attributeNameIndex = stream.readU2();
final Symbol<Name> attributeName = pool.symbolAt(attributeNameIndex, "attribute name");
final int attributeSize = stream.readS4();
final int startPosition = stream.getPosition();
if (attributeName.equals(Name.Code)) {
if (codeAttribute != null) {
throw ConstantPool.classFormatError("Duplicate Code attribute");
}
try (DebugCloseable code = CODE_PARSE.scope(context.getTimers())) {
methodAttributes[i] = codeAttribute = parseCodeAttribute(attributeName);
}
} else if (attributeName.equals(Name.Exceptions)) {
if (checkedExceptions != null) {
throw ConstantPool.classFormatError("Duplicate Exceptions attribute");
}
methodAttributes[i] = checkedExceptions = parseExceptions(attributeName);
} else if (attributeName.equals(Name.Synthetic)) {
methodFlags |= ACC_SYNTHETIC;
methodAttributes[i] = checkedExceptions = new Attribute(attributeName, null);
} else if (majorVersion >= JAVA_1_5_VERSION) {
if (attributeName.equals(Name.RuntimeVisibleAnnotations)) {
if (runtimeVisibleAnnotations != null) {
throw ConstantPool.classFormatError("Duplicate RuntimeVisibleAnnotations attribute");
}
// Check if java.lang.invoke.LambdaForm.Compiled is present here.
byte[] data = stream.readByteArray(attributeSize);
ClassfileStream subStream = new ClassfileStream(data, this.classfile);
int count = subStream.readU2();
for (int j = 0; j < count; j++) {
int typeIndex = parseAnnotation(subStream);
Utf8Constant constant = pool.utf8At(typeIndex, "annotation type");
// Validation of the type is done at runtime by guest java code.
Symbol<Type> annotType = constant.value();
if (Type.java_lang_invoke_LambdaForm$Compiled.equals(annotType)) {
methodFlags |= ACC_LAMBDA_FORM_COMPILED;
} else if (Type.java_lang_invoke_LambdaForm$Hidden.equals(annotType) || Type.jdk_internal_vm_annotation_Hidden.equals(annotType)) {
methodFlags |= ACC_HIDDEN;
} else if (Type.sun_reflect_CallerSensitive.equals(annotType) || Type.jdk_internal_reflect_CallerSensitive.equals(annotType)) {
methodFlags |= ACC_CALLER_SENSITIVE;
}
}
methodAttributes[i] = runtimeVisibleAnnotations = new Attribute(attributeName, data);
} else if (attributeName.equals(Name.MethodParameters)) {
if (methodParameters != null) {
throw ConstantPool.classFormatError("Duplicate MethodParameters attribute");
}
methodAttributes[i] = methodParameters = parseMethodParameters(attributeName);
} else {
Attribute attr = commonAttributeParser.parseCommonAttribute(attributeName, attributeSize);
// stream.skip(attributeSize);
methodAttributes[i] = attr == null ? new Attribute(attributeName, stream.readByteArray(attributeSize)) : attr;
}
} else {
// stream.skip(attributeSize);
methodAttributes[i] = new Attribute(attributeName, stream.readByteArray(attributeSize));
}
final int distance = stream.getPosition() - startPosition;
if (attributeSize != distance) {
final String message = "Invalid attribute_length for " + attributeName + " attribute (reported " + attributeSize + " != parsed " + distance + ")";
throw ConstantPool.classFormatError(message);
}
}
if (Modifier.isAbstract(methodFlags) || Modifier.isNative(methodFlags)) {
if (codeAttribute != null) {
throw ConstantPool.classFormatError("Code attribute supplied for native or abstract method");
}
} else {
if (codeAttribute == null) {
throw ConstantPool.classFormatError("Missing Code attribute");
}
}
if (classDefinitionInfo.isHidden()) {
methodFlags |= ACC_HIDDEN;
}
return ParserMethod.create(methodFlags, name, signature, methodAttributes);
}
use of com.oracle.truffle.espresso.perf.DebugCloseable in project graal by oracle.
the class ClassfileParser method parseMethods.
private ParserMethod[] parseMethods(boolean isInterface) {
int methodCount = stream.readU2();
if (methodCount == 0) {
return ParserMethod.EMPTY_ARRAY;
}
ParserMethod[] methods = new ParserMethod[methodCount];
/*
* Classes in general have lots of methods: use a hash set rather than array lookup for dup
* check.
*/
final HashSet<MethodKey> dup = new HashSet<>(methodCount);
for (int i = 0; i < methodCount; ++i) {
ParserMethod method;
try (DebugCloseable closeable = PARSE_SINGLE_METHOD.scope(context.getTimers())) {
method = parseMethod(isInterface);
}
methods[i] = method;
try (DebugCloseable closeable = NO_DUP_CHECK.scope(context.getTimers())) {
if (!dup.add(new MethodKey(method))) {
throw ConstantPool.classFormatError("Duplicate method name and signature: " + method.getName() + " " + method.getSignature());
}
}
}
return methods;
}
Aggregations