On Wed, Jul 11, 2012 at 4:38 PM, Andreas Rossberg <[email protected]>wrote:

> In any case, before you conclude that finalization is the answer to your
> problems, let me +1 Sven's recommendation on reading Boehm's paper on the
> subject. Finalization is pretty much an anti-pattern. There are some rare,
> low-level use cases, but usually it creates more problems than it solves.
> That's why we only provide it in the C++ API.
>

Just to beat a long-dead horse for a moment...

Quoting Boem's paper:

Page 1: "We argue that although finalization is rarely needed, it is often
critical when it is needed. In these cases, its absence would render the
garbage collector useless."

"Rarely needed" is, in my (not inconsiderable) experience, 100% wrong for
JS bindings. The vast majority of the interesting client-side NATIVE types
which we want to bind to JS require resource acquisition and a large
percentage of them require well-defined finalization/destruction in order
to guaranty proper behaviour.

Examples, just off the top of my head:

- File handles must be close()d in order to ensure that they are flushed.
Yes, the OS closes them when the process exit()s, but AFAIK they are not
automatically flush()ed.

- Database drivers, statement handles, and query cursors all have very
specific cleanup requirements, and failing to properly close() a db handle
"could" (though admittedly "shouldn't") lead to undefined behaviour e.g. db
corruption.

- Anything which heavily relies on parent/child relationships, UI toolkits
being a prime example. Getting those working properly in JS can be a real
PITA because the child/parent relationships must be tracked in both JS and
native space in order to keep all the objects around for their proper
lifetimes. (When i first implements an ncurses binding for JS i quickly
found i had to make JS aware of all child window references to keep them
from being GC'd out from under the parent window's nose.)


We (client-side users of scripting engines) don't bind trivial classes to
native implementations. Such impls are done in JS because it's 100x times
easier to do so (e.g. the canonical "Point" class example). When we bind
natives its because we need native functionality which we cannot get at
from JS, and the vast majority of such functionality requires access to
"interesting" native resources with arbitrarily complex compositions and
cleanup requirements. i don't know of a single commonly-used C/C++ library
which does _not_ require that clients clean up resources it asked the
library to allocate for them.


Section 3.3, bullet point #1: "There is usually not much of a point in
writing a finalizer that touched only the object being finalized, since
such object updates wouldn't normally be observable."

i understand that this assertion "can be true", but it assumes that the
statement from Page 1 is true, which it is absolutely not for the generic
case when binding native C/C++ types to JS.

To be clear: i'm not picking no v8 here. In time since i wrote the original
gripes which Michael S. linked to in the top post of this thread, i have
since come to understand much more about the difficulties of finalization
ordering and whatnot, and have a much deeper appreciation for the nature of
the problem. Nonetheless, assertions like Boem's quotes above, in my
opinion, simply hand-wave away a _majority_ of use cases as "not useful" or
"rarely seen," when in fact the problem is that they are just damned
difficult to solve. Obviously Boem is the top of his field, and i don't
discount his brilliance in this subject matter, but hand-waving away such
problems as being "infrequent" does him no credit.

-- 
----- stephan beal
http://wanderinghorse.net/home/stephan/
http://gplus.to/sgbeal

-- 
v8-users mailing list
[email protected]
http://groups.google.com/group/v8-users

Reply via email to