Bug 612150 - Eliminating JS_GetFunctionName. r=mrbkap
authorIgor Bukanov <igor@mir2.org>
Wed, 24 Nov 2010 17:56:43 +0100
changeset 58976 e35b70ffed69cf1729e8ba7dff19bbe974e9e52b
parent 58751 8921e3faccd2558eab22efb3212aadda978edb99
child 58977 fc0384edf67bc8dbc7c502a1f56481e7dbf98025
push id17488
push userrsayre@mozilla.com
push dateThu, 09 Dec 2010 18:38:23 +0000
treeherdermozilla-central@58dcad7165be [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmrbkap
bugs612150
milestone2.0b8pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 612150 - Eliminating JS_GetFunctionName. r=mrbkap
js/jsd/jsd.h
js/jsd/jsd_scpt.c
js/jsd/jsd_stak.c
js/jsd/jsd_step.c
js/jsd/jsd_val.c
js/jsd/jsd_xpc.cpp
js/jsd/jsdebug.c
js/jsd/jsdebug.h
js/src/jsapi.cpp
js/src/jsapi.h
js/src/jscntxt.h
js/src/jsgc.cpp
js/src/jsprobes.cpp
js/src/jsprvtd.h
js/src/jsstr.cpp
js/src/jsstr.h
--- a/js/jsd/jsd.h
+++ b/js/jsd/jsd.h
@@ -268,17 +268,17 @@ struct JSDStackFrameInfo
 #define GOT_CTOR    ((short) (1 << 3))
 
 struct JSDValue
 {
     jsval       val;
     intN        nref;
     JSCList     props;
     JSString*   string;
-    const char* funName;
+    JSString*   funName;
     const char* className;
     JSDValue*   proto;
     JSDValue*   parent;
     JSDValue*   ctor;
     uintN       flags;
 };
 
 struct JSDProperty
@@ -455,17 +455,17 @@ extern void *
 jsd_GetScriptPrivate (JSDScript *jsdscript);
 
 extern JSBool
 jsd_IsActiveScript(JSDContext* jsdc, JSDScript *jsdscript);
 
 extern const char*
 jsd_GetScriptFilename(JSDContext* jsdc, JSDScript *jsdscript);
 
-extern const char*
+extern JSString*
 jsd_GetScriptFunctionName(JSDContext* jsdc, JSDScript *jsdscript);
 
 extern uintN
 jsd_GetScriptBaseLineNumber(JSDContext* jsdc, JSDScript *jsdscript);
 
 extern uintN
 jsd_GetScriptLineExtent(JSDContext* jsdc, JSDScript *jsdscript);
 
@@ -719,17 +719,17 @@ jsd_IsStackFrameConstructing(JSDContext*
                              JSDThreadState* jsdthreadstate,
                              JSDStackFrameInfo* jsdframe);
 
 extern JSDValue*
 jsd_GetThisForStackFrame(JSDContext* jsdc,
                          JSDThreadState* jsdthreadstate,
                          JSDStackFrameInfo* jsdframe);
 
-extern const char*
+extern JSString*
 jsd_GetNameForStackFrame(JSDContext* jsdc, 
                          JSDThreadState* jsdthreadstate,
                          JSDStackFrameInfo* jsdframe);
 
 extern JSDThreadState*
 jsd_NewThreadState(JSDContext* jsdc, JSContext *cx);
 
 extern void
@@ -964,17 +964,17 @@ extern int32
 jsd_GetValueInt(JSDContext* jsdc, JSDValue* jsdval);
 
 extern jsdouble
 jsd_GetValueDouble(JSDContext* jsdc, JSDValue* jsdval);
 
 extern JSString*
 jsd_GetValueString(JSDContext* jsdc, JSDValue* jsdval);
 
-extern const char*
+extern JSString*
 jsd_GetValueFunctionName(JSDContext* jsdc, JSDValue* jsdval);
 
 /**************************************************/
 
 extern uintN
 jsd_GetCountOfProperties(JSDContext* jsdc, JSDValue* jsdval);
 
 extern JSDProperty*
--- a/js/jsd/jsd_scpt.c
+++ b/js/jsd/jsd_scpt.c
@@ -192,32 +192,39 @@ OutputDebugString (char *buf)
     fprintf (stderr, "%s", buf);
 }
 #endif
 
 static void
 _dumpJSDScript(JSDContext* jsdc, JSDScript* jsdscript, const char* leadingtext)
 {
     const char* name;
-    const char* fun;
+    JSString* fun;
     uintN base;
     uintN extent;
     char Buf[256];
-    
+    size_t n;
+
     name   = jsd_GetScriptFilename(jsdc, jsdscript);
     fun    = jsd_GetScriptFunctionName(jsdc, jsdscript);
     base   = jsd_GetScriptBaseLineNumber(jsdc, jsdscript);
     extent = jsd_GetScriptLineExtent(jsdc, jsdscript);
-    
-    sprintf( Buf, "%sscript=%08X, %s, %s, %d-%d\n", 
-             leadingtext,
-             (unsigned) jsdscript->script,
-             name ? name : "no URL", 
-             fun  ? fun  : "no fun", 
-             base, base + extent - 1 );
+    n = size_t(snprintf(Buf, sizeof(Buf), "%sscript=%08X, %s, ",
+                        leadingtext, (unsigned) jsdscript->script,
+                        name ? name : "no URL"));
+    if (n + 1 < sizeof(Buf)) {
+        if (fun) {
+            n += size_t(snprintf(Buf + n, sizeof(Buf) - n, "%s", "no fun"));
+        } else {
+            n += JS_PutEscapedString(Buf + n, sizeof(Buf) - n, fun, 0);
+            Buf[sizeof(Buf) - 1] = '\0';
+        }
+        if (n + 1 < sizeof(Buf))
+            snprintf(Buf + n, sizeof(Buf) - n, ", %d-%d\n", base, base + extent - 1);
+    }
     OutputDebugString( Buf );
 }
 
 static void
 _dumpJSDScriptList( JSDContext* jsdc )
 {
     JSDScript* iterp = NULL;
     JSDScript* jsdscript = NULL;
@@ -483,22 +490,25 @@ jsd_IsActiveScript(JSDContext* jsdc, JSD
 }        
 
 const char*
 jsd_GetScriptFilename(JSDContext* jsdc, JSDScript *jsdscript)
 {
     return jsdscript->url;
 }
 
-const char*
+JSString*
 jsd_GetScriptFunctionName(JSDContext* jsdc, JSDScript *jsdscript)
 {
+    JSString* str;
+
     if( ! jsdscript->function )
         return NULL;
-    return JS_GetFunctionName(jsdscript->function);
+    str = JS_GetFunctionId(jsdscript->function);
+    return str ? str : JS_GetEmptyString(jsdc->jsrt);
 }
 
 uintN
 jsd_GetScriptBaseLineNumber(JSDContext* jsdc, JSDScript *jsdscript)
 {
     return jsdscript->lineBase;
 }
 
--- a/js/jsd/jsd_stak.c
+++ b/js/jsd/jsd_stak.c
@@ -351,31 +351,31 @@ jsd_GetThisForStackFrame(JSDContext* jsd
         if(ok)
             jsdval = JSD_NewValue(jsdc, thisval);
     }
 
     JSD_UNLOCK_THREADSTATES(jsdc);
     return jsdval;
 }
 
-const char*
+JSString*
 jsd_GetNameForStackFrame(JSDContext* jsdc, 
                          JSDThreadState* jsdthreadstate,
                          JSDStackFrameInfo* jsdframe)
 {
-    const char *rv = NULL;
+    JSString *rv = NULL;
     
     JSD_LOCK_THREADSTATES(jsdc);
     
     if( jsd_IsValidFrameInThreadState(jsdc, jsdthreadstate, jsdframe) )
     {
         JSFunction *fun = JS_GetFrameFunction (jsdthreadstate->context,
                                                jsdframe->fp);
         if (fun)
-            rv = JS_GetFunctionName (fun);
+            rv = JS_GetFunctionId (fun);
     }
     
     JSD_UNLOCK_THREADSTATES(jsdc);
     return rv;
 }
 
 JSBool
 jsd_IsStackFrameDebugger(JSDContext* jsdc, 
--- a/js/jsd/jsd_step.c
+++ b/js/jsd/jsd_step.c
@@ -64,48 +64,50 @@ static char*
 
 static void
 _interpreterTrace(JSDContext* jsdc, JSContext *cx, JSStackFrame *fp,
                   JSBool before)
 {
     JSDScript* jsdscript = NULL;
     JSScript * script;
     static indent = 0;
-    const char* funName = NULL;
+    JSString* funName = NULL;
 
     script = JS_GetFrameScript(cx, fp);
     if(script)
     {
         JSD_LOCK_SCRIPTS(jsdc);
         jsdscript = jsd_FindOrCreateJSDScript(jsdc, cx, script, fp);
         JSD_UNLOCK_SCRIPTS(jsdc);
         if(jsdscript)
             funName = JSD_GetScriptFunctionName(jsdc, jsdscript);
     }
-    if(!funName)
-        funName = "TOP_LEVEL";
+
+    if(before)
+        printf("%sentering ", _indentSpaces(indent++));
+    else
+        printf("%sleaving ", _indentSpaces(--indent));
+
+    if (!funName)
+        printf("TOP_LEVEL");
+    else
+        JS_FileEscapedString(stdout, funName, 0);
 
     if(before)
     {
         jsval thisVal;
 
-        printf("%sentering %s %s this: ",
-               _indentSpaces(indent++),
-               funName,
-               JS_IsConstructorFrame(cx, fp) ? "constructing":"");
+        printf("%s this: ", JS_IsConstructorFrame(cx, fp) ? "constructing":"");
 
         if (JS_GetFrameThis(cx, fp, &thisVal))
-            printf("0x%0llx\n", (JSUword) thisVal);
+            printf("0x%0llx", (JSUword) thisVal);
         else
             puts("<unavailable>");
     }
-    else
-    {
-        printf("%sleaving %s\n", _indentSpaces(--indent), funName);
-    }
+    printf("\n");
     JS_ASSERT(indent >= 0);
 }
 #endif
 
 JSBool
 _callHook(JSDContext *jsdc, JSContext *cx, JSStackFrame *fp, JSBool before,
           uintN type, JSD_CallHookProc hook, void *hookData)
 {
--- a/js/jsd/jsd_val.c
+++ b/js/jsd/jsd_val.c
@@ -241,17 +241,17 @@ jsd_GetValueString(JSDContext* jsdc, JSD
             }
             JS_LeaveCrossCompartmentCall(call);
             JS_EndRequest(cx);
         }
     }
     return jsdval->string;
 }
 
-const char*
+JSString*
 jsd_GetValueFunctionName(JSDContext* jsdc, JSDValue* jsdval)
 {
     JSContext* cx = jsdc->dumbContext;
     JSFunction* fun;
     JSExceptionState* exceptionState;
     JSCrossCompartmentCall *call = NULL;
 
     if(!jsdval->funName && jsd_IsValueFunction(jsdc, jsdval))
@@ -267,17 +267,19 @@ jsd_GetValueFunctionName(JSDContext* jsd
 
         exceptionState = JS_SaveExceptionState(cx);
         fun = JS_ValueToFunction(cx, jsdval->val);
         JS_RestoreExceptionState(cx, exceptionState);
         JS_LeaveCrossCompartmentCall(call);
         JS_EndRequest(cx);
         if(!fun)
             return NULL;
-        jsdval->funName = JS_GetFunctionName(fun);
+        jsdval->funName = JS_GetFunctionId(fun);
+        if (!jsdval->funName)
+            jsdval->funName = JS_GetEmptyString(jsdc->jsrt);
     }
     return jsdval->funName;
 }
 
 /***************************************************************************/
 
 JSDValue*
 jsd_NewValue(JSDContext* jsdc, jsval val)
--- a/js/jsd/jsd_xpc.cpp
+++ b/js/jsd/jsd_xpc.cpp
@@ -948,16 +948,33 @@ jsdProperty::GetVarArgSlot(PRUint32 *_rv
 {
     *_rval = JSD_GetPropertyVarArgSlot (mCx, mProperty);
     return NS_OK;
 }
 
 /* Scripts */
 NS_IMPL_THREADSAFE_ISUPPORTS2(jsdScript, jsdIScript, jsdIEphemeral)
 
+static NS_IMETHODIMP
+AssignToJSString(nsACString *x, JSString *str)
+{
+    if (!str) {
+        x->SetLength(0);
+        return NS_OK;
+    }
+    size_t length = JS_GetStringEncodingLength(NULL, str);
+    if (length == size_t(-1))
+        return NS_ERROR_FAILURE;
+    x->SetLength(PRUint32(length));
+    if (x->Length() != PRUint32(length))
+        return NS_ERROR_OUT_OF_MEMORY;
+    JS_EncodeStringToBuffer(str, x->BeginWriting(), length);
+    return NS_OK;
+}
+
 jsdScript::jsdScript (JSDContext *aCx, JSDScript *aScript) : mValid(PR_FALSE),
                                                              mTag(0),
                                                              mCx(aCx),
                                                              mScript(aScript),
                                                              mFileName(0), 
                                                              mFunctionName(0),
                                                              mBaseLineNumber(0),
                                                              mLineExtent(0),
@@ -966,18 +983,22 @@ jsdScript::jsdScript (JSDContext *aCx, J
 {
     DEBUG_CREATE ("jsdScript", gScriptCount);
 
     if (mScript) {
         /* copy the script's information now, so we have it later, when it
          * gets destroyed. */
         JSD_LockScriptSubsystem(mCx);
         mFileName = new nsCString(JSD_GetScriptFilename(mCx, mScript));
-        mFunctionName =
-            new nsCString(JSD_GetScriptFunctionName(mCx, mScript));
+        mFunctionName = new nsCString();
+        if (mFunctionName) {
+            JSString *str = JSD_GetScriptFunctionName(mCx, mScript);
+            if (str)
+                AssignToJSString(mFunctionName, str);
+        }
         mBaseLineNumber = JSD_GetScriptBaseLineNumber(mCx, mScript);
         mLineExtent = JSD_GetScriptLineExtent(mCx, mScript);
         mFirstPC = JSD_GetClosestPC(mCx, mScript, 0);
         JSD_UnlockScriptSubsystem(mCx);
         
         mValid = PR_TRUE;
     }
 }
@@ -1839,17 +1860,21 @@ jsdStackFrame::GetExecutionContext(jsdIC
     *_rval = jsdContext::FromPtr (mCx, cx);
     return NS_OK;
 }
 
 NS_IMETHODIMP
 jsdStackFrame::GetFunctionName(nsACString &_rval)
 {
     ASSERT_VALID_EPHEMERAL;
-    _rval.Assign(JSD_GetNameForStackFrame(mCx, mThreadState, mStackFrameInfo));
+    JSString *str = JSD_GetNameForStackFrame(mCx, mThreadState, mStackFrameInfo);
+    if (str)
+        return AssignToJSString(&_rval, str);
+    
+    _rval.Assign("anonymous");
     return NS_OK;
 }
 
 NS_IMETHODIMP
 jsdStackFrame::GetIsDebugger(PRBool *_rval)
 {
     ASSERT_VALID_EPHEMERAL;
     *_rval = JSD_IsStackFrameDebugger (mCx, mThreadState, mStackFrameInfo);
@@ -2167,18 +2192,17 @@ jsdValue::GetJsConstructor (jsdIValue **
     *_rval = jsdValue::FromPtr (mCx, jsdv);
     return NS_OK;
 }
 
 NS_IMETHODIMP
 jsdValue::GetJsFunctionName(nsACString &_rval)
 {
     ASSERT_VALID_EPHEMERAL;
-    _rval.Assign(JSD_GetValueFunctionName(mCx, mValue));
-    return NS_OK;
+    return AssignToJSString(&_rval, JSD_GetValueFunctionName(mCx, mValue));
 }
 
 NS_IMETHODIMP
 jsdValue::GetBooleanValue(PRBool *_rval)
 {
     ASSERT_VALID_EPHEMERAL;
     *_rval = JSD_GetValueBoolean (mCx, mValue);
     return NS_OK;
--- a/js/jsd/jsdebug.c
+++ b/js/jsd/jsdebug.c
@@ -297,17 +297,17 @@ JSD_IsActiveScript(JSDContext* jsdc, JSD
 JSD_PUBLIC_API(const char*)
 JSD_GetScriptFilename(JSDContext* jsdc, JSDScript *jsdscript)
 {
     JSD_ASSERT_VALID_CONTEXT(jsdc);
     JSD_ASSERT_VALID_SCRIPT(jsdscript);
     return jsd_GetScriptFilename(jsdc, jsdscript);
 }
 
-JSD_PUBLIC_API(const char*)
+JSD_PUBLIC_API(JSString *)
 JSD_GetScriptFunctionName(JSDContext* jsdc, JSDScript *jsdscript)
 {
     JSD_ASSERT_VALID_CONTEXT(jsdc);
     JSD_ASSERT_VALID_SCRIPT(jsdscript);
     return jsd_GetScriptFunctionName(jsdc, jsdscript);
 }
 
 JSD_PUBLIC_API(uintN)
@@ -736,17 +736,17 @@ JSD_PUBLIC_API(JSDValue*)
 JSD_GetThisForStackFrame(JSDContext* jsdc,
                          JSDThreadState* jsdthreadstate,
                          JSDStackFrameInfo* jsdframe)
 {
     JSD_ASSERT_VALID_CONTEXT(jsdc);
     return jsd_GetThisForStackFrame(jsdc, jsdthreadstate, jsdframe);
 }
 
-JSD_PUBLIC_API(const char*)
+JSD_PUBLIC_API(JSString *)
 JSD_GetNameForStackFrame(JSDContext* jsdc,
                          JSDThreadState* jsdthreadstate,
                          JSDStackFrameInfo* jsdframe)
 {
     JSD_ASSERT_VALID_CONTEXT(jsdc);
     return jsd_GetNameForStackFrame(jsdc, jsdthreadstate, jsdframe);
 }
 
@@ -1103,17 +1103,17 @@ JSD_GetValueDouble(JSDContext* jsdc, JSD
 JSD_PUBLIC_API(JSString*)
 JSD_GetValueString(JSDContext* jsdc, JSDValue* jsdval)
 {
     JSD_ASSERT_VALID_CONTEXT(jsdc);
     JSD_ASSERT_VALID_VALUE(jsdval);
     return jsd_GetValueString(jsdc, jsdval);
 }
 
-JSD_PUBLIC_API(const char*)
+JSD_PUBLIC_API(JSString *)
 JSD_GetValueFunctionName(JSDContext* jsdc, JSDValue* jsdval)
 {
     JSD_ASSERT_VALID_CONTEXT(jsdc);
     JSD_ASSERT_VALID_VALUE(jsdval);
     return jsd_GetValueFunctionName(jsdc, jsdval);
 }
 
 /**************************************************/
--- a/js/jsd/jsdebug.h
+++ b/js/jsd/jsdebug.h
@@ -424,19 +424,20 @@ JSD_IsActiveScript(JSDContext* jsdc, JSD
 
 /*
 * Get the filename associated with this script
 */
 extern JSD_PUBLIC_API(const char*)
 JSD_GetScriptFilename(JSDContext* jsdc, JSDScript *jsdscript);
 
 /*
-* Get the function name associated with this script (NULL if not a function)
+* Get the function name associated with this script (NULL if not a function).
+* If the function does not have a name the result is an empty string.
 */
-extern JSD_PUBLIC_API(const char*)
+extern JSD_PUBLIC_API(JSString *)
 JSD_GetScriptFunctionName(JSDContext* jsdc, JSDScript *jsdscript);
 
 /*
 * Get the base linenumber of the sourcefile from which this script was loaded.
 * This is one-based -- i.e. the first line of a file is line '1'. This may
 * return 0 if this infomation is unknown.
 */
 extern JSD_PUBLIC_API(uintN)
@@ -950,17 +951,17 @@ extern JSD_PUBLIC_API(JSDValue*)
 JSD_GetThisForStackFrame(JSDContext* jsdc,
                          JSDThreadState* jsdthreadstate,
                          JSDStackFrameInfo* jsdframe);
 
 /*
 * Get the name of the function executing in this stack frame.  Especially useful
 * for native frames (without script objects.)
 */
-extern JSD_PUBLIC_API(const char*)
+extern JSD_PUBLIC_API(JSString *)
 JSD_GetNameForStackFrame(JSDContext* jsdc,
                          JSDThreadState* jsdthreadstate,
                          JSDStackFrameInfo* jsdframe);
 
 /*
 * True if stack frame represents a frame created as a result of a debugger
 * evaluation.
 */
@@ -1283,17 +1284,17 @@ JSD_GetValueDouble(JSDContext* jsdc, JSD
 */
 extern JSD_PUBLIC_API(JSString*)
 JSD_GetValueString(JSDContext* jsdc, JSDValue* jsdval);
 
 /*
 * Return name of function IFF JSDValue represents a function.
 * *** new for version 1.1 ****
 */
-extern JSD_PUBLIC_API(const char*)
+extern JSD_PUBLIC_API(JSString *)
 JSD_GetValueFunctionName(JSDContext* jsdc, JSDValue* jsdval);
 
 /**************************************************/
 
 /*
 * Return the number of properties for the JSDValue.
 * *** new for version 1.1 ****
 */
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -197,16 +197,23 @@ JS_GetPositiveInfinityValue(JSContext *c
 }
 
 JS_PUBLIC_API(jsval)
 JS_GetEmptyStringValue(JSContext *cx)
 {
     return STRING_TO_JSVAL(cx->runtime->emptyString);
 }
 
+JS_PUBLIC_API(JSString *)
+JS_GetEmptyString(JSRuntime *rt)
+{
+    JS_ASSERT(rt->state == JSRTS_UP);
+    return rt->emptyString;
+}
+
 static JSBool
 TryArgumentFormatter(JSContext *cx, const char **formatp, JSBool fromJS, jsval **vpp, va_list *app)
 {
     const char *format;
     JSArgumentFormatMap *map;
 
     format = *formatp;
     for (map = cx->argumentFormatMap; map; map = map->next) {
@@ -629,20 +636,16 @@ JSRuntime::init(uint32 maxbytes)
         return false;
 
 #if ENABLE_YARR_JIT
     regExpAllocator = JSC::ExecutableAllocator::create();
     if (!regExpAllocator)
         return false;
 #endif
 
-    deflatedStringCache = new js::DeflatedStringCache();
-    if (!deflatedStringCache || !deflatedStringCache->init())
-        return false;
-
     wrapObjectCallback = js::TransparentObjectWrapper;
 
 #ifdef JS_THREADSAFE
     /* this is asymmetric with JS_ShutDown: */
     if (!js_SetupLocks(8, 16))
         return false;
     rtLock = JS_NEW_LOCK();
     if (!rtLock)
@@ -678,21 +681,16 @@ JSRuntime::~JSRuntime()
                 cxcount, (cxcount == 1) ? "" : "s");
     }
 #endif
 
     js_FinishThreads(this);
     js_FreeRuntimeScriptState(this);
     js_FinishAtomState(this);
 
-    /*
-     * Finish the deflated string cache after the last GC and after
-     * calling js_FinishAtomState, which finalizes strings.
-     */
-    delete deflatedStringCache;
 #if ENABLE_YARR_JIT
     delete regExpAllocator;
 #endif
     js_FinishGC(this);
 #ifdef JS_THREADSAFE
     if (gcLock)
         JS_DESTROY_LOCK(gcLock);
     if (gcDone)
@@ -4207,25 +4205,16 @@ JS_CloneFunctionObject(JSContext *cx, JS
 }
 
 JS_PUBLIC_API(JSObject *)
 JS_GetFunctionObject(JSFunction *fun)
 {
     return FUN_OBJECT(fun);
 }
 
-JS_PUBLIC_API(const char *)
-JS_GetFunctionName(JSFunction *fun)
-{
-    if (!fun->atom)
-        return js_anonymous_str;
-    const char *byte = js_GetStringBytes(fun->atom);
-    return byte ? byte : "";
-}
-
 JS_PUBLIC_API(JSString *)
 JS_GetFunctionId(JSFunction *fun)
 {
     return fun->atom ? ATOM_TO_STRING(fun->atom) : NULL;
 }
 
 JS_PUBLIC_API(uintN)
 JS_GetFunctionFlags(JSFunction *fun)
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -540,16 +540,19 @@ extern JS_PUBLIC_API(jsval)
 JS_GetNegativeInfinityValue(JSContext *cx);
 
 extern JS_PUBLIC_API(jsval)
 JS_GetPositiveInfinityValue(JSContext *cx);
 
 extern JS_PUBLIC_API(jsval)
 JS_GetEmptyStringValue(JSContext *cx);
 
+extern JS_PUBLIC_API(JSString *)
+JS_GetEmptyString(JSRuntime *rt);
+
 /*
  * Format is a string of the following characters (spaces are insignificant),
  * specifying the tabulated type conversions:
  *
  *   b      JSBool          Boolean
  *   c      uint16/jschar   ECMA uint16, Unicode char
  *   i      int32           ECMA int32
  *   u      uint32          ECMA uint32
@@ -2335,31 +2338,20 @@ JS_NewFunction(JSContext *cx, JSNative c
 extern JS_PUBLIC_API(JSFunction *)
 JS_NewFunctionById(JSContext *cx, JSNative call, uintN nargs, uintN flags,
                    JSObject *parent, jsid id);
 
 extern JS_PUBLIC_API(JSObject *)
 JS_GetFunctionObject(JSFunction *fun);
 
 /*
- * Deprecated, useful only for diagnostics.  Use JS_GetFunctionId instead for
- * anonymous vs. "anonymous" disambiguation and Unicode fidelity.
- */
-extern JS_PUBLIC_API(const char *)
-JS_GetFunctionName(JSFunction *fun);
-
-/*
  * Return the function's identifier as a JSString, or null if fun is unnamed.
  * The returned string lives as long as fun, so you don't need to root a saved
  * reference to it if fun is well-connected or rooted, and provided you bound
  * the use of the saved reference by fun's lifetime.
- *
- * Prefer JS_GetFunctionId over JS_GetFunctionName because it returns null for
- * truly anonymous functions, and because it doesn't chop to ISO-Latin-1 chars
- * from UTF-16-ish jschars.
  */
 extern JS_PUBLIC_API(JSString *)
 JS_GetFunctionId(JSFunction *fun);
 
 /*
  * Return JSFUN_* flags for fun.
  */
 extern JS_PUBLIC_API(uintN)
--- a/js/src/jscntxt.h
+++ b/js/src/jscntxt.h
@@ -1364,18 +1364,16 @@ struct JSRuntime {
     JSTraceDataOp       gcExtraRootsTraceOp;
     void                *gcExtraRootsData;
 
     /* Well-known numbers held for use by this runtime's contexts. */
     js::Value           NaNValue;
     js::Value           negativeInfinityValue;
     js::Value           positiveInfinityValue;
 
-    js::DeflatedStringCache *deflatedStringCache;
-
     JSString            *emptyString;
 
     /* List of active contexts sharing this runtime; protected by gcLock. */
     JSCList             contextList;
 
     /* Per runtime debug hooks -- see jsprvtd.h and jsdbgapi.h. */
     JSDebugHooks        globalDebugHooks;
 
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -2198,22 +2198,16 @@ MarkAndSweep(JSContext *cx, JSGCInvocati
         FinalizeArenaList<JSObject_Slots16>(*comp, cx, FINALIZE_OBJECT16);
         FinalizeArenaList<JSFunction>(*comp, cx, FINALIZE_FUNCTION);
 #if JS_HAS_XML_SUPPORT
         FinalizeArenaList<JSXML>(*comp, cx, FINALIZE_XML);
 #endif
     }
     TIMESTAMP(sweepObjectEnd);
 
-    /*
-     * We sweep the deflated cache before we finalize the strings so the
-     * cache can safely use js_IsAboutToBeFinalized..
-     */
-    rt->deflatedStringCache->sweep(cx);
-
     for (JSCompartment **comp = rt->compartments.begin(); comp != rt->compartments.end(); comp++) {
         FinalizeArenaList<JSShortString>(*comp, cx, FINALIZE_SHORT_STRING);
         FinalizeArenaList<JSString>(*comp, cx, FINALIZE_STRING);
         FinalizeArenaList<JSExternalString>(*comp, cx, FINALIZE_EXTERNAL_STRING);
     }
 
     TIMESTAMP(sweepStringEnd);
 
--- a/js/src/jsprobes.cpp
+++ b/js/src/jsprobes.cpp
@@ -77,17 +77,17 @@ Probes::FunctionLineNumber(JSContext *cx
 }
 
 /*
  * This function is used to convert function arguments and return value (jsval)
  * into the following based on each value's type tag:
  *
  *      jsval      returned
  *      -------------------
- *      STRING  -> char *
+ *      STRING  -> void *
  *      INT     -> int
  *      DOUBLE  -> double *
  *      BOOLEAN -> int
  *      OBJECT  -> void *
  *
  * All are presented as void * for DTrace consumers to use, after shifting or
  * masking out the JavaScript type bits. This allows D scripts to use ints and
  * booleans directly and copyinstr() for string arguments, when types are known
@@ -104,19 +104,16 @@ jsprobes_jsvaltovoid(JSContext *cx, cons
         return (void *)JS_TYPE_STR(JSTYPE_NULL);
 
     if (argval.isUndefined())
         return (void *)JS_TYPE_STR(JSTYPE_VOID);
 
     if (argval.isBoolean())
         return (void *)argval.toBoolean();
 
-    if (argval.isString())
-        return (void *)js_GetStringBytes(cx, argval.toString());
-
     if (argval.isNumber()) {
         if (argval.isInt32())
             return (void *)argval.toInt32();
         // FIXME Now what?
         //return (void *)argval.toDouble();
     }
 
     return argval.toGCThing();
--- a/js/src/jsprvtd.h
+++ b/js/src/jsprvtd.h
@@ -159,18 +159,16 @@ template <class Key,
           class AllocPolicy = ContextAllocPolicy>
 class HashMap;
 
 template <class T,
           class HashPolicy = DefaultHasher<T>,
           class AllocPolicy = ContextAllocPolicy>
 class HashSet;
 
-class DeflatedStringCache;
-
 class PropertyCache;
 struct PropertyCacheEntry;
 
 struct Shape;
 struct EmptyShape;
 
 } /* namespace js */
 
--- a/js/src/jsstr.cpp
+++ b/js/src/jsstr.cpp
@@ -3289,22 +3289,16 @@ const JSString JSString::length2StringTa
 #ifdef __SUNPRO_CC
 #pragma pack(0)
 #else
 #pragma pack(pop)
 #endif
 
 #undef R
 
-#define R(c) FROM_SMALL_CHAR((c) >> 6), FROM_SMALL_CHAR((c) & 0x3f), 0x00
-
-const char JSString::deflatedLength2StringTable[] = { R12(0) };
-
-#undef R
-
 /*
  * Declare int strings. Only int strings from 100 to 255 actually have to be
  * generated, since the rest are either unit strings or length-2 strings. To
  * avoid the runtime cost of figuring out where to look for the string for a
  * particular integer, we precompute a table of JSString*s which refer to the
  * correct location of the int string.
  */
 #define R(c) {                                                                \
@@ -3345,48 +3339,26 @@ const JSString *const JSString::intStrin
 #undef R
 
 #ifdef __SUNPRO_CC
 #pragma pack(0)
 #else
 #pragma pack(pop)
 #endif
 
-#define R(c) ((c) / 100) + '0', ((c) / 10 % 10) + '0', ((c) % 10) + '0', 0x00
-
-const char JSString::deflatedIntStringTable[] = {
-    R7(100), /* 100 through 227 */
-    R4(100 + (1 << 7)), /* 228 through 243 */
-    R3(100 + (1 << 7) + (1 << 4)), /* 244 through 251 */
-    R2(100 + (1 << 7) + (1 << 4) + (1 << 3)) /* 252 through 255 */
-};
-
-#undef R
 #undef R2
 #undef R4
 #undef R6
 #undef R8
 #undef R10
 #undef R12
 
 #undef R3
 #undef R7
 
-/* Static table for common UTF8 encoding */
-#define U8(c)   char(((c) >> 6) | 0xc0), char(((c) & 0x3f) | 0x80), 0
-#define U(c)    U8(c), U8(c+1), U8(c+2), U8(c+3), U8(c+4), U8(c+5), U8(c+6), U8(c+7)
-
-const char JSString::deflatedUnitStringTable[] = {
-    U(0x80), U(0x88), U(0x90), U(0x98), U(0xa0), U(0xa8), U(0xb0), U(0xb8),
-    U(0xc0), U(0xc8), U(0xd0), U(0xd8), U(0xe0), U(0xe8), U(0xf0), U(0xf8)
-};
-
-#undef U
-#undef U8
-
 JSBool
 js_String(JSContext *cx, uintN argc, Value *vp)
 {
     Value *argv = vp + 2;
 
     JSString *str;
     if (argc > 0) {
         str = js_ValueToString(cx, argv[0]);
@@ -4007,17 +3979,17 @@ js_InflateString(JSContext *cx, const ch
      * For compatibility with callers of JS_DecodeBytes we must zero lengthp
      * on errors.
      */
     *lengthp = 0;
     return NULL;
 }
 
 /*
- * May be called with null cx by js_GetStringBytes, see below.
+ * May be called with null cx.
  */
 char *
 js_DeflateString(JSContext *cx, const jschar *chars, size_t nchars)
 {
     size_t nbytes, i;
     char *bytes;
 #ifdef DEBUG
     JSBool ok;
@@ -4052,17 +4024,17 @@ js_GetDeflatedStringLength(JSContext *cx
 {
     if (!js_CStringsAreUTF8)
         return nchars;
 
     return js_GetDeflatedUTF8StringLength(cx, chars, nchars);
 }
 
 /*
- * May be called with null cx through js_GetStringBytes, see below.
+ * May be called with null cx through public API, see below.
  */
 size_t
 js_GetDeflatedUTF8StringLength(JSContext *cx, const jschar *chars, size_t nchars)
 {
     size_t nbytes;
     const jschar *end;
     uintN c, c2;
     char buffer[10];
@@ -4295,162 +4267,16 @@ bufferTooSmall:
     *dstlenp = (origDstlen - dstlen);
     if (cx) {
         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
                              JSMSG_BUFFER_TOO_SMALL);
     }
     return JS_FALSE;
 }
 
-namespace js {
-
-DeflatedStringCache::DeflatedStringCache()
-{
-#ifdef JS_THREADSAFE
-    lock = NULL;
-#endif
-}
-
-bool
-DeflatedStringCache::init()
-{
-#ifdef JS_THREADSAFE
-    JS_ASSERT(!lock);
-    lock = JS_NEW_LOCK();
-    if (!lock)
-        return false;
-#endif
-
-    /*
-     * Make room for 2K deflated strings that a typical browser session
-     * creates.
-     */
-    return map.init(2048);
-}
-
-DeflatedStringCache::~DeflatedStringCache()
-{
-#ifdef JS_THREADSAFE
-    if (lock)
-        JS_DESTROY_LOCK(lock);
-#endif
-}
-
-void
-DeflatedStringCache::sweep(JSContext *cx)
-{
-    /*
-     * We must take a lock even during the GC as JS_GetFunctionName can be
-     * called outside the request.
-     */
-    JS_ACQUIRE_LOCK(lock);
-
-    for (Map::Enum e(map); !e.empty(); e.popFront()) {
-        JSString *str = e.front().key;
-        if (IsAboutToBeFinalized(str)) {
-            char *bytes = e.front().value;
-            e.removeFront();
-
-            /*
-             * We cannot use cx->free here as bytes may come from the
-             * embedding that calls JS_NewString(cx, bytes, length). Those
-             * bytes may not be allocated via js_malloc and may not have
-             * space for the background free list.
-             */
-            js_free(bytes);
-        }
-    }
-
-    JS_RELEASE_LOCK(lock);
-}
-
-char *
-DeflatedStringCache::getBytes(JSString *str)
-{
-    JS_ACQUIRE_LOCK(lock);
-    Map::AddPtr p = map.lookupForAdd(str);
-    char *bytes = p ? p->value : NULL;
-    JS_RELEASE_LOCK(lock);
-
-    if (bytes)
-        return bytes;
-
-    bytes = js_DeflateString(NULL, str->chars(), str->length());
-    if (!bytes)
-        return NULL;
-
-    /*
-     * In the single-threaded case we use the add method as js_DeflateString
-     * cannot mutate the map. In particular, it cannot run the GC that may
-     * delete entries from the map. But the JS_THREADSAFE version requires to
-     * deal with other threads adding the entries to the map.
-     */
-    char *bytesToFree = NULL;
-    JSBool ok;
-#ifdef JS_THREADSAFE
-    JS_ACQUIRE_LOCK(lock);
-    ok = map.relookupOrAdd(p, str, bytes);
-    if (ok && p->value != bytes) {
-        /* Some other thread has asked for str bytes .*/
-        JS_ASSERT(!strcmp(p->value, bytes));
-        bytesToFree = bytes;
-        bytes = p->value;
-    }
-    JS_RELEASE_LOCK(lock);
-#else  /* !JS_THREADSAFE */
-    ok = map.add(p, str, bytes);
-#endif
-    if (!ok) {
-        bytesToFree = bytes;
-        bytes = NULL;
-    }
-
-    if (bytesToFree)
-        js_free(bytesToFree);
-    return bytes;
-}
-
-} /* namespace js */
-
-const char *
-js_GetStringBytes(JSAtom *atom)
-{
-    JSString *str = ATOM_TO_STRING(atom);
-    if (JSString::isUnitString(str)) {
-        char *bytes;
-#ifdef IS_LITTLE_ENDIAN
-        /* Unit string data is {c, 0, 0, 0} so we can just cast. */
-        bytes = (char *)str->chars();
-#else
-        /* Unit string data is {0, c, 0, 0} so we can point into the middle. */
-        bytes = (char *)str->chars() + 1;
-#endif
-        return ((*bytes & 0x80) && js_CStringsAreUTF8)
-               ? JSString::deflatedUnitStringTable + ((*bytes & 0x7f) * 3)
-               : bytes;
-    }
-
-    /*
-     * We must burn some space on deflated int strings and length-2 strings
-     * to preserve static allocation (which is to say, JSRuntime independence).
-     */
-    if (JSString::isLength2String(str))
-        return JSString::deflatedLength2StringTable + ((str - JSString::length2StringTable) * 3);
-
-    if (JSString::isHundredString(str)) {
-        /*
-         * We handled the 1 and 2-digit number cases already, so we know that
-         * str is between 100 and 255.
-         */
-        return JSString::deflatedIntStringTable + ((str - JSString::hundredStringTable) * 4);
-    }
-
-    return GetGCThingRuntime(str)->deflatedStringCache->getBytes(str);
-}
-
 /*
  * From java.lang.Character.java:
  *
  * The character properties are currently encoded into 32 bits in the
  * following manner:
  *
  * 10 bits      signed offset used for converting case
  *  1 bit       if 1, adding the signed offset converts the character to
--- a/js/src/jsstr.h
+++ b/js/src/jsstr.h
@@ -509,19 +509,16 @@ struct JSString {
     static const JSString unitStringTable[];
     static const JSString length2StringTable[];
     static const JSString hundredStringTable[];
     /*
      * Since int strings can be unit strings, length-2 strings, or hundred
      * strings, we keep a table to map from integer to the correct string.
      */
     static const JSString *const intStringTable[];
-    static const char deflatedIntStringTable[];
-    static const char deflatedUnitStringTable[];
-    static const char deflatedLength2StringTable[];
 
     static JSString *unitString(jschar c);
     static JSString *getUnitString(JSContext *cx, JSString *str, size_t index);
     static JSString *length2String(jschar c1, jschar c2);
     static JSString *length2String(uint32 i);
     static JSString *intString(jsint i);
 
     static JSString *lookupStaticString(const jschar *chars, size_t length);
@@ -1141,23 +1138,16 @@ js_DeflateStringToBuffer(JSContext *cx, 
 
 /*
  * Same as js_DeflateStringToBuffer, but always treats 'bytes' as UTF-8.
  */
 extern JSBool
 js_DeflateStringToUTF8Buffer(JSContext *cx, const jschar *chars,
                              size_t charsLength, char *bytes, size_t *length);
 
-/*
- * Find or create a deflated string cache entry for str that contains its
- * characters chopped from Unicode code points into bytes.
- */
-extern const char *
-js_GetStringBytes(JSAtom *atom);
-
 /* Export a few natives and a helper to other files in SpiderMonkey. */
 extern JSBool
 js_str_escape(JSContext *cx, JSObject *obj, uintN argc, js::Value *argv,
               js::Value *rval);
 
 /*
  * The String.prototype.replace fast-native entry point is exported for joined
  * function optimization in js{interp,tracer}.cpp.
@@ -1218,59 +1208,9 @@ FileEscapedString(FILE *fp, JSString *st
     return PutEscapedStringImpl(NULL, 0, fp, str, quote) != size_t(-1);
 }
 
 } /* namespace js */
 
 extern JSBool
 js_String(JSContext *cx, uintN argc, js::Value *vp);
 
-namespace js {
-
-class DeflatedStringCache {
-  public:
-    DeflatedStringCache();
-    bool init();
-    ~DeflatedStringCache();
-
-    void sweep(JSContext *cx);
-
-  private:
-    struct StringPtrHasher
-    {
-        typedef JSString *Lookup;
-
-        static HashNumber hash(JSString *str) {
-            /*
-             * We hash only GC-allocated Strings. They are aligned on
-             * sizeof(JSString) boundary so we can improve hashing by stripping
-             * initial zeros.
-             */
-            const jsuword ALIGN_LOG = tl::FloorLog2<sizeof(JSString)>::result;
-            JS_STATIC_ASSERT(sizeof(JSString) == (size_t(1) << ALIGN_LOG));
-
-            jsuword ptr = reinterpret_cast<jsuword>(str);
-            jsuword key = ptr >> ALIGN_LOG;
-            JS_ASSERT((key << ALIGN_LOG) == ptr);
-            return HashNumber(key);
-        }
-
-        static bool match(JSString *s1, JSString *s2) {
-            return s1 == s2;
-        }
-    };
-
-    typedef HashMap<JSString *, char *, StringPtrHasher, SystemAllocPolicy> Map;
-
-    char *getBytes(JSString *str);
-
-    friend const char *
-    ::js_GetStringBytes(JSAtom *atom);
-
-    Map                 map;
-#ifdef JS_THREADSAFE
-    JSLock              *lock;
-#endif
-};
-
-} /* namespace js */
-
 #endif /* jsstr_h___ */