Re: Weak event listener
Le 27/03/2013 00:22, Kevin Gadd a écrit : OK, it seems like Weak References are now being discussed without the context of previous discussions of weak references, which is a little annoying. Non-contrived real-world use cases that require Weak References (or a primitive with similar capabilities, like a Map with weak values instead of weak keys, I'm not picky) have already been provided *on this list* the last time WRs were discussed. I provided two based on real applications I've worked on; I thought other people in the discussion thread provided more. I've been through the thread and I haven't read any use case that *requires* Weak References. Only use cases where they make life easier to various degrees. It's been agreed that in most cases, adding an explicit .dispose() or equivalent protocol could work too. The only use case where I have some intuition of WeakRefs making a significant difference is the data binding use case. I find the compile weakrefs from another language use case a bit too early since compiling to JS is such a recent trend. As I said in one message, there is always a need of cutting some reference somewhere [1] for WeakRefs to work. What process needs to be followed before people will believe that Weak References are a real primitive that solves real problems? Do you need a set of broken, non-functional 'real world' applications written in JS that work in a customized version of V8/SpiderMonkey that has WRs? Do you need more verbose descriptions of use cases than previously provided? I can try to provide more justification than I did previously if this is necessary; I wasn't aware that it was. From what I read, until Jason joined the discussion, it was mostly me that was being annoying on use cases. So I can give my criteria if that helps (as a reminder, I'm not part of TC39, so you're also free to ignore what I say). I'd like to see the description of a use case (something more specific than just data binding) and an implementation that has been thought with memory management in mind. If this implementation proves to be minimalistic and simple enough, but yet too complex to use without WeakRefs, I'll be convinced. The thought with memory management in mind part is important. I don't think I have ever seen a talk describing a library where the author talked about the lifecycle of the objects created/used by the library. Memory footprint is sometimes discussed, but not lifecycle. From what I've observed, it's only after a severe memory leak is observed that people start to think about object lifecycle. Obviously, at that time, it's sometimes too late to do major refactoring and a lot of people would love to have weakrefs as a quickfix tool. From what I've observed too, very few people seem to understand GC at all. A lot of people still cite cycles as an issue of GC. So I wonder how many people really think of object lifecycles properly when designing libraries/frameworks. But what if object lifecycle was considered in the design? Maybe we'd realize WeakRefs are necessary to dramatically reduce the burden/boilerplate of some use cases. Maybe we'd find out a different way of designing libraries and realize WeakRefs aren't that necessary after all. Maybe tomorrow, i'll be writing a library and see the light or see the design of a library and see the light that without weakrefs, life is so much harder. I haven't yet come across such a case, so I'm not convinced yet. David [1] https://mail.mozilla.org/pipermail/es-discuss/2013-March/028935.html ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak event listener
On Mon, Apr 1, 2013 at 8:34 AM, David Bruant bruan...@gmail.com wrote: Le 27/03/2013 00:22, Kevin Gadd a écrit : OK, it seems like Weak References are now being discussed without the context of previous discussions of weak references, which is a little annoying. Non-contrived real-world use cases that require Weak References (or a primitive with similar capabilities, like a Map with weak values instead of weak keys, I'm not picky) have already been provided *on this list* the last time WRs were discussed. I provided two based on real applications I've worked on; I thought other people in the discussion thread provided more. I've been through the thread and I haven't read any use case that *requires* Weak References. Only use cases where they make life easier to various degrees. It's been agreed that in most cases, adding an explicit .dispose() or equivalent protocol could work too. Using `.dispose()` is manual management of the allocation and deallocation of object. Manual memory management is fundamentally non-modular -- you can't encapsulate it in a library, and it requires describing memory management behavior in all your function specifications, the way that C libraries do. It's certainly possible to write large, complex apps in C. But that's not evidence that we should bring those practices to JS. Sam ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: preventExtensions trap and its true/false protocol
Hi David, The messages you cite discuss the return value of the oddball unknownPrivateSymbol trap. For the preventExtensions trap I see no reason to be inconsistent with the set and defineProperty traps. Also, Reflect.preventExtensions (and Reflect.set, Reflect.defineProperty) will make the boolean trap return value directly visible and usable. Personally, I find code like: if (Reflect.preventExtensions(obj)) { // success code } else { // failure code } cleaner than: try { Object.preventExtensions(obj); // success code } catch (e) { // failure code } Moreover, in the latter piece of code, we may accidentally catch the wrong exception. In short, I don't see what's wrong with the boolean return value protocol. I find it much cleaner than the throw/return protocol. In addition, boolean return values can be more easily combined using the boolean operators. throw/return exit signals can't be combined that straightforwardly. Cheers, Tom 2013/4/1 David Bruant bruan...@gmail.com Le 31/03/2013 21:17, Jeff Walden a écrit : On 03/31/2013 11:02 AM, David Bruant wrote: From the developer perspective, this doesn't really add anything since it's already possible to throw from within the trap (and that's probably more explicit and clearer than returning false). That puts the onus on the trap to throw the correct kind of error, right? What do you mean by correct? It's already possible to throw any sort of error from any trap; I'm not sure what's correct and what isn't in that context. Admittedly this should be easy enough to get right, but it is a slight bit of extra complexity, versus having the implementation throw the correct error in one central location. I think the difference is at best marginal. As a reader of people writing JS code, I'd rather have people explicitly throwing than having to remember which trap has a true/false protocol. As a web developer, I'm happy if the surface of things to test for web browser implementors is smaller ;-) (and that's going to be a net reduction in terms of spec and I guess in implementations if the trap result is just ignored) David __**_ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/**listinfo/es-discusshttps://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: preventExtensions trap and its true/false protocol
Le 01/04/2013 17:22, Tom Van Cutsem a écrit : Hi David, The messages you cite discuss the return value of the oddball unknownPrivateSymbol trap. I assumed the comments applied to true/false protocols in general, but I'm interested if there is disagreement on that point. For the preventExtensions trap I see no reason to be inconsistent with the set and defineProperty traps. Historically, the internal operations these relate to needed to return a boolean and a decision on throwing or not was made based on strictness of the code. This isn't true for Object.preventExtensions. Also, Reflect.preventExtensions (and Reflect.set, Reflect.defineProperty) will make the boolean trap return value directly visible and usable. Personally, I find code like: if (Reflect.preventExtensions(obj)) { Note that Object.preventExtensions/seal/freeze do not return a boolean, but the object being manipulated. Is this an expected inconsistency? I hadn't given a lot of thoughts to it, but that could make a lot of sense. // success code } else { // failure code } cleaner than: try { Object.preventExtensions(obj); // success code } catch (e) { // failure code } Moreover, in the latter piece of code, we may accidentally catch the wrong exception. That's what has been necessary to detect whether it was possible to freeze an host object or not (that is, detecting if it worked). In any case, since an error can be thrown anyway from the trap (and the error won't be swallowed), doing a try/catch may still be necessary. David ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: preventExtensions trap and its true/false protocol
On 3/31/2013 4:38 PM, David Bruant wrote: Le 31/03/2013 21:17, Jeff Walden a écrit : On 03/31/2013 11:02 AM, David Bruant wrote: From the developer perspective, this doesn't really add anything since it's already possible to throw from within the trap (and that's probably more explicit and clearer than returning false). That puts the onus on the trap to throw the correct kind of error, right? What do you mean by correct? It's already possible to throw any sort of error from any trap; I'm not sure what's correct and what isn't in that context. The developer probably won't know what the correct error to throw is, assuming their goal is to fail exactly like Object.preventExtensions does. That is, the error that will be thrown from Object.preventExtensions is only specified as a TypeError; different engines can (and often do) have different error messages, and different localizations will also have different messages. This is something a developer can't hope to mimic. That and throwing isn't always the correct action when the preventExtension trap fail (Reflect.preventExtensions). Boolean is definitely the right thing for this trap to return. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: preventExtensions trap and its true/false protocol
On 04/01/2013 09:41 AM, Brandon Benvie wrote: That is, the error that will be thrown from Object.preventExtensions is only specified as a TypeError; different engines can (and often do) have different error messages, and different localizations will also have different messages. This is something a developer can't hope to mimic. Note that this could also be construed as a feature, in certain cases. The dead object proxy Mozilla has, previously mentioned here (can't find a link), has all its traps throw an error with a message saying Dead object. If the trap returns true/false, it's no longer possible for preventExtensions to say that the object in question is dead, not just can't be made non-extensible. Now, whether this use case, and other cases we could conjure up with a little thought, actually motivate reserving the throw to the trap -- that's another matter. I'm just saying there are some small tradeoffs both ways here. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak event listener
Right. David, I thought I had you convinced at: http://www.mail-archive.com/es-discuss@mozilla.org/msg21480.html /be Sam Tobin-Hochstadt wrote: On Mon, Apr 1, 2013 at 8:34 AM, David Bruantbruan...@gmail.com wrote: Le 27/03/2013 00:22, Kevin Gadd a écrit : OK, it seems like Weak References are now being discussed without the context of previous discussions of weak references, which is a little annoying. Non-contrived real-world use cases that require Weak References (or a primitive with similar capabilities, like a Map with weak values instead of weak keys, I'm not picky) have already been provided *on this list* the last time WRs were discussed. I provided two based on real applications I've worked on; I thought other people in the discussion thread provided more. I've been through the thread and I haven't read any use case that *requires* Weak References. Only use cases where they make life easier to various degrees. It's been agreed that in most cases, adding an explicit .dispose() or equivalent protocol could work too. Using `.dispose()` is manual management of the allocation and deallocation of object. Manual memory management is fundamentally non-modular -- you can't encapsulate it in a library, and it requires describing memory management behavior in all your function specifications, the way that C libraries do. It's certainly possible to write large, complex apps in C. But that's not evidence that we should bring those practices to JS. Sam ___ 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: memory safety and weak references
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.com wrote: On Mar 29, 2013, at 7:36 AM, David Herman dher...@mozilla.com wrote: On Mar 27, 2013, at 4:52 AM, Sam Tobin-Hochstadt sa...@ccs.neu.edu wrote: On Tue, Mar 26, 2013 at 11:44 PM, Oliver Hunt 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 ___ 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: 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.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.com wrote: On Mar 29, 2013, at 7:36 AM, David Herman dher...@mozilla.com wrote: On Mar 27, 2013, at 4:52 AM, Sam Tobin-Hochstadt sa...@ccs.neu.edu wrote: On Tue, Mar 26, 2013 at 11:44 PM, Oliver Hunt 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 ___ 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: memory safety and weak references
Marius Gundersen 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, No, that's not the issue in this (sub-)thread. Oliver was just recollecting thoughts about a position he took in favor of WeakMaps having non-object keys. You're right that any double (e.g.) that might be confused for a pointer in a VM implementation makes a bad bug, and VMs must carefully avoid (find and fix!) such bugs. The issue about non-object WeakMap keys was about semantics only, not implementation safety bugs. If I can put 42 in a WeakMap, it can never be removed, since I can forge that value by uttering the 42 literal again, or (in a way refractory to analysis) concatenating 4 and 2, etc. /be 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.com mailto:oli...@apple.com wrote: On Mar 29, 2013, at 7:36 AM, David Herman dher...@mozilla.com mailto:dher...@mozilla.com wrote: On Mar 27, 2013, at 4:52 AM, Sam Tobin-Hochstadt sa...@ccs.neu.edu mailto:sa...@ccs.neu.edu wrote: On Tue, Mar 26, 2013 at 11:44 PM, Oliver Hunt oli...@apple.com mailto: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 ___ 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 https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
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. The issue about non-object WeakMap keys was about semantics only, not implementation safety bugs. If I can put 42 in a WeakMap, it can never be removed, since I can forge that value by uttering the 42 literal again, or (in a way refractory to analysis) concatenating 4 and 2, etc. This is why I suggested, in the other thread, a system for weak event listeners. This would not be a problem if the only allowed argument to a weak reference is a function. An iterable weak set of functions would not have this problem, would solve the suggested usecases for weak references (observables/events): Marius Gundersen On Mon, Apr 1, 2013 at 10:39 PM, Brendan Eich bren...@mozilla.com wrote: Marius Gundersen 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, No, that's not the issue in this (sub-)thread. Oliver was just recollecting thoughts about a position he took in favor of WeakMaps having non-object keys. You're right that any double (e.g.) that might be confused for a pointer in a VM implementation makes a bad bug, and VMs must carefully avoid (find and fix!) such bugs. The issue about non-object WeakMap keys was about semantics only, not implementation safety bugs. If I can put 42 in a WeakMap, it can never be removed, since I can forge that value by uttering the 42 literal again, or (in a way refractory to analysis) concatenating 4 and 2, etc. /be 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.com mailto: oli...@apple.com wrote: On Mar 29, 2013, at 7:36 AM, David Herman dher...@mozilla.com mailto:dher...@mozilla.com wrote: On Mar 27, 2013, at 4:52 AM, Sam Tobin-Hochstadt sa...@ccs.neu.edu mailto:sa...@ccs.neu.edu wrote: On Tue, Mar 26, 2013 at 11:44 PM, Oliver Hunt oli...@apple.com mailto: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 __**_ es-discuss mailing list es-discuss@mozilla.org mailto:es-discuss@mozilla.org** https://mail.mozilla.org/**listinfo/es-discusshttps://mail.mozilla.org/listinfo/es-discuss __**_ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/**listinfo/es-discusshttps://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: memory safety and weak references
Marius Gundersen wrote: This is why I suggested, in the other thread, a system for weak event listeners. This would not be a problem if the only allowed argument to a weak reference is a function. An iterable weak set of functions would not have this problem, would solve the suggested usecases for weak references (observables/events): WeakMaps are useful for membranes too, not just event listeners: http://wiki.ecmascript.org/doku.php?id=harmony:proxiess=proxy#an_identity-preserving_membrane http://wiki.ecmascript.org/doku.php?id=harmony:proxiess=proxy#garbage_collection_behavior /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: memory safety and weak references
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
In that case it would be alive unless you destroyed the local variable 'x', but in some environments the compiler is free to treat it as dead. I believe in .NET the variable 'x' is only alive up until its last reference, so the variable would become dead immediately after the construction of the weak reference. The WR itself definitely should not affect object liveness. If you mean liveness in terms of like... escape analysis? Then I think you would have no issues as long as the weak reference doesn't escape. Optimization in the presence of weak references is probably not something authors should rely on, though. P.S. That gc() call wouldn't be guaranteed to collect x. The GC is free to keep it alive for whatever reason it chooses (I'm not aware of any of these reasons, but I've encountered this behavior before) On Mon, Apr 1, 2013 at 2:37 PM, Hudson, Rick rick.hud...@intel.com wrote: 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.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
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
On Mon, Apr 1, 2013 at 2:56 PM, Brendan Eich bren...@mozilla.com wrote: 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. Not necessarily. For example, a conservative gc might not be able to see that foo is no longer actually reachable. http://wiki.ecmascript.org/doku.php?id=strawman:gc_semantics explains that this is why it states such matters as SHOULDs rather than MUSTs. Of course, if we imagine a gc() function with a stronger contract, then the above would follow. I am skeptical that we could ever state such a stronger contract that all JS implementors could agree to. -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: memory safety and weak references
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
On Mon, Apr 1, 2013 at 3:12 PM, Hudson, Rick 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. If we agree on that then I think we agree that someWeakRef.get(); is allowed to return null. I see. I misunderstood the question. Yes, I believe this should be allowed but not required. http://wiki.ecmascript.org/doku.php?id=strawman:gc_semantics states Our safety requirements allow some reachable objects to be collected as well, so long as the garbage collector can ascertain that they will never be reached. - 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 -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: memory safety and weak references
On Apr 1, 2013, at 3:12 PM, Hudson, Rick 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: memory safety and weak references
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: memory safety and weak references
Hi Rick, thanks for the clarifications. With the example as written, no later uses of x (even inside a direct eval or closure that captures x and might be called after the gc()!) then I agree with Mark -- should not must. /be Hudson, Rick wrote: 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.com mailto: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: endianness (was: Observability of NaN distinctions — is this a concern?)
On Sun, Mar 31, 2013 at 1:42 PM, Kevin Gadd kevin.g...@gmail.com wrote: One could also argue that people using typed arrays to alias and munge individual values should be using DataView instead. If it performs poorly, that can hopefully be addressed in the JS runtimes (the way it's specified doesn't seem to prevent it from being efficient). Agreed. DataView's methods are all simple and should be easy to optimize. Because they include a conditional byte swap, they can't run quite as fast as the typed arrays' accessors -- but they shouldn't need to. DataView was designed to support file and network I/O, where throughput is limited by the disk or network connection. The typed array views were designed for in-memory assembly of data to be submitted to the graphics card, sound card, etc., and must run as fast as possible. -kg On Sun, Mar 31, 2013 at 1:37 PM, Vladimir Vukicevic vladi...@mozilla.com wrote: (Apologies for breaking threading -- subscribed too late to have original message to reply to.) David Herman wrote: On Mar 27, 2013, at 6:51 AM, Andreas Rossberg rossberg at google.com wrote: There actually are (third-party) projects with ports of V8 and/or Chromium to big endian architectures. It would be helpful to have more information about what these platforms and projects are. The Wii-U is probably the highest profile example of this; PowerPC base, and they're doing a bunch of HTML5 apps stuff like what they announced at GDC. WebGL code should not break or become prohibitively expensive on them all of a sudden. But WebGL code doesn't break either way. It's if we *don't* mandate little-endian that code breaks. As for the expense, it has to be weighed against content breaking. Not to mention the burden it places on developers to write portable code without even having big-endian user agents to test on. (I suppose they could use DI and shim the typed array constructors with simulated big-endian versions. Ugh...) The problem, as I see it at least, is that if little-endian is mandated, then effectively we *have* broken WebGL, or the possibility o ever having performant WebGL on those platforms. The underlying OpenGL API will always be native-endian. While big-endian processors often do have ways of efficiently doing byte-swapped loads and stores, that doesn't apply to passing bulk data down. For example, vertex skinning is the base method of doing skeletal animation. It's often done on the CPU, and it involves transforming a bunch of floating point data. The result is then uploaded to the GPU for rendering. If typed arrays are fixed to be little endian, that means that on big endian platforms one of two things will need to happen: - the application will need to manually byte swap (in JS) by aliasing the Float32Array as a UInt8Array and twiddling bytes. - the WebGL implementation will need to make a copy of every incoming 1 byte element size buffer and do the byte swapping before passing it down to GL -- it can either allocate a second buffer, swap into it, and then throw it away, or it can swap before the GL call and unswap after the GL call in-place. If the typed array views are specified to be little-endian, the latter is what would need to be done in order to allow existing content to run. I agree that this would make WebGL unusably slow on big-endian architectures. -Ken Both of these are essentially murder for performance; so by attempting to prevent code from breaking you're basically guaranteeing that all code will effectively break due to performance -- except that developers have no option to write portable and performant code. The other thing is, I suspect that a large chunk of code using typed arrays today will work just fine on big endian platforms, provided that the arrays are defined to be native-endian. Very few code actually aliases and does munging; the only issues might come up with are loading data from the network, but those are present regardless. - Vlad ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- -kg ___ 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
RegExp Flags
SM and v8 exhibit different behavior when evaluating the following: false ? /abc/ii : 0; In v8, no syntax error is thrown, presumably because regular expression flags are only validated when a RegExp object is created. In SM, a syntax error is thrown because flag validation is performed by the scanner. The current spec seems to lean toward the v8 interpretation. Thoughts? { Kevin } ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: RegExp Flags
I think SM behavior is right to the spec. According to 7.8.5, the error must be treated as an early error (Clause 16) And early error should be reported before evaluation of the Program (section 16) An early error is an error that can be detected and reported prior to the evaluation of any construct in the Program containing the error. An implementation must report early errors in a Program prior to the first evaluation of that Program. On Tue, Apr 2, 2013 at 1:22 PM, Kevin Smith zenpars...@gmail.com wrote: SM and v8 exhibit different behavior when evaluating the following: false ? /abc/ii : 0; In v8, no syntax error is thrown, presumably because regular expression flags are only validated when a RegExp object is created. In SM, a syntax error is thrown because flag validation is performed by the scanner. The current spec seems to lean toward the v8 interpretation. Thoughts? { Kevin } ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- Regards, Yusuke Suzuki ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: RegExp Flags
Original message Subject:RE: RegExp Flags From:Allen Wirfs-Brock al...@wirfs-brock.com To:zenpars...@gmail.com Cc: It's supposed to be an early syntax error. See last sentence of http://www.ecma-international.org/ecma-262/5.1/#sec-7.8.5 ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: RegExp Flags
I've already reported this issue :) https://code.google.com/p/v8/issues/detail?id=896 On Tue, Apr 2, 2013 at 2:33 PM, Allen Wirfs-Brock al...@wirfs-brock.comwrote: Original message Subject:RE: RegExp Flags From:Allen Wirfs-Brock al...@wirfs-brock.com To:zenpars...@gmail.com Cc: It's supposed to be an early syntax error. See last sentence of http://www.ecma-international.org/ecma-262/5.1/#sec-7.8.5 ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- Regards, Yusuke Suzuki ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss