Bug 584298. Do a bit less work in ReadableToJSVal on the fast path. r=jst
authorBoris Zbarsky <bzbarsky@mit.edu>
Fri, 06 Aug 2010 20:46:52 -0400
changeset 49065 4ba110e42f258340b28860db35f1190aef863cc0
parent 49064 48a78e198bfd4f0348fe53a7fd7c357593cc8363
child 49066 1907ad5a3f9ad401edc78ef43f7256e26fc745f7
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjst
bugs584298
milestone2.0b4pre
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 584298. Do a bit less work in ReadableToJSVal on the fast path. r=jst
js/src/xpconnect/src/xpcconvert.cpp
js/src/xpconnect/src/xpcprivate.h
js/src/xpconnect/src/xpcquickstubs.cpp
js/src/xpconnect/src/xpcstring.cpp
js/src/xpconnect/src/xpcwrappedjs.cpp
--- a/js/src/xpconnect/src/xpcconvert.cpp
+++ b/js/src/xpconnect/src/xpcconvert.cpp
@@ -325,19 +325,22 @@ XPCConvert::NativeData2JS(XPCLazyCallCon
 
         case nsXPTType::T_DOMSTRING:
             {
                 const nsAString* p = *((const nsAString**)s);
                 if(!p)
                     break;
 
                 if(!p->IsVoid()) {
-                    jsval str = XPCStringConvert::ReadableToJSVal(cx, *p);
+                    nsStringBuffer* buf;
+                    jsval str = XPCStringConvert::ReadableToJSVal(cx, *p, &buf);
                     if(JSVAL_IS_NULL(str))
                         return JS_FALSE;
+                    if(buf)
+                        buf->AddRef();
 
                     *d = str;
                 }
 
                 // *d is defaulted to JSVAL_NULL so no need to set it
                 // again if p is a "void" string
 
                 break;
--- a/js/src/xpconnect/src/xpcprivate.h
+++ b/js/src/xpconnect/src/xpcprivate.h
@@ -108,16 +108,17 @@
 #include "nsVariant.h"
 #include "nsIPropertyBag.h"
 #include "nsIProperty.h"
 #include "nsCOMArray.h"
 #include "nsTArray.h"
 #include "nsBaseHashtable.h"
 #include "nsHashKeys.h"
 #include "nsWrapperCache.h"
+#include "nsStringBuffer.h"
 
 #include "nsIXPCScriptNotify.h"  // used to notify: ScriptEvaluated
 
 #ifndef XPCONNECT_STANDALONE
 #define XPC_USE_SECURITY_CHECKED_COMPONENT
 #include "nsIScriptObjectPrincipal.h"
 #include "nsIPrincipal.h"
 #endif
@@ -3221,19 +3222,21 @@ private:
 
 /***************************************************************************/
 
 // readable string conversions, static methods only
 class XPCStringConvert
 {
 public:
 
+    // If the string shares the readable's buffer, that buffer will
+    // get assigned to *sharedBuffer.  Otherwise null will be
+    // assigned.
     static jsval ReadableToJSVal(JSContext *cx, const nsAString &readable,
-                                 PRBool dontAddrefShared = PR_FALSE,
-                                 PRBool* sharedBuffer = nsnull);
+                                 nsStringBuffer** sharedBuffer);
 
     static XPCReadableJSStringWrapper *JSStringToReadable(XPCCallContext& ccx,
                                                           JSString *str);
 
     static void ShutdownDOMStringFinalizer();
 
 private:
     XPCStringConvert();         // not implemented
--- a/js/src/xpconnect/src/xpcquickstubs.cpp
+++ b/js/src/xpconnect/src/xpcquickstubs.cpp
@@ -1066,23 +1066,22 @@ xpc_qsStringToJsval(JSContext *cx, nsStr
 {
     // From the T_DOMSTRING case in XPCConvert::NativeData2JS.
     if(str.IsVoid())
     {
         *rval = JSVAL_NULL;
         return JS_TRUE;
     }
 
-    PRBool isShared = PR_FALSE;
-    jsval jsstr =
-        XPCStringConvert::ReadableToJSVal(cx, str, PR_TRUE, &isShared);
+    nsStringBuffer* sharedBuffer;
+    jsval jsstr = XPCStringConvert::ReadableToJSVal(cx, str, &sharedBuffer);
     if (JSVAL_IS_NULL(jsstr))
         return JS_FALSE;
     *rval = jsstr;
-    if (isShared)
+    if (sharedBuffer)
     {
         // The string was shared but ReadableToJSVal didn't addref it.
         // Move the ownership from str to jsstr.
         str.ForgetSharedBuffer();
     }
     return JS_TRUE;
 }
 
@@ -1091,23 +1090,22 @@ xpc_qsStringToJsstring(JSContext *cx, ns
 {
     // From the T_DOMSTRING case in XPCConvert::NativeData2JS.
     if(str.IsVoid())
     {
         *rval = nsnull;
         return JS_TRUE;
     }
 
-    PRBool isShared = PR_FALSE;
-    jsval jsstr =
-        XPCStringConvert::ReadableToJSVal(cx, str, PR_TRUE, &isShared);
+    nsStringBuffer* sharedBuffer;
+    jsval jsstr = XPCStringConvert::ReadableToJSVal(cx, str, &sharedBuffer);
     if(JSVAL_IS_NULL(jsstr))
         return JS_FALSE;
     *rval = JSVAL_TO_STRING(jsstr);
-    if (isShared)
+    if (sharedBuffer)
     {
         // The string was shared but ReadableToJSVal didn't addref it.
         // Move the ownership from str to jsstr.
         str.ForgetSharedBuffer();
     }
     return JS_TRUE;
 }
 
--- a/js/src/xpconnect/src/xpcstring.cpp
+++ b/js/src/xpconnect/src/xpcstring.cpp
@@ -73,24 +73,20 @@ XPCStringConvert::ShutdownDOMStringFinal
     sDOMStringFinalizerIndex = -1;
 }
 
 // convert a readable to a JSString, copying string data
 // static
 jsval
 XPCStringConvert::ReadableToJSVal(JSContext *cx,
                                   const nsAString &readable,
-                                  PRBool dontAddrefShared,
-                                  PRBool* sharedBuffer)
+                                  nsStringBuffer** sharedBuffer)
 {
     JSString *str;
-    if (sharedBuffer)
-    {
-        *sharedBuffer = PR_FALSE;
-    }
+    *sharedBuffer = nsnull;
 
     PRUint32 length = readable.Length();
 
     JSAtom *atom;
     if (length == 0 && (atom = cx->runtime->atomState.emptyAtom))
     {
         return ATOM_TO_JSVAL(atom);
     }
@@ -109,24 +105,17 @@ XPCStringConvert::ReadableToJSVal(JSCont
         }
 
         str = JS_NewExternalString(cx, 
                                    reinterpret_cast<jschar *>(buf->Data()),
                                    length, sDOMStringFinalizerIndex);
 
         if (str)
         {
-            if (sharedBuffer)
-            {
-                *sharedBuffer = PR_TRUE;
-            }
-            if (!dontAddrefShared)
-            {
-                buf->AddRef();
-            }
+            *sharedBuffer = buf;
         }
     }
     else
     {
         // blech, have to copy.
 
         jschar *chars = reinterpret_cast<jschar *>
                                         (JS_malloc(cx, (length + 1) *
--- a/js/src/xpconnect/src/xpcwrappedjs.cpp
+++ b/js/src/xpconnect/src/xpcwrappedjs.cpp
@@ -615,19 +615,22 @@ nsXPCWrappedJS::GetEnumerator(nsISimpleE
 /* nsIVariant getProperty (in AString name); */
 NS_IMETHODIMP 
 nsXPCWrappedJS::GetProperty(const nsAString & name, nsIVariant **_retval)
 {
     XPCCallContext ccx(NATIVE_CALLER);
     if(!ccx.IsValid())
         return NS_ERROR_UNEXPECTED;
 
-    jsval jsstr = XPCStringConvert::ReadableToJSVal(ccx, name);
+    nsStringBuffer* buf;
+    jsval jsstr = XPCStringConvert::ReadableToJSVal(ccx, name, &buf);
     if(JSVAL_IS_NULL(jsstr))
         return NS_ERROR_OUT_OF_MEMORY;
+    if(buf)
+        buf->AddRef();
 
     return nsXPCWrappedJSClass::
         GetNamedPropertyAsVariant(ccx, mJSObj, jsstr, _retval);
 }
 
 /***************************************************************************/
 
 NS_IMETHODIMP