Subj : Re: GC questions To : Brad DeGrazia From : Brendan Eich Date : Thu Jun 19 2003 10:18 am Brad DeGrazia wrote: > Currently I'm using SpiderMonkey on a single thread (no problems with it), > but will be opening it up to a multi-threaded environment soon. My app uses > EvaluateScript to execute scripts that mostly call defined C functions. Is > it necessary to have any sort of GC protection (Begin/EndRequest) within my > C functions that are called from JavaScript? Only if a native function calls a blocking operation, whether an i/o system call, or a mutex lock or monitor entry call, or anything that might make the calling thread wait indefinitely. In that case, and only in that case (only around the blocking call, not around the entire body of the native function), you should use JS_SuspendRequest and JS_ResumeRequest. I do basic things in there > like extract the passed arguments from argv[] using JS_Value* and set an > appropriate return value (rval) using the JS_New* functions. Do you call out to other methods or functions? Might one of them evaluate a script, or otherwise do something that could lead to the GC running? If so, you need to make sure any newborn GC-things created by JS_ValueTo* calls are protected by local roots before you make such nested calls. > > Also, I was looking at the Garbage Collecting tips document > http://www.mozilla.org/js/spidermonkey/gctips.html and was wondering if > anyone could explain how in tip #3, "argv[0] = STRING_TO_JSVAL(str1); " > avoids GC problems? Sure -- the GC scans argv for all active frames on all contexts, when marking live GC-things. I see that the macro is performing a bitwise OR on the > JSString* str1, but the purpose of this is beyond me. I ask this because > most of my code extracts string parameters by doing something like this: > > CString str( JS_GetStringBytes(JS_ValueToString(argv[0])) ); > > After reading a bunch of posts, I'm beginning to wonder if that's a misuse > of the JS_ functions. Does CString's constructor copy the bytes at the address returned by JS_GetStringBytes? If so, you're ok. If not, and it makes the str variable point to those bytes, then you need ensure that they stay alive as long as the CString instance does. The following will keep those bytes alive as long as argv[0] is valid (until your native function returns): JSString *jstr = JS_ValueToString(argv[0]); if (!jstr) return JS_FALSE; argv[0] = STRING_TO_JSVAL(jstr); CString cstr(JS_GetStringBytes(jstr)); But if, as one would hope, CString's constructor does copy into a separately allocated buffer that lives as long as the CString instance lives, then you might simplify your code further using JS_ConvertArguments -- this pays off especially if you have several arguments to convert. /be .