Skip to content

IsolateThread

opencode-agent[bot] edited this page May 10, 2026 · 1 revision

IsolateThread

Thread wrapper for isolated execution contexts with dual-statics architecture. IsolateThread provides the execution mechanism for isolated environments, managing separate static fields and execution contexts while sharing kernel resources.

Overview

IsolateThread (core/src/core/org/jnode/vm/isolate/IsolateThread.java) is the thread type used to start a new isolate in JNode. It extends java.lang.Thread and serves as the entry point for isolate execution, wrapping the main thread of each isolate with isolate-specific I/O streams, plugin manager reference, and most critically, the isolate's VmIsolatedStatics table.

When a new isolate is started via VmIsolate.start(), the VM creates an IsolateThread as the isolate's main thread. The IsolateThread constructor passes the isolate's VmIsolatedStatics table to the underlying Thread via super(group, null, isolate.getMainClassName(), isolate.getIsolatedStaticsTable()). This statics table becomes the thread's "isolated statics" reference, which is switched when the thread enters or exits an isolate context.

Each IsolateThread also carries redirectable standard I/O streams (stdout, stderr, stdin) bound at construction time via VmStreamBindings. This ensures isolate output is isolated from the parent isolate's console. Additionally, it holds a reference to the PluginManager to support plugin loading within the isolate.

Key Components

Class / FileRole
core/src/core/org/jnode/vm/isolate/IsolateThread.javaThread wrapper implementation — constructor binds I/O and statics table, run() delegates to VmIsolate.run()
core/src/core/org/jnode/vm/isolate/VmIsolate.javaIsolate context management — owns the VmIsolatedStatics table, creates IsolateThread, lifecycle state machine
core/src/core/org/jnode/vm/isolate/IsolateThreadFactory.javaFactory pattern for creating Thread instances that belong to a specific isolate's statics table
core/src/core/org/jnode/vm/isolate/VmStreamBindings.javaPer-isolate stdin/stdout/stderr redirection
core/src/core/org/jnode/vm/memmgr/VmIsolatedStatics.javaPer-isolate static field storage (131,072 slots)

How It Works

IsolateThread Creation and Startup

When VmIsolate.start() is called, it performs the following steps to create and start the main thread:

// Create a new ThreadGroup rooted under the system isolatethis.threadGroup = newThreadGroup(StaticData.getRoot().threadGroup, mainClass);
// Create redirectable I/O streams for this isolatefinalPrintStreamstdout = bindings.createIsolatedOut();
finalPrintStreamstderr = bindings.createIsolatedErr();
finalInputStreamstdin = bindings.createIsolatedIn();
// Create the main IsolateThread, binding the isolate's statics tablefinalIsolateThreadmainThread = newIsolateThread(
threadGroup, this, piManager, stdout, stderr, stdin);
// Start the threadmainThread.start();

The run() Method

The IsolateThread.run() method is deliberately simple — it delegates to VmIsolate.run():

@Overridepublicfinalvoidrun() {
isolate.run(this);
}

VmIsolate.run() then:

  1. Sets IsolatedStaticData.current = VmIsolate.this as the current isolate
  2. Redirects System.setOut/setErr/setIn to the thread's isolated streams
  3. Sets system properties from the isolate's initial properties
  4. Sets the context classloader to an isolate-specific classloader
  5. Loads and invokes the main class's main(String[]) method

Thread Group and Statics Binding

The IsolateThread constructor passes the statics table to the underlying Thread constructor:

IsolateThread(ThreadGroupgroup, VmIsolateisolate,
PluginManagerpiManager, PrintStreamstdout, PrintStreamstderr,
InputStreamstdin) {
super(group, null, isolate.getMainClassName(),
isolate.getIsolatedStaticsTable());
this.isolate = isolate;
// ...
}

The fourth argument to Thread — the VmIsolatedStatics table — is stored as the thread's inherited access control context and is used by VmThread.switchToIsolate() to update the processor's statics reference when switching between isolates.

I/O Stream Redirection

A notable side effect in the constructor: it immediately redirects System.in/out/err to the isolated streams:

System.setIn(stdin);
System.setOut(stdout);
System.setErr(stderr);

This is marked with a // TODO crawley, review this comment indicating this side effect during thread construction may have unintended consequences.

Gotchas & Non-Obvious Behavior

  • Statics table passed to Thread constructor — The VmIsolatedStatics table is not directly stored in IsolateThread but is passed to the underlying Thread constructor. The VM scheduler retrieves it via VmThread.getIsolatedStatics() when context-switching.
  • Side-effecting constructorIsolateThread's constructor calls System.setIn/setOut/setErr, which affects the creating thread's System streams, not just the new thread's. This is a known concern flagged by the TODO comment.
  • No override of Thread.interrupt()IsolateThread does not override interrupt(). Thread termination uses ThreadGroup.stop() in VmIsolate.halt() and stopAllThreads().
  • ThreadGroup hierarchy — All isolate thread groups are nested under the root isolate's thread group, but each isolate has its own VmIsolatedStatics table, providing the isolation boundary.
  • Root isolate has no IsolateThread — The root isolate (kernel) runs in the primordial thread created by the boot sequence, not via IsolateThread. Only child isolates use IsolateThread as their main thread.

Related Pages

Clone this wiki locally