More fun with scopes and ScriptObjectMirror
Tim Fox
timvolpe at gmail.com
Thu Dec 12 01:42:59 PST 2013
On 12/12/13 09:08, Attila Szegedi wrote:
> On Dec 12, 2013, at 10:02 AM, Tim Fox <timvolpe at gmail.com
> <mailto:timvolpe at gmail.com>> wrote:
>
>> On 12/12/13 08:49, Attila Szegedi wrote:
>>> On Dec 12, 2013, at 8:00 AM, Tim Fox <timvolpe at gmail.com
>>> <mailto:timvolpe at gmail.com>> wrote:
>>>
>>>> On 11/12/13 12:53, Attila Szegedi wrote:
>>>>> On Dec 11, 2013, at 1:13 PM, Tim Fox <timvolpe at gmail.com
>>>>> <mailto:timvolpe at gmail.com>> wrote:
>>>>>
>>>>>> Confused...
>>>>>>
>>>>>> I assumed that if two scripts where run with their own script
>>>>>> context, then they would already have separate globals, i.e. if I do
>>>>>>
>>>>>> myglobal = 1
>>>>>>
>>>>>> in module 1 that won't be visible in module 2.
>>>>> That's true, but then you also end up with the need for
>>>>> ScriptObjectMirrors between them, and that was what I suggested
>>>>> you try to avoid.
>>>>>
>>>>>> So I'm not sure really what --global-per-engine really means, if
>>>>>> the modules have their own globals anyway. I guess my
>>>>>> understanding must be wrong somewhere.
>>>>> Well, it will mean that modules won't have their own globals…
>>>>> --global-per-engine will make it so that the Global object is
>>>>> specific to the ScriptEngine, and not to the ScriptContext, e.g.
>>>>> even if you replace the ScriptContext of the engine, when scripts
>>>>> are run, they'll still see the same global object as before the
>>>>> replacement. The gist of it is:
>>>>>
>>>>> a) without --global-per-engine, the Global object is specific to a
>>>>> ScriptContext, each ScriptContext has its own. ENGINE_SCOPE
>>>>> Bindings object of the context is actually a mirror of its Global.
>>>>> b) with --global-per-engine, the Global object lives in the
>>>>> ScriptEngine. ENGINE_SCOPE Bindings object of the context is just
>>>>> a vanilla SimpleBindings (or whatever you set it to), and Global
>>>>> will delegate property getters for non-existent properties to it
>>>>> (but it'll still receive property setters, so new global variables
>>>>> created by one script will be visible by another; no isolation there).
>>>>
>>>> One more question on this. With --global-per-engine, and multiple
>>>> ScriptContext instances - if all the ScriptContext instances share
>>>> a single a single global, how is this different from just having a
>>>> single ScriptContext in which you execute all JavaScript?
>>>
>>> Not much. Using separate ScriptContexts with single engine is pretty
>>> much equivalent to modifying the initial ScriptContext of the
>>> engine. When I thought you'll end up using Java code to implement
>>> module loading, I suggested either using separate contexts, or at
>>> least changing the ENGINE_SCOPE bindings of the original context to
>>> contain "module", "exports", etc. but if you now implement those as
>>> parameters of an anonymous function that you put around the module
>>> source code and eval(), then you don't need even that.
>>>
>>> So, yeah, you can have a single context for all JavaScript. As I
>>> said earlier, it'll be single-threaded, but JavaScript the language
>>> is by nature single-threaded (that's why node.js is single-threaded
>>> too). Probably the better way to say it is that JavaScript language
>>> has no defined multithreaded semantics, and thus a JavaScript
>>> execution environment is unsafe to use in a multithreaded manner.
>>
>> Regarding thread safety... Unlike node, Vert.x is multi-threaded,
>> however we guarantee that code in a particular Verticle is never
>> executed concurrently by more than one thread.
>>
>> In other words - we have a single engine which might contain many
>> scripts, and may have many threads executing different scripts in it
>> at any one time, but we guarantee that any particular script is never
>> executed concurrently by more than one thread. So we don't need any
>> multithreaded JS semantics.
>>
>> This works well with Rhino and DynJS. So I assume it's ok for a
>> single engine to be executed concurrently as long as those threads
>> don't bump into each other, i.e. don't try and execute the same code
>> concurrently?
>
> Code execution is not a concern, multiple threads executing same code
> is okay. Concurrent mutation of shared data is a concern. If those
> verticles also have data separation, and whatever data they share they
> only use as read-only (talking about native JS objects, arrays, and
> global vars here; you can obviously share threadsafe POJOs). Native JS
> objects and arrays in Nashorn aren't threadsafe. That's a conscious
> design decision; since the language doesn't have defined multithreaded
> semantics, it doesn't make much sense to pay the price for it in terms
> of code complexity and runtime cost.
+1. This fits the Vert.x model well... we don't share any mutable state
between verticles, and I don't have any desire for the engine to support
it. Vert.x has an "actor-like" approach to concurrency - where each
verticle is like an actor (single threaded) and communicates with other
verticles by passing immutable messages.
>
> Attila.
>
More information about the nashorn-dev
mailing list