Bug 534136 Part 4: Inline accessors on nsIAtom. r=peterv sr=jst
authorJonas Sicking <jonas@sicking.cc>
Mon, 08 Mar 2010 07:45:00 -0800
changeset 39102 5901c6b98f836784818fc0495a1775f02726ee5c
parent 39101 1995edaefd3f79ca174f28635cbdce3d6db0bbe8
child 39103 62bc77046ac9bbf386f2258766f18bf382fcde36
push id12012
push usersicking@mozilla.com
push dateMon, 08 Mar 2010 15:47:04 +0000
treeherdermozilla-central@f8dd7b5b02ef [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspeterv, jst
bugs534136
milestone1.9.3a3pre
Bug 534136 Part 4: Inline accessors on nsIAtom. r=peterv sr=jst
content/base/src/nsDOMDocumentType.cpp
parser/html/nsHtml5Atom.cpp
parser/html/nsHtml5Atom.h
xpcom/ds/nsAtomTable.cpp
xpcom/ds/nsAtomTable.h
xpcom/ds/nsIAtom.idl
--- a/content/base/src/nsDOMDocumentType.cpp
+++ b/content/base/src/nsDOMDocumentType.cpp
@@ -147,17 +147,18 @@ const nsTextFragment*
 nsDOMDocumentType::GetText()
 {
   return nsnull;
 }
 
 NS_IMETHODIMP    
 nsDOMDocumentType::GetName(nsAString& aName)
 {
-  return mName->ToString(aName);
+  mName->ToString(aName);
+  return NS_OK;
 }
 
 NS_IMETHODIMP    
 nsDOMDocumentType::GetEntities(nsIDOMNamedNodeMap** aEntities)
 {
   NS_ENSURE_ARG_POINTER(aEntities);
 
   *aEntities = mEntities;
@@ -200,17 +201,18 @@ nsDOMDocumentType::GetInternalSubset(nsA
 {
   aInternalSubset = mInternalSubset;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMDocumentType::GetNodeName(nsAString& aNodeName)
 {
-  return mName->ToString(aNodeName);
+  mName->ToString(aNodeName);
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMDocumentType::GetNodeValue(nsAString& aNodeValue)
 {
   SetDOMStringToNull(aNodeValue);
 
   return NS_OK;
--- a/parser/html/nsHtml5Atom.cpp
+++ b/parser/html/nsHtml5Atom.cpp
@@ -33,22 +33,34 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsHtml5Atom.h"
 
 nsHtml5Atom::nsHtml5Atom(const nsAString& aString)
-  : mData(aString)
 {
+  mLength = aString.Length();
+  nsStringBuffer* buf = nsStringBuffer::FromString(aString);
+  if (buf) {
+    buf->AddRef();
+    mString = static_cast<PRUnichar*>(buf->Data());
+  }
+  else {
+    buf = nsStringBuffer::Alloc((mLength + 1) * sizeof(PRUnichar));
+    mString = static_cast<PRUnichar*>(buf->Data());
+    CopyUnicodeTo(aString, 0, mString, mLength);
+    mString[mLength] = PRUnichar(0);
+  }
 }
 
 nsHtml5Atom::~nsHtml5Atom()
 {
+  nsStringBuffer::FromData(mString)->Release();
 }
 
 NS_IMETHODIMP_(nsrefcnt)
 nsHtml5Atom::AddRef()
 {
   NS_NOTREACHED("Attempt to AddRef an nsHtml5Atom.");
   return 2;
 }
@@ -62,55 +74,41 @@ nsHtml5Atom::Release()
 
 NS_IMETHODIMP
 nsHtml5Atom::QueryInterface(REFNSIID aIID, void** aInstancePtr)
 {
   NS_NOTREACHED("Attempt to call QueryInterface an nsHtml5Atom.");
   return NS_ERROR_UNEXPECTED;
 }
 
-NS_IMETHODIMP
-nsHtml5Atom::ToString(nsAString& aReturn)
+NS_IMETHODIMP 
+nsHtml5Atom::ScriptableToString(nsAString& aBuf)
 {
-  aReturn.Assign(mData);
-  return NS_OK;
+  NS_NOTREACHED("Should not call ScriptableToString.");
+  return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
 nsHtml5Atom::ToUTF8String(nsACString& aReturn)
 {
   NS_NOTREACHED("Should not attempt to convert to an UTF-8 string.");
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
-NS_IMETHODIMP
-nsHtml5Atom::GetUTF16String(const PRUnichar **aReturn)
-{
-  NS_NOTREACHED("Should not attempt to get a UTF-16 string from nsHtml5Atom");
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-NS_IMETHODIMP_(PRUint32)
-nsHtml5Atom::GetLength()
-{
-  NS_NOTREACHED("Should not attempt to get a length from nsHtml5Atom");
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
 NS_IMETHODIMP_(PRBool)
 nsHtml5Atom::IsStaticAtom()
 {
   return PR_FALSE;
 }
 
 NS_IMETHODIMP
-nsHtml5Atom::Equals(const nsAString& aString, PRBool *aReturn)
+nsHtml5Atom::ScriptableEquals(const nsAString& aString, PRBool* aResult)
 {
-  *aReturn = mData.Equals(aString);
-  return NS_OK;
+  NS_NOTREACHED("Should not call ScriptableEquals.");
+  return NS_ERROR_NOT_IMPLEMENTED;
 }
 
-NS_IMETHODIMP
-nsHtml5Atom::EqualsUTF8(const nsACString& aString, PRBool *aReturn)
+NS_IMETHODIMP_(PRBool)
+nsHtml5Atom::EqualsUTF8(const nsACString& aString)
 {
   NS_NOTREACHED("Should not attempt to compare with an UTF-8 string.");
-  return NS_ERROR_NOT_IMPLEMENTED;
+  return PR_FALSE;
 }
--- a/parser/html/nsHtml5Atom.h
+++ b/parser/html/nsHtml5Atom.h
@@ -50,14 +50,11 @@
 class nsHtml5Atom : public nsIAtom
 {
   public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSIATOM
 
     nsHtml5Atom(const nsAString& aString);
     ~nsHtml5Atom();
-
-  private:
-    nsString mData;
 };
 
 #endif // nsHtml5Atom_h_
--- a/xpcom/ds/nsAtomTable.cpp
+++ b/xpcom/ds/nsAtomTable.cpp
@@ -125,17 +125,17 @@ struct AtomTableEntry : public PLDHashEn
     return keyHash == 1;
   }
 
   inline void SetAtomImpl(AtomImpl* aAtom) {
     NS_ASSERTION(keyHash > 1,
                  "SetAtomImpl() called on non-atom AtomTableEntry!");
     NS_ASSERTION(aAtom, "Setting null atom");
     mBits = PtrBits(aAtom);
-    mLength = aAtom->mLength;
+    mLength = aAtom->GetLength();
   }
 
   inline void ClearAtom() {
     mBits = nsnull;
   }
 
   inline PRBool HasValue() const {
     NS_ASSERTION(keyHash > 1,
@@ -152,17 +152,17 @@ struct AtomTableEntry : public PLDHashEn
 
   // type-agnostic accessors
 
   // get the string buffer
   inline const PRUnichar* getAtomString() const {
     NS_ASSERTION(keyHash > 1,
                  "getAtomString() called on non-atom AtomTableEntry!");
 
-    return GetAtomImpl()->mString;
+    return GetAtomImpl()->GetUTF16String();
   }
 
   // get the string buffer
   inline const char* getUTF8String() const {
     NS_ASSERTION(keyHash == 0,
                  "getUTF8String() called on non-UTF8 AtomTableEntry!");
 
     return (char *)mBits;
@@ -339,38 +339,46 @@ NS_PurgeAtomTable()
 #endif
     PL_DHashTableFinish(&gAtomTable);
     gAtomTable.entryCount = 0;
     gAtomTable.ops = nsnull;
   }
 }
 
 AtomImpl::AtomImpl(const nsAString& aString)
-  : mLength(aString.Length())
 {
+  mLength = aString.Length();
   nsStringBuffer* buf = nsStringBuffer::FromString(aString);
   if (buf) {
     buf->AddRef();
     mString = static_cast<PRUnichar*>(buf->Data());
   }
   else {
     buf = nsStringBuffer::Alloc((mLength + 1) * sizeof(PRUnichar));
     mString = static_cast<PRUnichar*>(buf->Data());
     CopyUnicodeTo(aString, 0, mString, mLength);
     mString[mLength] = PRUnichar(0);
   }
+
+  NS_ASSERTION(mString[mLength] == PRUnichar(0), "null terminated");
+  NS_ASSERTION(buf && buf->StorageSize() >= (mLength+1) * sizeof(PRUnichar),
+               "enough storage");
+  NS_ASSERTION(Equals(aString), "correct data");
 }
 
 AtomImpl::AtomImpl(nsStringBuffer* aStringBuffer, PRUint32 aLength)
-  : mLength(aLength),
-    mString(static_cast<PRUnichar*>(aStringBuffer->Data()))
 {
+  mLength = aLength;
+  mString = static_cast<PRUnichar*>(aStringBuffer->Data());
   // Technically we could currently avoid doing this addref by instead making
   // the static atom buffers have an initial refcount of 2.
   aStringBuffer->AddRef();
+
+  NS_ASSERTION(mString[mLength] == PRUnichar(0), "null terminated");
+  NS_ASSERTION(aStringBuffer && aStringBuffer->StorageSize() == (mLength+1) * 2, "correct storage");
 }
 
 AtomImpl::~AtomImpl()
 {
   NS_PRECONDITION(gAtomTable.ops, "uninitialized atom hashtable");
   // Permanent atoms are removed from the hashtable at shutdown, and we
   // don't want to remove them twice.  See comment above in
   // |AtomTableClearEntry|.
@@ -423,53 +431,38 @@ void* PermanentAtomImpl::operator new ( 
   NS_ASSERTION(!aAtom->IsPermanent(),
                "converting atom that's already permanent");
 
   // Just let the constructor overwrite the vtable pointer.
   return aAtom;
 }
 
 NS_IMETHODIMP 
-AtomImpl::ToString(nsAString& aBuf)
+AtomImpl::ScriptableToString(nsAString& aBuf)
 {
   nsStringBuffer::FromData(mString)->ToString(mLength, aBuf);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 AtomImpl::ToUTF8String(nsACString& aBuf)
 {
   CopyUTF16toUTF8(nsDependentString(mString, mLength), aBuf);
   return NS_OK;
 }
 
-NS_IMETHODIMP 
-AtomImpl::GetUTF16String(const PRUnichar **aResult)
+NS_IMETHODIMP_(PRBool)
+AtomImpl::EqualsUTF8(const nsACString& aString)
 {
-  NS_PRECONDITION(aResult, "null out param");
-  *aResult = mString;
-  return NS_OK;
-}
-
-NS_IMETHODIMP_(PRUint32)
-AtomImpl::GetLength()
-{
-  return mLength;
+  return CompareUTF8toUTF16(aString,
+                            nsDependentString(mString, mLength)) == 0;
 }
 
 NS_IMETHODIMP
-AtomImpl::EqualsUTF8(const nsACString& aString, PRBool* aResult)
-{
-  *aResult = CompareUTF8toUTF16(aString,
-                                nsDependentString(mString, mLength)) == 0;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-AtomImpl::Equals(const nsAString& aString, PRBool* aResult)
+AtomImpl::ScriptableEquals(const nsAString& aString, PRBool* aResult)
 {
   *aResult = aString.Equals(nsDependentString(mString, mLength));
   return NS_OK;
 }
 
 NS_IMETHODIMP_(PRBool)
 AtomImpl::IsStaticAtom()
 {
--- a/xpcom/ds/nsAtomTable.h
+++ b/xpcom/ds/nsAtomTable.h
@@ -80,22 +80,16 @@ public:
 
   // We can't use the virtual function in the base class destructor.
   PRBool IsPermanentInDestructor() {
     return mRefCnt == REFCNT_PERMANENT_SENTINEL;
   }
 
   // for |#ifdef NS_BUILD_REFCNT_LOGGING| access to reference count
   nsrefcnt GetRefCount() { return mRefCnt; }
-
-  // The length of the string in the atom.
-  PRUint32 mLength;
-
-  // This always points to the data owned by a nsStringBuffer
-  PRUnichar* mString;
 };
 
 /**
  * A non-refcounted implementation of nsIAtom.
  */
 
 class PermanentAtomImpl : public AtomImpl {
 public:
--- a/xpcom/ds/nsIAtom.idl
+++ b/xpcom/ds/nsIAtom.idl
@@ -35,73 +35,69 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 #include "nsISupports.idl"
 
 %{C++
 #include "nsStringGlue.h"
 #include "nsCOMPtr.h"
+#include "nsStringBuffer.h"
 %}
 
 /*
  * Should this really be scriptable?  Using atoms from script or proxies
  * could be dangerous since double-wrapping could lead to loss of
  * pointer identity.
  */
  
-[scriptable, uuid(96c82146-56f3-4b43-817f-25d6db1ad8e8)]
+[scriptable, uuid(1f341018-521a-49de-b806-1bef5c9a00b0)]
 interface nsIAtom : nsISupports
 {
   /**
    * Get the Unicode or UTF8 value for the string
    */
-  AString toString(); 
-  AUTF8String toUTF8String();
+  [binaryname(ScriptableToString)] AString toString(); 
+  [noscript] AUTF8String toUTF8String();
   
   /**
-   * Return a pointer to a zero terminated UTF16 string.
-   */
-  [noscript] void getUTF16String([shared, retval] out wstring aResult);
-  [notxpcom] unsigned long getLength();
-
-  /**
    * Compare the atom to a specific string value
    * Note that this will NEVER return/throw an error condition.
    */
-  boolean equals(in AString aString);
+  [binaryname(ScriptableEquals)] boolean equals(in AString aString);
   
-  boolean equalsUTF8(in AUTF8String aString);
-
-%{C++
-  // note this is NOT virtual so this won't muck with the vtable!
-  inline PRBool Equals(const nsAString& s) {
-    PRBool result;
-    Equals(s, &result);
-    return result;
-  }
+  [noscript, notxpcom] boolean equalsUTF8(in AUTF8String aString);
 
-  inline PRBool EqualsUTF8(const nsACString& s) {
-    PRBool result;
-    EqualsUTF8(s, &result);
-    return result;
-  }
-
-  inline const PRUnichar* GetUTF16String() {
-    const PRUnichar* result;
-    GetUTF16String(&result);
-    return result;
-  }
-
-%}
-  
   /**
    * Returns true if the atom is static and false otherwise.
    */
   [noscript, notxpcom] boolean isStaticAtom();
+
+%{C++
+  // note this is NOT virtual so this won't muck with the vtable!
+  inline PRBool Equals(const nsAString& aString) {
+    return aString.Equals(nsDependentString(mString, mLength));
+  }
+
+  inline const PRUnichar* GetUTF16String() {
+    return mString;
+  }
+
+  inline const PRUint32 GetLength() {
+    return mLength;
+  }
+
+  inline void ToString(nsAString& aBuf) {
+    nsStringBuffer::FromData(mString)->ToString(mLength, aBuf);
+  }
+
+protected:
+  PRUint32 mLength;
+  PRUnichar* mString;
+%}
 };
 
 
 %{C++
 /*
  * The three forms of NS_NewAtom and do_GetAtom (for use with
  * |nsCOMPtr<nsIAtom>|) return the atom for the string given.  At any
  * given time there will always be one atom representing a given string.