Skip to content

Commit

Permalink
[GR-9200] Eagerly allocate java.lang.Thread instance for each thread.
Browse files Browse the repository at this point in the history
PullRequest: graal/3681
  • Loading branch information
Christian Wimmer committed May 28, 2019
2 parents 8d7e1a9 + 6c2e0dd commit 794acd7
Show file tree
Hide file tree
Showing 30 changed files with 1,043 additions and 709 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public static final class Prologue {
"Failed to enter (or attach to) the global isolate in the current thread.");

static void enter() {
int code = CEntryPointActions.enterAttachThread(GLOBAL_ISOLATE.get().read());
int code = CEntryPointActions.enterAttachThread(GLOBAL_ISOLATE.get().read(), true);
if (code != 0) {
CEntryPointActions.failFatally(code, errorMessage.get());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,29 @@ public enum EnterAction {
protected final EnterAction enterAction;

@OptionalInput protected ValueNode parameter;
private final boolean ensureJavaThread;

public CEntryPointEnterNode(EnterAction enterAction, ValueNode parameter) {
public static CEntryPointEnterNode createIsolate(ValueNode parameters) {
return new CEntryPointEnterNode(EnterAction.CreateIsolate, parameters, false);
}

public static CEntryPointEnterNode attachThread(ValueNode isolate, boolean ensureJavaThread) {
return new CEntryPointEnterNode(EnterAction.AttachThread, isolate, ensureJavaThread);
}

public static CEntryPointEnterNode enter(ValueNode isolateThread) {
return new CEntryPointEnterNode(EnterAction.Enter, isolateThread, false);
}

public static CEntryPointEnterNode enterIsolate(ValueNode isolate) {
return new CEntryPointEnterNode(EnterAction.EnterIsolate, isolate, false);
}

protected CEntryPointEnterNode(EnterAction enterAction, ValueNode parameter, boolean ensureJavaThread) {
super(TYPE, StampFactory.forKind(JavaKind.Int));
this.enterAction = enterAction;
this.parameter = parameter;
this.ensureJavaThread = ensureJavaThread;
}

public EnterAction getEnterAction() {
Expand All @@ -72,6 +90,10 @@ public ValueNode getParameter() {
return parameter;
}

public boolean getEnsureJavaThread() {
return ensureJavaThread;
}

@Override
public void lower(LoweringTool tool) {
tool.getLowerer().lower(this, tool);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ public final class CEntryPointSnippets extends SubstrateTemplates implements Sni
public static final SubstrateForeignCallDescriptor CREATE_ISOLATE = SnippetRuntime.findForeignCall(CEntryPointSnippets.class, "createIsolate", false, LocationIdentity.any());
public static final SubstrateForeignCallDescriptor INITIALIZE_ISOLATE = SnippetRuntime.findForeignCall(CEntryPointSnippets.class, "initializeIsolate", false, LocationIdentity.any());
public static final SubstrateForeignCallDescriptor ATTACH_THREAD = SnippetRuntime.findForeignCall(CEntryPointSnippets.class, "attachThread", false, LocationIdentity.any());
public static final SubstrateForeignCallDescriptor ENSURE_JAVA_THREAD = SnippetRuntime.findForeignCall(CEntryPointSnippets.class, "ensureJavaThread", false, LocationIdentity.any());
public static final SubstrateForeignCallDescriptor ENTER_ISOLATE_MT = SnippetRuntime.findForeignCall(CEntryPointSnippets.class, "enterIsolateMT", false, LocationIdentity.any());
public static final SubstrateForeignCallDescriptor DETACH_THREAD_MT = SnippetRuntime.findForeignCall(CEntryPointSnippets.class, "detachThreadMT", false, LocationIdentity.any());
public static final SubstrateForeignCallDescriptor REPORT_EXCEPTION = SnippetRuntime.findForeignCall(CEntryPointSnippets.class, "reportException", false, LocationIdentity.any());
Expand All @@ -111,7 +112,7 @@ public final class CEntryPointSnippets extends SubstrateTemplates implements Sni
public static final SubstrateForeignCallDescriptor FAIL_FATALLY = SnippetRuntime.findForeignCall(CEntryPointSnippets.class, "failFatally", false, LocationIdentity.any());
public static final SubstrateForeignCallDescriptor VERIFY_ISOLATE_THREAD = SnippetRuntime.findForeignCall(CEntryPointSnippets.class, "verifyIsolateThread", false, LocationIdentity.any());

public static final SubstrateForeignCallDescriptor[] FOREIGN_CALLS = {CREATE_ISOLATE, INITIALIZE_ISOLATE, ATTACH_THREAD, ENTER_ISOLATE_MT,
public static final SubstrateForeignCallDescriptor[] FOREIGN_CALLS = {CREATE_ISOLATE, INITIALIZE_ISOLATE, ATTACH_THREAD, ENSURE_JAVA_THREAD, ENTER_ISOLATE_MT,
DETACH_THREAD_MT, REPORT_EXCEPTION, TEAR_DOWN_ISOLATE, IS_ATTACHED_MT, FAIL_FATALLY, VERIFY_ISOLATE_THREAD};

@NodeIntrinsic(value = ForeignCallNode.class)
Expand Down Expand Up @@ -186,29 +187,43 @@ private static int createIsolate(CEntryPointCreateIsolateParameters parameters,
return CEntryPointErrors.THREADING_INITIALIZATION_FAILED;
}
}
return attachThread(isolate.read(), vmThreadSize);
error = attachThread(isolate.read(), vmThreadSize);
if (error != CEntryPointErrors.NO_ERROR) {
return error;
}

JavaThreads.singleton().initializeIsolate();

return CEntryPointErrors.NO_ERROR;
}

@SubstrateForeignCallTarget
private static int initializeIsolate() {
int result = CEntryPointErrors.NO_ERROR;
boolean success = PlatformNativeLibrarySupport.singleton().initializeBuiltinLibraries();
if (!success) {
return CEntryPointErrors.ISOLATE_INITIALIZATION_FAILED;
}
return result;
return CEntryPointErrors.NO_ERROR;
}

@Snippet
public static int attachThreadSnippet(Isolate isolate, @ConstantParameter int vmThreadSize) {
public static int attachThreadSnippet(Isolate isolate, boolean ensureJavaThread, @ConstantParameter int vmThreadSize) {
if (MultiThreaded.getValue()) {
writeCurrentVMThread(VMThreads.nullThread());
}
int result = runtimeCall(ATTACH_THREAD, isolate, vmThreadSize);
if (MultiThreaded.getValue() && result == CEntryPointErrors.NO_ERROR) {

int error = runtimeCall(ATTACH_THREAD, isolate, vmThreadSize);
if (error != CEntryPointErrors.NO_ERROR) {
return error;
}

if (MultiThreaded.getValue()) {
Safepoint.transitionNativeToJava();
}
return result;
if (ensureJavaThread) {
runtimeCallEnsureJavaThread(ENSURE_JAVA_THREAD);
}
return CEntryPointErrors.NO_ERROR;
}

@Uninterruptible(reason = "Thread state not yet set up.")
Expand Down Expand Up @@ -240,6 +255,14 @@ private static int attachThread(Isolate isolate, int vmThreadSize) {
return CEntryPointErrors.NO_ERROR;
}

@NodeIntrinsic(value = ForeignCallNode.class)
public static native void runtimeCallEnsureJavaThread(@ConstantNodeParameter ForeignCallDescriptor descriptor);

@SubstrateForeignCallTarget
private static void ensureJavaThread() {
JavaThreads.ensureJavaThread();
}

@Snippet
public static int detachThreadSnippet() {
int result = CEntryPointErrors.NO_ERROR;
Expand Down Expand Up @@ -489,6 +512,7 @@ public void lower(CEntryPointEnterNode node, LoweringTool tool) {
case AttachThread:
args = new Arguments(attachThread, node.graph().getGuardsStage(), tool.getLoweringStage());
args.add("isolate", node.getParameter());
args.add("ensureJavaThread", node.getEnsureJavaThread());
args.addConst("vmThreadSize", vmThreadSize);
break;
case EnterIsolate:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import com.oracle.svm.core.heap.Heap;
import com.oracle.svm.core.heap.PhysicalMemory;
import com.oracle.svm.core.posix.headers.Unistd;
import com.oracle.svm.core.thread.JavaThreads;
import com.oracle.svm.core.util.UnsignedUtils;

@Platforms(InternalPlatform.LINUX_AND_JNI.class)
Expand All @@ -61,7 +62,7 @@ public UnsignedWord size() {
return getSize();
}
/* If I can not allocate, return MAX_VALUE. */
if (Heap.getHeap().isAllocationDisallowed()) {
if (Heap.getHeap().isAllocationDisallowed() || !JavaThreads.currentJavaThreadInitialized()) {
return UnsignedUtils.MAX_VALUE;
}
/* Compute and cache the physical memory size. Races are idempotent. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ private static class PthreadStartRoutinePrologue {

@SuppressWarnings("unused")
static void enter(ThreadStartData data) {
int code = CEntryPointActions.enterAttachThread(data.getIsolate());
int code = CEntryPointActions.enterAttachThread(data.getIsolate(), false);
if (code != 0) {
CEntryPointActions.failFatally(code, errorMessage.get());
}
Expand All @@ -196,12 +196,10 @@ static WordBase pthreadStartRoutine(ThreadStartData data) {
}

@Override
protected void noteThreadStart(Thread thread) {
protected void beforeThreadRun(Thread thread) {
/* Complete the initialization of the thread, now that it is (nearly) running. */
setPthreadIdentifier(thread, Pthread.pthread_self());
setNativeName(thread, thread.getName());

super.noteThreadStart(thread);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ private static class OSThreadStartRoutinePrologue {

@SuppressWarnings("unused")
static void enter(WindowsThreadStartData data) {
int code = CEntryPointActions.enterAttachThread(data.getIsolate());
int code = CEntryPointActions.enterAttachThread(data.getIsolate(), false);
if (code != 0) {
CEntryPointActions.failFatally(code, errorMessage.get());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,17 +114,9 @@ public List<String> getInputArguments() {
}
}

private static final Thread preallocatedThread;
static {
preallocatedThread = new Thread("main");
preallocatedThread.setDaemon(false);
}

@CEntryPoint
@CEntryPointOptions(prologue = EnterCreateIsolatePrologue.class, include = CEntryPointOptions.NotIncludedAutomatically.class)
public static int run(int paramArgc, CCharPointerPointer paramArgv) throws Exception {
JavaThreads.singleton().assignJavaThread(preallocatedThread, true);

JavaMainWrapper.argc = paramArgc;
JavaMainWrapper.argv = paramArgv;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ private static void dumpVMThreads(Log log) {
log.indent(true);
for (IsolateThread vmThread = VMThreads.firstThread(); vmThread != VMThreads.nullThread(); vmThread = VMThreads.nextThread(vmThread)) {
log.string("VMThread ").zhex(vmThread.rawValue()).spaces(2).string(VMThreads.StatusSupport.getStatusString(vmThread))
.spaces(2).object(JavaThreads.singleton().fromVMThread(vmThread)).newline();
.spaces(2).object(JavaThreads.fromVMThread(vmThread)).newline();
}
log.indent(false);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import org.graalvm.word.WordFactory;

import com.oracle.svm.core.annotate.Uninterruptible;
import com.oracle.svm.core.thread.JavaThreads;

/**
* Advanced entry and leave actions for entry point methods annotated with {@link CEntryPoint}.
Expand All @@ -48,9 +49,9 @@ private CEntryPointActions() {
}

/**
* Creates a new isolate, then {@linkplain #enterAttachThread(Isolate) attaches} the current
* thread to the created isolate, creating a context for the thread in the isolate, and then
* enters that context before returning.
* Creates a new isolate, then {@linkplain #enterAttachThread attaches} the current thread to
* the created isolate, creating a context for the thread in the isolate, and then enters that
* context before returning.
*
* @param params initialization parameters.
* @return 0 on success, otherwise non-zero.
Expand All @@ -62,13 +63,18 @@ private CEntryPointActions() {
* context. If the thread has already been attached, this does not cause the operation to fail.
*
* @param isolate an existing isolate.
* @param ensureJavaThread when set to true, the method ensures that the
* {@link java.lang.Thread} object for the newly attached thread is created. If the
* parameter is set to false, a later call to one of the
* {@link JavaThreads#ensureJavaThread} methods early after the prologue must be used
* to do the initialization manually.
* @return 0 on success, otherwise non-zero.
*/
public static native int enterAttachThread(Isolate isolate);
public static native int enterAttachThread(Isolate isolate, boolean ensureJavaThread);

/**
* Enters an existing context for the current thread (for example, one created with
* {@link #enterAttachThread(Isolate)}).
* {@link #enterAttachThread}).
*
* @param thread existing context for the current thread.
* @return 0 on success, otherwise non-zero.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public static IsolateThread createIsolate() {
@CEntryPointBuiltinImplementation(builtin = Builtin.ATTACH_THREAD)
public static IsolateThread attachThread(Isolate isolate) {
IsolateThread result = WordFactory.nullPointer();
int status = CEntryPointActions.enterAttachThread(isolate);
int status = CEntryPointActions.enterAttachThread(isolate, true);
if (status == 0) {
result = CurrentIsolate.getCurrentThread();
status = CEntryPointActions.leave();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ public static int createIsolate(CEntryPointCreateIsolateParameters params, Isola
"the thread's isolate thread structure."})
@CEntryPointOptions(prologue = NoPrologue.class, epilogue = NoEpilogue.class, nameTransformation = NameTransformation.class)
public static int attachThread(Isolate isolate, IsolateThreadPointer thread) {
int result = CEntryPointActions.enterAttachThread(isolate);
int result = CEntryPointActions.enterAttachThread(isolate, true);
if (result == 0) {
thread.write(CurrentIsolate.getCurrentThread());
result = CEntryPointActions.leave();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -674,7 +674,7 @@ private DeoptimizedFrame deoptSourceFrameOperation(CodePointer pc, boolean ignor
* the same object can be re-locked multiple times, we change the thread after
* all virtual frames have been reconstructed.
*/
ImageSingletons.lookup(MonitorSupport.class).setExclusiveOwnerThread(lockee, JavaThreads.singleton().createIfNotExisting(currentThread));
ImageSingletons.lookup(MonitorSupport.class).setExclusiveOwnerThread(lockee, JavaThreads.fromVMThread(currentThread));
}
}
}
Expand Down
Loading

0 comments on commit 794acd7

Please sign in to comment.