Runtime.JS
V8 JavaScript kernel
2014
This talk:
- focused on server JavaScript
- includes low-level technical details
- about open-source project
Runtime.JS is an operating system kernel built on V8 engine
Runtime.JS:
- system optimized to run JavaScript applications
- can execute JavaScript only
- non-blocking and asynchronous I/O from the ground up
- built from scratch
- only for x86_64
- inspired by Node.JS
What's the problem with existing systems?
... as a platforms for JavaScript applications
Mainstream operating systems are not the most efficient platforms for JavaScript applications
Problems with mainstream systems as a platforms for JavaScript applications:
- designed to solve different problems
- too complex, introduce too many architecture layers
- inefficient API, most system calls block
Problems with mainstream systems as a platforms for JavaScript applications:
- inefficient event notifications (using polling)
- "unsafe" C language at a core
- written mostly by C programmers to run C programs
Software stack (Node + Linux)
JavaScript Application |
Isolate (V8 VM instance) |
← isolation |
Main thread (event loop) |
Thread pool |
← async API |
libuv |
← async API |
Process (node) |
← isolation |
System call API |
← isolation |
Kernel (Linux) |
Hardware |
Process isolation
- protects kernel from applications
- protects applications from each other
- uses an address space for every process
- introduces context switches (usermode and kernelmode, between processes)
- introduces kernel System Call interface
VM isolation (V8)
- JavaScript is "safe" language
- V8 compiles JavaScript into trusted native code
- sandbox, VM controls everything program is allowed to do
- often called "software isolation"
Process vs. VM isolation
- paying twice when using both
- JavaScript VM provides everything process isolation can offer
- process isolation required only for native untrusted code
Runtime.JS is a kernel optimized to run JavaScript applications
Optimizations not available for
general-purpose kernels
- VM isolation/protection system
- JS-optimized kernel interface
- JS objects for applications communication
- kernel notifications using event loop
- kernel-side JavaScript
How does JavaScript kernel look like?
- no binaries support
- no processes
- no process isolation we no longer need
- no legacy POSIX interfaces
- no system calls
How does JavaScript kernel look like?
- software isolated applications (isolates)
- single address space
- builtin V8 engine
- all I/O is non-blocking and asynchronous
- global event loop for the whole system
- lightweight threads for preemptive multitasking
Software stack (Runtime.JS)
JavaScript Application |
Isolate (V8 VM instance) |
System event loop |
Kernel (Runtime) |
Hardware |
Why JavaScript?
- bytecode of the Web
- well tested, runs on almost every device
- easy to write asynchronous I/O code
- powerful enough to write system components
- safe and secure
Software isolated applications
- no processes, just isolates
- each program runs in it's own isolate
- inter-isolate communication (IIC) using RPC
Event loop
- global event loop for the whole system
- each isolate has it's own execution stack (kinda like threads)
- event loop controls and switches between stacks
- possible to interrupt JavaScript execution (v8 RequestInterrupt)
function foo() { for (;;); }
Inter-isolate communication (IIC)
- implemented as RPC (Remote Procedure Calls)
- cross-isolate function calls
- built on JavaScript promises
Inter-isolate communication (IIC)
Synchronous function call example:
Isolate 1:
function add(a, b) {
return a + b;
}
Isolate 2:
var promise = add(1, 2);
promise.then(function(sum) {
// outputs "3"
console.log(sum);
})
Inter-isolate communication (IIC)
Asynchronous function call example:
Isolate 1:
function foo() {
return new Promise(function(resolve) {
setTimeout(resolve, 2000);
});
}
Isolate 2:
var promise = foo();
promise.then(function() {
// outputs "Hello World!" after 2 seconds
console.log('Hello World!');
})
Inter-isolate communication (IIC)
Zero-copy ArrayBuffer transfer example:
Isolate 1:
var buffer = new ArrayBuffer(128);
function getData() {
return buffer;
}
// "buffer.byteLength == 0" after getData() call
Isolate 2:
getData().then(function(buffer) {
// outputs "128"
console.log(buffer.byteLength);
})
Inter-isolate communication (IIC)
Can also pass functions:
Isolate 1:
function foo(name) {
return "Hello " + name + "!";
}
function getFoo() {
return foo;
}
Isolate 2:
getFoo().then(function(foo) {
foo('World').then(function(str) {
// outputs "Hello World!"
console.log(str);
});
})
Isolate API
Functions available to each isolate
// Global isolate object
// Isolate data
isolate.data
// Environment data
isolate.env
// Data provided by kernel
isolate.system
// Exit isolate
isolate.exit()
// Write isolate log
isolate.log()
DEMO
Runtime.JS hosted and should respond to UDP packets
- QEMU/KVM
- Virtio NIC driver
# command line
nc -u runtimetest.org 9000
Project status
- experimental project, in development
- not ready to use (not yet), lacks many important features
- most APIs will probably change
- targets mainly KVM
Runtime.JS benefits
- network-first server system
- safe environment, sandboxed applications
- asynchronous I/O everywhere
- hackable JavaScript, full control over everything
- pretty small (less than 10 MiB)
Future work
- TCP/HTTP protocols
- Filesystems support
- Optimize everything
- Lock APIs
- Xen support
About Node
- not compatible with Node
- provides lower API layer than Node
- might be possible to port Node?
- maybe NPM as system package manager?
Links
Web
- http://runtimejs.org/
GitHub
- https://github.com/runtimejs/runtime