Don't generate state keys at all, if there's nothing to get. Bug 388387, r+sr=sicking.
authorbzbarsky@mit.edu
Fri, 20 Jul 2007 20:00:02 -0700
changeset 3727 638e3d4c61ab20bfa40506d1856cf5c0e82af579
parent 3726 d9ba446637ab2d5702105bf8a82db6315f5cb8f7
child 3728 af28791d0ff3bf27076cb16963015a6ca3e2385a
push id1
push userbsmedberg@mozilla.com
push dateThu, 20 Mar 2008 16:49:24 +0000
treeherdermozilla-central@61007906a1f8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs388387
milestone1.9a7pre
Don't generate state keys at all, if there's nothing to get. Bug 388387, r+sr=sicking.
content/html/content/src/nsGenericHTMLElement.cpp
content/html/content/src/nsGenericHTMLElement.h
layout/base/nsILayoutHistoryState.h
layout/base/nsLayoutHistoryState.cpp
--- a/content/html/content/src/nsGenericHTMLElement.cpp
+++ b/content/html/content/src/nsGenericHTMLElement.cpp
@@ -1728,17 +1728,17 @@ nsGenericHTMLElement::GetPrimaryPresStat
 {
   NS_ENSURE_ARG_POINTER(aPresState);
   *aPresState = nsnull;
 
   nsresult result = NS_OK;
 
   nsCOMPtr<nsILayoutHistoryState> history;
   nsCAutoString key;
-  GetLayoutHistoryAndKey(aContent, getter_AddRefs(history), key);
+  GetLayoutHistoryAndKey(aContent, PR_FALSE, getter_AddRefs(history), key);
 
   if (history) {
     // Get the pres state for this key, if it doesn't exist, create one
     result = history->GetState(key, aPresState);
     if (!*aPresState) {
       result = NS_NewPresState(aPresState);
       if (NS_SUCCEEDED(result)) {
         result = history->AddState(key, *aPresState);
@@ -1747,16 +1747,17 @@ nsGenericHTMLElement::GetPrimaryPresStat
   }
 
   return result;
 }
 
 
 nsresult
 nsGenericHTMLElement::GetLayoutHistoryAndKey(nsGenericHTMLElement* aContent,
+                                             PRBool aRead,
                                              nsILayoutHistoryState** aHistory,
                                              nsACString& aKey)
 {
   //
   // Get the pres shell
   //
   nsCOMPtr<nsIDocument> doc = aContent->GetDocument();
   if (!doc) {
@@ -1766,16 +1767,21 @@ nsGenericHTMLElement::GetLayoutHistoryAn
   //
   // Get the history (don't bother with the key if the history is not there)
   //
   *aHistory = doc->GetLayoutHistoryState().get();
   if (!*aHistory) {
     return NS_OK;
   }
 
+  if (aRead && !(*aHistory)->HasStates()) {
+    NS_RELEASE(*aHistory);
+    return NS_OK;
+  }
+
   //
   // Get the state key
   //
   nsresult rv = nsContentUtils::GenerateStateKey(aContent, doc,
                                                  nsIStatefulFrame::eNoID,
                                                  aKey);
   if (NS_FAILED(rv)) {
     NS_RELEASE(*aHistory);
@@ -1796,17 +1802,18 @@ nsGenericHTMLElement::GetLayoutHistoryAn
 }
 
 PRBool
 nsGenericHTMLElement::RestoreFormControlState(nsGenericHTMLElement* aContent,
                                               nsIFormControl* aControl)
 {
   nsCOMPtr<nsILayoutHistoryState> history;
   nsCAutoString key;
-  nsresult rv = GetLayoutHistoryAndKey(aContent, getter_AddRefs(history), key);
+  nsresult rv = GetLayoutHistoryAndKey(aContent, PR_TRUE,
+                                       getter_AddRefs(history), key);
   if (!history) {
     return PR_FALSE;
   }
 
   nsPresState *state;
   // Get the pres state for this key
   rv = history->GetState(key, &state);
   if (state) {
--- a/content/html/content/src/nsGenericHTMLElement.h
+++ b/content/html/content/src/nsGenericHTMLElement.h
@@ -522,20 +522,23 @@ public:
    */
   static nsresult GetPrimaryPresState(nsGenericHTMLElement* aContent,
                                       nsPresState** aPresState);
   /**
    * Get the layout history object *and* generate the key for a particular
    * piece of content.
    *
    * @param aContent the content to generate the key for
+   * @param aRead if true, won't return a layout history state (and won't
+   *              generate a key) if the layout history state is empty.
    * @param aState the history state object (out param)
    * @param aKey the key (out param)
    */
   static nsresult GetLayoutHistoryAndKey(nsGenericHTMLElement* aContent,
+                                         PRBool aRead,
                                          nsILayoutHistoryState** aState,
                                          nsACString& aKey);
   /**
    * Restore the state for a form control.  Ends up calling
    * nsIFormControl::RestoreState().
    *
    * @param aContent an nsGenericHTMLElement* pointing to the form control
    * @param aControl an nsIFormControl* pointing to the form control
--- a/layout/base/nsILayoutHistoryState.h
+++ b/layout/base/nsILayoutHistoryState.h
@@ -45,18 +45,18 @@
 #define _nsILayoutHistoryState_h
 
 #include "nsISupports.h"
 #include "nsStringFwd.h"
 
 class nsPresState;
 
 #define NS_ILAYOUTHISTORYSTATE_IID \
-{0xe6abfb7c, 0x6624, 0x4b4d, \
-{0x9d, 0xfe, 0xea, 0x62, 0xae, 0xfe, 0x03, 0x31}}
+{ 0x99003f0f, 0x7ade, 0x44a1, \
+ { 0x81, 0x74, 0xe3, 0x6a, 0xa5, 0xbb, 0x6b, 0x10 } }
 
 class nsILayoutHistoryState : public nsISupports {
  public: 
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_ILAYOUTHISTORYSTATE_IID)
 
   /**
    * Set |aState| as the state object for |aKey|.
    * This _transfers_ownership_ of |aState| to the LayoutHistoryState.
@@ -69,16 +69,21 @@ class nsILayoutHistoryState : public nsI
    * Look up the state object for |aKey|.
    */
   NS_IMETHOD GetState(const nsCString& aKey, nsPresState** aState) = 0;
 
   /**
    * Remove the state object for |aKey|.
    */
   NS_IMETHOD RemoveState(const nsCString& aKey) = 0;
+
+  /**
+   * Check whether this history has any states in it
+   */
+  NS_IMETHOD_(PRBool) HasStates() const = 0;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsILayoutHistoryState,
                               NS_ILAYOUTHISTORYSTATE_IID)
 
 nsresult
 NS_NewLayoutHistoryState(nsILayoutHistoryState** aState);
 
--- a/layout/base/nsLayoutHistoryState.cpp
+++ b/layout/base/nsLayoutHistoryState.cpp
@@ -53,16 +53,17 @@ public:
   NS_HIDDEN_(nsresult) Init();
 
   NS_DECL_ISUPPORTS
 
   // nsILayoutHistoryState
   NS_IMETHOD AddState(const nsCString& aKey, nsPresState* aState);
   NS_IMETHOD GetState(const nsCString& aKey, nsPresState** aState);
   NS_IMETHOD RemoveState(const nsCString& aKey);
+  NS_IMETHOD_(PRBool) HasStates() const;
 
 
 private:
   ~nsLayoutHistoryState() {}
 
   nsClassHashtable<nsCStringHashKey,nsPresState> mStates;
 };
 
@@ -111,8 +112,14 @@ nsLayoutHistoryState::GetState(const nsC
 }
 
 NS_IMETHODIMP
 nsLayoutHistoryState::RemoveState(const nsCString& aKey)
 {
   mStates.Remove(aKey);
   return NS_OK;
 }
+
+NS_IMETHODIMP_(PRBool)
+nsLayoutHistoryState::HasStates() const
+{
+  return mStates.Count() != 0;
+}