use of com.oracle.truffle.espresso.runtime.StaticObject in project graal by oracle.
the class EspressoThreadRegistry method createGuestThreadFromHost.
public StaticObject createGuestThreadFromHost(Thread hostThread, Meta meta, VM vm, String name, StaticObject threadGroup) {
if (meta == null) {
// Don't attempt guest thread creation
return null;
}
synchronized (activeThreadLock) {
StaticObject exisitingThread = getGuestThreadFromHost(hostThread);
if (exisitingThread != null) {
// already a live guest thread for this host thread
return exisitingThread;
}
vm.attachThread(hostThread);
StaticObject guestThread = meta.java_lang_Thread.allocateInstance();
// Allow guest Thread.currentThread() to work.
meta.java_lang_Thread_priority.setInt(guestThread, Thread.NORM_PRIORITY);
meta.HIDDEN_HOST_THREAD.setHiddenObject(guestThread, Thread.currentThread());
// register the new guest thread
registerThread(hostThread, guestThread);
if (name == null) {
meta.java_lang_Thread_init_ThreadGroup_Runnable.invokeDirect(guestThread, mainThreadGroup, StaticObject.NULL);
} else {
meta.java_lang_Thread_init_ThreadGroup_String.invokeDirect(guestThread, threadGroup, meta.toGuestString(name));
}
meta.java_lang_Thread_threadStatus.setInt(guestThread, State.RUNNABLE.value);
// now add to the main thread group
meta.java_lang_ThreadGroup_add.invokeDirect(threadGroup, guestThread);
logger.fine(() -> {
String guestName = getThreadAccess().getThreadName(guestThread);
long guestId = getThreadAccess().getThreadId(guestThread);
return String.format("createGuestThreadFromHost: [HOST:%s, %d], [GUEST:%s, %d]", hostThread.getName(), hostThread.getId(), guestName, guestId);
});
return guestThread;
}
}
use of com.oracle.truffle.espresso.runtime.StaticObject in project graal by oracle.
the class EspressoThreadRegistry method createMainThread.
/**
* The order in which methods are called and fields are set here is important, it mimics
* HotSpot's implementation.
*/
public void createMainThread(Meta meta) {
StaticObject systemThreadGroup = meta.java_lang_ThreadGroup.allocateInstance();
// private
meta.java_lang_ThreadGroup.lookupDeclaredMethod(Symbol.Name._init_, Symbol.Signature._void).invokeDirect(systemThreadGroup);
Thread hostThread = Thread.currentThread();
StaticObject mainThread = meta.java_lang_Thread.allocateInstance();
// Allow guest Thread.currentThread() to work.
meta.java_lang_Thread_priority.setInt(mainThread, Thread.NORM_PRIORITY);
meta.HIDDEN_HOST_THREAD.setHiddenObject(mainThread, hostThread);
mainThreadGroup = meta.java_lang_ThreadGroup.allocateInstance();
registerMainThread(hostThread, mainThread);
// Guest Thread.currentThread() must work as this point.
// public ThreadGroup(ThreadGroup parent, String name)
meta.java_lang_ThreadGroup.lookupDeclaredMethod(Symbol.Name._init_, //
Symbol.Signature._void_ThreadGroup_String).invokeDirect(mainThreadGroup, /* parent */
systemThreadGroup, /* name */
meta.toGuestString("main"));
// public Thread(ThreadGroup group, String name)
meta.java_lang_Thread.lookupDeclaredMethod(Symbol.Name._init_, //
Symbol.Signature._void_ThreadGroup_String).invokeDirect(mainThread, /* group */
mainThreadGroup, /* name */
meta.toGuestString("main"));
meta.java_lang_Thread_threadStatus.setInt(mainThread, State.RUNNABLE.value);
// Notify native backend about main thread.
getNativeAccess().prepareThread();
mainThreadCreated = true;
logger.fine(() -> {
String guestName = getThreadAccess().getThreadName(mainThread);
long guestId = getThreadAccess().getThreadId(mainThread);
return String.format("createMainThread: [HOST:%s, %d], [GUEST:%s, %d]", hostThread.getName(), hostThread.getId(), guestName, guestId);
});
}
use of com.oracle.truffle.espresso.runtime.StaticObject in project graal by oracle.
the class EspressoThreadRegistry method refactorGuestThreads.
private void refactorGuestThreads(int id, StaticObject self) {
assert Thread.holdsLock(activeThreadLock);
Object[] oldThreads = guestThreads;
int minID = id;
int maxID = id;
ArrayList<StaticObject> toRelocate = new ArrayList<>();
for (int i = 1; i < oldThreads.length; i++) {
if (oldThreads[i] != null) {
StaticObject guestThread = (StaticObject) oldThreads[i];
if (getThreadAccess().isAlive(guestThread)) {
Thread hostThread = getThreadAccess().getHost(guestThread);
int hostID = (int) hostThread.getId();
if (hostID < minID) {
minID = hostID;
}
if (hostID > maxID) {
maxID = hostID;
}
toRelocate.add(guestThread);
}
}
}
int span = maxID - minID;
// To store the offset.
int newLength = 1;
// To store what we currently have.
newLength += span;
// Some leeway
newLength += Math.max(toRelocate.size() + 1, span / 2);
// If all other threads are terminated, span is 0. have at least the original default size.
newLength = Math.max(newLength, DEFAULT_THREAD_ARRAY_SIZE);
// Create the new thread array.
Object[] newThreads = new Object[newLength];
int newOffset = minID - 1;
newThreads[0] = newOffset;
for (StaticObject guestThread : toRelocate) {
int hostId = (int) context.getThreadAccess().getHost(guestThread).getId();
newThreads[hostId - newOffset] = guestThread;
}
newThreads[id - newOffset] = self;
guestThreads = newThreads;
}
use of com.oracle.truffle.espresso.runtime.StaticObject in project graal by oracle.
the class ThreadsAccess method guestInterrupt.
@Override
public void guestInterrupt(Thread t, StaticObject guest) {
StaticObject g = guest;
if (g == null) {
g = getThreadFromHost(t);
}
doInterrupt(g);
}
use of com.oracle.truffle.espresso.runtime.StaticObject in project graal by oracle.
the class Target_sun_reflect_NativeMethodAccessorImpl method invoke0.
/**
* Invokes the underlying method represented by this {@code Method} object, on the specified
* object with the specified parameters. Individual parameters are automatically unwrapped to
* match primitive formal parameters, and both primitive and reference parameters are subject to
* method invocation conversions as necessary.
*
* <p>
* If the underlying method is static, then the specified {@code receiver} argument is ignored.
* It may be null.
*
* <p>
* If the number of formal parameters required by the underlying method is 0, the supplied
* {@code args} array may be of length 0 or null.
*
* <p>
* If the underlying method is an instance method, it is invoked using dynamic method lookup as
* documented in The Java Language Specification, Second Edition, section 15.12.4.4; in
* particular, overriding based on the runtime type of the target object will occur.
*
* <p>
* If the underlying method is static, the class that declared the method is initialized if it
* has not already been initialized.
*
* <p>
* If the method completes normally, the value it returns is returned to the caller of invoke;
* if the value has a primitive type, it is first appropriately wrapped in an object. However,
* if the value has the type of an array of a primitive type, the elements of the array are
* <i>not</i> wrapped in objects; in other words, an array of primitive type is returned. If the
* underlying method return type is void, the invocation returns null.
*
* @param receiver the object the underlying method is invoked from
* @param args the arguments used for the method call
* @return the result of dispatching the method represented by this object on {@code receiver}
* with parameters {@code args}
*
* IllegalAccessException if this {@code Method} object is enforcing Java language
* access control and the underlying method is inaccessible.
*
* IllegalArgumentException if the method is an instance method and the specified object
* argument is not an instance of the class or interface declaring the underlying method
* (or of a subclass or implementor thereof); if the number of actual and formal
* parameters differ; if an unwrapping conversion for primitive arguments fails; or if,
* after possible unwrapping, a parameter value cannot be converted to the corresponding
* formal parameter type by a method invocation conversion. // @exception
* InvocationTargetException if the underlying method throws an exception.
*
* NullPointerException if the specified object is null and the method is an instance
* method. exception ExceptionInInitializerError if the initialization provoked by this
* method fails.
*/
@Substitution
@JavaType(Object.class)
public static StaticObject invoke0(@JavaType(java.lang.reflect.Method.class) StaticObject guestMethod, @JavaType(Object.class) StaticObject receiver, @JavaType(Object[].class) StaticObject args, @Inject Meta meta) {
StaticObject curMethod = guestMethod;
Method reflectedMethod = null;
while (reflectedMethod == null) {
reflectedMethod = (Method) meta.HIDDEN_METHOD_KEY.getHiddenObject(curMethod);
if (reflectedMethod == null) {
curMethod = meta.java_lang_reflect_Method_root.getObject(curMethod);
}
}
Klass klass = meta.java_lang_reflect_Method_clazz.getObject(guestMethod).getMirrorKlass();
if (klass == meta.java_lang_invoke_MethodHandle && (reflectedMethod.getName() == Name.invoke || reflectedMethod.getName() == Name.invokeExact)) {
StaticObject cause = Meta.initExceptionWithMessage(meta.java_lang_UnsupportedOperationException, "Cannot reflectively invoke MethodHandle.{invoke,invokeExact}");
StaticObject invocationTargetException = Meta.initExceptionWithCause(meta.java_lang_reflect_InvocationTargetException, cause);
throw meta.throwException(invocationTargetException);
}
StaticObject parameterTypes = meta.java_lang_reflect_Method_parameterTypes.getObject(guestMethod);
StaticObject result = callMethodReflectively(meta, receiver, args, reflectedMethod, klass, parameterTypes);
return result;
}
Aggregations