As you say there are basically no threads in JavaScript. Therefore
the threading support in V8 is very simple. Normally you only use V8
in one thread. That's nice and simple. If you want to use more than
one thread you have to make use of the V8::Locker class from
include/v8.h. See that file for more details. This puts a single big
lock around everything V8 does. So although the program as a whole
can have more than one OS thread that uses V8 there can be only one
thread at a given time that is using V8. If the thread owns the mutex
it can use V8, and if it doesn't then it can't. Only one thread can
own the mutex at a time.
> I'm going to assume that the V8 "context" refers to a "web page" (i.e.
> in a browser each web page maps to a single and separate context). My
That's pretty much right. If you have iframes you can have several
contexts active, but that is just a reflection of the fact that an
iframe acts like its own little web page in some ways.
> first question is whether V8 permits multiple threads within a
> context, whether execution of javascript within a context has been
Contexts and threads have nothing to do with each other in V8. A
single thread can handle several contexts (as in Chromium) or a
context could be used by more than one thread. The important thing is
that only one thread is doing V8 stuff at a tme.
> serialized (i.e. if you call a function in a context while a second
> thread is already calling a function in the same context, does the
> second thread block on the first?), and if V8 can somehow permits
> multithreading within a context (which I really doubt), how would the
> javascript code running in the context be affected by this (suddenly
> needing to do its own mutexing?).
>
> The second question has to do with suspending threads of execution.
> In a browser there are a number of long-running commands that contain
> what I describe as "their own message pump". If you do an alert('hi')
> or issue a synchronous XHR request then you are liable to find some of
> your own code executing beneath that call on the call stack (whether
> triggered by an event, setTimeout, or whatever).
I don't think you'll find that in Chromium. It is theoretically
possible with V8. The thread waiting for the OK button in the alert()
command could release the V8 mutex (for example with a V8::Unlocker
object - see include/v8.h) and other threads could get the mutex and
run. As I said this isn't done in Chromium. In Chromium nothing
happens JS-wise while the alert() is active. (I'm ignoring HTML5
worker threads here - they are fairly independent of the rest of the
browser.
> Otherwise the thread
> is effectively idle, waiting for user input or for response from a
> server. The embedded equivalent I'm assuming would be that the C++
> code is re-entered, presumably with a very lengthy c++ call stack. I
> would like to avoid locking a large number of threads as idle if
> possible, although I'm guessing that the JavaScript state cannot be
> suspended while in the middle of a function call.
A function call like alert() will call out to C++ (via an interceptor
I think) so it can in theory relinquish the mutex. In practice this
doesn't happen in Chromium.
> Has anyone explored assigning operating system fibers to javascript
> contexts? This would permit one to "shelve" threads of execution
> while in the middle of a function call, although it does add the
> responsibility of managing and assigning fibers to threads. Does V8
> care if it unexpectedly finds itself running on a different os thread,
> or would it even notice? Or is this overkill?
If V8 unexpectedly finds itself running on a different OS thread it is
likely to crash fairly soon. There are asserts in the debug mode to
try to catch this case. On the other hand if you use V8::Locker then
a thread change is not unexpected and V8 should cope.
> My third question would be regarding governors to prevent runaway
> script or memory usage. From what I've read in other threads though
> there is no surefire way to interrupt a running script (DebugBreak?),
> although there may be some discussion on installing an interrupt
> somewhere.
In Chromium a JS loop is allowed to run until it terminates or the
process is killed. In V8 it is possible to suspend a thread at almost
any point (the debugger uses this) and it is possible to switch to
another thread at almost any point (the preemption option uses this).
At the moment there is no way to terminate a running script that
doesn't want to terminate, but we probably want to add that.
--
Erik Corry, Software Engineer
Google Denmark ApS. CVR nr. 28 86 69 84
c/o Philip & Partners, 7 Vognmagergade, P.O. Box 2227, DK-1018
Copenhagen K, Denmark.