Multi-threading - re-using compiled scripts

927 views
Skip to first unread message

MikeM

unread,
Sep 2, 2008, 4:47:09 PM9/2/08
to v8-users
I've been using Spidermonkey for a number of years for my JS embedding
needs.
How does a spidermonkey context compare with V8 context?

Also, I would like to be able to compile a script 1 time and execute
it in several different threads at the same time.
See possible suedo code follows (not tested or course)
Thanks!

------THREAD #1 compiles and saved scripts for later use ----

//Create a persistent script that can be saved for later use outside
this methods scope.
Persistent<Script> oMySavedScript= Script::New();

HandleScope localScope;
Handle<String> sMyScript = String::New("javascript to run goes here");

oMySavedScript= Script::Compile(sMyScript);
if (oMySavedScript.IsEmpty())
{
String::AsciiValue error(try_catch.Exception());
// The script failed to compile; bail out.
return false;
}

//Now save the compiled script in a map using a unique name for later
re-use...
pScriptEngine->SaveCompiledScript("Script-01", oMySavedScript);

//Setup a global context to be re-used in different threads.
Persistent<Context> g_oContext = Context::New();
---------------------------------------


----THREAD #2 ----------------

Context::Scope oGlobal(g_oContext); //Create global scope

Persistent<Script> oScriptToRun = pScriptEngine-
>GetCompiledScript("Script-01"); //Retrieve from map of saved
scripts.

HandleScope localScope;
Handle<Value> result = oScriptToRun->Run();
-------------------------------------


Later code would destroy the saved script and perform other cleanup as
necessary.

Erik Corry

unread,
Sep 3, 2008, 7:32:27 AM9/3/08
to v8-users


On Sep 2, 10:47 pm, MikeM <Mi...@reteksolutions.com> wrote:
> I've been using Spidermonkey for a number of years for my JS embedding
> needs.
> How does a spidermonkey context compare with V8 context?

I'm not familiar with SpiderMonkey contexts.

> Also, I would like to be able to compile a script 1 time and execute
> it in several different threads at the same time.

This isn't possible. You have to either use locking to ensure that
only one script is executing at a time or you have to use several
processes.

MikeM

unread,
Sep 3, 2008, 7:41:46 AM9/3/08
to v8-users
> This isn't possible.  You have to either use locking to ensure that
> only one script is executing at a time or you have to use several
> processes.

Thanks for the reply.

In a server side environment running JS it would be very easy to have
over 500+ threads running JS simultaneously.
Using processes would be too heavy weight (at least in windows) and
kill the server.

Would it be possible to add appropriate thread syncronization to V8 to
allow mulitple threads to run at the same time?
Is the script class immutable and would it support this?

I'm thinking it would be worth adding such a feature for C++
embedders.
I'm not asking you to make this patch, just to speak about it
architecturally and the do-ability of such a patch.
Would the garbage collector be able to run fast under high contention?

Feng Qian

unread,
Sep 3, 2008, 10:41:27 AM9/3/08
to v8-u...@googlegroups.com
V8 was designed to in single-threaded environment. So there is no locks around common
data structures such as heaps and accessing static variables. We thought adding locks
around these data structures can slow down allocations.

V8 api has a Locker class that can be used to protect V8. Application can embed V8 in
a multi-threading program by using Locker around V8 api calls.

Feng Qian

unread,
Sep 3, 2008, 10:43:31 AM9/3/08
to v8-u...@googlegroups.com
On Wed, Sep 3, 2008 at 4:41 AM, MikeM <Mi...@reteksolutions.com> wrote:
As far as GC part, it is a generational one. In general case, it is very fast.
In the browser, we saw applications that have noticeable pause in FF or Safari
due to GC, but not often in Chrome.
 



i3x1...@gmail.com

unread,
Sep 3, 2008, 2:14:47 PM9/3/08
to v8-users
What you're asking appears to be possible, and quite easy.

First, see the following link for how multithreading seems to work in
V8. You'll find that it won't be necessary to modify V8 and make it
threadsafe (not to mention a huge undertaking).

http://groups.google.com/group/v8-users/browse_thread/thread/3f66bb4cf86d836e/163379d7082c317d?#163379d7082c317d

With that all in mind, take a look at how you compile and run a
script. The class Script has two methods: Compile and Run. When you
Compile a script, it gives you back a Local handle to a Script object
(suggesting that Script privately holds the result of compilation).
Problem is, since it's Local and not Persistent, it (along with the
result of compilation) will be destroyed as soon as you leave the
current scope, so it can't be shared among threads. The v8::Persistent
class, however, provides a way to duplicate handles with the New
method. Pass your Local<Script> into Persistent::New, and your Script
object becomes persistent in the garbage collector.

Code would look something like this (untested)-

Local<Script> local_compiled_script = Script::compile("var i=0;
while(i<1000) { i++; }"); // Compile a script, and store a
Local:Handle to it
Persistent<Script> persistent_compiled_script =
Persistent::New(local_compiled_script); // Create a new
Persistent:Handle, and initialize it with the object referenced in the
local_compiled_script handle

...and now you can call persistent_compiled_script->Run() as many
times as you want in as many different places as you want, and the
Script object will not be garbage collected since it's now the subject
of a Persistent handle.

MikeM

unread,
Sep 3, 2008, 2:29:01 PM9/3/08
to v8-users
The persistance of the Script object is the easy part.
If the engine itself only allows 1 thread at a time to run with its
own "scheduler" that won't work.
In a truly mulit-threaded world the OS does the thread scheduling and
common data structures are protected with locks.

Feng Qian indicated that in his post above which says:

> "So there is no locks around commondata structures such as heaps and accessing static variables.
> We thought adding locks around these data structures can slow down allocations.".

Basically that says to me that without a patch of some kind it won't
be thread safe or truly multi-threaded.
I'm thinking of adding some conditional compile with locks using a
symbol like V8_MULTI_THREADED and a few macros.

That way it won't have any affect on the single threaded usage by the
Chrome browser.
Hopefully it won't be too difficult to get around the default "thread
scheduler".
Reply all
Reply to author
Forward
0 new messages