RE: Aligning from() and map()

2013-12-06 Thread Hudson, Rick
Agreed, index is the index of the destination where the value returned from the 
closure parameter will be placed. This is the right way to think about index. 
Using it directly on the source is at best redundant since element === 
collection[index]. The fact that the destination isn't available yet doesn't 
make the destination index useless. One use case that comes to mind is a 
convolution like a blur function in image processing. The index indicates the 
location in the destination where the newly created value is to be placed.

- Rick

-Original Message-
From: Allen Wirfs-Brock [mailto:al...@wirfs-brock.com] 
Sent: Friday, December 06, 2013 4:07 PM
To: Hudson, Rick
Cc: Niko Matsakis; es-discuss@mozilla.org
Subject: Re: Aligning from() and map()


On Dec 6, 2013, at 12:18 PM, Hudson, Rick wrote:

 Allen 1)  For the map method, the source and destination collection are the 
 same object so the collection argument to the closure parameter identifiers 
 both the source and destination object
 
 Not sure I'm following you here. The collection passed to the closure 
 parameter (aka callback function) in map is the source and not the 
 destination. As far as I can tell the destination isn't available until map 
 returns it.

Right, sorry first post of the morning.  Coffee wasn't active yet.

There is still a difference.  With map, the source collection is the this value 
of the map method and has implementation level visibility of the source 
collection.  The map method is specified to do explicit index iteration over 
the indices of the source collection.   With the from method, the source may 
simply be an Iterable Iterator (an Iterator with a @@iterator method). The 
ultimate source of the data isn't necessarily known to the from method and 
since index-based iteration isn't used to access the iterator, any index passed 
to the closure would be a destination index.  But, as you point out, the 
destination object isn't available to the closure. 

Allen




___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Parallel JavaScript: exception throwing vs. sequential fallback

2013-08-07 Thread Hudson, Rick
Parallel JavaScript: exception throwing vs. sequential fallback
When a parallel method such as mapPar is called with an elemental function that 
prevents parallelization, for example by writing to a global, we can either 
throw an exception or fall back to sequential execution. The current TC39 POR 
is to throw an exception. I think falling back to sequential execution is the 
better alternative.
To maintain temporal immutability and determinism the exception needs to be 
thrown before any global state is altered. This implies that that the elemental 
(callback) function needs to be instrumented to prevent writing to non-local 
variables before even being run once. Some JITs execute a few iterations using 
an interpreter in order to do gather type information. Instrumenting this code 
to throw before global state is modified comes at not only a performance hit 
but also will imposes considerable reworking of the JIT infrastructure for it 
to be reused to do the instrumenting. This is potentially a heavy 
implementation burden.
The second problem is that throwing an exception prior to modifying global 
state will also complicates a JavaScript implementation of a sequential 
polyfill since such a polyfill would have to instrument the elemental function. 
Given that closures can easily hide aspects of code that needs to be 
instrumented such a polyfill is unlikely to be possible.
On the other hand falling back to a sequential implementation avoids both of 
these problems. If and when a write to a global is detected falling back to 
sequential code would be straightforward. The Interpreter/JIT could run the 
first few iterations sequentially, checkpoint where it is in the sequential 
iteration space, JIT the code, including any instrumentation that is needed, 
run the code concurrently, and if a write to a global is detected then fall 
back to the checkpoint and resume sequential iterations. The semantics of 
Parallel JavaScript make maintaining such a checkpoint trivial.
We should revisit the decision to throw an exception in light of these 
implementation issues and change to semantics that allow a sequential schedule 
to be a legal scheduling for any elemental function whether it is temporally 
immutable or not.
-Rick


___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


RE: Why does Array.from also take a mapFn?

2013-06-25 Thread Hudson, Rick
I'm trying to understand this particular line.

var squaredSmalls_try3 = Int16Array.from(smalls, map(v= v*v));  //the plan is 
for this to work.

To me I would expect a complaint that map is undefined. Should map be implied?
var squaredSmalls_try3 = Int16Array.from(smalls, (v= v*v));  //the plan is for 
this to work.
Or specified
var squaredSmalls_try3 = Int16Array.from(smalls, Array.map, (v= v*v));  //the 
plan is for this to work.

- Rick

-Original Message-
From: es-discuss-boun...@mozilla.org [mailto:es-discuss-boun...@mozilla.org] On 
Behalf Of Allen Wirfs-Brock
Sent: Monday, June 24, 2013 3:50 PM
To: Domenic Denicola
Cc: es-discuss
Subject: Re: Why does Array.from also take a mapFn?

First, you normally want map and other iterative array functions to return the 
same type of collect it was applied to:

var smalls = Int8Array.of(34, 78, -150, 127, -3, 12);
var negatedSmalls = smalls.map(v= -v);   //negatedSmalltalk should also be 
a Int8Array

but sometimes you don't

var squaredSmalls_try1 = smalls.map(v= v*v);   //no good if result is 
Int8Array because many values will be truncated

var squaredSmalls_try2= Int16Array.from(smalls.map(v= v*v));   // still no 
good, because intermediate array is Int8Array

var squaredSmalls_try3 = Int16Array.from(smalls, map(v= v*v));  //the plan is 
for this to work.

filter, etc. doesn't have this sort of problem because the values placed in the 
target array are all values that were retrieved from the source array. 

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


RE: another rivertrail question

2013-04-05 Thread Hudson, Rick
(typeError instanceof Error) is true so an implementation is free to throw 
typeError.

It does not count as a side effect.

What happens when a kernel throws an exception is not covered in the strawman.

I suggest that an exception coming from within a kernel function will result in 
an exception being thrown from the high level ParallelArray method. If more 
than one kernel throws an exception the ParallelArray method is free to choose 
which one is thrown to its caller.


-Rick



From: es-discuss-boun...@mozilla.org [mailto:es-discuss-boun...@mozilla.org] On 
Behalf Of Norm Rubin
Sent: Friday, April 05, 2013 8:54 AM
To: es-discuss@mozilla.org
Subject: another rivertrail question

In an elemental function  does throwing an error, count as a side effect?

For instance

V2 = new Array(10, function(){return 23} ,14)

V1 = ParallelArray(14,12,10)

   V1.map( function(e,i)  { var temp = array[e-12] = v2[i].toFixed() ; ...  })

Since the toFixed will  throw a type error when i =1, and a range error when e 
= 10

If this is a side effect, then it is not an elemental function and should throw 
Error, not typeError or rangeError









This email message is for the sole use of the intended recipient(s) and may 
contain confidential information.  Any unauthorized review, use, disclosure or 
distribution is prohibited.  If you are not the intended recipient, please 
contact the sender by reply email and destroy all copies of the original 
message.

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


RE: parallel map and dot product

2013-04-04 Thread Hudson, Rick
In this case it is the same as with a normal array.

function dotProduct(v1, v2) {
return v1.map(function (e, i) {return e*v2[i];}).reduce(function (a, b) {return 
a+b;});
}


-Rick


From: es-discuss-boun...@mozilla.org [mailto:es-discuss-boun...@mozilla.org] On 
Behalf Of Norm Rubin
Sent: Thursday, April 04, 2013 2:31 PM
To: es-discuss@mozilla.org
Subject: parallel map and dot product

I've started to read through the parallel JavaScript  proposal  and have a 
novice question
How would you write a dot product
Given:

P1 = parallelArray(1,2,3)
P2 = ParallelArray(4,5,6)

We want to compute
1*4 + 2*5 + 3*6

As far as I can tell, you need a reduce to do the sums, so you first need to 
construct
 P12 = ParallelArray(1*4, 2*5, 3*6)

Is there a way to generate this using map?



This email message is for the sole use of the intended recipient(s) and may 
contain confidential information.  Any unauthorized review, use, disclosure or 
distribution is prohibited.  If you are not the intended recipient, please 
contact the sender by reply email and destroy all copies of the original 
message.

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


RE: memory safety and weak references

2013-04-01 Thread Hudson, Rick
This brings up another interesting point. Do WeakRefs change a compiler's 
liveness analysis? This could complicate some apparently useful optimizations.

{
var x = new Something();
someWeakRef.set(x);
// Is x dead? (yes) Is x required to contribute to the root set? (I hope 
not.)
gc();
someWeakRef.get() // null or foo?
...
}


-Rick
For the optimization see
@inproceedings{Agesen:1998:GCL:277650.277738,
author = {Agesen, Ole and Detlefs, David and Moss, J. Eliot},
title = {Garbage collection and local variable type-precision and liveness in 
Java virtual machines},
booktitle = {Proceedings of the ACM SIGPLAN 1998 conference on Programming 
language design and implementation},
series = {PLDI '98},
year = {1998},
isbn = {0-89791-987-4},
location = {Montreal, Quebec, Canada},
pages = {269--279},
numpages = {11},
url = {http://doi.acm.org/10.1145/277650.277738},
doi = {10.1145/277650.277738},
acmid = {277738},
publisher = {ACM},
address = {New York, NY, USA},
}
From: es-discuss-boun...@mozilla.org [mailto:es-discuss-boun...@mozilla.org] On 
Behalf Of Oliver Hunt
Sent: Monday, April 01, 2013 4:37 PM
To: Marius Gundersen
Cc: es-discuss discussion
Subject: Re: memory safety and weak references

There are numerous problems with weak references and primitives, mostly 
revolving around the ability to regenerate a primitive, e.g.

someWeakRef.set(foo)
gc()
var something = foo
someWeakRef.get() // null or foo?

 vs.

someWeakRef.set(foo)
var something = foo
gc()
someWeakRef.get() // null or foo?

vs.

someWeakRef.set(foo)
var something = fo
something += o
gc()
someWeakRef.get() // null or foo?

And of course all this just becomes worse for numeric primitives -- All 
existing engines use tagged values for some set of numeric values, and can also 
end up with the same value stored in different ways.  V8 (at least in 32bit) gc 
allocates doubles, but not a subset of integers, this means that if you get the 
value 1 as a double then it might be gc'd and so the weak ref could go away, 
but if it were in the tagged int form it would not.

JSC doesn't immediately intern strings, but over time duplicates do get merged, 
at which point weakness starts acquiring odd behaviour.  Because off the 
implicitly shared heap in different pages this may even be exploitable as a way 
to find out information about other pages (essentially the weak reference to a 
primitive allows a side channel for determining content of other pages that you 
would not otherwise have access to)

This means that any consistent semantic for primitives results in useless 
behaviour - either the weak ref has to be (essentially) strong on primitives, 
or be cleared on ever gc() regardless of liveness of other references.

--Oliver


On Apr 1, 2013, at 1:22 PM, Marius Gundersen 
gunder...@gmail.commailto:gunder...@gmail.com wrote:


This seems to be more a problem with the garbage collector than with weak 
references. If I understood it correctly, any double value can look like a 
pointer, and the garbage collector will check what it is pointing at. To me 
this seems like a source for memory leaks. This problem exists even without 
weak references (or weak iterable maps/sets); the weak references just makes it 
observable. Does this mean the main reason weak references (or, again, weak 
iterable maps/sets) are not to be implemented is because of a bug in the 
garbage collector of popular JS enginges? As noted earlier, the implementation 
of the garbage collector is not specified in the ecmascript standard, so this 
is a problem with implementors, not with the specification.
Again, I'm far from an expert on GC or JS implementations (and would love a 
simplified explanation if I have misunderstood the problem), but this seems 
less like a problem with weak references, and more like a problem with specific 
implementations of GCs.
Marius Gundersen

On Fri, Mar 29, 2013 at 3:47 AM, Oliver Hunt 
oli...@apple.commailto:oli...@apple.com wrote:

On Mar 29, 2013, at 7:36 AM, David Herman 
dher...@mozilla.commailto:dher...@mozilla.com wrote:

 On Mar 27, 2013, at 4:52 AM, Sam Tobin-Hochstadt 
 sa...@ccs.neu.edumailto:sa...@ccs.neu.edu wrote:

 On Tue, Mar 26, 2013 at 11:44 PM, Oliver Hunt 
 oli...@apple.commailto:oli...@apple.com wrote:
 That said I believe that this does kill any dreams i may have had w.r.t 
 primitive-keyed WeakMaps, kudos to MarkM.

 Wouldn't a primitive-keyed WeakMap just be a strong Map for those
 keys?  And therefore immune to any GC attacks?

 Indeed, and also deeply misleading (a weak map with strongly held entries?), 
 which is why I argued that WeakMap should disallow primitive keys.

 Oliver-- can you clarify what you were hoping for?
I was dreaming of primitive keys, i was convinced in an earlier meeting of the 
problems that they would cause, but this security problem is a nail in the 
coffin :-/


 Dave


___

RE: memory safety and weak references

2013-04-01 Thread Hudson, Rick
If the compiler can prove x does not escape the block and it is not used again 
then it is dead and the compiler is free to reuse the stack slot holding the 
last reference.

So I am arguing that x = null; is not required to kill x.

If we agree on that then I think we agree that someWeakRef.get(); is allowed to 
return null.

- Rick

-Original Message-
From: Brendan Eich [mailto:bren...@mozilla.com] 
Sent: Monday, April 01, 2013 5:56 PM
To: Hudson, Rick
Cc: Oliver Hunt; Marius Gundersen; es-discuss discussion
Subject: Re: memory safety and weak references

Hudson, Rick wrote:

 This brings up another interesting point. Do WeakRefs change a 
 compiler's liveness analysis?


Yes, of course.

 This could complicate some apparently useful optimizations.

 {

 var x = new Something();

 someWeakRef.set(x);

 // Is x dead? (yes) Is x required to contribute to the root set? (I 
 hope not.)


You dind't kill x yet. Did you forget

x = null;

here?

 gc();

 someWeakRef.get() // null or foo?


If x = null; happened before gc() then null else the original ref.

/be

 ...

 }

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


RE: memory safety and weak references

2013-04-01 Thread Hudson, Rick
Didn't mean to imply that one is required to use an optimization. I just wanted 
to make it clear that one could.


-Rick

From: Oliver Hunt [mailto:oli...@apple.com]
Sent: Monday, April 01, 2013 6:18 PM
To: Hudson, Rick
Cc: Brendan Eich; Marius Gundersen; es-discuss discussion
Subject: Re: memory safety and weak references


On Apr 1, 2013, at 3:12 PM, Hudson, Rick 
rick.hud...@intel.commailto:rick.hud...@intel.com wrote:


If the compiler can prove x does not escape the block and it is not used again 
then it is dead and the compiler is free to reuse the stack slot holding the 
last reference.

So I am arguing that x = null; is not required to kill x.

That semantic would mean that the interpreter would need to do escape analysis, 
and then the moment a variable became dead it would be required to clear it, 
even if it did not need that slot for anything else.

The world is filled with papers on ways to reduce the conservatism of a GC, but 
you have to balance the cost of work required for that increased conservatism 
against the win you might get from reduced liveness.

But all of this is kind of moot, as weak refs are by definition going to have 
some degree of non-determinism w.r.t liveness, and the initial discussion was 
of weak refs to primitives which have their own, completely separate problems 
(as was already covered)

--Oliver

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


RE: Observability of NaN distinctions — is this a concern?

2013-03-26 Thread Hudson, Rick
 jussi.kallioko...@gmail.com
 wrote:

 That's just because ES has had no notion of bits for floating points before.
 Other than that, ES NaN works like IEEE NaN, e.g.


Some background about the latest GLS spec and IEEE NaNs from 
http://www.opengl.org/registry/doc/GLSLangSpec.4.20.11.clean.pdf

Section 4.1.4 states
As an input value to one of the processing units, a single-precision or 
double-precision floating-point
variable is expected to match the corresponding IEEE 754 floating-point 
definition for precision and
dynamic range. Floating-point variables within a shader are also encoded 
according to the IEEE 754
specification for single-precision floating-point values (logically, not 
necessarily physically).

Section 4.7.1 goes on to provide a detailed list of reduced (from IEEE 754) 
precision requirements 
for single precision floats and then states the following:
The precision of double-precision operations is at least that of single 
precision.

4.7.1 also sets up the requirements of operations to produce NaNs as follows:
 NaNs are not required to be generated. Support for signaling NaNs is not 
required and
exceptions are never raised. Operations and built-in functions that operate on 
a NaN are 
not required to return a NaN as the result.

So any statement that the GLS spec follows IEEE 754 treatment of double 
precision is only a 
statement about input values.

- Rick


-Original Message-
From: es-discuss-boun...@mozilla.org [mailto:es-discuss-boun...@mozilla.org] On 
Behalf Of Andreas Rossberg
Sent: Tuesday, March 26, 2013 6:40 AM
To: Oliver Hunt
Cc: Mark S. Miller; Brendan Eich; es-discuss
Subject: Re: Observability of NaN distinctions — is this a concern?

I'm with Dave and Oliver. Worrying about the performance cost of NaN 
normalisation has a strong smell of premature micro optimisation. The one 
branch per float store, whose cost should be amortised by branch prediction 
when frequent, seems very unlikely to be measurable compared to everything else 
going on when executing JavaScript.

As for the this is not a common problem argument, use cases should only trump 
principles if the cost is unbearable.

/Andreas


On 26 March 2013 09:29, Oliver Hunt oli...@apple.com wrote:

 On Mar 26, 2013, at 9:12 PM, Jussi Kalliokoski 
 jussi.kallioko...@gmail.com
 wrote:

 That's just because ES has had no notion of bits for floating points before.
 Other than that, ES NaN works like IEEE NaN, e.g.

 0/0 === NaN // false
 isNaN(0/0) // true


 That's true in any language - comparing to NaN is almost always 
 defined explicitly as producing false.  You're not looking at bit 
 patterns, here so conflating NaN compares with bit values is kind of 
 pointless.











 We need to stop raising this causes performance problems type 
 issues without a concrete example of that problem.  I remember 
 having to work very hard to stop WebGL from being a gaping security 
 hole in the first place and it's disappointing to see these same 
 issues being re-raised in a different forum to try and get them bypassed 
 here.


 Before saying security hole, please elaborate. Also, when it comes 
 to standards, I think change should be justified with data, rather 
 than the other way around.


 Done.


 You'll have to do better than that. ;)


 Ok, I'll try to go over this again, because for whatever reason it 
 doesn't appear to stick:

 If you have a double-typed array, and access a member:
 typedArray[0]

 Then in ES it is a double that can be one of these values: 
 +Infinitity, -Infinity, NaN, or a discrete value representable in IEEE double 
 spec.
 There are no signaling NaNs, nor is there any exposure of what the 
 underlying bit pattern of the NaN is.

 So the runtime loads this double, and then stores it somewhere, 
 anywhere, it doesn't matter where, eg.
 var tmp = typedArray[0];

 Now you store it:
 typedArray[whatever] = tmp;

 The specification must allow a bitwise comparison of 
 typedArray[whatever] to typedArray[0] to return false, as it is not 
 possible for any NaN-boxing engine to maintain the bit equality that 
 you would otherwise desire, as that would be trivially exploitable.  
 When I say security and correctness i mean it in the can't be remotely 
 pwned sense.

 Given that we can't guarantee that the bit pattern will remain 
 unchanged the spec should mandate normalizing to the non-signalling NaN.

 --Oliver



 Cheers,
 Jussi






 Cheers,
 Jussi


 --Oliver

  Allen
 
 
 
 
 
  /be
 
  On Mar 25, 2013, at 4:33 PM, Kenneth Russell k...@google.com wrote:
 
  On Mon, Mar 25, 2013 at 4:23 PM, Brendan Eich 
  bren...@mozilla.com
  wrote:
  Allen Wirfs-Brock wrote:
 
  On Mar 25, 2013, at 4:05 PM, Brendan Eich wrote:
 
  Allen Wirfs-Brock wrote:
 
  BTW, isn't cannonicalization of endian-ness for both 
  integers and floats a bigger interop issue than NaN 
  cannonicalization?  I know this was discussed in the past, 
  but it doesn't seem to be covered in the latest Khronos 
  spec.  Was 

RE: Pure functions in EcmaScript

2012-12-02 Thread Hudson, Rick
Function purity, while an interesting concept, probably isn't as important as 
the function being associative. Our work with Parallel EcmaScript (aka River 
Trail) http://wiki.ecmascript.org/doku.php?id=strawman:data_parallelism has 
shown that for a useful set of kernel functions the compiler can conservatively 
determine that a function does not modify non-local variables.  We have found 
no need for function annotation, instead if one passes a function to a 
ParallelArray method we trust but verify that it modifies only local variables. 
Beyond this check we do not attempt to prove that a function is associative.  
The results are guaranteed only to be the result of some ordering and never 
return an out of thin air value. Floating point anomalies aside, if the 
function is associative the result will be deterministic.

-   Rick

-Original Message-
From: es-discuss-boun...@mozilla.org [mailto:es-discuss-boun...@mozilla.org] On 
Behalf Of Brendan Eich
Sent: Wednesday, November 28, 2012 4:48 PM
To: Axel Rauschmayer
Cc: es-discuss
Subject: Re: Pure functions in EcmaScript

Axel Rauschmayer wrote:
 Would returning NaN be impure (apart from running the risk of it 
 having been changed to something different, globally)?

You can't say apart from..., that's exactly the risk. It could be replaced 
with a global getter that has effects.

Isolating a pure function to a sandbox or prepared global environment saves 
this, but then the function's pure annotation can't be enough to express 
what's required.

/be

 On Nov 28, 2012, at 21:35 , Oliver Hunt oli...@apple.com 
 mailto:oli...@apple.com wrote:


 On Nov 28, 2012, at 12:25 PM, Waldemar Horwat walde...@google.com 
 mailto:walde...@google.com wrote:

 On Wed, Nov 28, 2012 at 5:39 AM, Marius Gundersen 
 gunder...@gmail.com mailto:gunder...@gmail.com wrote:

 On Wed, Nov 28, 2012 at 1:20 PM, Andreas Rossberg
 rossb...@google.com mailto:rossb...@google.com wrote:

 Second, due to the extremely impure nature of JavaScript,
 there aren't
 many useful pure functions you could even write. For
 example, your
 'sum' function is not pure, because the implicit conversions
 required
 by + can cause arbitrary side effects.


 Functions passed to the array methods map, reduce, filter, etc
 would be good candidates for pure/side-effect-free functions.
 These functions shouldn't alter any state; they should only
 return a new value based on the parameter they were sent.


 You haven't addressed Andreas's point: Almost any function you write 
 is nonpure, including your sum example. As a fun exercise, go ahead 
 and write a pure version of your sum example.

 Waldemar
 Here you go:

 function sum(a, b) {
var undefined;
switch (typeof a) {
case number:
case string:
break;
default:
return +undefined;
}
 switch (typeof b) {
case number:
case string:
break;
default:
return +undefined;
}
return a + b;
 }




 ___
 es-discuss mailing list
 es-discuss@mozilla.org mailto:es-discuss@mozilla.org 
 https://mail.mozilla.org/listinfo/es-discuss

 ___
 es-discuss mailing list
 es-discuss@mozilla.org mailto:es-discuss@mozilla.org 
 https://mail.mozilla.org/listinfo/es-discuss

 --
 Dr. Axel Rauschmayer
 a...@rauschma.de mailto:a...@rauschma.de

 home: rauschma.de http://rauschma.de
 twitter: twitter.com/rauschma http://twitter.com/rauschma
 blog: 2ality.com http://2ality.com

 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


RE: `free` operator

2012-10-28 Thread Hudson, Rick
Another performance killing but valuable heap debugging tool, implementable if 
you have a GC write barrier that covers all pointer writes, is to have the 
write barrier trace any and all writes/overwrites of the pointer to the traced 
object. It isn't magic and the GC has to also trace the object as it is moved 
about but it is a step in the right direction and a tool I have used to debug 
GC implementations.

This type of functionality should be part of the debugger / software 
development environment and not part of the language,  performant runtime, or 
ES standard.

- Rick

-Original Message-
From: es-discuss-boun...@mozilla.org [mailto:es-discuss-boun...@mozilla.org] On 
Behalf Of Brendan Eich
Sent: Sunday, October 28, 2012 4:49 PM
To: David Bruant
Cc: es-discuss
Subject: Re: `free` operator

Of course we are not going to add *unsafe* manual memory management to 
JS. No need to worry about that!

Isaac proposed safe yet horribly inefficient memory management, whereby 
any unwanted strong refs are found (by a global scan) and then nulled or 
set to undefined. This is bad for the reasons given on the thread, but 
also because it requires a full GC in general.

Safe and efficient manual memory management is a feature of Rust and 
other languages which range from Research to (at best) Advanced 
Technology, and which seem to require fancy type/ownership systems.

As a debugging tool, something like Alex's assertFree (of course, you 
couldn't have a weak ref to pass in, so maybe assertSingleRef is a 
better name) could be done. Again, in some (many high performance) 
implementations, it would require a full mark/sweep GC. So it is a 
debug-build or debug-mode only tool, not to be used lightly.

What I did years ago as a debugging tool in SpiderMonkey, which I 
believe survives in the JS_DumpHeap C API, is along these lines. Rather 
than null any leaky paths to cover up the bug, it dumps all paths by 
which the allegedly single-ref (or just mysteriously still-alive) 
GC-thing-to-find that you pass in as an optional parameter still is 
connected to the graph of rooted live things.

The path names are formed by property names with unambiguous or 
sufficiently unlikely separators. Internal strong refs (e.g., roots in 
native data structures held as opaque or private parts of a JS object, 
e.g. a DOM object peering a C++ struct or class instance) may be given 
constant-string names when made strong (rooted).

Usually when debugging a leak, getting the set of strong-ref paths leads 
quickly to progress in fixing the bug.

/be

David Bruant wrote:
 2012/10/26 Isaac Schlueter i...@izs.me mailto:i...@izs.me

 (...)


 We've got some band-aids in place in the node http.js file to prevent
 parser leaks.  A more forcible free() method would have made it much
 easier.  The long-term solution is to rewrite the program (...)

 So you're suggesting that a language-level feature with abusive 
 authority introducing use-after-free bugs (and maybe others) should be 
 included to solve short-term problems?

 Yehuda's action at a distance complaint is definitely a valid
 concern.  However, note that an object can't be freed unless you have
 a reference to the object.

 Everyone has a reference to built-ins so a bug or an attacker could 
 free built-ins.

 Thus, any code that would set my reference
 to undefined could only do so if it was also capable of mutating the
 object in any other way (adding/removing properties, etc.)

 So, we already have this:

 function () {
 // acquire a ref from some external code
 // no way of knowing what else is sharing this object
 var x = func()
 x.foo = 'bar'
 // other code...
 doAnotherThing()
 // not guaranteed!
 assert(x.foo === 'bar')
 }

 With non-configurable properties and making objects non-extensible, 
 you have a way to prevent this, a way to protect your objects from 
 action at a distance. Even proxies are required to respect some 
 invariants for the sake of application securability.
 The free operator you're proposing cannot be protected against. Anyone 
 can release any object it has a reference to without the object 
 creator (or the other object reference holder) having their word to 
 say to prevent it. That's unbalanced.

 Whenever you have a reference to an object that is shared with some
 other code, there's the potential for action at a distance.  The
 proposal here is to make that action a bit more powerful.

 I don't agree that it's necessarily a problem in production.  We free
 objects in other languages all the time.

 I agree with you, C and C++ are absurdly unsafe languages. No wonder 
 double free and use after-free bugs are so common! As the rumor goes, 
 use-after-free bugs lead to security issues sometimes [1]. Really not 
 an example to follow in my opinion.

 What do you think about the revokable proxy solution? I agree it's 
 less sexy than a 

RE: Function#fork

2012-09-24 Thread Hudson, Rick
Besides web workers there are two straw man proposals that address adding 
parallelism and concurrency to JavaScript.

http://wiki.ecmascript.org/doku.php?id=strawman:data_parallelism and 
http://wiki.ecmascript.org/doku.php?id=strawman:concurrency.

The Parallel JavaScript (River Trail) proposal has a prototype implementation 
available at https://github.com/rivertrail/rivertrail/wiki. You should be able 
to implement your example's functionality using this API.

The latest HotPar 
https://www.usenix.org/conference/hotpar12/tech-schedule/workshop-program had 
two interesting papers

Parallel Programming for the 
Webhttps://www.usenix.org/conference/hotpar12/parallel-programming-web 
https://www.usenix.org/conference/hotpar12/parallel-programming-web
and
Parallel Closures: A New Twist on an Old Idea 
https://www.usenix.org/conference/hotpar12/parallel-closures-new-twist-old-idea

These projects each address some important part of the general problem of 
adding parallelism and concurrency to JavaScript.

Feedback is always appreciated.


-Rick



From: es-discuss-boun...@mozilla.org [mailto:es-discuss-boun...@mozilla.org] On 
Behalf Of Jussi Kalliokoski
Sent: Monday, September 24, 2012 8:44 AM
To: es-discuss
Subject: Function#fork

Hello everyone,

I've been thinking a lot about parallel processing in the context of 
JavaScript, and this is really a hard problem. I'm very curious to hear what 
everyone's opinions are about it's problems and so forth, but I don't think an 
open question like that will give very interesting results, so I have an 
example problem for discussion (while it seems like a bad idea to me, and 
unlikely to ever get to the language, what I want to know is everyone's 
reasoning behind their opinions whether it's for or against).

What if we introduce Function#fork(), which would call the function in another 
thread that shares state with the current one (how much state it shares is an 
open question I'd like to hear ideas about, but one possibility is that only 
the function arguments are shared) using a similar signature to Function#call 
except that the first argument would be a callback, which would have error as 
its first argument (if the forked function throws with the given arguments, it 
can be controlled) and the return value of the forked function as the second 
argument.

 * What are the technical limitations of this?
 * What are the bad/good implications of this on the language users?
 * Better ideas?
 * etc.

I have a detailed example of showing Function#fork in action [1] (I was 
supposed to make a simplified test, but got a bit carried away and made it do 
parallel fragment shading), it uses a simple fill-in for the Function#fork 
using setTimeout instead of an actual thread.

Cheers,
Jussi

[1] https://gist.github.com/3775697
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


RE: [[strawman:data_parallelism]] |this| and fat arrows

2012-06-22 Thread Hudson, Rick
Hey Mark, 

You asked How/why might including index and the array itself distract the 
programmer from parallel thinking?
If we present index as a location and not as the nth invocation of kernel 
function then we are fine. Array.map overloads index to serve both purposes. My 
concern is that if we are too close to Array then programmers will assume we 
are the same and the same sequential semantics will hold. There is nothing 
inherently non-parallel about a location.

You are correct that we are talking more about programmer psychology, art, and 
pedagogy and there is no formal technical reason to go either way. While 
passing 3 arguments might be more expensive than passing one in today's 
implementations there are probably compiler optimizations that can ameliorate 
the effects.

Let's look closely at the change you are suggesting on a very simple map 
invocation.

function add1(element) {return element+1;}
strawmanPA.map(add1);
alternatePA.map(add1);

OK, JavaScript's argument passing semantics mean no difference for the common 
case where the result is dependent upon just the element. The alternate is even 
upwardly compatible.

Now let's consider a typical geometric decomposition function like a vector 
blur.

function blurStrawman(index, array) {
  if (index  1) return array[index]; 
  return (array[index]+array[index-1])/2;
}
function blurAlternate(element, index, array) {
  if (index  1) return element; 
  return (element+array[index-1])/2;
}

strawmanPA.combine(blurStrawman);
strawmanPA.map(blurAlternate);

OK, blurAlternate again seems reasonable. 

I've played with other codes and I'm finding it increasingly hard to argue 
against your suggestions for arrays. Future proofing the cases where we might 
want to extend ParallelArray to objects seems fine since JavaScript blurs field 
names and indices allowing for index to have a reasonable meaning in the 
context of objects.

Unless someone else speaks up I'll drop combine and change map and filter so 
the kernel function takes element, index, array.

Cheers,
- Rick

-Original Message-
From: Mark S. Miller [mailto:erig...@google.com] 
Sent: Friday, June 15, 2012 6:06 PM
To: Hudson, Rick
Cc: es-discuss
Subject: Re: [[strawman:data_parallelism]] |this| and fat arrows

On Fri, Jun 15, 2012 at 11:35 PM, Hudson, Rick rick.hud...@intel.com wrote:
 Hey Mark,
 ParallelArray and index are left out because of our desire to provide a few 
 good methods that help/force programmers to think about parallel algorithms 
 and not just speeding up sequential algorithms. Array map is really just 
 syntactic sugar for for loops and invites thinking that depends on order. For 
 ParallelArray map we felt that the value was the semantically important thing 
 and the user should not be distracted by the index. Not having index 
 available is one step towards thinking in more parallel ways.

Hi Rick, the claim made in the paragraph above seems to be the core
argument. I respect the kind of argument you're making -- programmer
psychology is important, and it is our responsibility as language
designers to take it into account, and to help steer programmers
towards certain ways of thinking about the problem and away from
others. Sometimes these psychological issues have no corresponding
formal basis, but are still important nevertheless. Arguments by
non-psychologists like us about psychology can often be fuzzy, but
this does not relieve us of responsibility of taking these into
account.

However, I don't have any intuition that supports the specific claim.
Let's take map specifically. How/why might including index and the
array itself distract the programmer from parallel thinking? First, do
we agree that there's no formal problem, and the issue is only
psychology? If so, perhaps you could provide some examples that would
help illustrate the psychological issue you have in mind? At this
point, I just don't get it.

-- 
    Cheers,
    --MarkM
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


RE: [[strawman:data_parallelism]] |this| and fat arrows

2012-06-15 Thread Hudson, Rick
Hey Mark,
ParallelArray and index are left out because of our desire to provide a few 
good methods that help/force programmers to think about parallel algorithms and 
not just speeding up sequential algorithms. Array map is really just syntactic 
sugar for for loops and invites thinking that depends on order. For 
ParallelArray map we felt that the value was the semantically important thing 
and the user should not be distracted by the index. Not having index available 
is one step towards thinking in more parallel ways.

In situations where index is more semantically important than the value we 
provide the method combine.  Here we pass the ParallelArray and the index and 
not the value to the kernel function. A blur function that averages the values 
surrounding some location would naturally use combine. The documentation 
encourages the programmer to think of index as the _destination_ of the value 
the kernel function returns. Again the intent is to try and break away from 
sequential thinking. 

Filter is like combine, it gets the ParallelArray and the index and allows 
filtering based on location. If one accepts the above map/combine arguments 
then one could make a reasonable argument that there should be a filter based 
on value and a filter based on location. (Thanks you've forced me to think 
about this again.)

The other methods have less use for index. 
Reduce) we agree that passing in the index doesn't make sense.
Scan) has the same problems with index that reduce has.
Scatter) takes an array of destination indices and a 2 arg conflict function. 
The index of both of the source elements isn't always available so it doesn't 
make sense here either.

Not passing in the ParallelArray was a tougher decision. We really liked the 
way we had |this| bound to the ParallelArray since it made composition / nested 
parallelism straight forward and natural. With the exception of combine and 
filter the programmer has to arrange for the ParallelArray to be available in 
order to do composition.

I think a clean break from high order Array methods is the way to go here, 
syntactically similar forms with semantically different meaning is worth 
avoiding.

- Rick
 
Guy Steele Language design is as much the art of what to leave out as what to 
put in.

-Original Message-
From: Mark S. Miller [mailto:erig...@google.com] 
Sent: Thursday, June 14, 2012 7:32 PM
To: Hudson, Rick
Cc: es-discuss
Subject: Re: [[strawman:data_parallelism]] |this| and fat arrows

Hi Rick,

Even without =, I think this is an improvement to the API overall, as
it makes it more similar to the corresponding array methods. However,
I do not see the problem with making it much more similar. I agree
regarding reduce and reduceRight, but fortunately, these already
violate the general pattern for the other higher order array methods
-- in that they call their callbackfn with this always bound to
undefined. In retrospect, I wish we had called the existing function
reduceLeft so yours could be called simply reduce and have the
name difference suggest the lack of order.

Regarding the others, the general pattern from the ho array methods is

array.foo(callbackfn, possible-other-args, optional-this-arg)

calls back

callbackfn(value, index, array, this-arg-or-undefined)

I wish that the optional-this-arg had been omitted from ES5, but for
the sake of compat with the Prototype library and other
implementations of these methods, I lost that argument. In retrospect
I agree with that decision, even though I still believe that the
this-arg has net negative value. By the same reasoning, I think you
should follow this pattern as well except when there's a good argument
not to. For reduce you make a good argument.

Further comments inline below.

On Fri, Jun 15, 2012 at 4:27 AM, Hudson, Rick rick.hud...@intel.com wrote:
 Proposed change to [[strawman:data_parallelism]]



 The ParallelArray methods map, combine, reduce, scan, scatter, and filter,
 each take a kernel function as an argument. Within this kernel function
 |this| is currently bound to the ParallelArray. This was natural and
 non-controversial

I disagree that it was non-controversial -- I argued against it on
compat grounds at the time. But I agree with your point that = makes
that old design even less viable.

 as long as we used the function(){..} form which did not
 restrict how |this| was bound and explaining the semantics in terms of call
 or apply was perfectly reasonable. = is likely to change that.  =, as
 proposed, enforces a lexical |this| and is semantically different than the
 function () {..} form. Going forward we expect folks to use the = form more
 than the function form. For the most part we will be leaving the kernel
 signatures as they are except that we will no longer bind |this| to the
 ParalleArray is inside a kernel function. Instead |this| will be bound in
 accordance to existing JavaScript specifications and
 [[strawman:data_parallelism

RE: Use cases for WeakMap

2011-05-17 Thread Hudson, Rick

This is all a bit off topic but performance does matter and folks seem to be 
underestimating the wealth of community knowledge that exists in this area.

Who underestimates?

Sorry, this wasn't meant to slight anyone.  I have spent a career standing on 
the shoulders of Allen and his colleagues. My respect should not be 
underestimated.

Interesting pointer.


-Rick

From: Brendan Eich [mailto:bren...@mozilla.com]
Sent: Monday, May 16, 2011 6:44 PM
To: Hudson, Rick
Cc: Allen Wirfs-Brock; Oliver Hunt; Andreas Gal; es-discuss
Subject: Re: Use cases for WeakMap

On May 16, 2011, at 2:46 PM, Hudson, Rick wrote:


This is all a bit off topic but performance does matter and folks seem to be 
underestimating the wealth of community knowledge that exists in this area.

Who underestimates?

A bunch of us are aware of all this. Allen certainly knows all about it, and 
we've been talking shop with him for years, long before he joined Mozilla :-P. 
I recall a conversation like this one about sparse hashcode implementation with 
Allen, Lars Thomas Hansen (then of Opera), and Graydon Hoare from four or five 
years ago...

http://wiki.ecmascript.org/doku.php?id=proposals:hashcodes (check the history)

However, in this thread, the issue is not optimizing hashcode or other metadata 
sparsely associated with objects. That's a good thing, implementations should 
do it. Having the hashcode in the object wins, compared to having it 
(initially) in a side table, but who's counting?

The issue under dispute was neither sparse hashcode nor sparse fish property 
association, where the property would be accessed by JS user code that 
referenced the containing object itself. Rather, it was whether a frozen object 
needed any hidden mutable state to be a key in a WeakMap. And since this state 
would be manipulated by the GC, it matters if it's in the object, since the GC 
would be touching more potentially randomly distributed memory, thrashing more 
cache.

So far as I can tell, there's no demonstrated need for this hidden-mutable 
key-in-weakmap object state. And it does seem that touching key objects 
unnecessarily will hurt weakmap-aware GC performance. But I may be 
underestimating... :-/

/be

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Concerns about weak refs and weak maps.

2010-10-28 Thread Hudson, Rick
I have concerns about weak refs and weak maps, one concern related to 
usability, one related to performance bugs, and another other related to 
changing the complexity of the GC algorithm.

Usability
Weak maps act as a GC API and in doing so violate GC's greatest strength:  the 
user does not have to be concerned with memory management.  Since the user can 
never observe that a key/value pair has been deleted,  weak maps are much 
better than weak refs but they still seem capable of causing hard to diagnose 
and fix performance bugs related to memory pressure and the particular GC 
implementation.

GC implementation
Software stacks on multicores will need GCs to become increasingly concurrent 
and latency free. Weak maps cause concurrent GCs and additional mutator 
synchronizations.  While a concurrent GC already has to do some 
synchronization, each additional synchronization point impedes scalability. My 
concern is that the number of synchronization points might be proportional to 
the number of k, v pairs in the weak maps (see below).

GC Complexity
Another potential performance bug is that the complexity of the Abstract GC 
Algorithm at http://wiki.ecmascript.org/doku.php?id=harmony:weak_maps appears 
to be O(n**2), since each loop may only discover a single retained key k from 
(k,v) whose walk of the related value v discovers only a single unretained k. 
This would then be repeated and require rescanning all the weak maps in the 
each of the following iterations. Concurrent GCs would probable require one or 
more mutator synchronizations at each iteration.

My sense is that the value of a simple efficient concurrent GC and reduced 
latency is higher than the value of weak maps so weak maps should not be part 
of the standard.


-  Rick



___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


RE: Concerns about weak refs and weak maps.

2010-10-28 Thread Hudson, Rick
Hi Brendan,

I think we all agree that EcmaScript, the language, should not contain threads 
with shared memory constructs such as locks or transactions. We seem to 
disagree as to whether EcmaScript, the implementation, should be multithreaded. 
If bridge builders, compiler writers, GC implementations, need better 
(non-application visible) tools then running their tools concurrently seems the 
way forward. Web workers that share immutable heap object behind a message 
passing façade could provide reasonable performance without changing the 
(HTML5) standard. Optimizers running in a separate thread also seem like a good 
idea.  Moving the scans of weak maps into a stop the world GC only makes the GC 
more intrusive while removing the application writers ability to optimize their 
applications.

In the GC literature 50 milliseconds latency is considered the upper bound if 
one wishes to provide an acceptable client experience.  10 milliseconds is what 
one wants for a game experience. This is increasingly hard to achieve with a 
stop the world collector as the memory foot print grows while CPU speed does 
not.

In the long run I believe that EcmaScript will not be able to compete with 
other languages in providing highly responsive client side applications without 
a concurrent GC.

But to answer your direct question:
 If you remove the concurrent GC concern, then what is your sense?
GC latency will increase as memory footprint and use of weak maps increases. 
Large application using weak maps will have performance bugs that will end up 
on the GC implementer's desk where they will be hard to diagnose and fix.

Perhaps if folks talk privately to the top half dozen Java GC implementers 
EcmaScipt might be able to avoid some of their pain.


-  Rick



From: Brendan Eich [mailto:bren...@mozilla.com]
Sent: Thursday, October 28, 2010 2:39 PM
To: Hudson, Rick
Cc: es-discuss; Andreas Gal
Subject: Re: Concerns about weak refs and weak maps.

On Oct 28, 2010, at 2:10 PM, Hudson, Rick wrote:


I have concerns about weak refs and weak maps, one concern related to 
usability, one related to performance bugs, and another other related to 
changing the complexity of the GC algorithm.

Hi Rick, your comments are on target, but I'll differ on some fine points 
below. Thanks for writing.



Usability
Weak maps act as a GC API and in doing so violate GC's greatest strength:  the 
user does not have to be concerned with memory management.  Since the user can 
never observe that a key/value pair has been deleted,  weak maps are much 
better than weak refs but they still seem capable of causing hard to diagnose 
and fix performance bugs related to memory pressure and the particular GC 
implementation.

This is all true, but developers are already concerned with memory management. 
GC is good, I like it, but it is not and never will be perfect (enough). Even 
V8 is facing criticism in its nodejs.orghttp://nodejs.org embedding, for 
among other things having too-small heap limits. Node users are retracing the 
JVM user footprints and asking for an explicit library call, gc(), to force 
collection.

So weakmaps can't be the breaking point that throws concern over memeory 
management via GC into users' faces. It's an issue on the client side too, 
already (and for many years, mostly due to cycles crossing through the DOM, 
which is under separate, often ref-counted, management, back to JS via the 
global object containing a closure capturing its environment, including 
document).

Plus, weakmaps give JS bridge-builders and compiler/runtime writers a needed 
tool, without which the only options are too costly (linear search of an array 
matching object reference identity) and leak-prone (strong references only).



 GC implementation
Software stacks on multicores will need GCs to become increasingly concurrent 
and latency free. Weak maps cause concurrent GCs and additional mutator 
synchronizations.  While a concurrent GC already has to do some 
synchronization, each additional synchronization point impedes scalability. My 
concern is that the number of synchronization points might be proportional to 
the number of k, v pairs in the weak maps (see below).

Browsers do not multithread JS, the language has no such execution model. More, 
it won't get one. Nodejs uses a single thread for all requests, requiring 
continuation passing style coding. There are alternatives, along Erlang lines, 
but they do not involve shared mutable state. So no global, concurrent GC is in 
the cards, on client or server -- my best projection (and strong advice!).



 GC Complexity
Another potential performance bug is that the complexity of the Abstract GC 
Algorithm at http://wiki.ecmascript.org/doku.php?id=harmony:weak_maps appears 
to be O(n**2), since each loop may only discover a single retained key k from 
(k,v) whose walk of the related value v discovers only a single unretained k. 
This would then be repeated and require rescanning all