Re: Weak callbacks?
On Thu, Nov 7, 2013 at 6:40 PM, K. Gadd k...@luminance.org wrote: To contrive a scenario that might illustrate where event listeners aren't necessarily enough: Let's say I have an entity system for a game that is modelling thousands of independent entities that interact. In this system, entity A might decide to chase after entity B, so it grabs a reference to entity B in order to chase after it. Meanwhile, entity B might be chasing after entity C, so it has a reference to entity C. Now, let's say entity C and entity B both are removed from the simulation. At this point, as long as entity A is alive, so are B and C (in GC terms) even though the latter two are not participating in the simulation. But if you were to rely on weak references for a use case like this, you'd nondeterministically get strange behavior. Entity A will be chasing something that is not in the simulation, until GC happens and it fixes itself. (As a bonus, the weirdness will happen in one implementation and not another, and you and your users will blame the implementation. So there will be pressure on implementers to reduce the nondeterminism by doing GC more frequently—which trades off against other performance measures.) And in this case, it all seems unnecessary. There is apparently already explicit code for both removing B and C, and later coping with their disappearance (since the weak reference may go null). That code could just as easily set a bit on B and C marking them as removed, and then test that in the chasing code. -j ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak callbacks?
Le 08/11/2013 17:09, Jason Orendorff a écrit : (As a bonus, the weirdness will happen in one implementation and not another, and you and your users will blame the implementation. So there will be pressure on implementers to reduce the nondeterminism by doing GC more frequently—which trades off against other performance measures.) Super-bonus: Heisenbugs (bugs that happen in prod, but not while debugging) https://en.wikipedia.org/wiki/Heisenbug And in this case, it all seems unnecessary. There is apparently already explicit code for both removing B and C, and later coping with their disappearance (since the weak reference may go null). That code could just as easily set a bit on B and C marking them as removed, and then test that in the chasing code. Agreed. In a way, Kevin conceded it when he wrote in an earlier message: I had to manually remove the event listeners at an appropriate time (and finding an appropriate time can be difficult!) And this looks very much like a software engineering issue, not a language issue. Maybe we (JavaScript developers!) should invest in better memory tooling see how far it gets us. We have fantastic tooling for studying time perf (Chrome has 2 types of profilers and the timeline view to help with the 60fps, Firefox and IE11 getting there too), how come we're still doing low-level heap snapshots for memory perf? Is space fundamentally that much harder to study than time? Taking the tooling road first, worst case, we throw the tooling away... not an option when a feature is in the wild. Let's try at least? David ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak callbacks?
Please try -- such experiments are interesting. But even if this experiment is successful, I hope and expect that we'll have weakrefs and post-mortem finalization in ES7. They are needed for many other things, such as distributed acyclic garbage collection (as in adapting the CapTP ideas to distributed JS). On Fri, Nov 8, 2013 at 8:57 AM, David Bruant bruan...@gmail.com wrote: Le 08/11/2013 17:09, Jason Orendorff a écrit : (As a bonus, the weirdness will happen in one implementation and not another, and you and your users will blame the implementation. So there will be pressure on implementers to reduce the nondeterminism by doing GC more frequently—which trades off against other performance measures.) Super-bonus: Heisenbugs (bugs that happen in prod, but not while debugging) https://en.wikipedia.org/wiki/Heisenbug And in this case, it all seems unnecessary. There is apparently already explicit code for both removing B and C, and later coping with their disappearance (since the weak reference may go null). That code could just as easily set a bit on B and C marking them as removed, and then test that in the chasing code. Agreed. In a way, Kevin conceded it when he wrote in an earlier message: I had to manually remove the event listeners at an appropriate time (and finding an appropriate time can be difficult!) And this looks very much like a software engineering issue, not a language issue. Maybe we (JavaScript developers!) should invest in better memory tooling see how far it gets us. We have fantastic tooling for studying time perf (Chrome has 2 types of profilers and the timeline view to help with the 60fps, Firefox and IE11 getting there too), how come we're still doing low-level heap snapshots for memory perf? Is space fundamentally that much harder to study than time? Taking the tooling road first, worst case, we throw the tooling away... not an option when a feature is in the wild. Let's try at least? David -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Rev21 ES6 Draft now available
PDFs and .doc file available at http://wiki.ecmascript.org/doku.php?id=harmony:specification_drafts#november_8_2013_draft_rev_21 New in this revision: • Updated Module Syntax and static semantics • Scripts no longer may contain import statements • Specified how to determine if a call is in tail position • The call and apply functions now internally do tail calls to the target function • Tweaked the new operator so it will work in tail position • Eliminated the [[Invoke]] MOP operation • Calling the next method of an completed generator returns a “done” result instead of throwing • The length property of bound functions is now configurable/non-writable • Clarified requirements of String localeCompare when no language sensitive comparison support is available. • Tweaked the ordering of a few steps in Array.from to enable self-hosting using for-of • Added ToInt8 and similar abstract operation • Defined name property of %TypedArray% and the individual typed array constructors • Significant fixed to yield * evaluation semantics • Fixed handling of identifier ‘yield’ in generator function parameter lists • A little static semantic cleanup making sure that FunctionDeclarations and GeneratorDeclarations have the same top level scoping rules ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak callbacks?
More tooling is great for developing new software in ES, but it does nothing to address use cases where existing software and algorithms can't be ported without Weak References. Perhaps enough research will allow us to arrive at some sort of general 'best practice' for replacing the use of weak references with something else; sounds like something some people with PhDs could write a paper on :) On Fri, Nov 8, 2013 at 8:57 AM, David Bruant bruan...@gmail.com wrote: Le 08/11/2013 17:09, Jason Orendorff a écrit : (As a bonus, the weirdness will happen in one implementation and not another, and you and your users will blame the implementation. So there will be pressure on implementers to reduce the nondeterminism by doing GC more frequently—which trades off against other performance measures.) Super-bonus: Heisenbugs (bugs that happen in prod, but not while debugging) https://en.wikipedia.org/wiki/Heisenbug And in this case, it all seems unnecessary. There is apparently already explicit code for both removing B and C, and later coping with their disappearance (since the weak reference may go null). That code could just as easily set a bit on B and C marking them as removed, and then test that in the chasing code. Agreed. In a way, Kevin conceded it when he wrote in an earlier message: I had to manually remove the event listeners at an appropriate time (and finding an appropriate time can be difficult!) And this looks very much like a software engineering issue, not a language issue. Maybe we (JavaScript developers!) should invest in better memory tooling see how far it gets us. We have fantastic tooling for studying time perf (Chrome has 2 types of profilers and the timeline view to help with the 60fps, Firefox and IE11 getting there too), how come we're still doing low-level heap snapshots for memory perf? Is space fundamentally that much harder to study than time? Taking the tooling road first, worst case, we throw the tooling away... not an option when a feature is in the wild. Let's try at least? David ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak callbacks?
On Nov 7, 2013, at 3:16 PM, Mark Miller wrote: I agree. This is a good use for weakrefs without the need for finalization. Thanks! On Thu, Nov 7, 2013 at 3:12 PM, K. Gadd k...@luminance.org wrote: The problem is that the cycles remain uncollectable for a very long period of time, even though functionally the references don't need to be strong. Ah, these are all basically the same problem and you will likely see the same latency effects for all of them. Any GC design where you may have serious latency for collection cyclic structures (for example, a generational heap where the circular structure crosses generations) is very likely to also have similar latency for zapping weak references that are used in the similarly shaped data structures. Allen___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Specification of use before declaration errors
Hello es-discuss, I'm having difficulty figuring out where the ES6 draft spec specifies that a use before declaration error should be thrown. My last understanding of the temporal dead zone was that ECMAScript would always issue a use before declaration error at runtime, regardless whether it can be statically determined or not. However it seems like the evaluation semantics of var declarations, for example, do not lead to any line that throws a ReferenceError. That is, consider this code: function f() { { var x = 5; let x; } } f(); I think the var declaration creates a binding for x in the function's lexical environment, but then binds to the x in the block's environment for the initialization. As such, the initialization should throw a use before declaration error. But this is what I cannot find in the spec. Maybe I am wrong about the semantics here? If I am not wrong then this raises the question of order of operations. Is the RHS evaluated first, then the error is thrown? Or is the LHS name evaluated first, throwing if it is a binding that is currently in its TDZ? E.g. is g() called here before throwing? function g() { console.log('hello'); return 0; } function f() { { var x = g(); let x; } } f(); How about for-in/of loops? Is g() called here? function g() { console.log('hello'); return { a: 1, b: 2, c: 3 }; } function f() { { for (var x in g()) { console.log('unreachable'); } let x; } } Ian Halliday ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Specification of use before declaration errors
On Nov 8, 2013, at 3:35 PM, Ian Halliday wrote: Hello es-discuss, I’m having difficulty figuring out where the ES6 draft spec specifies that a “use before declaration” error should be thrown. My last understanding of the temporal dead zone was that ECMAScript would always issue a “use before declaration” error at runtime, regardless whether it can be statically determined or not. However it seems like the evaluation semantics of var declarations, for example, do not lead to any line that throws a ReferenceError. That is, consider this code: function f() { { var x = 5; let x; declaring the same name using a let and a var is an early error: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-block-static-semantics-early-errors or for the function level http://people.mozilla.org/~jorendorff/es6-draft.html#sec-function-definitions-static-semantics-early-errors } } f(); I think the var declaration creates a binding for x in the function’s lexical environment, but then binds to the x in the block’s environment for the initialization. As such, the initialization should throw a “use before declaration” error. But this is what I cannot find in the spec. Maybe I am wrong about the semantics here? because an early error exists, the surround script or module is never evaluated. Allen___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak callbacks?
The difference is that if the large cycle is only uncollected because the weak references haven't been zapped, in a low memory/out of memory situation, the runtime's collector can go through and zap all weak references. If I write an ES application and do my own cycle collection/weak reference zapping, I have no way to respond to that low/out of memory situation by doing a collection on demand, so instead my application will run out of memory at arbitrary points in time. The latency is not actually a major concern here, and I wouldn't argue that weak references improve on latency. Weak references make it *possible* for the language's collector to collect those cycles *at all*. Without them, the only way they can be collected is if the *application* collects them, and it has no trivial way to do so at the correct time. I can't comment on how weak references would work in an ES collector either, but I can imagine weak reference implementations that would not prevent collection in the first place, so zapping would not be necessary in order for those cycles to be collected. IIRC, some weak reference implementations work by having the strong object maintain a list of the weak references that point to it, and the weak references do not actually keep the strong object alive. In such a scenario, you would not need to zap references for the object to be collected; rather, collecting the object would replace all the weak references with null, thus ensuring that the dead object stays unreachable. On Fri, Nov 8, 2013 at 2:42 PM, Allen Wirfs-Brock al...@wirfs-brock.comwrote: On Nov 7, 2013, at 3:16 PM, Mark Miller wrote: I agree. This is a good use for weakrefs without the need for finalization. Thanks! On Thu, Nov 7, 2013 at 3:12 PM, K. Gadd k...@luminance.org wrote: The problem is that the cycles remain uncollectable for a very long period of time, even though functionally the references don't need to be strong. Ah, these are all basically the same problem and you will likely see the same latency effects for all of them. Any GC design where you may have serious latency for collection cyclic structures (for example, a generational heap where the circular structure crosses generations) is very likely to also have similar latency for zapping weak references that are used in the similarly shaped data structures. Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak callbacks?
Le 08/11/2013 20:35, Mark S. Miller a écrit : Please try -- such experiments are interesting. I am :-) But even if this experiment is successful, I hope and expect that we'll have weakrefs and post-mortem finalization in ES7. They are needed for many other things, such as distributed acyclic garbage collection (as in adapting the CapTP ideas to distributed JS). yes... Speaking of which, could you explain the use of proxyRef.get from the related example? [1] At least in the executor function, I don't understand how the object could be still alive and why the call is needed. David [1] http://wiki.ecmascript.org/doku.php?id=strawman:weak_references#distributed_acyclic_garbage_collection ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak callbacks?
Hi David, there's a distributed race condition that's fixed by the use of importCount. Fixing it using post-mortem finalization creates a local race condition which is fixed by this test, not if the proxy is *still* alive, but if a new proxy has been installed as its reincarnation. For background, see http://www.erights.org/elib/distrib/captp/dagc.html and http://www.erights.org/elib/distrib/captp/DeliverOp.html. Kenton Varda is implementing a high performance adaptation of CapTP https://github.com/kentonv/capnproto/blob/master/c++/src/capnp/rpc.capnp as part of Cap'n Proto http://kentonv.github.io/capnproto/. (Kenton did Google's protobufs 2 and open sourced them before leaving Google to do this successor.) This CapTP-in-Cap'n Proto has essentially the same distributed gc logic for coping with the distributed race conditions, but in its C++ bindings, relies on local manual collection rather than observation of local GC, so it doesn't have the same local race condition. The distributed race condition is that VatA notices (by finalization of the proxy) that it has dropped all local references to its bobProxy for VatB's Bob object. So VatA sends a GCExportOp(i, importCount) (in original CapTP terminology) to VatB. However, in the meantime, a message from VatB to VatA contains a reference to VatB's Bob. When it serializes the references to Bob, it sees that Bob is already registered in its VatB-to-VatA exports table at index i, so it serializes the reference as an ImportDesc(i). (When it sends Bob the first time it sends a NewFarDesc instead.) The GCExportOp(i, importCount) from VatA-to-VatB might cross on the wire with the ImportDesc(i) from VatB to VatA, which is the distributed race condition issue. The solution is that every time VatB sends an ImportDesc(i) to VatA, it increments exportCount[i] in its VatB to VatA export table. Everytime VatA unserializes an ImportDesc(i), it calls the Import(i) function at http://wiki.ecmascript.org/doku.php?id=strawman:weak_references#distributed_acyclic_garbage_collection, which increments importCount[i] and returns a valid proxy registered in is VatA-from-VatB imports table at i. If the existing proxy still exists, it uses that one. Otherwise it creates a new one. When VatB receiver the GCExportOp(i, importCount) from VatA, it decrements its exportCount by that amount. If its exportCount reaches 0, then it knows it can null out entry i in its exports table, enabling local collection of Bob if there are no other local uses. Otherwise, it knows that it needs to keep Bob registered as exports[i]. The local race condition is that VatA's local GC might have collected bobProxy, therefore nulling out the proxyRef, and scheduled a notification of the handler that would send the GCExportOp. However, already queued on VatA ahead of the notification of the handler is the processing of the ImportDesc from VatB, so that gets processed first, creating a successor proxy at imports[i]. Finally, when the handler does get notified, it needs to check if such a successor has already been installed and is still alive. I know this is complex, but after many years of looking at it, I don't know how to make it any simpler. Consider this a challenge ;). (OTOH, after many years of use, I've come to have high confidence in it.) The Dec Src Network Object system has similar solutions to many of these distributed race condition problems. But they had a very different model of local concurrency (shared state concurrency with Tony Hoare monitors IIRC), so they had different local race condition problems. On Fri, Nov 8, 2013 at 4:49 PM, David Bruant bruan...@gmail.com wrote: Le 08/11/2013 20:35, Mark S. Miller a écrit : Please try -- such experiments are interesting. I am :-) But even if this experiment is successful, I hope and expect that we'll have weakrefs and post-mortem finalization in ES7. They are needed for many other things, such as distributed acyclic garbage collection (as in adapting the CapTP ideas to distributed JS). yes... Speaking of which, could you explain the use of proxyRef.get from the related example? [1] At least in the executor function, I don't understand how the object could be still alive and why the call is needed. David [1] http://wiki.ecmascript.org/doku.php?id=strawman:weak_ references#distributed_acyclic_garbage_collection -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss