From 256e50f2afa9df522eb1f3843ea82cd780f672d6 Mon Sep 17 00:00:00 2001 From: "brendan%mozilla.org" Date: Thu, 20 Oct 2005 18:58:24 +0000 Subject: [PATCH] Use local roots effectively (312278, r=igor). git-svn-id: svn://10.0.0.236/trunk@182604 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/js/src/jsarray.c | 6 +++++- mozilla/js/src/jsobj.c | 17 ++++++++++++----- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/mozilla/js/src/jsarray.c b/mozilla/js/src/jsarray.c index 3b6a39bdc5e..1a0c233fc79 100644 --- a/mozilla/js/src/jsarray.c +++ b/mozilla/js/src/jsarray.c @@ -363,7 +363,6 @@ array_join_sub(JSContext *cx, JSObject *obj, JSString *sep, JSBool literalize, jsval *rval, JSBool localeString) { JSBool ok; - jsval v; jsuint length, index; jschar *chars, *ochars; size_t nchars, growth, seplen, tmplen; @@ -444,6 +443,9 @@ array_join_sub(JSContext *cx, JSObject *obj, JSString *sep, JSBool literalize, sepstr = NULL; seplen = JSSTRING_LENGTH(sep); + /* Use rval to locally root each element value as we loop and convert. */ +#define v (*rval) + v = JSVAL_NULL; for (index = 0; index < length; index++) { ok = JS_GetElement(cx, obj, index, &v); @@ -518,6 +520,8 @@ array_join_sub(JSContext *cx, JSObject *obj, JSString *sep, JSBool literalize, return ok; } +#undef v + make_string: if (!chars) { JS_ReportOutOfMemory(cx); diff --git a/mozilla/js/src/jsobj.c b/mozilla/js/src/jsobj.c index 1d131efe965..1fa9cdc5eac 100644 --- a/mozilla/js/src/jsobj.c +++ b/mozilla/js/src/jsobj.c @@ -628,7 +628,7 @@ js_LeaveSharpObject(JSContext *cx, JSIdArray **idap) } } -#define OBJ_TOSTRING_EXTRA 3 /* for 3 local GC roots */ +#define OBJ_TOSTRING_EXTRA 4 /* for 4 local GC roots */ #if JS_HAS_INITIALIZERS || JS_HAS_TOSOURCE JSBool @@ -649,7 +649,7 @@ js_obj_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, JSProperty *prop; uintN attrs; #endif - jsval val[2]; + jsval *val; JSString *gsop[2]; JSAtom *atom; JSString *idstr, *valstr, *str; @@ -759,6 +759,13 @@ js_obj_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, comma = NULL; + /* + * We have four local roots for cooked and raw value GC safety. Hoist the + * "argv + 2" out of the loop using the val local, which refers to the raw + * (unconverted, "uncooked") values. + */ + val = argv + 2; + for (i = 0, length = ida->length; i < length; i++) { /* Get strings for id and value and GC-root them via argv. */ id = ida->vector[i]; @@ -826,7 +833,7 @@ js_obj_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, ok = JS_FALSE; goto error; } - argv[0] = STRING_TO_JSVAL(idstr); + *rval = STRING_TO_JSVAL(idstr); /* local root */ /* * If id is a string that's a reserved identifier, or else id is not @@ -841,7 +848,7 @@ js_obj_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, ok = JS_FALSE; goto error; } - argv[0] = STRING_TO_JSVAL(idstr); + *rval = STRING_TO_JSVAL(idstr); /* local root */ } idstrchars = JSSTRING_CHARS(idstr); idstrlength = JSSTRING_LENGTH(idstr); @@ -853,7 +860,7 @@ js_obj_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, ok = JS_FALSE; goto error; } - argv[1+j] = STRING_TO_JSVAL(valstr); + argv[j] = STRING_TO_JSVAL(valstr); /* local root */ vchars = JSSTRING_CHARS(valstr); vlength = JSSTRING_LENGTH(valstr);