v8 and threads?

89 views
Skip to first unread message

Erik Anderson

unread,
Aug 14, 2009, 9:12:04 PM8/14/09
to v8-users
I'm trying to familiarize myself with v8, it's structure and
capabilities, seeing how it can be used as an embedded scripting
language. I haven't really had much hands-on experience yet so I'm
hoping my poking around isn't too stupid or way off in left-field
here, I do have some questions about threading however.

With javascript in normal browsers, I'm fairly certain that there is
only one thread active (from the point of view of the script anyhow).
While a single function is running no events occur, the screen may not
even update, and the page in general goes unresponsive (I'm talking in
general, my experience is mostly with IE, Chrome may be different).
Google Gears attempts to add the concept of multithreading to
JavaScript but the communication pathway is extremely limited, I'm
guessing to prevent interaction between scripts running in the two
pages.

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
first question is whether V8 permits multiple threads within a
context, whether execution of javascript within a context has been
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). 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.

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?

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.

Erik Corry

unread,
Aug 15, 2009, 3:14:22 PM8/15/09
to v8-u...@googlegroups.com
2009/8/15 Erik Anderson <odyss...@gmail.com>:

>
> I'm trying to familiarize myself with v8, it's structure and
> capabilities, seeing how it can be used as an embedded scripting
> language.  I haven't really had much hands-on experience yet so I'm
> hoping my poking around isn't too stupid or way off in left-field
> here, I do have some questions about threading however.
>
> With javascript in normal browsers, I'm fairly certain that there is
> only one thread active (from the point of view of the script anyhow).
> While a single function is running no events occur, the screen may not
> even update, and the page in general goes unresponsive (I'm talking in
> general, my experience is mostly with IE, Chrome may be different).
> Google Gears attempts to add the concept of multithreading to
> JavaScript but the communication pathway is extremely limited, I'm
> guessing to prevent interaction between scripts running in the two
> pages.

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.

Erik Anderson

unread,
Aug 15, 2009, 7:40:37 PM8/15/09
to v8-users

On Aug 15, 12:14 pm, Erik Corry <erik.co...@gmail.com> wrote:
> 2009/8/15 Erik Anderson <odysseus...@gmail.com>:
>
>
> > With javascript in normal browsers, I'm fairly certain that there is
> > only one thread active (from the point of view of the script anyhow).
> > While a single function is running no events occur, the screen may not
> > even update, and the page in general goes unresponsive (I'm talking in
> > general, my experience is mostly with IE, Chrome may be different).
> > Google Gears attempts to add the concept of multithreading to
> > JavaScript but the communication pathway is extremely limited, I'm
> > guessing to prevent interaction between scripts running in the two
> > pages.
>
> 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.

Okay, so from this it sounds like a context is NOT the same thing as a
webpage in V8 and that they interfere with each other. That's rather
disappointing. Can I then create a separate V8 for each "page" in the
program to force them to be independent, or would the instances find
out about each other and force the supervisor program into wrangling
them into separate processes like Chrome does?

> > 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.

So Chrome doesn't permit any javascript to execute within an alert()?
I guess I shouldn't be too surprised, but at least it's better than IE
not even refreshing the screen (!) while any javascript is running.
Reply all
Reply to author
Forward
0 new messages