Subj : Re: Problems with garbage collection and read-only properties. To : netscape.public.mozilla.jseng From : Brendan Eich Date : Thu Nov 20 2003 11:31 am Brendan Eich wrote: > If you want to use the property value (slots) storage provided by > native objects, you can do that several ways. If you don't want to > use a slot, use the JSPROP_SHARED attribute on the property (which > should really be defined in the class prototype, if you support more > than one instance of the class), and store the property value yourself > in private data. In the latter case, you'll need to implement > JSClass.mark yourself, and call JS_MarkGCThing on any gc-thing > (JSObject *, JSString *, or jsdouble * -- or a jsval for which > JSVAL_IS_GCTHING reports true). [snip] > If you switch to defining properties via JS_InitClass, so they take up > memory only once per property per class in the class's prototype > object, then you don't need the prototype property to have any value. > But since you're using tinyids, you do want the class getProperty hook > handle ids for which JSVAL_IS_INT(id) reports true, usually by > switching on JSVAL_TO_INT(id) with cases for all the well-known > tinyids. Each case would then fetch the appropriate private data > member, which (again) you are reponsible for marking via your > JSClass.mark hook. > > Then the problem becomes: how to set the private data member so that > subsequent getProperty calls can return it via *vp. That's up to you: > you define the native data structure, you can provide setters for its > members. To connect the first paragraph cited above with the second and third: the second and third describe the case where you manage the value storage for your properties, in per-object private data structs whose members you must mark via a non-null JSClass.mark. The first paragraph says to use JSPROP_SHARED among the prototype property's attributes, and define the property with a tinyid only in the class prototype (using JS_InitClass). But if you want to use the object's slots vector to store values for these properties, you can do that instead of using private data. In this case, you don't need JSClass.mark, but you do need JSCLASS_HAS_RESERVED_SLOTS (see jsapi.h). Then you would set each reserved slot associated with a tinyid using JS_SetReservedSlot. These slots will be marked by the GC. The trade-off is simple: if you need to define your own private data (JS_SetPrivate, etc.), and especially if that private data struct is useful in your native (C or C++) code in its own right, then you probably want to use JSPROP_SHARED and manage the value storage yourself, in the private data, with your own JSClass.mark. If you don't have per-object private data, or don't need to store the tinyid'd properties values there, you may as well use reserved slots. /be .