From 8fd0c73b2626c9a67b95e75ce18877997f0511ad Mon Sep 17 00:00:00 2001 From: roytam1 Date: Sat, 13 Mar 2021 11:00:00 +0800 Subject: [PATCH] import changes from `dev' branch of rmottola/Arctic-Fox: - test part of Bug 789788 - Revise the don't-use-document-fonts option (1b6a0e6ed) - Bug 1172782 - Change how nsTHashtable::Clear() works. r=froydnj. (c8c2adc51) - Bug 1180072 - Remove PL_DHashTableEnumerate(). r=froydnj. (b5448efda) - Bug 1180122 - Make Chaos Mode affect PLDHashTable's iterators. r=froydnj. (11fd0e222) - Bug 1182516 - Add Chaos Mode environment variable MOZ_CHAOSMODE. r=roc (d636f6c90) - Bug 1182516 - Fix mid-air conflict with 3fd2ab6cb762 on a CLOSED TREE. r=bustage (8dec46b7a) - Bug 1184280 - Remove warning about mDisabledJSAndPlugins being false. r=ehsan (c23e96fc1) - Bug 1181411 - Test some expected aborts in PLDHashTable. r=glandium. (682788df7) - Bug 1185399 (part 1) - Remove macros from pldhash.h. r=froydnj. (15001ff2a) - Bug 1185399 (part 2) - Remove macros from pldhash.cpp. r=froydnj. (afeddcc90) - Bug 1187197 (part 1) - Move comments from PL_DHashTable* functions to the equivalent methods. r=froydnj. (78921590e) - Bug 1187197 (part 2) - Put function return types on their own line. r=froydnj. (9aae02f83) - Bug 1187197 (part 3) - Convert pldhash.{cpp,h} to C++ style comments. r=froydnj. (57afe7e1f) - Bug 1202526 (part 1) - Add PLDHashTable::RemoveEntry(). r=froydnj. (1b5453695) - Bug 1202526 (part 2) - Avoid PL_DHashTableRawRemove() in nsLoadGroup. r=mcmanus. (1ad20b17f) - Bug 1202526 (part 3) - Avoid PL_DHashTableRawRemove() in nsDocument. r=bz. (cdde6eff0) - Bug 1202526 (part 4) - Avoid PL_DHashTableRawRemove() in nsPropertyTable. r=bz. (ed437f4d6) - Bug 1202526 (part 5) - Use PLDHashTable::RemoveEntry() in nsSecureBrowserUIImpl. r=dkeeler. (ac1d44066) - Bug 1202526 (part 6) - Use PLDHashTable::RemoveEntry() in XULDocument. r=bz. (2639a053e) - Bug 1202526 (part 7) - Use PLDHashTable::RemoveEntry() in prefs code. r=bz. (2eb3b1097) - Bug 1202526 (part 8) - Use PLDHashTable::RemoveEntry() in the cycle collector. r=mccr8. (ec77d7635) - Bug 1130096 - Convert embedding/components/commandhandler/ to Gecko style. r=mccr8 (a5aecf9de) - Bug 1184842. Remove layout.frames.force_resizability pref. r=mats (9226b0caf) - Bug 1184842. Remove frameset mVisibilityOverride since it's always false now. r=mats (1b439feb8) - Bug 1184842. Change nsAttrAndChildArray::SetAndTakeAttr to nsAttrAndChildArray::SetAndSwapAttr. r=peterv (1442f0eae) - Bug 1184842. Make SetAttrAndNotify use the real old value instead of aOldValue when possible. r=bz (bc45970f5) - Bug 1184842. Add aOldValue parameter to nsNodeUtils::AttributeChanged. r=peterv (31bf8c08e) - Bug 1184842. Pass aOldValue to all mutation observers. r=peterv (e69daf7f7) - Bug 1184842. Allow BeforeSetAttr to preparse aValue. r=peterv (9c51655de) - follow up fix to Bug 1184842. Allow BeforeSetAttr to preparse aValue (fb997a066) - Bug 1149042 - Call AttributeWillChange before a style="" attribute gets created when touching element.style. r=smaug (41f2ea361) - Bug 1184842. Pass preparsed attribute values to nsNodeUtils::AttributeWillChange. r=peterv (646622252) - Bug 1013743, MutationObserver should observe only the subtree it is attached to, r=wchen (ad606eb15) - Bug 1184842. Add aNewValue to nsIMutationObserver::AttributeWillChange. r=peterv (796042972) - Bug 1184842. Preparse class attribute values in Element::BeforeSetAttr. r=peterv (e18989b2b) - Bug 1154149 - Remove nsPresContext arguments from a bunch of nsStyleSBug 1154149 - Remove nsPresContext arguments from a bunch of nsStyleS (b7797ef66) - Bug 1184842. Route aOldValue/aNewValue to AttributeData. r=heycam (14489941b) - Bug 1184842. Restyling should consider only the classes that have changed. r=heycam (5a5e670dc) - Bug 1121760 (part 1) - Remove PL_DHashTableSearch(). r=poiru. (d92813655) --- accessible/generic/DocAccessible.cpp | 6 +- docshell/shistory/src/nsSHEntryShared.cpp | 6 +- dom/base/Element.cpp | 73 ++- dom/base/Element.h | 26 +- dom/base/ShadowRoot.cpp | 3 +- dom/base/nsAttrAndChildArray.cpp | 8 +- dom/base/nsAttrAndChildArray.h | 5 +- dom/base/nsAttrValue.h | 6 + dom/base/nsAttrValueInlines.h | 10 + dom/base/nsAttrValueOrString.h | 16 + dom/base/nsContentList.cpp | 3 +- dom/base/nsContentUtils.cpp | 15 +- dom/base/nsDOMMutationObserver.cpp | 47 +- dom/base/nsDOMMutationObserver.h | 25 +- dom/base/nsDocument.cpp | 13 +- dom/base/nsFrameLoader.cpp | 3 +- dom/base/nsIMutationObserver.h | 27 +- dom/base/nsNodeUtils.cpp | 10 +- dom/base/nsNodeUtils.h | 11 +- dom/base/nsPropertyTable.cpp | 25 +- dom/base/nsScriptElement.cpp | 3 +- dom/base/nsScriptNameSpaceManager.cpp | 14 +- dom/base/nsStyledElement.cpp | 2 +- dom/base/nsTextNode.cpp | 3 +- dom/base/test/test_mutationobservers.html | 157 +++++- dom/events/IMEContentObserver.cpp | 6 +- dom/html/HTMLButtonElement.cpp | 2 +- dom/html/HTMLButtonElement.h | 2 +- dom/html/HTMLDetailsElement.cpp | 2 +- dom/html/HTMLDetailsElement.h | 2 +- dom/html/HTMLImageElement.cpp | 2 +- dom/html/HTMLImageElement.h | 2 +- dom/html/HTMLInputElement.cpp | 2 +- dom/html/HTMLInputElement.h | 2 +- dom/html/HTMLOptionElement.cpp | 2 +- dom/html/HTMLOptionElement.h | 2 +- dom/html/HTMLPropertiesCollection.cpp | 6 +- dom/html/HTMLSelectElement.cpp | 2 +- dom/html/HTMLSelectElement.h | 2 +- dom/html/HTMLTableElement.cpp | 2 +- dom/html/HTMLTableElement.h | 2 +- dom/html/HTMLTextAreaElement.cpp | 2 +- dom/html/HTMLTextAreaElement.h | 2 +- dom/html/UndoManager.cpp | 3 +- dom/html/nsDOMStringMap.cpp | 3 +- dom/html/nsGenericHTMLElement.cpp | 2 +- dom/html/nsGenericHTMLElement.h | 2 +- dom/plugins/base/nsJSNPRuntime.cpp | 12 +- dom/svg/SVGMPathElement.cpp | 3 +- dom/svg/SVGUseElement.cpp | 3 +- dom/svg/nsSVGElement.cpp | 9 +- dom/svg/nsSVGElement.h | 9 +- dom/xml/nsXMLPrettyPrinter.cpp | 3 +- dom/xslt/xpath/XPathResult.cpp | 3 +- dom/xslt/xslt/txMozillaXSLTProcessor.cpp | 3 +- dom/xul/XULDocument.cpp | 29 +- dom/xul/nsXULElement.cpp | 10 +- dom/xul/nsXULElement.h | 2 +- dom/xul/templates/nsContentSupportMap.h | 2 +- dom/xul/templates/nsTemplateMap.h | 7 +- dom/xul/templates/nsXULContentBuilder.cpp | 5 +- dom/xul/templates/nsXULTemplateBuilder.cpp | 3 +- editor/composer/nsEditingSession.cpp | 4 +- .../nsBaseCommandController.cpp | 58 +-- .../commandhandler/nsBaseCommandController.h | 38 +- .../commandhandler/nsCommandGroup.cpp | 224 ++++---- .../commandhandler/nsCommandGroup.h | 12 +- .../commandhandler/nsCommandManager.cpp | 174 +++---- .../commandhandler/nsCommandManager.h | 31 +- .../commandhandler/nsCommandParams.cpp | 66 ++- .../commandhandler/nsCommandParams.h | 21 +- .../nsControllerCommandTable.cpp | 139 +++-- .../commandhandler/nsControllerCommandTable.h | 14 +- gfx/layers/apz/util/ActiveElementManager.cpp | 2 +- gfx/thebes/gfxFT2FontList.cpp | 4 +- js/xpconnect/src/XPCMaps.h | 14 +- layout/base/RestyleManager.cpp | 24 +- layout/base/RestyleManager.h | 6 +- layout/base/nsFrameManager.cpp | 5 +- layout/base/nsPresContext.cpp | 4 +- layout/base/nsPresShell.cpp | 19 +- layout/generic/nsFrameSetFrame.cpp | 89 +--- layout/generic/nsFrameSetFrame.h | 3 - layout/generic/nsImageMap.cpp | 3 +- layout/generic/nsLineBox.h | 2 +- layout/inspector/inDOMView.cpp | 3 +- layout/reftests/bugs/1022481-1-ref.html | 12 +- layout/style/CounterStyleManager.cpp | 4 +- layout/style/StyleRule.cpp | 4 +- layout/style/nsAnimationManager.cpp | 3 +- layout/style/nsCSSRuleProcessor.cpp | 70 ++- layout/style/nsCSSRules.cpp | 4 +- layout/style/nsCSSRules.h | 4 +- layout/style/nsComputedDOMStyle.cpp | 2 +- layout/style/nsComputedDOMStyle.h | 2 +- layout/style/nsDOMCSSAttrDeclaration.cpp | 36 +- layout/style/nsDOMCSSAttrDeclaration.h | 2 +- layout/style/nsDOMCSSDeclaration.cpp | 24 +- layout/style/nsDOMCSSDeclaration.h | 24 +- layout/style/nsRuleProcessorData.h | 4 + layout/style/nsStyleContext.cpp | 2 +- layout/style/nsStyleSet.cpp | 80 ++- layout/style/nsStyleSet.h | 38 +- layout/svg/SVGTextFrame.cpp | 3 +- layout/svg/nsSVGEffects.cpp | 3 +- layout/xul/tree/nsTreeContentView.cpp | 3 +- mfbt/ChaosMode.cpp | 2 + mfbt/ChaosMode.h | 43 +- modules/libpref/init/all.js | 3 - modules/libpref/prefapi.cpp | 4 +- netwerk/base/nsLoadGroup.cpp | 10 +- netwerk/base/nsSocketTransportService2.cpp | 2 +- netwerk/cache/nsCacheEntry.cpp | 2 +- netwerk/cache/nsDiskCacheBinding.cpp | 14 +- netwerk/dns/nsHostResolver.cpp | 10 +- netwerk/protocol/http/nsHttpConnection.cpp | 2 +- netwerk/protocol/http/nsHttpConnectionMgr.cpp | 2 +- parser/htmlparser/nsHTMLEntities.cpp | 9 +- rdf/base/nsInMemoryDataSource.cpp | 32 +- rdf/base/nsRDFService.cpp | 38 +- .../manager/ssl/nsSecureBrowserUIImpl.cpp | 5 +- .../satchel/nsFormFillController.cpp | 6 +- toolkit/components/telemetry/Telemetry.cpp | 3 +- toolkit/content/widgets/notification.xml | 6 - toolkit/xre/nsAppRunner.cpp | 12 +- toolkit/xre/nsSigHandlers.cpp | 4 +- uriloader/base/nsDocLoader.cpp | 3 +- widget/cocoa/nsMenuGroupOwnerX.mm | 6 +- widget/nsBaseAppShell.cpp | 2 +- xpcom/base/nsCycleCollector.cpp | 23 +- xpcom/ds/nsPersistentProperties.cpp | 6 +- xpcom/ds/nsStaticNameTable.cpp | 6 +- xpcom/glue/nsTHashtable.cpp | 16 - xpcom/glue/nsTHashtable.h | 33 +- xpcom/glue/objs.mozbuild | 1 - xpcom/glue/pldhash.cpp | 439 ++++++++-------- xpcom/glue/pldhash.h | 477 ++++++++---------- xpcom/libxpcomrt/moz.build | 1 - xpcom/tests/gtest/TestPLDHash.cpp | 121 ++++- xpcom/threads/TimerThread.cpp | 4 +- xpcom/threads/nsEventQueue.cpp | 2 +- xpcom/threads/nsThread.cpp | 4 +- 142 files changed, 1739 insertions(+), 1571 deletions(-) delete mode 100644 xpcom/glue/nsTHashtable.cpp diff --git a/accessible/generic/DocAccessible.cpp b/accessible/generic/DocAccessible.cpp index 214d0b8796..8d81710bac 100644 --- a/accessible/generic/DocAccessible.cpp +++ b/accessible/generic/DocAccessible.cpp @@ -693,7 +693,8 @@ void DocAccessible::AttributeWillChange(nsIDocument* aDocument, dom::Element* aElement, int32_t aNameSpaceID, - nsIAtom* aAttribute, int32_t aModType) + nsIAtom* aAttribute, int32_t aModType, + const nsAttrValue* aNewValue) { Accessible* accessible = GetAccessible(aElement); if (!accessible) { @@ -734,7 +735,8 @@ void DocAccessible::AttributeChanged(nsIDocument* aDocument, dom::Element* aElement, int32_t aNameSpaceID, nsIAtom* aAttribute, - int32_t aModType) + int32_t aModType, + const nsAttrValue* aOldValue) { NS_ASSERTION(!IsDefunct(), "Attribute changed called on defunct document accessible!"); diff --git a/docshell/shistory/src/nsSHEntryShared.cpp b/docshell/shistory/src/nsSHEntryShared.cpp index c4aba9293b..ee84868113 100644 --- a/docshell/shistory/src/nsSHEntryShared.cpp +++ b/docshell/shistory/src/nsSHEntryShared.cpp @@ -325,7 +325,8 @@ nsSHEntryShared::AttributeWillChange(nsIDocument* aDocument, dom::Element* aContent, int32_t aNameSpaceID, nsIAtom* aAttribute, - int32_t aModType) + int32_t aModType, + const nsAttrValue* aOldValue) { } @@ -334,7 +335,8 @@ nsSHEntryShared::AttributeChanged(nsIDocument* aDocument, dom::Element* aElement, int32_t aNameSpaceID, nsIAtom* aAttribute, - int32_t aModType) + int32_t aModType, + const nsAttrValue* aOldValue) { RemoveFromBFCacheAsync(); } diff --git a/dom/base/Element.cpp b/dom/base/Element.cpp index 57ffc4bb5c..f7ffea6b28 100644 --- a/dom/base/Element.cpp +++ b/dom/base/Element.cpp @@ -2274,9 +2274,11 @@ Element::SetAttr(int32_t aNamespaceID, nsIAtom* aName, nsresult rv = BeforeSetAttr(aNamespaceID, aName, &value, aNotify); NS_ENSURE_SUCCESS(rv, rv); + nsAttrValue* preparsedAttrValue = value.GetStoredAttrValue(); if (aNotify) { - nsNodeUtils::AttributeWillChange(this, aNamespaceID, aName, modType); + nsNodeUtils::AttributeWillChange(this, aNamespaceID, aName, modType, + preparsedAttrValue); } // Hold a script blocker while calling ParseAttribute since that can call @@ -2284,6 +2286,11 @@ Element::SetAttr(int32_t aNamespaceID, nsIAtom* aName, nsAutoScriptBlocker scriptBlocker; nsAttrValue attrValue; + if (preparsedAttrValue) { + attrValue.SwapValueWith(*preparsedAttrValue); + } + // Even the value was pre-parsed in BeforeSetAttr, we still need to call + // ParseAttribute because it can have side effects. if (!ParseAttribute(aNamespaceID, aName, aValue, attrValue)) { attrValue.SetTo(aValue); } @@ -2323,7 +2330,8 @@ Element::SetParsedAttr(int32_t aNamespaceID, nsIAtom* aName, NS_ENSURE_SUCCESS(rv, rv); if (aNotify) { - nsNodeUtils::AttributeWillChange(this, aNamespaceID, aName, modType); + nsNodeUtils::AttributeWillChange(this, aNamespaceID, aName, modType, + &aParsedValue); } return SetAttrAndNotify(aNamespaceID, aName, aPrefix, oldValue, @@ -2350,10 +2358,10 @@ Element::SetAttrAndNotify(int32_t aNamespaceID, nsMutationGuard::DidMutate(); // Copy aParsedValue for later use since it will be lost when we call - // SetAndTakeMappedAttr below - nsAttrValue aValueForAfterSetAttr; + // SetAndSwapMappedAttr below + nsAttrValue valueForAfterSetAttr; if (aCallAfterSetAttr) { - aValueForAfterSetAttr.SetTo(aParsedValue); + valueForAfterSetAttr.SetTo(aParsedValue); } bool hadValidDir = false; @@ -2369,7 +2377,7 @@ Element::SetAttrAndNotify(int32_t aNamespaceID, // stuff to Element? if (!IsAttributeMapped(aName) || !SetMappedAttribute(document, aName, aParsedValue, &rv)) { - rv = mAttrsAndChildren.SetAndTakeAttr(aName, aParsedValue); + rv = mAttrsAndChildren.SetAndSwapAttr(aName, aParsedValue); } } else { @@ -2378,8 +2386,13 @@ Element::SetAttrAndNotify(int32_t aNamespaceID, aNamespaceID, nsIDOMNode::ATTRIBUTE_NODE); - rv = mAttrsAndChildren.SetAndTakeAttr(ni, aParsedValue); + rv = mAttrsAndChildren.SetAndSwapAttr(ni, aParsedValue); } + + // If the old value owns its own data, we know it is OK to keep using it. + const nsAttrValue* oldValue = + aParsedValue.StoresOwnData() ? &aParsedValue : &aOldValue; + NS_ENSURE_SUCCESS(rv, rv); if (document || HasFlag(NODE_FORCE_XBL_BINDINGS)) { @@ -2393,8 +2406,8 @@ Element::SetAttrAndNotify(int32_t aNamespaceID, nsIDocument* ownerDoc = OwnerDoc(); if (ownerDoc && GetCustomElementData()) { - nsCOMPtr oldValueAtom = aOldValue.GetAsAtom(); - nsCOMPtr newValueAtom = aValueForAfterSetAttr.GetAsAtom(); + nsCOMPtr oldValueAtom = oldValue->GetAsAtom(); + nsCOMPtr newValueAtom = valueForAfterSetAttr.GetAsAtom(); LifecycleCallbackArgs args = { nsDependentAtomString(aName), aModType == nsIDOMMutationEvent::ADDITION ? @@ -2406,17 +2419,21 @@ Element::SetAttrAndNotify(int32_t aNamespaceID, } if (aCallAfterSetAttr) { - rv = AfterSetAttr(aNamespaceID, aName, &aValueForAfterSetAttr, aNotify); + rv = AfterSetAttr(aNamespaceID, aName, &valueForAfterSetAttr, aNotify); NS_ENSURE_SUCCESS(rv, rv); if (aNamespaceID == kNameSpaceID_None && aName == nsGkAtoms::dir) { - OnSetDirAttr(this, &aValueForAfterSetAttr, + OnSetDirAttr(this, &valueForAfterSetAttr, hadValidDir, hadDirAuto, aNotify); } } if (aNotify) { - nsNodeUtils::AttributeChanged(this, aNamespaceID, aName, aModType); + // Don't pass aOldValue to AttributeChanged since it may not be reliable. + // Callers only compute aOldValue under certain conditions which may not + // be triggered by all nsIMutationObservers. + nsNodeUtils::AttributeChanged(this, aNamespaceID, aName, aModType, + oldValue == &aParsedValue ? &aParsedValue : nullptr); } if (aFireMutation) { @@ -2434,8 +2451,8 @@ Element::SetAttrAndNotify(int32_t aNamespaceID, if (!newValue.IsEmpty()) { mutation.mNewAttrValue = do_GetAtom(newValue); } - if (!aOldValue.IsEmptyString()) { - mutation.mPrevAttrValue = aOldValue.GetAsAtom(); + if (!oldValue->IsEmptyString()) { + mutation.mPrevAttrValue = oldValue->GetAsAtom(); } mutation.mAttrChange = aModType; @@ -2446,6 +2463,25 @@ Element::SetAttrAndNotify(int32_t aNamespaceID, return NS_OK; } +nsresult +Element::BeforeSetAttr(int32_t aNamespaceID, nsIAtom* aName, + nsAttrValueOrString* aValue, bool aNotify) +{ + if (aNamespaceID == kNameSpaceID_None) { + if (aName == nsGkAtoms::_class) { + // aValue->GetAttrValue will only be non-null here when this is called + // via Element::SetParsedAttr. This shouldn't happen for "class", but + // this will handle it. + if (aValue && !aValue->GetAttrValue()) { + nsAttrValue attr; + attr.ParseAtomArray(aValue->String()); + aValue->TakeParsedValue(attr); + } + } + } + return NS_OK; +} + bool Element::ParseAttribute(int32_t aNamespaceID, nsIAtom* aAttribute, @@ -2455,7 +2491,7 @@ Element::ParseAttribute(int32_t aNamespaceID, if (aNamespaceID == kNameSpaceID_None) { if (aAttribute == nsGkAtoms::_class) { SetFlags(NODE_MAY_HAVE_CLASS); - aResult.ParseAtomArray(aValue); + // Result should have been preparsed above. return true; } if (aAttribute == nsGkAtoms::id) { @@ -2562,7 +2598,8 @@ Element::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aName, if (aNotify) { nsNodeUtils::AttributeWillChange(this, aNameSpaceID, aName, - nsIDOMMutationEvent::REMOVAL); + nsIDOMMutationEvent::REMOVAL, + nullptr); } bool hasMutationListeners = aNotify && @@ -2628,8 +2665,10 @@ Element::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aName, } if (aNotify) { + // We can always pass oldValue here since there is no new value which could + // have corrupted it. nsNodeUtils::AttributeChanged(this, aNameSpaceID, aName, - nsIDOMMutationEvent::REMOVAL); + nsIDOMMutationEvent::REMOVAL, &oldValue); } rv = AfterSetAttr(aNameSpaceID, aName, nullptr, aNotify); diff --git a/dom/base/Element.h b/dom/base/Element.h index 04476b9a8d..110a3d2cca 100644 --- a/dom/base/Element.h +++ b/dom/base/Element.h @@ -486,6 +486,8 @@ public: virtual nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName, nsIAtom* aPrefix, const nsAString& aValue, bool aNotify) override; + // aParsedValue receives the old value of the attribute. That's useful if + // either the input or output value of aParsedValue is StoresOwnData. nsresult SetParsedAttr(int32_t aNameSpaceID, nsIAtom* aName, nsIAtom* aPrefix, nsAttrValue& aParsedValue, bool aNotify); // GetAttr is not inlined on purpose, to keep down codesize from all @@ -1128,10 +1130,15 @@ protected: * @param aNamespaceID namespace of attribute * @param aAttribute local-name of attribute * @param aPrefix aPrefix of attribute - * @param aOldValue previous value of attribute. Only needed if - * aFireMutation is true or if the element is a - * custom element (in web components). - * @param aParsedValue parsed new value of attribute + * @param aOldValue The old value of the attribute to use as a fallback + * in the cases where the actual old value (i.e. + * its current value) is !StoresOwnData() --- in which + * case the current value is probably already useless. + * If the current value is StoresOwnData() (or absent), + * aOldValue will not be used. + * @param aParsedValue parsed new value of attribute. Replaced by the + * old value of the attribute. This old value is only + * useful if either it or the new value is StoresOwnData. * @param aModType nsIDOMMutationEvent::MODIFICATION or ADDITION. Only * needed if aFireMutation or aNotify is true. * @param aFireMutation should mutation-events be fired? @@ -1204,17 +1211,16 @@ protected: * @param aName the localname of the attribute being set * @param aValue the value it's being set to represented as either a string or * a parsed nsAttrValue. Alternatively, if the attr is being removed it - * will be null. + * will be null. BeforeSetAttr is allowed to modify aValue by parsing + * the string to an nsAttrValue (to avoid having to reparse it in + * ParseAttribute). * @param aNotify Whether we plan to notify document observers. */ // Note that this is inlined so that when subclasses call it it gets // inlined. Those calls don't go through a vtable. virtual nsresult BeforeSetAttr(int32_t aNamespaceID, nsIAtom* aName, - const nsAttrValueOrString* aValue, - bool aNotify) - { - return NS_OK; - } + nsAttrValueOrString* aValue, + bool aNotify); /** * Hook that is called by Element::SetAttr to allow subclasses to diff --git a/dom/base/ShadowRoot.cpp b/dom/base/ShadowRoot.cpp index 95c8af58b9..fabb707f24 100644 --- a/dom/base/ShadowRoot.cpp +++ b/dom/base/ShadowRoot.cpp @@ -613,7 +613,8 @@ ShadowRoot::AttributeChanged(nsIDocument* aDocument, Element* aElement, int32_t aNameSpaceID, nsIAtom* aAttribute, - int32_t aModType) + int32_t aModType, + const nsAttrValue* aOldValue) { if (!IsPooledNode(aElement, aElement->GetParent(), mPoolHost)) { return; diff --git a/dom/base/nsAttrAndChildArray.cpp b/dom/base/nsAttrAndChildArray.cpp index 857554559e..ec66820b0e 100644 --- a/dom/base/nsAttrAndChildArray.cpp +++ b/dom/base/nsAttrAndChildArray.cpp @@ -390,14 +390,12 @@ nsAttrAndChildArray::AttrAt(uint32_t aPos) const } nsresult -nsAttrAndChildArray::SetAndTakeAttr(nsIAtom* aLocalName, nsAttrValue& aValue) +nsAttrAndChildArray::SetAndSwapAttr(nsIAtom* aLocalName, nsAttrValue& aValue) { uint32_t i, slotCount = AttrSlotCount(); for (i = 0; i < slotCount && AttrSlotIsTaken(i); ++i) { if (ATTRS(mImpl)[i].mName.Equals(aLocalName)) { - ATTRS(mImpl)[i].mValue.Reset(); ATTRS(mImpl)[i].mValue.SwapValueWith(aValue); - return NS_OK; } } @@ -417,12 +415,12 @@ nsAttrAndChildArray::SetAndTakeAttr(nsIAtom* aLocalName, nsAttrValue& aValue) } nsresult -nsAttrAndChildArray::SetAndTakeAttr(mozilla::dom::NodeInfo* aName, nsAttrValue& aValue) +nsAttrAndChildArray::SetAndSwapAttr(mozilla::dom::NodeInfo* aName, nsAttrValue& aValue) { int32_t namespaceID = aName->NamespaceID(); nsIAtom* localName = aName->NameAtom(); if (namespaceID == kNameSpaceID_None) { - return SetAndTakeAttr(localName, aValue); + return SetAndSwapAttr(localName, aValue); } uint32_t i, slotCount = AttrSlotCount(); diff --git a/dom/base/nsAttrAndChildArray.h b/dom/base/nsAttrAndChildArray.h index 3967621dcb..394920f449 100644 --- a/dom/base/nsAttrAndChildArray.h +++ b/dom/base/nsAttrAndChildArray.h @@ -88,8 +88,9 @@ public: const nsAttrValue* GetAttr(const nsAString& aName, nsCaseTreatment aCaseSensitive) const; const nsAttrValue* AttrAt(uint32_t aPos) const; - nsresult SetAndTakeAttr(nsIAtom* aLocalName, nsAttrValue& aValue); - nsresult SetAndTakeAttr(mozilla::dom::NodeInfo* aName, nsAttrValue& aValue); + // SetAndSwapAttr swaps the current attribute value with aValue. + nsresult SetAndSwapAttr(nsIAtom* aLocalName, nsAttrValue& aValue); + nsresult SetAndSwapAttr(mozilla::dom::NodeInfo* aName, nsAttrValue& aValue); // Remove the attr at position aPos. The value of the attr is placed in // aValue; any value that was already in aValue is destroyed. diff --git a/dom/base/nsAttrValue.h b/dom/base/nsAttrValue.h index 84c0f7aacb..66c1b0c47f 100644 --- a/dom/base/nsAttrValue.h +++ b/dom/base/nsAttrValue.h @@ -127,6 +127,12 @@ public: static void Shutdown(); ValueType Type() const; + // Returns true when this value is self-contained and does not depend on + // the state of its associated element. + // Returns false when this value depends on the state of its associated + // element and may be invalid if that state has been changed by changes to + // that element state outside of attribute setting. + inline bool StoresOwnData() const; void Reset(); diff --git a/dom/base/nsAttrValueInlines.h b/dom/base/nsAttrValueInlines.h index 8e399c9fc5..e392491d5f 100644 --- a/dom/base/nsAttrValueInlines.h +++ b/dom/base/nsAttrValueInlines.h @@ -191,6 +191,16 @@ nsAttrValue::IsSVGType(ValueType aType) const return aType >= eSVGTypesBegin && aType <= eSVGTypesEnd; } +inline bool +nsAttrValue::StoresOwnData() const +{ + if (BaseType() != eOtherBase) { + return true; + } + ValueType t = Type(); + return t != eCSSStyleRule && !IsSVGType(t); +} + inline void nsAttrValue::SetPtrValueAndType(void* aValue, ValueBaseType aType) { diff --git a/dom/base/nsAttrValueOrString.h b/dom/base/nsAttrValueOrString.h index 07476e5cba..df0dac17de 100644 --- a/dom/base/nsAttrValueOrString.h +++ b/dom/base/nsAttrValueOrString.h @@ -49,6 +49,21 @@ public: , mCheapString(nullptr) { } + void TakeParsedValue(nsAttrValue& aValue) + { + mStoredAttrValue.SwapValueWith(aValue); + mAttrValue = &mStoredAttrValue; + mStringPtr = nullptr; + } + /** + * If TakeParsedValue has been called, returns the value that it set. + */ + nsAttrValue* GetStoredAttrValue() + { + return mAttrValue == &mStoredAttrValue ? &mStoredAttrValue : nullptr; + } + const nsAttrValue* GetAttrValue() { return mAttrValue; } + /** * Returns a reference to the string value of the contents of this object. * @@ -74,6 +89,7 @@ protected: const nsAttrValue* mAttrValue; mutable const nsAString* mStringPtr; mutable nsCheapString mCheapString; + nsAttrValue mStoredAttrValue; }; #endif // nsAttrValueOrString_h___ diff --git a/dom/base/nsContentList.cpp b/dom/base/nsContentList.cpp index 5e74f35d45..ff465b62d7 100644 --- a/dom/base/nsContentList.cpp +++ b/dom/base/nsContentList.cpp @@ -671,7 +671,8 @@ nsContentList::Item(uint32_t aIndex) void nsContentList::AttributeChanged(nsIDocument *aDocument, Element* aElement, int32_t aNameSpaceID, nsIAtom* aAttribute, - int32_t aModType) + int32_t aModType, + const nsAttrValue* aOldValue) { NS_PRECONDITION(aElement, "Must have a content node to work with"); diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp index 81f823c1ad..e57e4f2833 100644 --- a/dom/base/nsContentUtils.cpp +++ b/dom/base/nsContentUtils.cpp @@ -4037,9 +4037,8 @@ nsContentUtils::TraverseListenerManager(nsINode *aNode, return; } - EventListenerManagerMapEntry *entry = - static_cast - (PL_DHashTableSearch(sEventListenerManagersHash, aNode)); + auto entry = static_cast + (sEventListenerManagersHash->Search(aNode)); if (entry) { CycleCollectionNoteChild(cb, entry->mListenerManager.get(), "[via hash] mListenerManager"); @@ -4087,9 +4086,8 @@ nsContentUtils::GetExistingListenerManagerForNode(const nsINode *aNode) return nullptr; } - EventListenerManagerMapEntry *entry = - static_cast - (PL_DHashTableSearch(sEventListenerManagersHash, aNode)); + auto entry = static_cast + (sEventListenerManagersHash->Search(aNode)); if (entry) { return entry->mListenerManager; } @@ -4102,9 +4100,8 @@ void nsContentUtils::RemoveListenerManager(nsINode *aNode) { if (sEventListenerManagersHash) { - EventListenerManagerMapEntry *entry = - static_cast - (PL_DHashTableSearch(sEventListenerManagersHash, aNode)); + auto entry = static_cast + (sEventListenerManagersHash->Search(aNode)); if (entry) { nsRefPtr listenerManager; listenerManager.swap(entry->mListenerManager); diff --git a/dom/base/nsDOMMutationObserver.cpp b/dom/base/nsDOMMutationObserver.cpp index 281adbb1eb..8f9fc0b6ad 100644 --- a/dom/base/nsDOMMutationObserver.cpp +++ b/dom/base/nsDOMMutationObserver.cpp @@ -64,6 +64,13 @@ NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(nsDOMMutationRecord, // Observer +bool +nsMutationReceiverBase::IsObservable(nsIContent* aContent) +{ + return !aContent->ChromeOnlyAccess() && + (Observer()->IsChrome() || !aContent->IsInAnonymousSubtree()); +} + NS_IMPL_ADDREF(nsMutationReceiver) NS_IMPL_RELEASE(nsMutationReceiver) @@ -108,11 +115,11 @@ nsMutationReceiver::AttributeWillChange(nsIDocument* aDocument, mozilla::dom::Element* aElement, int32_t aNameSpaceID, nsIAtom* aAttribute, - int32_t aModType) + int32_t aModType, + const nsAttrValue* aNewValue) { if (nsAutoMutationBatch::IsBatching() || - !ObservesAttr(aElement, aNameSpaceID, aAttribute) || - aElement->ChromeOnlyAccess()) { + !ObservesAttr(RegisterTarget(), aElement, aNameSpaceID, aAttribute)) { return; } @@ -147,14 +154,16 @@ nsMutationReceiver::CharacterDataWillChange(nsIDocument *aDocument, CharacterDataChangeInfo* aInfo) { if (nsAutoMutationBatch::IsBatching() || - !CharacterData() || !(Subtree() || aContent == Target()) || - aContent->ChromeOnlyAccess()) { + !CharacterData() || + (!Subtree() && aContent != Target()) || + (Subtree() && RegisterTarget()->SubtreeRoot() != aContent->SubtreeRoot()) || + !IsObservable(aContent)) { return; } - + nsDOMMutationRecord* m = Observer()->CurrentRecord(nsGkAtoms::characterData); - + NS_ASSERTION(!m->mTarget || m->mTarget == aContent, "Wrong target!"); @@ -173,8 +182,11 @@ nsMutationReceiver::ContentAppended(nsIDocument* aDocument, int32_t aNewIndexInContainer) { nsINode* parent = NODE_FROM(aContainer, aDocument); - bool wantsChildList = ChildList() && (Subtree() || parent == Target()); - if (!wantsChildList || aFirstNewContent->ChromeOnlyAccess()) { + bool wantsChildList = + ChildList() && + ((Subtree() && RegisterTarget()->SubtreeRoot() == parent->SubtreeRoot()) || + parent == Target()); + if (!wantsChildList || !IsObservable(aFirstNewContent)) { return; } @@ -211,8 +223,11 @@ nsMutationReceiver::ContentInserted(nsIDocument* aDocument, int32_t aIndexInContainer) { nsINode* parent = NODE_FROM(aContainer, aDocument); - bool wantsChildList = ChildList() && (Subtree() || parent == Target()); - if (!wantsChildList || aChild->ChromeOnlyAccess()) { + bool wantsChildList = + ChildList() && + ((Subtree() && RegisterTarget()->SubtreeRoot() == parent->SubtreeRoot()) || + parent == Target()); + if (!wantsChildList || !IsObservable(aChild)) { return; } @@ -243,11 +258,14 @@ nsMutationReceiver::ContentRemoved(nsIDocument* aDocument, int32_t aIndexInContainer, nsIContent* aPreviousSibling) { - if (aChild->ChromeOnlyAccess()) { + if (!IsObservable(aChild)) { return; } nsINode* parent = NODE_FROM(aContainer, aDocument); + if (Subtree() && parent->SubtreeRoot() != RegisterTarget()->SubtreeRoot()) { + return; + } if (nsAutoMutationBatch::IsBatching()) { if (nsAutoMutationBatch::IsRemovalDone()) { // This can happen for example if HTML parser parses to @@ -265,7 +283,7 @@ nsMutationReceiver::ContentRemoved(nsIDocument* aDocument, } return; - } + } if (Subtree()) { // Try to avoid creating transient observer if the node @@ -719,8 +737,9 @@ nsDOMMutationObserver::Constructor(const mozilla::dom::GlobalObject& aGlobal, return nullptr; } MOZ_ASSERT(window->IsInnerWindow()); + bool isChrome = nsContentUtils::IsChromeDoc(window->GetExtantDoc()); nsRefPtr observer = - new nsDOMMutationObserver(window.forget(), aCb); + new nsDOMMutationObserver(window.forget(), aCb, isChrome); return observer.forget(); } diff --git a/dom/base/nsDOMMutationObserver.h b/dom/base/nsDOMMutationObserver.h index 91ccfede41..292823a378 100644 --- a/dom/base/nsDOMMutationObserver.h +++ b/dom/base/nsDOMMutationObserver.h @@ -248,14 +248,20 @@ protected: mRegisterTarget->OwnerDoc()->SetMayHaveDOMMutationObservers(); } - bool ObservesAttr(mozilla::dom::Element* aElement, + bool IsObservable(nsIContent* aContent); + + bool ObservesAttr(nsINode* aRegisterTarget, + mozilla::dom::Element* aElement, int32_t aNameSpaceID, nsIAtom* aAttr) { if (mParent) { - return mParent->ObservesAttr(aElement, aNameSpaceID, aAttr); + return mParent->ObservesAttr(aRegisterTarget, aElement, aNameSpaceID, aAttr); } - if (!Attributes() || (!Subtree() && aElement != Target())) { + if (!Attributes() || + (!Subtree() && aElement != Target()) || + (Subtree() && aRegisterTarget->SubtreeRoot() != aElement->SubtreeRoot()) || + !IsObservable(aElement)) { return false; } if (AllAttributes()) { @@ -368,7 +374,7 @@ public: { // We can reuse AttributeWillChange implementation. AttributeWillChange(aDocument, aElement, aNameSpaceID, aAttribute, - nsIDOMMutationEvent::MODIFICATION); + nsIDOMMutationEvent::MODIFICATION, nullptr); } protected: @@ -447,9 +453,10 @@ class nsDOMMutationObserver final : public nsISupports, { public: nsDOMMutationObserver(already_AddRefed&& aOwner, - mozilla::dom::MutationCallback& aCb) + mozilla::dom::MutationCallback& aCb, + bool aChrome) : mOwner(aOwner), mLastPendingMutation(nullptr), mPendingMutationCount(0), - mCallback(&aCb), mWaitingForRun(false), mId(++sCount) + mCallback(&aCb), mWaitingForRun(false), mIsChrome(aChrome), mId(++sCount) { } NS_DECL_CYCLE_COLLECTING_ISUPPORTS @@ -471,6 +478,11 @@ public: return mOwner; } + bool IsChrome() + { + return mIsChrome; + } + void Observe(nsINode& aTarget, const mozilla::dom::MutationObserverInit& aOptions, mozilla::ErrorResult& aRv); @@ -572,6 +584,7 @@ protected: nsRefPtr mCallback; bool mWaitingForRun; + bool mIsChrome; uint64_t mId; diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp index a7ccdd1453..f1ed287eec 100644 --- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -3989,13 +3989,7 @@ nsDocument::SetSubDocumentFor(Element* aElement, nsIDocument* aSubDoc) // aSubDoc is nullptr, remove the mapping if (mSubDocuments) { - SubDocMapEntry *entry = - static_cast - (PL_DHashTableSearch(mSubDocuments, aElement)); - - if (entry) { - PL_DHashTableRawRemove(mSubDocuments, entry); - } + PL_DHashTableRemove(mSubDocuments, aElement); } } else { if (!mSubDocuments) { @@ -4041,9 +4035,8 @@ nsIDocument* nsDocument::GetSubDocumentFor(nsIContent *aContent) const { if (mSubDocuments && aContent->IsElement()) { - SubDocMapEntry *entry = - static_cast - (PL_DHashTableSearch(mSubDocuments, aContent->AsElement())); + auto entry = static_cast + (mSubDocuments->Search(aContent->AsElement())); if (entry) { return entry->mSubDocument; diff --git a/dom/base/nsFrameLoader.cpp b/dom/base/nsFrameLoader.cpp index b6209614ee..e14003a315 100644 --- a/dom/base/nsFrameLoader.cpp +++ b/dom/base/nsFrameLoader.cpp @@ -2607,7 +2607,8 @@ nsFrameLoader::AttributeChanged(nsIDocument* aDocument, mozilla::dom::Element* aElement, int32_t aNameSpaceID, nsIAtom* aAttribute, - int32_t aModType) + int32_t aModType, + const nsAttrValue* aOldValue) { MOZ_ASSERT(mObservingOwnerContent); // TODO: Implement ContentShellAdded for remote browsers (bug 658304) diff --git a/dom/base/nsIMutationObserver.h b/dom/base/nsIMutationObserver.h index 22245475a6..ac45bc1b3d 100644 --- a/dom/base/nsIMutationObserver.h +++ b/dom/base/nsIMutationObserver.h @@ -9,6 +9,7 @@ #include "nsISupports.h" +class nsAttrValue; class nsIAtom; class nsIContent; class nsIDocument; @@ -21,8 +22,8 @@ class Element; } // namespace mozilla #define NS_IMUTATION_OBSERVER_IID \ -{ 0x16fe5e3e, 0xeadc, 0x4312, \ - { 0x9d, 0x44, 0xb6, 0xbe, 0xdd, 0x6b, 0x54, 0x74 } } +{ 0xdd74f0cc, 0x2849, 0x4d05, \ + { 0x9c, 0xe3, 0xb0, 0x95, 0x3e, 0xc2, 0xfd, 0x44 } } /** * Information details about a characterdata change. Basically, we @@ -157,6 +158,8 @@ public: * @param aModType Whether or not the attribute will be added, changed, or * removed. The constants are defined in * nsIDOMMutationEvent.h. + * @param aNewValue The new value, IF it has been preparsed by + * BeforeSetAttr, otherwise null. * * @note Callers of this method might not hold a strong reference to the * observer. The observer is responsible for making sure it stays @@ -168,7 +171,8 @@ public: mozilla::dom::Element* aElement, int32_t aNameSpaceID, nsIAtom* aAttribute, - int32_t aModType) = 0; + int32_t aModType, + const nsAttrValue* aNewValue) = 0; /** * Notification that an attribute of an element has changed. @@ -180,6 +184,8 @@ public: * @param aModType Whether or not the attribute was added, changed, or * removed. The constants are defined in * nsIDOMMutationEvent.h. + * @param aOldValue The old value, if either the old value or the new + * value are StoresOwnData() (or absent); null otherwise. * * @note Callers of this method might not hold a strong reference to the * observer. The observer is responsible for making sure it stays @@ -191,7 +197,8 @@ public: mozilla::dom::Element* aElement, int32_t aNameSpaceID, nsIAtom* aAttribute, - int32_t aModType) = 0; + int32_t aModType, + const nsAttrValue* aOldValue) = 0; /** * Notification that an attribute of an element has been @@ -336,14 +343,16 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsIMutationObserver, NS_IMUTATION_OBSERVER_IID) mozilla::dom::Element* aElement, \ int32_t aNameSpaceID, \ nsIAtom* aAttribute, \ - int32_t aModType) override; + int32_t aModType, \ + const nsAttrValue* aNewValue) override; #define NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED \ virtual void AttributeChanged(nsIDocument* aDocument, \ mozilla::dom::Element* aElement, \ int32_t aNameSpaceID, \ nsIAtom* aAttribute, \ - int32_t aModType) override; + int32_t aModType, \ + const nsAttrValue* aOldValue) override; #define NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED \ virtual void ContentAppended(nsIDocument* aDocument, \ @@ -405,7 +414,8 @@ _class::AttributeWillChange(nsIDocument* aDocument, \ mozilla::dom::Element* aElement, \ int32_t aNameSpaceID, \ nsIAtom* aAttribute, \ - int32_t aModType) \ + int32_t aModType, \ + const nsAttrValue* aNewValue) \ { \ } \ void \ @@ -413,7 +423,8 @@ _class::AttributeChanged(nsIDocument* aDocument, \ mozilla::dom::Element* aElement, \ int32_t aNameSpaceID, \ nsIAtom* aAttribute, \ - int32_t aModType) \ + int32_t aModType, \ + const nsAttrValue* aOldValue) \ { \ } \ void \ diff --git a/dom/base/nsNodeUtils.cpp b/dom/base/nsNodeUtils.cpp index c712ac4395..17f186ce5c 100644 --- a/dom/base/nsNodeUtils.cpp +++ b/dom/base/nsNodeUtils.cpp @@ -123,24 +123,26 @@ void nsNodeUtils::AttributeWillChange(Element* aElement, int32_t aNameSpaceID, nsIAtom* aAttribute, - int32_t aModType) + int32_t aModType, + const nsAttrValue* aNewValue) { nsIDocument* doc = aElement->OwnerDoc(); IMPL_MUTATION_NOTIFICATION(AttributeWillChange, aElement, (doc, aElement, aNameSpaceID, aAttribute, - aModType)); + aModType, aNewValue)); } void nsNodeUtils::AttributeChanged(Element* aElement, int32_t aNameSpaceID, nsIAtom* aAttribute, - int32_t aModType) + int32_t aModType, + const nsAttrValue* aOldValue) { nsIDocument* doc = aElement->OwnerDoc(); IMPL_MUTATION_NOTIFICATION(AttributeChanged, aElement, (doc, aElement, aNameSpaceID, aAttribute, - aModType)); + aModType, aOldValue)); } void diff --git a/dom/base/nsNodeUtils.h b/dom/base/nsNodeUtils.h index 00f420a0cf..850d63c27f 100644 --- a/dom/base/nsNodeUtils.h +++ b/dom/base/nsNodeUtils.h @@ -48,12 +48,15 @@ public: * @param aNameSpaceID Namespace of changing attribute * @param aAttribute Local-name of changing attribute * @param aModType Type of change (add/change/removal) + * @param aNewValue The parsed new value, but only if BeforeSetAttr + * preparsed it!!! * @see nsIMutationObserver::AttributeWillChange */ static void AttributeWillChange(mozilla::dom::Element* aElement, int32_t aNameSpaceID, nsIAtom* aAttribute, - int32_t aModType); + int32_t aModType, + const nsAttrValue* aNewValue); /** * Send AttributeChanged notifications to nsIMutationObservers. @@ -61,12 +64,16 @@ public: * @param aNameSpaceID Namespace of changed attribute * @param aAttribute Local-name of changed attribute * @param aModType Type of change (add/change/removal) + * @param aOldValue If the old value was StoresOwnData() (or absent), + * that value, otherwise null * @see nsIMutationObserver::AttributeChanged */ static void AttributeChanged(mozilla::dom::Element* aElement, int32_t aNameSpaceID, nsIAtom* aAttribute, - int32_t aModType); + int32_t aModType, + const nsAttrValue* aOldValue); + /** * Send AttributeSetToCurrentValue notifications to nsIMutationObservers. * @param aElement Element whose data changed diff --git a/dom/base/nsPropertyTable.cpp b/dom/base/nsPropertyTable.cpp index 2cff061b2d..7710bc9719 100644 --- a/dom/base/nsPropertyTable.cpp +++ b/dom/base/nsPropertyTable.cpp @@ -93,9 +93,8 @@ nsPropertyTable::TransferOrDeleteAllPropertiesFor(nsPropertyOwner aObject, nsresult rv = NS_OK; for (PropertyList* prop = mPropertyList; prop; prop = prop->mNext) { if (prop->mTransfer) { - PropertyListMapEntry *entry = - static_cast - (PL_DHashTableSearch(&prop->mObjectValueMap, aObject)); + auto entry = static_cast + (prop->mObjectValueMap.Search(aObject)); if (entry) { rv = aOtherTable->SetProperty(aObject, prop->mName, entry->value, prop->mDtorFunc, @@ -107,7 +106,7 @@ nsPropertyTable::TransferOrDeleteAllPropertiesFor(nsPropertyOwner aObject, break; } - PL_DHashTableRawRemove(&prop->mObjectValueMap, entry); + prop->mObjectValueMap.RemoveEntry(entry); } } else { @@ -124,8 +123,8 @@ nsPropertyTable::Enumerate(nsPropertyOwner aObject, { PropertyList* prop; for (prop = mPropertyList; prop; prop = prop->mNext) { - PropertyListMapEntry *entry = static_cast - (PL_DHashTableSearch(&prop->mObjectValueMap, aObject)); + auto entry = static_cast + (prop->mObjectValueMap.Search(aObject)); if (entry) { aCallback(const_cast(aObject.get()), prop->mName, entry->value, aData); @@ -157,14 +156,13 @@ nsPropertyTable::GetPropertyInternal(nsPropertyOwner aObject, PropertyList* propertyList = GetPropertyListFor(aPropertyName); if (propertyList) { - PropertyListMapEntry *entry = - static_cast - (PL_DHashTableSearch(&propertyList->mObjectValueMap, aObject)); + auto entry = static_cast + (propertyList->mObjectValueMap.Search(aObject)); if (entry) { propValue = entry->value; if (aRemove) { // don't call propertyList->mDtorFunc. That's the caller's job now. - PL_DHashTableRawRemove(&propertyList->mObjectValueMap, entry); + propertyList->mObjectValueMap.RemoveEntry(entry); } rv = NS_OK; } @@ -294,14 +292,13 @@ nsPropertyTable::PropertyList::Destroy() bool nsPropertyTable::PropertyList::DeletePropertyFor(nsPropertyOwner aObject) { - PropertyListMapEntry *entry = - static_cast - (PL_DHashTableSearch(&mObjectValueMap, aObject)); + auto entry = + static_cast(mObjectValueMap.Search(aObject)); if (!entry) return false; void* value = entry->value; - PL_DHashTableRawRemove(&mObjectValueMap, entry); + mObjectValueMap.RemoveEntry(entry); if (mDtorFunc) mDtorFunc(const_cast(aObject.get()), mName, value, mDtorData); diff --git a/dom/base/nsScriptElement.cpp b/dom/base/nsScriptElement.cpp index 3d1331f603..40e44f1440 100644 --- a/dom/base/nsScriptElement.cpp +++ b/dom/base/nsScriptElement.cpp @@ -83,7 +83,8 @@ nsScriptElement::AttributeChanged(nsIDocument* aDocument, Element* aElement, int32_t aNameSpaceID, nsIAtom* aAttribute, - int32_t aModType) + int32_t aModType, + const nsAttrValue* aOldValue) { MaybeProcessScript(); } diff --git a/dom/base/nsScriptNameSpaceManager.cpp b/dom/base/nsScriptNameSpaceManager.cpp index fc87f9a256..e6aa973dbf 100644 --- a/dom/base/nsScriptNameSpaceManager.cpp +++ b/dom/base/nsScriptNameSpaceManager.cpp @@ -159,10 +159,8 @@ nsScriptNameSpaceManager::GetConstructorProto(const nsGlobalNameStruct* aStruct) NS_ASSERTION(aStruct->mType == nsGlobalNameStruct::eTypeExternalConstructorAlias, "This function only works on constructor aliases!"); if (!aStruct->mAlias->mProto) { - GlobalNameMapEntry *proto = - static_cast - (PL_DHashTableSearch(&mGlobalNames, - &aStruct->mAlias->mProtoName)); + auto proto = static_cast + (mGlobalNames.Search(&aStruct->mAlias->mProtoName)); if (proto) { aStruct->mAlias->mProto = &proto->mGlobalName; } @@ -344,9 +342,7 @@ nsGlobalNameStruct* nsScriptNameSpaceManager::LookupNameInternal(const nsAString& aName, const char16_t **aClassName) { - GlobalNameMapEntry *entry = - static_cast - (PL_DHashTableSearch(&mGlobalNames, &aName)); + auto entry = static_cast(mGlobalNames.Search(&aName)); if (entry) { if (aClassName) { @@ -364,9 +360,7 @@ nsScriptNameSpaceManager::LookupNameInternal(const nsAString& aName, const nsGlobalNameStruct* nsScriptNameSpaceManager::LookupNavigatorName(const nsAString& aName) { - GlobalNameMapEntry *entry = - static_cast - (PL_DHashTableSearch(&mNavigatorNames, &aName)); + auto entry = static_cast(mNavigatorNames.Search(&aName)); return entry ? &entry->mGlobalName : nullptr; } diff --git a/dom/base/nsStyledElement.cpp b/dom/base/nsStyledElement.cpp index 2530b48058..a8d4d984ae 100644 --- a/dom/base/nsStyledElement.cpp +++ b/dom/base/nsStyledElement.cpp @@ -138,7 +138,7 @@ nsStyledElementNotElementCSSInlineStyle::ReparseStyleAttribute(bool aForceInData ParseStyleAttribute(stringValue, attrValue, aForceInDataDoc); // Don't bother going through SetInlineStyleRule, we don't want to fire off // mutation events or document notifications anyway - nsresult rv = mAttrsAndChildren.SetAndTakeAttr(nsGkAtoms::style, attrValue); + nsresult rv = mAttrsAndChildren.SetAndSwapAttr(nsGkAtoms::style, attrValue); NS_ENSURE_SUCCESS(rv, rv); } diff --git a/dom/base/nsTextNode.cpp b/dom/base/nsTextNode.cpp index bb143cb5f3..1d30ca93f7 100644 --- a/dom/base/nsTextNode.cpp +++ b/dom/base/nsTextNode.cpp @@ -268,7 +268,8 @@ nsAttributeTextNode::AttributeChanged(nsIDocument* aDocument, Element* aElement, int32_t aNameSpaceID, nsIAtom* aAttribute, - int32_t aModType) + int32_t aModType, + const nsAttrValue* aOldValue) { if (aNameSpaceID == mNameSpaceID && aAttribute == mAttrName && aElement == mGrandparent) { diff --git a/dom/base/test/test_mutationobservers.html b/dom/base/test/test_mutationobservers.html index 657b4099ed..076da19d8c 100644 --- a/dom/base/test/test_mutationobservers.html +++ b/dom/base/test/test_mutationobservers.html @@ -20,6 +20,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=641821 /** Test for Bug 641821 **/ +SimpleTest.requestFlakyTimeout("requestFlakyTimeout is silly. (But make sure marquee has time to initialize itself.)"); + var div = document.createElement("div"); var M; @@ -580,7 +582,7 @@ function testExpandos() { var m2 = new M(function(records, observer) { is(observer.expandoProperty, true); observer.disconnect(); - then(); + then(testOutsideShadowDOM); }); m2.expandoProperty = true; m2.observe(div, { attributes: true }); @@ -596,6 +598,159 @@ function testExpandos() { div.setAttribute("foo", "bar2"); } +function testOutsideShadowDOM() { + var m = new M(function(records, observer) { + is(records.length, 1); + is(records[0].type, "attributes", "Should have got attributes"); + observer.disconnect(); + then(testInsideShadowDOM); + }); + m.observe(div, { + attributes: true, + childList: true, + characterData: true, + subtree: true + }) + var sr = div.createShadowRoot(); + sr.innerHTML = "text"; + sr.firstChild.setAttribute("foo", "bar"); + sr.firstChild.firstChild.data = "text2"; + sr.firstChild.appendChild(document.createElement("div")); + div.setAttribute("foo", "bar"); +} + +function testInsideShadowDOM() { + var m = new M(function(records, observer) { + is(records.length, 4); + is(records[0].type, "childList"); + is(records[1].type, "attributes"); + is(records[2].type, "characterData"); + is(records[3].type, "childList"); + observer.disconnect(); + then(testMarquee); + }); + var sr = div.createShadowRoot(); + m.observe(sr, { + attributes: true, + childList: true, + characterData: true, + subtree: true + }); + + sr.innerHTML = "text"; + sr.firstChild.setAttribute("foo", "bar"); + sr.firstChild.firstChild.data = "text2"; + sr.firstChild.appendChild(document.createElement("div")); + div.setAttribute("foo", "bar2"); + +} + +function testMarquee() { + var m = new M(function(records, observer) { + is(records.length, 1); + is(records[0].type, "attributes"); + is(records[0].attributeName, "ok"); + is(records[0].oldValue, null); + observer.disconnect(); + then(testStyleCreate); + }); + var marquee = document.createElement("marquee"); + m.observe(marquee, { + attributes: true, + attributeOldValue: true, + childList: true, + characterData: true, + subtree: true + }); + document.body.appendChild(marquee); + setTimeout(function() {marquee.setAttribute("ok", "ok")}, 500); +} + +function testStyleCreate() { + m = new M(function(records, observer) { + is(records.length, 1, "number of records"); + is(records[0].type, "attributes", "record.type"); + is(records[0].attributeName, "style", "record.attributeName"); + is(records[0].oldValue, null, "record.oldValue"); + isnot(div.getAttribute("style"), null, "style attribute after creation"); + observer.disconnect(); + m = null; + div.removeAttribute("style"); + then(testStyleModify); + }); + m.observe(div, { attributes: true, attributeOldValue: true }); + is(div.getAttribute("style"), null, "style attribute before creation"); + div.style.color = "blue"; +} + +function testStyleModify() { + div.style.color = "yellow"; + m = new M(function(records, observer) { + is(records.length, 1, "number of records"); + is(records[0].type, "attributes", "record.type"); + is(records[0].attributeName, "style", "record.attributeName"); + isnot(div.getAttribute("style"), null, "style attribute after modification"); + observer.disconnect(); + m = null; + div.removeAttribute("style"); + then(testStyleRead); + }); + m.observe(div, { attributes: true }); + isnot(div.getAttribute("style"), null, "style attribute before modification"); + div.style.color = "blue"; +} + +function testStyleRead() { + m = new M(function(records, observer) { + is(records.length, 1, "number of records"); + is(records[0].type, "attributes", "record.type"); + is(records[0].attributeName, "data-test", "record.attributeName"); + is(div.getAttribute("style"), null, "style attribute after read"); + observer.disconnect(); + div.removeAttribute("data-test"); + m = null; + then(testStyleRemoveProperty); + }); + m.observe(div, { attributes: true }); + is(div.getAttribute("style"), null, "style attribute before read"); + var value = div.style.color; // shouldn't generate any mutation records + div.setAttribute("data-test", "a"); +} + +function testStyleRemoveProperty() { + div.style.color = "blue"; + m = new M(function(records, observer) { + is(records.length, 1, "number of records"); + is(records[0].type, "attributes", "record.type"); + is(records[0].attributeName, "style", "record.attributeName"); + isnot(div.getAttribute("style"), null, "style attribute after successful removeProperty"); + observer.disconnect(); + m = null; + div.removeAttribute("style"); + then(testStyleRemoveProperty2); + }); + m.observe(div, { attributes: true }); + isnot(div.getAttribute("style"), null, "style attribute before successful removeProperty"); + div.style.removeProperty("color"); +} + +function testStyleRemoveProperty2() { + m = new M(function(records, observer) { + is(records.length, 1, "number of records"); + is(records[0].type, "attributes", "record.type"); + is(records[0].attributeName, "data-test", "record.attributeName"); + is(div.getAttribute("style"), null, "style attribute after unsuccessful removeProperty"); + observer.disconnect(); + m = null; + div.removeAttribute("data-test"); + then(); + }); + m.observe(div, { attributes: true }); + is(div.getAttribute("style"), null, "style attribute before unsuccessful removeProperty"); + div.style.removeProperty("color"); // shouldn't generate any mutation records + div.setAttribute("data-test", "a"); +} + SimpleTest.waitForExplicitFinish(); diff --git a/dom/events/IMEContentObserver.cpp b/dom/events/IMEContentObserver.cpp index 5dd212945f..ec5d2f3b19 100644 --- a/dom/events/IMEContentObserver.cpp +++ b/dom/events/IMEContentObserver.cpp @@ -744,7 +744,8 @@ IMEContentObserver::AttributeWillChange(nsIDocument* aDocument, dom::Element* aElement, int32_t aNameSpaceID, nsIAtom* aAttribute, - int32_t aModType) + int32_t aModType, + const nsAttrValue* aNewValue) { nsIContent *content = GetContentBR(aElement); mPreAttrChangeLength = content ? @@ -756,7 +757,8 @@ IMEContentObserver::AttributeChanged(nsIDocument* aDocument, dom::Element* aElement, int32_t aNameSpaceID, nsIAtom* aAttribute, - int32_t aModType) + int32_t aModType, + const nsAttrValue* aOldValue) { mEndOfAddedTextCache.Clear(); mStartOfRemovingTextRangeCache.Clear(); diff --git a/dom/html/HTMLButtonElement.cpp b/dom/html/HTMLButtonElement.cpp index 56fe5def56..4a37c6cead 100644 --- a/dom/html/HTMLButtonElement.cpp +++ b/dom/html/HTMLButtonElement.cpp @@ -491,7 +491,7 @@ HTMLButtonElement::DoneCreatingElement() nsresult HTMLButtonElement::BeforeSetAttr(int32_t aNameSpaceID, nsIAtom* aName, - const nsAttrValueOrString* aValue, + nsAttrValueOrString* aValue, bool aNotify) { if (aNotify && aName == nsGkAtoms::disabled && diff --git a/dom/html/HTMLButtonElement.h b/dom/html/HTMLButtonElement.h index 2300ef8f28..8a48beaa11 100644 --- a/dom/html/HTMLButtonElement.h +++ b/dom/html/HTMLButtonElement.h @@ -80,7 +80,7 @@ public: * Called when an attribute is about to be changed */ virtual nsresult BeforeSetAttr(int32_t aNameSpaceID, nsIAtom* aName, - const nsAttrValueOrString* aValue, + nsAttrValueOrString* aValue, bool aNotify) override; /** * Called when an attribute has just been changed diff --git a/dom/html/HTMLDetailsElement.cpp b/dom/html/HTMLDetailsElement.cpp index f912e13548..a91af49c6b 100644 --- a/dom/html/HTMLDetailsElement.cpp +++ b/dom/html/HTMLDetailsElement.cpp @@ -50,7 +50,7 @@ HTMLDetailsElement::GetAttributeChangeHint(const nsIAtom* aAttribute, nsresult HTMLDetailsElement::BeforeSetAttr(int32_t aNameSpaceID, nsIAtom* aName, - const nsAttrValueOrString* aValue, + nsAttrValueOrString* aValue, bool aNotify) { if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::open) { diff --git a/dom/html/HTMLDetailsElement.h b/dom/html/HTMLDetailsElement.h index e88157ce98..eef4faefd6 100644 --- a/dom/html/HTMLDetailsElement.h +++ b/dom/html/HTMLDetailsElement.h @@ -39,7 +39,7 @@ public: int32_t aModType) const override; nsresult BeforeSetAttr(int32_t aNameSpaceID, nsIAtom* aName, - const nsAttrValueOrString* aValue, + nsAttrValueOrString* aValue, bool aNotify) override; // WebIDL methods. diff --git a/dom/html/HTMLImageElement.cpp b/dom/html/HTMLImageElement.cpp index a46c0ee99f..b59b80c065 100644 --- a/dom/html/HTMLImageElement.cpp +++ b/dom/html/HTMLImageElement.cpp @@ -371,7 +371,7 @@ HTMLImageElement::GetAttributeMappingFunction() const nsresult HTMLImageElement::BeforeSetAttr(int32_t aNameSpaceID, nsIAtom* aName, - const nsAttrValueOrString* aValue, + nsAttrValueOrString* aValue, bool aNotify) { diff --git a/dom/html/HTMLImageElement.h b/dom/html/HTMLImageElement.h index 9a5a3ab632..8d5d5a15fb 100644 --- a/dom/html/HTMLImageElement.h +++ b/dom/html/HTMLImageElement.h @@ -320,7 +320,7 @@ protected: void UpdateFormOwner(); virtual nsresult BeforeSetAttr(int32_t aNameSpaceID, nsIAtom* aName, - const nsAttrValueOrString* aValue, + nsAttrValueOrString* aValue, bool aNotify) override; virtual nsresult AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName, diff --git a/dom/html/HTMLInputElement.cpp b/dom/html/HTMLInputElement.cpp index 09da9dfdaf..e0938a4ad7 100644 --- a/dom/html/HTMLInputElement.cpp +++ b/dom/html/HTMLInputElement.cpp @@ -1331,7 +1331,7 @@ HTMLInputElement::Clone(mozilla::dom::NodeInfo* aNodeInfo, nsINode** aResult) co nsresult HTMLInputElement::BeforeSetAttr(int32_t aNameSpaceID, nsIAtom* aName, - const nsAttrValueOrString* aValue, + nsAttrValueOrString* aValue, bool aNotify) { if (aNameSpaceID == kNameSpaceID_None) { diff --git a/dom/html/HTMLInputElement.h b/dom/html/HTMLInputElement.h index 551d4a090b..852e5f79bf 100644 --- a/dom/html/HTMLInputElement.h +++ b/dom/html/HTMLInputElement.h @@ -865,7 +865,7 @@ protected: * Called when an attribute is about to be changed */ virtual nsresult BeforeSetAttr(int32_t aNameSpaceID, nsIAtom* aName, - const nsAttrValueOrString* aValue, + nsAttrValueOrString* aValue, bool aNotify) override; /** * Called when an attribute has just been changed diff --git a/dom/html/HTMLOptionElement.cpp b/dom/html/HTMLOptionElement.cpp index a8a7c4752f..4d0dbe2a14 100644 --- a/dom/html/HTMLOptionElement.cpp +++ b/dom/html/HTMLOptionElement.cpp @@ -215,7 +215,7 @@ HTMLOptionElement::GetAttributeChangeHint(const nsIAtom* aAttribute, nsresult HTMLOptionElement::BeforeSetAttr(int32_t aNamespaceID, nsIAtom* aName, - const nsAttrValueOrString* aValue, + nsAttrValueOrString* aValue, bool aNotify) { nsresult rv = nsGenericHTMLElement::BeforeSetAttr(aNamespaceID, aName, diff --git a/dom/html/HTMLOptionElement.h b/dom/html/HTMLOptionElement.h index e8da575d86..32ad875cd1 100644 --- a/dom/html/HTMLOptionElement.h +++ b/dom/html/HTMLOptionElement.h @@ -47,7 +47,7 @@ public: int32_t aModType) const override; virtual nsresult BeforeSetAttr(int32_t aNamespaceID, nsIAtom* aName, - const nsAttrValueOrString* aValue, + nsAttrValueOrString* aValue, bool aNotify) override; virtual nsresult AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName, const nsAttrValue* aValue, bool aNotify) override; diff --git a/dom/html/HTMLPropertiesCollection.cpp b/dom/html/HTMLPropertiesCollection.cpp index 8a511534a2..0cdd29ca78 100644 --- a/dom/html/HTMLPropertiesCollection.cpp +++ b/dom/html/HTMLPropertiesCollection.cpp @@ -159,7 +159,8 @@ HTMLPropertiesCollection::NamedItem(const nsAString& aName) void HTMLPropertiesCollection::AttributeChanged(nsIDocument *aDocument, Element* aElement, int32_t aNameSpaceID, nsIAtom* aAttribute, - int32_t aModType) + int32_t aModType, + const nsAttrValue* aOldValue) { mIsDirty = true; } @@ -438,7 +439,8 @@ PropertyNodeList::GetValues(JSContext* aCx, nsTArray& aResult, void PropertyNodeList::AttributeChanged(nsIDocument* aDocument, Element* aElement, int32_t aNameSpaceID, nsIAtom* aAttribute, - int32_t aModType) + int32_t aModType, + const nsAttrValue* aOldValue) { mIsDirty = true; } diff --git a/dom/html/HTMLSelectElement.cpp b/dom/html/HTMLSelectElement.cpp index e112e0a2ab..a9b7640cc2 100644 --- a/dom/html/HTMLSelectElement.cpp +++ b/dom/html/HTMLSelectElement.cpp @@ -1328,7 +1328,7 @@ HTMLSelectElement::UnbindFromTree(bool aDeep, bool aNullParent) nsresult HTMLSelectElement::BeforeSetAttr(int32_t aNameSpaceID, nsIAtom* aName, - const nsAttrValueOrString* aValue, + nsAttrValueOrString* aValue, bool aNotify) { if (aNotify && aName == nsGkAtoms::disabled && diff --git a/dom/html/HTMLSelectElement.h b/dom/html/HTMLSelectElement.h index 6150dc17a3..06d1a5d51c 100644 --- a/dom/html/HTMLSelectElement.h +++ b/dom/html/HTMLSelectElement.h @@ -372,7 +372,7 @@ public: bool aCompileEventHandlers) override; virtual void UnbindFromTree(bool aDeep, bool aNullParent) override; virtual nsresult BeforeSetAttr(int32_t aNameSpaceID, nsIAtom* aName, - const nsAttrValueOrString* aValue, + nsAttrValueOrString* aValue, bool aNotify) override; virtual nsresult AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName, const nsAttrValue* aValue, bool aNotify) override; diff --git a/dom/html/HTMLTableElement.cpp b/dom/html/HTMLTableElement.cpp index b12903eabe..5290aefaba 100644 --- a/dom/html/HTMLTableElement.cpp +++ b/dom/html/HTMLTableElement.cpp @@ -956,7 +956,7 @@ HTMLTableElement::UnbindFromTree(bool aDeep, bool aNullParent) nsresult HTMLTableElement::BeforeSetAttr(int32_t aNameSpaceID, nsIAtom* aName, - const nsAttrValueOrString* aValue, + nsAttrValueOrString* aValue, bool aNotify) { if (aName == nsGkAtoms::cellpadding && aNameSpaceID == kNameSpaceID_None) { diff --git a/dom/html/HTMLTableElement.h b/dom/html/HTMLTableElement.h index 0c3b67f323..35e96505c7 100644 --- a/dom/html/HTMLTableElement.h +++ b/dom/html/HTMLTableElement.h @@ -191,7 +191,7 @@ public: * Called when an attribute is about to be changed */ virtual nsresult BeforeSetAttr(int32_t aNameSpaceID, nsIAtom* aName, - const nsAttrValueOrString* aValue, + nsAttrValueOrString* aValue, bool aNotify) override; /** * Called when an attribute has just been changed diff --git a/dom/html/HTMLTextAreaElement.cpp b/dom/html/HTMLTextAreaElement.cpp index c514cd0307..98d944fc92 100644 --- a/dom/html/HTMLTextAreaElement.cpp +++ b/dom/html/HTMLTextAreaElement.cpp @@ -1209,7 +1209,7 @@ HTMLTextAreaElement::UnbindFromTree(bool aDeep, bool aNullParent) nsresult HTMLTextAreaElement::BeforeSetAttr(int32_t aNameSpaceID, nsIAtom* aName, - const nsAttrValueOrString* aValue, + nsAttrValueOrString* aValue, bool aNotify) { if (aNotify && aName == nsGkAtoms::disabled && diff --git a/dom/html/HTMLTextAreaElement.h b/dom/html/HTMLTextAreaElement.h index 730088d156..969a66fd44 100644 --- a/dom/html/HTMLTextAreaElement.h +++ b/dom/html/HTMLTextAreaElement.h @@ -140,7 +140,7 @@ public: * Called when an attribute is about to be changed */ virtual nsresult BeforeSetAttr(int32_t aNameSpaceID, nsIAtom* aName, - const nsAttrValueOrString* aValue, + nsAttrValueOrString* aValue, bool aNotify) override; // nsIMutationObserver diff --git a/dom/html/UndoManager.cpp b/dom/html/UndoManager.cpp index 7d891aedde..40a37d08ca 100644 --- a/dom/html/UndoManager.cpp +++ b/dom/html/UndoManager.cpp @@ -649,7 +649,8 @@ UndoMutationObserver::AttributeWillChange(nsIDocument* aDocument, mozilla::dom::Element* aElement, int32_t aNameSpaceID, nsIAtom* aAttribute, - int32_t aModType) + int32_t aModType, + const nsAttrValue* aNewValue) { if (!IsManagerForMutation(aElement)) { return; diff --git a/dom/html/nsDOMStringMap.cpp b/dom/html/nsDOMStringMap.cpp index 6a1e7a4062..fe2b863886 100644 --- a/dom/html/nsDOMStringMap.cpp +++ b/dom/html/nsDOMStringMap.cpp @@ -259,7 +259,8 @@ bool nsDOMStringMap::AttrToDataProp(const nsAString& aAttr, void nsDOMStringMap::AttributeChanged(nsIDocument *aDocument, Element* aElement, int32_t aNameSpaceID, nsIAtom* aAttribute, - int32_t aModType) + int32_t aModType, + const nsAttrValue* aOldValue) { if ((aModType == nsIDOMMutationEvent::ADDITION || aModType == nsIDOMMutationEvent::REMOVAL) && diff --git a/dom/html/nsGenericHTMLElement.cpp b/dom/html/nsGenericHTMLElement.cpp index dec2eef7be..cfcba87219 100644 --- a/dom/html/nsGenericHTMLElement.cpp +++ b/dom/html/nsGenericHTMLElement.cpp @@ -2097,7 +2097,7 @@ nsGenericHTMLFormElement::UnbindFromTree(bool aDeep, bool aNullParent) nsresult nsGenericHTMLFormElement::BeforeSetAttr(int32_t aNameSpaceID, nsIAtom* aName, - const nsAttrValueOrString* aValue, + nsAttrValueOrString* aValue, bool aNotify) { if (aNameSpaceID == kNameSpaceID_None) { diff --git a/dom/html/nsGenericHTMLElement.h b/dom/html/nsGenericHTMLElement.h index 62fd90a2c4..2c96bf6f7d 100644 --- a/dom/html/nsGenericHTMLElement.h +++ b/dom/html/nsGenericHTMLElement.h @@ -1372,7 +1372,7 @@ protected: virtual ~nsGenericHTMLFormElement(); virtual nsresult BeforeSetAttr(int32_t aNameSpaceID, nsIAtom* aName, - const nsAttrValueOrString* aValue, + nsAttrValueOrString* aValue, bool aNotify) override; virtual nsresult AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName, diff --git a/dom/plugins/base/nsJSNPRuntime.cpp b/dom/plugins/base/nsJSNPRuntime.cpp index 14cf138e63..52b7cf5c7b 100644 --- a/dom/plugins/base/nsJSNPRuntime.cpp +++ b/dom/plugins/base/nsJSNPRuntime.cpp @@ -1783,11 +1783,11 @@ NPObjWrapper_ObjectMoved(JSObject* obj, const JSObject* old) return; } - // Calling PL_DHashTableSearch() will not result in GC. + // Calling PLDHashTable::Search() will not result in GC. JS::AutoSuppressGCAnalysis nogc; - NPObjWrapperHashEntry* entry = static_cast - (PL_DHashTableSearch(sNPObjWrappers, npobj)); + auto entry = + static_cast(sNPObjWrappers->Search(npobj)); MOZ_ASSERT(entry && entry->mJSObj); MOZ_ASSERT(entry->mJSObj == old); entry->mJSObj = obj; @@ -1839,8 +1839,8 @@ nsNPObjWrapper::OnDestroy(NPObject* npobj) return; } - NPObjWrapperHashEntry* entry = static_cast - (PL_DHashTableSearch(sNPObjWrappers, npobj)); + auto entry = + static_cast(sNPObjWrappers->Search(npobj)); if (entry && entry->mJSObj) { // Found a live NPObject wrapper, null out its JSObjects' private @@ -1923,7 +1923,7 @@ nsNPObjWrapper::GetNewOrUsed(NPP npp, JSContext* cx, NPObject* npobj) // Reload entry if the JS_NewObject call caused a GC and reallocated // the table (see bug 445229). This is guaranteed to succeed. - NS_ASSERTION(PL_DHashTableSearch(sNPObjWrappers, npobj), + NS_ASSERTION(sNPObjWrappers->Search(npobj), "Hashtable didn't find what we just added?"); } diff --git a/dom/svg/SVGMPathElement.cpp b/dom/svg/SVGMPathElement.cpp index c6f7ebceca..cc89c5ce36 100644 --- a/dom/svg/SVGMPathElement.cpp +++ b/dom/svg/SVGMPathElement.cpp @@ -165,7 +165,8 @@ SVGMPathElement::AttributeChanged(nsIDocument* aDocument, Element* aElement, int32_t aNameSpaceID, nsIAtom* aAttribute, - int32_t aModType) + int32_t aModType, + const nsAttrValue* aOldValue) { if (aNameSpaceID == kNameSpaceID_None) { if (aAttribute == nsGkAtoms::d) { diff --git a/dom/svg/SVGUseElement.cpp b/dom/svg/SVGUseElement.cpp index a6bd8ec8d1..b4d7d0a3e1 100644 --- a/dom/svg/SVGUseElement.cpp +++ b/dom/svg/SVGUseElement.cpp @@ -156,7 +156,8 @@ SVGUseElement::AttributeChanged(nsIDocument* aDocument, Element* aElement, int32_t aNameSpaceID, nsIAtom* aAttribute, - int32_t aModType) + int32_t aModType, + const nsAttrValue* aOldValue) { if (nsContentUtils::IsInSameAnonymousTree(this, aElement)) { TriggerReclone(); diff --git a/dom/svg/nsSVGElement.cpp b/dom/svg/nsSVGElement.cpp index cbfc9454c4..216c8adafa 100644 --- a/dom/svg/nsSVGElement.cpp +++ b/dom/svg/nsSVGElement.cpp @@ -273,7 +273,7 @@ nsSVGElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent, ParseStyleAttribute(stringValue, attrValue, true); // Don't bother going through SetInlineStyleRule, we don't want to fire off // mutation events or document notifications anyway - rv = mAttrsAndChildren.SetAndTakeAttr(nsGkAtoms::style, attrValue); + rv = mAttrsAndChildren.SetAndSwapAttr(nsGkAtoms::style, attrValue); NS_ENSURE_SUCCESS(rv, rv); } @@ -1439,7 +1439,8 @@ nsSVGElement::WillChangeValue(nsIAtom* aName) uint8_t modType = attrValue ? static_cast(nsIDOMMutationEvent::MODIFICATION) : static_cast(nsIDOMMutationEvent::ADDITION); - nsNodeUtils::AttributeWillChange(this, kNameSpaceID_None, aName, modType); + nsNodeUtils::AttributeWillChange(this, kNameSpaceID_None, aName, modType, + nullptr); return emptyOrOldAttrValue; } @@ -1454,6 +1455,8 @@ nsSVGElement::WillChangeValue(nsIAtom* aName) * b) WillChangeXXX will ensure the object represents a serialized version of * the old attribute value so that the value doesn't change when the * underlying SVG type is updated. + * + * aNewValue is replaced with the old value. */ void nsSVGElement::DidChangeValue(nsIAtom* aName, @@ -1489,7 +1492,7 @@ nsSVGElement::MaybeSerializeAttrBeforeRemoval(nsIAtom* aName, bool aNotify) nsAutoString serializedValue; attrValue->ToString(serializedValue); nsAttrValue oldAttrValue(serializedValue); - mAttrsAndChildren.SetAndTakeAttr(aName, oldAttrValue); + mAttrsAndChildren.SetAndSwapAttr(aName, oldAttrValue); } /* static */ diff --git a/dom/svg/nsSVGElement.h b/dom/svg/nsSVGElement.h index d86e3c13c7..b9bed3c35c 100644 --- a/dom/svg/nsSVGElement.h +++ b/dom/svg/nsSVGElement.h @@ -331,8 +331,11 @@ protected: // BeforeSetAttr since it would involve allocating extra SVG value types. // See the comment in nsSVGElement::WillChangeValue. virtual nsresult BeforeSetAttr(int32_t aNamespaceID, nsIAtom* aName, - const nsAttrValueOrString* aValue, - bool aNotify) override final { return NS_OK; } + nsAttrValueOrString* aValue, + bool aNotify) override final + { + return nsSVGElementBase::BeforeSetAttr(aNamespaceID, aName, aValue, aNotify); + } #endif // DEBUG virtual nsresult AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName, const nsAttrValue* aValue, bool aNotify) override; @@ -347,6 +350,8 @@ protected: mozilla::css::StyleRule* GetAnimatedContentStyleRule(); nsAttrValue WillChangeValue(nsIAtom* aName); + // aNewValue is set to the old value. This value may be invalid if + // !StoresOwnData. void DidChangeValue(nsIAtom* aName, const nsAttrValue& aEmptyOrOldValue, nsAttrValue& aNewValue); void MaybeSerializeAttrBeforeRemoval(nsIAtom* aName, bool aNotify); diff --git a/dom/xml/nsXMLPrettyPrinter.cpp b/dom/xml/nsXMLPrettyPrinter.cpp index f18ff7bce7..906ffc4308 100644 --- a/dom/xml/nsXMLPrettyPrinter.cpp +++ b/dom/xml/nsXMLPrettyPrinter.cpp @@ -218,7 +218,8 @@ nsXMLPrettyPrinter::AttributeChanged(nsIDocument* aDocument, Element* aElement, int32_t aNameSpaceID, nsIAtom* aAttribute, - int32_t aModType) + int32_t aModType, + const nsAttrValue* aOldValue) { MaybeUnhook(aElement); } diff --git a/dom/xslt/xpath/XPathResult.cpp b/dom/xslt/xpath/XPathResult.cpp index cd76f3083a..f3ea155c60 100644 --- a/dom/xslt/xpath/XPathResult.cpp +++ b/dom/xslt/xpath/XPathResult.cpp @@ -136,7 +136,8 @@ XPathResult::AttributeChanged(nsIDocument* aDocument, Element* aElement, int32_t aNameSpaceID, nsIAtom* aAttribute, - int32_t aModType) + int32_t aModType, + const nsAttrValue* aOldValue) { Invalidate(aElement); } diff --git a/dom/xslt/xslt/txMozillaXSLTProcessor.cpp b/dom/xslt/xslt/txMozillaXSLTProcessor.cpp index 08fef4599d..78a6a95d28 100644 --- a/dom/xslt/xslt/txMozillaXSLTProcessor.cpp +++ b/dom/xslt/xslt/txMozillaXSLTProcessor.cpp @@ -1245,7 +1245,8 @@ txMozillaXSLTProcessor::AttributeChanged(nsIDocument* aDocument, Element* aElement, int32_t aNameSpaceID, nsIAtom* aAttribute, - int32_t aModType) + int32_t aModType, + const nsAttrValue* aOldValue) { mStylesheet = nullptr; } diff --git a/dom/xul/XULDocument.cpp b/dom/xul/XULDocument.cpp index e919c9b4d3..664571d2fb 100644 --- a/dom/xul/XULDocument.cpp +++ b/dom/xul/XULDocument.cpp @@ -768,10 +768,8 @@ XULDocument::AddBroadcastListenerFor(Element& aBroadcaster, Element& aListener, mBroadcasterMap = new PLDHashTable(&gOps, sizeof(BroadcasterMapEntry)); } - BroadcasterMapEntry* entry = - static_cast - (PL_DHashTableSearch(mBroadcasterMap, &aBroadcaster)); - + auto entry = static_cast + (mBroadcasterMap->Search(&aBroadcaster)); if (!entry) { entry = static_cast (PL_DHashTableAdd(mBroadcasterMap, &aBroadcaster, fallible)); @@ -829,10 +827,8 @@ XULDocument::RemoveBroadcastListenerFor(Element& aBroadcaster, if (! mBroadcasterMap) return; - BroadcasterMapEntry* entry = - static_cast - (PL_DHashTableSearch(mBroadcasterMap, &aBroadcaster)); - + auto entry = static_cast + (mBroadcasterMap->Search(&aBroadcaster)); if (entry) { nsCOMPtr attr = do_GetAtom(aAttr); for (size_t i = entry->mListeners.Length() - 1; i != (size_t)-1; --i) { @@ -844,7 +840,7 @@ XULDocument::RemoveBroadcastListenerFor(Element& aBroadcaster, delete bl; if (entry->mListeners.IsEmpty()) - PL_DHashTableRemove(mBroadcasterMap, &aBroadcaster); + mBroadcasterMap->RemoveEntry(entry); break; } @@ -914,7 +910,8 @@ XULDocument::ExecuteOnBroadcastHandlerFor(Element* aBroadcaster, void XULDocument::AttributeWillChange(nsIDocument* aDocument, Element* aElement, int32_t aNameSpaceID, - nsIAtom* aAttribute, int32_t aModType) + nsIAtom* aAttribute, int32_t aModType, + const nsAttrValue* aNewValue) { MOZ_ASSERT(aElement, "Null content!"); NS_PRECONDITION(aAttribute, "Must have an attribute that's changing!"); @@ -931,7 +928,8 @@ XULDocument::AttributeWillChange(nsIDocument* aDocument, void XULDocument::AttributeChanged(nsIDocument* aDocument, Element* aElement, int32_t aNameSpaceID, - nsIAtom* aAttribute, int32_t aModType) + nsIAtom* aAttribute, int32_t aModType, + const nsAttrValue* aOldValue) { NS_ASSERTION(aDocument == this, "unexpected doc"); @@ -949,9 +947,8 @@ XULDocument::AttributeChanged(nsIDocument* aDocument, // Synchronize broadcast listeners if (mBroadcasterMap && CanBroadcast(aNameSpaceID, aAttribute)) { - BroadcasterMapEntry* entry = - static_cast - (PL_DHashTableSearch(mBroadcasterMap, aElement)); + auto entry = static_cast + (mBroadcasterMap->Search(aElement)); if (entry) { // We've got listeners: push the value. @@ -4127,8 +4124,8 @@ XULDocument::BroadcastAttributeChangeFromOverlay(nsIContent* aNode, if (!aNode->IsElement()) return rv; - BroadcasterMapEntry* entry = static_cast - (PL_DHashTableSearch(mBroadcasterMap, aNode->AsElement())); + auto entry = static_cast + (mBroadcasterMap->Search(aNode->AsElement())); if (!entry) return rv; diff --git a/dom/xul/nsXULElement.cpp b/dom/xul/nsXULElement.cpp index 21a59b6d3c..d5d75ae878 100644 --- a/dom/xul/nsXULElement.cpp +++ b/dom/xul/nsXULElement.cpp @@ -403,10 +403,10 @@ nsXULElement::Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult) const } if (originalName->IsAtom()) { - rv = element->mAttrsAndChildren.SetAndTakeAttr(originalName->Atom(), + rv = element->mAttrsAndChildren.SetAndSwapAttr(originalName->Atom(), attrValue); } else { - rv = element->mAttrsAndChildren.SetAndTakeAttr(originalName->NodeInfo(), + rv = element->mAttrsAndChildren.SetAndSwapAttr(originalName->NodeInfo(), attrValue); } NS_ENSURE_SUCCESS(rv, rv); @@ -1045,7 +1045,7 @@ nsXULElement::UnregisterAccessKey(const nsAString& aOldValue) nsresult nsXULElement::BeforeSetAttr(int32_t aNamespaceID, nsIAtom* aName, - const nsAttrValueOrString* aValue, bool aNotify) + nsAttrValueOrString* aValue, bool aNotify) { if (aNamespaceID == kNameSpaceID_None && aName == nsGkAtoms::accesskey && IsInDoc()) { @@ -1891,10 +1891,10 @@ nsXULElement::MakeHeavyweight(nsXULPrototypeElement* aPrototype) // XXX we might wanna have a SetAndTakeAttr that takes an nsAttrName if (protoattr->mName.IsAtom()) { - rv = mAttrsAndChildren.SetAndTakeAttr(protoattr->mName.Atom(), attrValue); + rv = mAttrsAndChildren.SetAndSwapAttr(protoattr->mName.Atom(), attrValue); } else { - rv = mAttrsAndChildren.SetAndTakeAttr(protoattr->mName.NodeInfo(), + rv = mAttrsAndChildren.SetAndSwapAttr(protoattr->mName.NodeInfo(), attrValue); } NS_ENSURE_SUCCESS(rv, rv); diff --git a/dom/xul/nsXULElement.h b/dom/xul/nsXULElement.h index 3b4a88e0e0..cb6a631185 100644 --- a/dom/xul/nsXULElement.h +++ b/dom/xul/nsXULElement.h @@ -657,7 +657,7 @@ protected: nsresult MakeHeavyweight(nsXULPrototypeElement* aPrototype); virtual nsresult BeforeSetAttr(int32_t aNamespaceID, nsIAtom* aName, - const nsAttrValueOrString* aValue, + nsAttrValueOrString* aValue, bool aNotify) override; virtual nsresult AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName, const nsAttrValue* aValue, bool aNotify) override; diff --git a/dom/xul/templates/nsContentSupportMap.h b/dom/xul/templates/nsContentSupportMap.h index 594128edf0..3667b9238e 100644 --- a/dom/xul/templates/nsContentSupportMap.h +++ b/dom/xul/templates/nsContentSupportMap.h @@ -38,7 +38,7 @@ public: } bool Get(nsIContent* aElement, nsTemplateMatch** aMatch) { - PLDHashEntryHdr* hdr = PL_DHashTableSearch(&mMap, aElement); + PLDHashEntryHdr* hdr = mMap.Search(aElement); if (!hdr) return false; diff --git a/dom/xul/templates/nsTemplateMap.h b/dom/xul/templates/nsTemplateMap.h index 56e1504b15..a06e929c70 100644 --- a/dom/xul/templates/nsTemplateMap.h +++ b/dom/xul/templates/nsTemplateMap.h @@ -25,8 +25,7 @@ public: void Put(nsIContent* aContent, nsIContent* aTemplate) { - NS_ASSERTION(!PL_DHashTableSearch(&mTable, aContent), - "aContent already in map"); + NS_ASSERTION(!mTable.Search(aContent), "aContent already in map"); Entry* entry = static_cast (PL_DHashTableAdd(&mTable, aContent, fallible)); @@ -51,9 +50,7 @@ public: void GetTemplateFor(nsIContent* aContent, nsIContent** aResult) { - Entry* entry = - static_cast(PL_DHashTableSearch(&mTable, aContent)); - + auto entry = static_cast(mTable.Search(aContent)); if (entry) NS_IF_ADDREF(*aResult = entry->mTemplate); else diff --git a/dom/xul/templates/nsXULContentBuilder.cpp b/dom/xul/templates/nsXULContentBuilder.cpp index e6e3e050f1..890728c2fe 100644 --- a/dom/xul/templates/nsXULContentBuilder.cpp +++ b/dom/xul/templates/nsXULContentBuilder.cpp @@ -1510,7 +1510,8 @@ nsXULContentBuilder::AttributeChanged(nsIDocument* aDocument, Element* aElement, int32_t aNameSpaceID, nsIAtom* aAttribute, - int32_t aModType) + int32_t aModType, + const nsAttrValue* aOldValue) { nsCOMPtr kungFuDeathGrip(this); @@ -1536,7 +1537,7 @@ nsXULContentBuilder::AttributeChanged(nsIDocument* aDocument, // Pass along to the generic template builder. nsXULTemplateBuilder::AttributeChanged(aDocument, aElement, aNameSpaceID, - aAttribute, aModType); + aAttribute, aModType, aOldValue); } void diff --git a/dom/xul/templates/nsXULTemplateBuilder.cpp b/dom/xul/templates/nsXULTemplateBuilder.cpp index 82e7fcfe7e..3dd12cf02f 100644 --- a/dom/xul/templates/nsXULTemplateBuilder.cpp +++ b/dom/xul/templates/nsXULTemplateBuilder.cpp @@ -1093,7 +1093,8 @@ nsXULTemplateBuilder::AttributeChanged(nsIDocument* aDocument, Element* aElement, int32_t aNameSpaceID, nsIAtom* aAttribute, - int32_t aModType) + int32_t aModType, + const nsAttrValue* aOldValue) { if (aElement == mRoot && aNameSpaceID == kNameSpaceID_None) { // Check for a change to the 'ref' attribute on an atom, in which diff --git a/editor/composer/nsEditingSession.cpp b/editor/composer/nsEditingSession.cpp index e3451728ee..1a104de3cf 100644 --- a/editor/composer/nsEditingSession.cpp +++ b/editor/composer/nsEditingSession.cpp @@ -208,7 +208,9 @@ nsEditingSession::DisableJSAndPlugins(nsIDOMWindow *aWindow) NS_IMETHODIMP nsEditingSession::RestoreJSAndPlugins(nsIDOMWindow *aWindow) { - NS_ENSURE_TRUE(mDisabledJSAndPlugins, NS_OK); + if (!mDisabledJSAndPlugins) { + return NS_OK; + } mDisabledJSAndPlugins = false; diff --git a/embedding/components/commandhandler/nsBaseCommandController.cpp b/embedding/components/commandhandler/nsBaseCommandController.cpp index 24afacf919..4ae3d443fb 100644 --- a/embedding/components/commandhandler/nsBaseCommandController.cpp +++ b/embedding/components/commandhandler/nsBaseCommandController.cpp @@ -31,20 +31,22 @@ nsBaseCommandController::~nsBaseCommandController() } NS_IMETHODIMP -nsBaseCommandController::Init(nsIControllerCommandTable *aCommandTable) +nsBaseCommandController::Init(nsIControllerCommandTable* aCommandTable) { nsresult rv = NS_OK; - if (aCommandTable) - mCommandTable = aCommandTable; // owning addref - else - mCommandTable = do_CreateInstance(NS_CONTROLLERCOMMANDTABLE_CONTRACTID, &rv); - + if (aCommandTable) { + mCommandTable = aCommandTable; + } else { + mCommandTable = + do_CreateInstance(NS_CONTROLLERCOMMANDTABLE_CONTRACTID, &rv); + } + return rv; } NS_IMETHODIMP -nsBaseCommandController::SetCommandContext(nsISupports *aCommandContext) +nsBaseCommandController::SetCommandContext(nsISupports* aCommandContext) { mCommandContextWeakPtr = nullptr; mCommandContextRawPtr = nullptr; @@ -55,8 +57,7 @@ nsBaseCommandController::SetCommandContext(nsISupports *aCommandContext) nsresult rv = weak->GetWeakReference(getter_AddRefs(mCommandContextWeakPtr)); NS_ENSURE_SUCCESS(rv, rv); - } - else { + } else { mCommandContextRawPtr = aCommandContext; } } @@ -65,32 +66,30 @@ nsBaseCommandController::SetCommandContext(nsISupports *aCommandContext) } NS_IMETHODIMP -nsBaseCommandController::GetInterface(const nsIID & aIID, void * *result) +nsBaseCommandController::GetInterface(const nsIID& aIID, void** aResult) { - NS_ENSURE_ARG_POINTER(result); + NS_ENSURE_ARG_POINTER(aResult); - if (NS_SUCCEEDED(QueryInterface(aIID, result))) + if (NS_SUCCEEDED(QueryInterface(aIID, aResult))) { return NS_OK; + } - if (aIID.Equals(NS_GET_IID(nsIControllerCommandTable))) - { - if (mCommandTable) - return mCommandTable->QueryInterface(aIID, result); + if (aIID.Equals(NS_GET_IID(nsIControllerCommandTable))) { + if (mCommandTable) { + return mCommandTable->QueryInterface(aIID, aResult); + } return NS_ERROR_NOT_INITIALIZED; } - + return NS_NOINTERFACE; } - - /* ======================================================================= * nsIController * ======================================================================= */ NS_IMETHODIMP -nsBaseCommandController::IsCommandEnabled(const char *aCommand, - bool *aResult) +nsBaseCommandController::IsCommandEnabled(const char* aCommand, bool* aResult) { NS_ENSURE_ARG_POINTER(aCommand); NS_ENSURE_ARG_POINTER(aResult); @@ -106,7 +105,7 @@ nsBaseCommandController::IsCommandEnabled(const char *aCommand, } NS_IMETHODIMP -nsBaseCommandController::SupportsCommand(const char *aCommand, bool *aResult) +nsBaseCommandController::SupportsCommand(const char* aCommand, bool* aResult) { NS_ENSURE_ARG_POINTER(aCommand); NS_ENSURE_ARG_POINTER(aResult); @@ -122,7 +121,7 @@ nsBaseCommandController::SupportsCommand(const char *aCommand, bool *aResult) } NS_IMETHODIMP -nsBaseCommandController::DoCommand(const char *aCommand) +nsBaseCommandController::DoCommand(const char* aCommand) { NS_ENSURE_ARG_POINTER(aCommand); NS_ENSURE_STATE(mCommandTable); @@ -137,8 +136,8 @@ nsBaseCommandController::DoCommand(const char *aCommand) } NS_IMETHODIMP -nsBaseCommandController::DoCommandWithParams(const char *aCommand, - nsICommandParams *aParams) +nsBaseCommandController::DoCommandWithParams(const char* aCommand, + nsICommandParams* aParams) { NS_ENSURE_ARG_POINTER(aCommand); NS_ENSURE_STATE(mCommandTable); @@ -153,8 +152,8 @@ nsBaseCommandController::DoCommandWithParams(const char *aCommand, } NS_IMETHODIMP -nsBaseCommandController::GetCommandStateWithParams(const char *aCommand, - nsICommandParams *aParams) +nsBaseCommandController::GetCommandStateWithParams(const char* aCommand, + nsICommandParams* aParams) { NS_ENSURE_ARG_POINTER(aCommand); NS_ENSURE_STATE(mCommandTable); @@ -169,14 +168,15 @@ nsBaseCommandController::GetCommandStateWithParams(const char *aCommand, } NS_IMETHODIMP -nsBaseCommandController::OnEvent(const char * aEventName) +nsBaseCommandController::OnEvent(const char* aEventName) { NS_ENSURE_ARG_POINTER(aEventName); return NS_OK; } NS_IMETHODIMP -nsBaseCommandController::GetSupportedCommands(uint32_t* aCount, char*** aCommands) +nsBaseCommandController::GetSupportedCommands(uint32_t* aCount, + char*** aCommands) { NS_ENSURE_STATE(mCommandTable); return mCommandTable->GetSupportedCommands(aCount, aCommands); diff --git a/embedding/components/commandhandler/nsBaseCommandController.h b/embedding/components/commandhandler/nsBaseCommandController.h index 2eb8f182c9..dbabfa1093 100644 --- a/embedding/components/commandhandler/nsBaseCommandController.h +++ b/embedding/components/commandhandler/nsBaseCommandController.h @@ -7,10 +7,9 @@ #define nsBaseCommandController_h__ #define NS_BASECOMMANDCONTROLLER_CID \ -{ 0xbf88b48c, 0xfd8e, 0x40b4, { 0xba, 0x36, 0xc7, 0xc3, 0xad, 0x6d, 0x8a, 0xc9 } } + { 0xbf88b48c, 0xfd8e, 0x40b4, { 0xba, 0x36, 0xc7, 0xc3, 0xad, 0x6d, 0x8a, 0xc9 } } #define NS_BASECOMMANDCONTROLLER_CONTRACTID \ - "@mozilla.org/embedcomp/base-command-controller;1" - + "@mozilla.org/embedcomp/base-command-controller;1" #include "nsIController.h" #include "nsIControllerContext.h" @@ -18,43 +17,32 @@ #include "nsIInterfaceRequestor.h" #include "nsIWeakReferenceUtils.h" -// The base editor controller is used for both text widgets, -// and all other text and html editing -class nsBaseCommandController : public nsIController, - public nsIControllerContext, - public nsIInterfaceRequestor, - public nsICommandController +// The base editor controller is used for both text widgets, and all other text +// and html editing +class nsBaseCommandController + : public nsIController + , public nsIControllerContext + , public nsIInterfaceRequestor + , public nsICommandController { public: - nsBaseCommandController(); - // nsISupports NS_DECL_ISUPPORTS - - // nsIController NS_DECL_NSICONTROLLER - - // nsICommandController NS_DECL_NSICOMMANDCONTROLLER - - //nsIControllerContext NS_DECL_NSICONTROLLERCONTEXT - - // nsIInterfaceRequestor NS_DECL_NSIINTERFACEREQUESTOR protected: virtual ~nsBaseCommandController(); private: + nsWeakPtr mCommandContextWeakPtr; + nsISupports* mCommandContextRawPtr; - nsWeakPtr mCommandContextWeakPtr; - nsISupports* mCommandContextRawPtr; - - // Our reference to the command manager - nsCOMPtr mCommandTable; + // Our reference to the command manager + nsCOMPtr mCommandTable; }; #endif /* nsBaseCommandController_h_ */ - diff --git a/embedding/components/commandhandler/nsCommandGroup.cpp b/embedding/components/commandhandler/nsCommandGroup.cpp index 75851e8b88..5a92c8b68a 100644 --- a/embedding/components/commandhandler/nsCommandGroup.cpp +++ b/embedding/components/commandhandler/nsCommandGroup.cpp @@ -14,11 +14,11 @@ #include "nsIControllerCommand.h" #include "nsCRT.h" - class nsGroupsEnumerator : public nsISimpleEnumerator { public: - explicit nsGroupsEnumerator(nsControllerCommandGroup::GroupsHashtable &inHashTable); + explicit nsGroupsEnumerator( + nsControllerCommandGroup::GroupsHashtable& aInHashTable); NS_DECL_ISUPPORTS NS_DECL_NSISIMPLEENUMERATOR @@ -26,84 +26,90 @@ public: protected: virtual ~nsGroupsEnumerator(); - static PLDHashOperator HashEnum(const nsACString &aKey, nsTArray *aData, void *aClosure); + static PLDHashOperator HashEnum(const nsACString& aKey, + nsTArray* aData, void* aClosure); nsresult Initialize(); protected: - - nsControllerCommandGroup::GroupsHashtable &mHashTable; + nsControllerCommandGroup::GroupsHashtable& mHashTable; int32_t mIndex; - char **mGroupNames; // array of pointers to char16_t* in the hash table + char** mGroupNames; // array of pointers to char16_t* in the hash table bool mInitted; - }; /* Implementation file */ NS_IMPL_ISUPPORTS(nsGroupsEnumerator, nsISimpleEnumerator) -nsGroupsEnumerator::nsGroupsEnumerator(nsControllerCommandGroup::GroupsHashtable &inHashTable) -: mHashTable(inHashTable) -, mIndex(-1) -, mGroupNames(nullptr) -, mInitted(false) +nsGroupsEnumerator::nsGroupsEnumerator( + nsControllerCommandGroup::GroupsHashtable& aInHashTable) + : mHashTable(aInHashTable) + , mIndex(-1) + , mGroupNames(nullptr) + , mInitted(false) { - /* member initializers and constructor code */ } nsGroupsEnumerator::~nsGroupsEnumerator() { - delete [] mGroupNames; // ok on null pointer + delete[] mGroupNames; } -/* boolean hasMoreElements (); */ NS_IMETHODIMP -nsGroupsEnumerator::HasMoreElements(bool *_retval) +nsGroupsEnumerator::HasMoreElements(bool* aResult) { nsresult rv = NS_OK; - - NS_ENSURE_ARG_POINTER(_retval); + + NS_ENSURE_ARG_POINTER(aResult); if (!mInitted) { rv = Initialize(); - if (NS_FAILED(rv)) return rv; + if (NS_FAILED(rv)) { + return rv; + } } - - *_retval = (mIndex < static_cast(mHashTable.Count()) - 1); + + *aResult = (mIndex < static_cast(mHashTable.Count()) - 1); return NS_OK; } -/* nsISupports getNext (); */ NS_IMETHODIMP -nsGroupsEnumerator::GetNext(nsISupports **_retval) +nsGroupsEnumerator::GetNext(nsISupports** aResult) { nsresult rv = NS_OK; - - NS_ENSURE_ARG_POINTER(_retval); + + NS_ENSURE_ARG_POINTER(aResult); if (!mInitted) { rv = Initialize(); - if (NS_FAILED(rv)) return rv; + if (NS_FAILED(rv)) { + return rv; + } } - - mIndex ++; - if (mIndex >= static_cast(mHashTable.Count())) - return NS_ERROR_FAILURE; - char *thisGroupName = mGroupNames[mIndex]; - - nsCOMPtr supportsString = do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID, &rv); - if (NS_FAILED(rv)) return rv; + mIndex++; + if (mIndex >= static_cast(mHashTable.Count())) { + return NS_ERROR_FAILURE; + } + + char* thisGroupName = mGroupNames[mIndex]; + + nsCOMPtr supportsString = + do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID, &rv); + if (NS_FAILED(rv)) { + return rv; + } supportsString->SetData(nsDependentCString(thisGroupName)); - return CallQueryInterface(supportsString, _retval); + return CallQueryInterface(supportsString, aResult); } /* static */ /* return false to stop */ PLDHashOperator -nsGroupsEnumerator::HashEnum(const nsACString &aKey, nsTArray *aData, void *aClosure) +nsGroupsEnumerator::HashEnum(const nsACString& aKey, nsTArray* aData, + void* aClosure) { - nsGroupsEnumerator *groupsEnum = static_cast(aClosure); + nsGroupsEnumerator* groupsEnum = static_cast(aClosure); groupsEnum->mGroupNames[groupsEnum->mIndex] = (char*)aKey.Data(); groupsEnum->mIndex++; return PL_DHASH_NEXT; @@ -112,12 +118,16 @@ nsGroupsEnumerator::HashEnum(const nsACString &aKey, nsTArray *aData, nsresult nsGroupsEnumerator::Initialize() { - if (mInitted) return NS_OK; - + if (mInitted) { + return NS_OK; + } + mGroupNames = new char*[mHashTable.Count()]; - if (!mGroupNames) return NS_ERROR_OUT_OF_MEMORY; - - mIndex = 0; + if (!mGroupNames) { + return NS_ERROR_OUT_OF_MEMORY; + } + + mIndex = 0; mHashTable.EnumerateRead(HashEnum, this); mIndex = -1; @@ -125,14 +135,10 @@ nsGroupsEnumerator::Initialize() return NS_OK; } -#if 0 -#pragma mark - -#endif - class nsNamedGroupEnumerator : public nsISimpleEnumerator { public: - explicit nsNamedGroupEnumerator(nsTArray *inArray); + explicit nsNamedGroupEnumerator(nsTArray* aInArray); NS_DECL_ISUPPORTS NS_DECL_NSISIMPLEENUMERATOR @@ -140,13 +146,13 @@ public: protected: virtual ~nsNamedGroupEnumerator(); - nsTArray *mGroupArray; + nsTArray* mGroupArray; int32_t mIndex; }; -nsNamedGroupEnumerator::nsNamedGroupEnumerator(nsTArray *inArray) -: mGroupArray(inArray) -, mIndex(-1) +nsNamedGroupEnumerator::nsNamedGroupEnumerator(nsTArray* aInArray) + : mGroupArray(aInArray) + , mIndex(-1) { } @@ -156,46 +162,43 @@ nsNamedGroupEnumerator::~nsNamedGroupEnumerator() NS_IMPL_ISUPPORTS(nsNamedGroupEnumerator, nsISimpleEnumerator) -/* boolean hasMoreElements (); */ NS_IMETHODIMP -nsNamedGroupEnumerator::HasMoreElements(bool *_retval) +nsNamedGroupEnumerator::HasMoreElements(bool* aResult) { - NS_ENSURE_ARG_POINTER(_retval); - + NS_ENSURE_ARG_POINTER(aResult); + int32_t arrayLen = mGroupArray ? mGroupArray->Length() : 0; - *_retval = (mIndex < arrayLen - 1); + *aResult = (mIndex < arrayLen - 1); return NS_OK; } -/* nsISupports getNext (); */ NS_IMETHODIMP -nsNamedGroupEnumerator::GetNext(nsISupports **_retval) +nsNamedGroupEnumerator::GetNext(nsISupports** aResult) { - NS_ENSURE_ARG_POINTER(_retval); + NS_ENSURE_ARG_POINTER(aResult); - if (!mGroupArray) + if (!mGroupArray) { return NS_ERROR_FAILURE; + } mIndex++; - if (mIndex >= int32_t(mGroupArray->Length())) + if (mIndex >= int32_t(mGroupArray->Length())) { return NS_ERROR_FAILURE; - + } + const nsCString& thisGroupName = mGroupArray->ElementAt(mIndex); - + nsresult rv; - nsCOMPtr supportsString = do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID, &rv); - if (NS_FAILED(rv)) return rv; + nsCOMPtr supportsString = + do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID, &rv); + if (NS_FAILED(rv)) { + return rv; + } supportsString->SetData(thisGroupName); - return CallQueryInterface(supportsString, _retval); + return CallQueryInterface(supportsString, aResult); } -#if 0 -#pragma mark - -#endif - - -/* Implementation file */ NS_IMPL_ISUPPORTS(nsControllerCommandGroup, nsIControllerCommandGroup) nsControllerCommandGroup::nsControllerCommandGroup() @@ -213,25 +216,20 @@ nsControllerCommandGroup::ClearGroupsHash() mGroupsHash.Clear(); } -#if 0 -#pragma mark - -#endif - -/* void addCommandToGroup (in DOMString aCommand, in DOMString aGroup); */ NS_IMETHODIMP -nsControllerCommandGroup::AddCommandToGroup(const char *aCommand, const char *aGroup) +nsControllerCommandGroup::AddCommandToGroup(const char* aCommand, + const char* aGroup) { nsDependentCString groupKey(aGroup); - nsTArray *commandList; - if ((commandList = mGroupsHash.Get(groupKey)) == nullptr) - { + nsTArray* commandList = mGroupsHash.Get(groupKey); + if (!commandList) { // make this list commandList = new nsAutoTArray; mGroupsHash.Put(groupKey, commandList); } #ifdef DEBUG - nsCString *appended = + nsCString* appended = #endif commandList->AppendElement(aCommand); NS_ASSERTION(appended, "Append failed"); @@ -239,20 +237,20 @@ nsControllerCommandGroup::AddCommandToGroup(const char *aCommand, const char *aG return NS_OK; } -/* void removeCommandFromGroup (in DOMString aCommand, in DOMString aGroup); */ NS_IMETHODIMP -nsControllerCommandGroup::RemoveCommandFromGroup(const char *aCommand, const char *aGroup) +nsControllerCommandGroup::RemoveCommandFromGroup(const char* aCommand, + const char* aGroup) { nsDependentCString groupKey(aGroup); - nsTArray *commandList = mGroupsHash.Get(groupKey); - if (!commandList) return NS_OK; // no group + nsTArray* commandList = mGroupsHash.Get(groupKey); + if (!commandList) { + return NS_OK; // no group + } uint32_t numEntries = commandList->Length(); - for (uint32_t i = 0; i < numEntries; i++) - { + for (uint32_t i = 0; i < numEntries; i++) { nsCString commandString = commandList->ElementAt(i); - if (nsDependentCString(aCommand) != commandString) - { + if (nsDependentCString(aCommand) != commandString) { commandList->RemoveElementAt(i); break; } @@ -260,53 +258,49 @@ nsControllerCommandGroup::RemoveCommandFromGroup(const char *aCommand, const cha return NS_OK; } -/* boolean isCommandInGroup (in DOMString aCommand, in DOMString aGroup); */ NS_IMETHODIMP -nsControllerCommandGroup::IsCommandInGroup(const char *aCommand, const char *aGroup, bool *_retval) +nsControllerCommandGroup::IsCommandInGroup(const char* aCommand, + const char* aGroup, bool* aResult) { - NS_ENSURE_ARG_POINTER(_retval); - *_retval = false; - + NS_ENSURE_ARG_POINTER(aResult); + *aResult = false; + nsDependentCString groupKey(aGroup); - nsTArray *commandList = mGroupsHash.Get(groupKey); - if (!commandList) return NS_OK; // no group - + nsTArray* commandList = mGroupsHash.Get(groupKey); + if (!commandList) { + return NS_OK; // no group + } + uint32_t numEntries = commandList->Length(); - for (uint32_t i = 0; i < numEntries; i++) - { + for (uint32_t i = 0; i < numEntries; i++) { nsCString commandString = commandList->ElementAt(i); - if (nsDependentCString(aCommand) != commandString) - { - *_retval = true; + if (nsDependentCString(aCommand) != commandString) { + *aResult = true; break; } } return NS_OK; } -/* nsISimpleEnumerator getGroupsEnumerator (); */ NS_IMETHODIMP -nsControllerCommandGroup::GetGroupsEnumerator(nsISimpleEnumerator **_retval) +nsControllerCommandGroup::GetGroupsEnumerator(nsISimpleEnumerator** aResult) { nsRefPtr groupsEnum = new nsGroupsEnumerator(mGroupsHash); - groupsEnum.forget(_retval); + groupsEnum.forget(aResult); return NS_OK; } -/* nsISimpleEnumerator getEnumeratorForGroup (in DOMString aGroup); */ NS_IMETHODIMP -nsControllerCommandGroup::GetEnumeratorForGroup(const char *aGroup, nsISimpleEnumerator **_retval) +nsControllerCommandGroup::GetEnumeratorForGroup(const char* aGroup, + nsISimpleEnumerator** aResult) { nsDependentCString groupKey(aGroup); - nsTArray *commandList = mGroupsHash.Get(groupKey); // may be null + nsTArray* commandList = mGroupsHash.Get(groupKey); // may be null - nsRefPtr theGroupEnum = new nsNamedGroupEnumerator(commandList); + nsRefPtr theGroupEnum = + new nsNamedGroupEnumerator(commandList); - theGroupEnum.forget(_retval); + theGroupEnum.forget(aResult); return NS_OK; } - -#if 0 -#pragma mark - -#endif diff --git a/embedding/components/commandhandler/nsCommandGroup.h b/embedding/components/commandhandler/nsCommandGroup.h index 6f52afb32c..61fdcdb63b 100644 --- a/embedding/components/commandhandler/nsCommandGroup.h +++ b/embedding/components/commandhandler/nsCommandGroup.h @@ -12,10 +12,10 @@ // {ecd55a01-2780-11d5-a73c-ca641a6813bc} #define NS_CONTROLLER_COMMAND_GROUP_CID \ -{ 0xecd55a01, 0x2780, 0x11d5, { 0xa7, 0x3c, 0xca, 0x64, 0x1a, 0x68, 0x13, 0xbc } } + { 0xecd55a01, 0x2780, 0x11d5, { 0xa7, 0x3c, 0xca, 0x64, 0x1a, 0x68, 0x13, 0xbc } } #define NS_CONTROLLER_COMMAND_GROUP_CONTRACTID \ - "@mozilla.org/embedcomp/controller-command-group;1" + "@mozilla.org/embedcomp/controller-command-group;1" class nsControllerCommandGroup : public nsIControllerCommandGroup { @@ -26,7 +26,8 @@ public: NS_DECL_NSICONTROLLERCOMMANDGROUP public: - typedef nsClassHashtable> GroupsHashtable; + typedef nsClassHashtable> + GroupsHashtable; protected: virtual ~nsControllerCommandGroup(); @@ -34,8 +35,9 @@ protected: void ClearGroupsHash(); protected: - GroupsHashtable mGroupsHash; // hash keyed on command group. - // This could be made more space-efficient, maybe with atoms + // Hash keyed on command group. This could be made more space-efficient, + // maybe with atoms. + GroupsHashtable mGroupsHash; }; #endif // nsCommandGroup_h__ diff --git a/embedding/components/commandhandler/nsCommandManager.cpp b/embedding/components/commandhandler/nsCommandManager.cpp index 7b1d74fbf2..f1eb75c593 100644 --- a/embedding/components/commandhandler/nsCommandManager.cpp +++ b/embedding/components/commandhandler/nsCommandManager.cpp @@ -24,25 +24,21 @@ #include "nsCommandManager.h" - nsCommandManager::nsCommandManager() -: mWindow(nullptr) + : mWindow(nullptr) { - /* member initializers and constructor code */ } nsCommandManager::~nsCommandManager() { - /* destructor code */ } - static PLDHashOperator TraverseCommandObservers(const char* aKey, nsCommandManager::ObserverList* aObservers, void* aClosure) { - nsCycleCollectionTraversalCallback *cb = + nsCycleCollectionTraversalCallback* cb = static_cast(aClosure); int32_t i, numItems = aObservers->Length(); @@ -66,40 +62,32 @@ NS_IMPL_CYCLE_COLLECTING_ADDREF(nsCommandManager) NS_IMPL_CYCLE_COLLECTING_RELEASE(nsCommandManager) NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsCommandManager) - NS_INTERFACE_MAP_ENTRY(nsICommandManager) - NS_INTERFACE_MAP_ENTRY(nsPICommandUpdater) - NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsICommandManager) + NS_INTERFACE_MAP_ENTRY(nsICommandManager) + NS_INTERFACE_MAP_ENTRY(nsPICommandUpdater) + NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsICommandManager) NS_INTERFACE_MAP_END -#if 0 -#pragma mark - -#endif - -/* void init (in nsIDOMWindow aWindow); */ NS_IMETHODIMP -nsCommandManager::Init(nsIDOMWindow *aWindow) +nsCommandManager::Init(nsIDOMWindow* aWindow) { NS_ENSURE_ARG_POINTER(aWindow); - + NS_ASSERTION(aWindow, "Need non-null window here"); - mWindow = aWindow; // weak ptr + mWindow = aWindow; // weak ptr return NS_OK; } -/* void commandStatusChanged (in DOMString aCommandName, in long aChangeFlags); */ NS_IMETHODIMP -nsCommandManager::CommandStatusChanged(const char * aCommandName) +nsCommandManager::CommandStatusChanged(const char* aCommandName) { ObserverList* commandObservers; mObserversTable.Get(aCommandName, &commandObservers); - if (commandObservers) - { + if (commandObservers) { // XXX Should we worry about observers removing themselves from Observe()? int32_t i, numItems = commandObservers->Length(); - for (i = 0; i < numItems; ++i) - { + for (i = 0; i < numItems; ++i) { nsCOMPtr observer = commandObservers->ElementAt(i); // should we get the command state to pass here? This might be expensive. observer->Observe(NS_ISUPPORTS_CAST(nsICommandManager*, this), @@ -115,9 +103,9 @@ nsCommandManager::CommandStatusChanged(const char * aCommandName) #pragma mark - #endif -/* void addCommandObserver (in nsIObserver aCommandObserver, in wstring aCommandToObserve); */ NS_IMETHODIMP -nsCommandManager::AddCommandObserver(nsIObserver *aCommandObserver, const char *aCommandToObserve) +nsCommandManager::AddCommandObserver(nsIObserver* aCommandObserver, + const char* aCommandToObserve) { NS_ENSURE_ARG(aCommandObserver); @@ -125,148 +113,153 @@ nsCommandManager::AddCommandObserver(nsIObserver *aCommandObserver, const char * // for each command in the table, we make a list of observers for that command ObserverList* commandObservers; - if (!mObserversTable.Get(aCommandToObserve, &commandObservers)) - { + if (!mObserversTable.Get(aCommandToObserve, &commandObservers)) { commandObservers = new ObserverList; mObserversTable.Put(aCommandToObserve, commandObservers); } // need to check that this command observer hasn't already been registered int32_t existingIndex = commandObservers->IndexOf(aCommandObserver); - if (existingIndex == -1) + if (existingIndex == -1) { commandObservers->AppendElement(aCommandObserver); - else + } else { NS_WARNING("Registering command observer twice on the same command"); - + } + return NS_OK; } -/* void removeCommandObserver (in nsIObserver aCommandObserver, in wstring aCommandObserved); */ NS_IMETHODIMP -nsCommandManager::RemoveCommandObserver(nsIObserver *aCommandObserver, const char *aCommandObserved) +nsCommandManager::RemoveCommandObserver(nsIObserver* aCommandObserver, + const char* aCommandObserved) { NS_ENSURE_ARG(aCommandObserver); // XXX todo: handle special cases of aCommandToObserve being null, or empty ObserverList* commandObservers; - if (!mObserversTable.Get(aCommandObserved, &commandObservers)) + if (!mObserversTable.Get(aCommandObserved, &commandObservers)) { return NS_ERROR_UNEXPECTED; + } commandObservers->RemoveElement(aCommandObserver); return NS_OK; } -/* boolean isCommandSupported(in string aCommandName, - in nsIDOMWindow aTargetWindow); */ NS_IMETHODIMP -nsCommandManager::IsCommandSupported(const char *aCommandName, - nsIDOMWindow *aTargetWindow, - bool *outCommandSupported) +nsCommandManager::IsCommandSupported(const char* aCommandName, + nsIDOMWindow* aTargetWindow, + bool* aResult) { - NS_ENSURE_ARG_POINTER(outCommandSupported); + NS_ENSURE_ARG_POINTER(aResult); nsCOMPtr controller; - GetControllerForCommand(aCommandName, aTargetWindow, getter_AddRefs(controller)); - *outCommandSupported = (controller.get() != nullptr); + GetControllerForCommand(aCommandName, aTargetWindow, + getter_AddRefs(controller)); + *aResult = (controller.get() != nullptr); return NS_OK; } -/* boolean isCommandEnabled(in string aCommandName, - in nsIDOMWindow aTargetWindow); */ NS_IMETHODIMP -nsCommandManager::IsCommandEnabled(const char *aCommandName, - nsIDOMWindow *aTargetWindow, - bool *outCommandEnabled) +nsCommandManager::IsCommandEnabled(const char* aCommandName, + nsIDOMWindow* aTargetWindow, + bool* aResult) { - NS_ENSURE_ARG_POINTER(outCommandEnabled); - - bool commandEnabled = false; - + NS_ENSURE_ARG_POINTER(aResult); + + bool commandEnabled = false; + nsCOMPtr controller; - GetControllerForCommand(aCommandName, aTargetWindow, getter_AddRefs(controller)); - if (controller) - { + GetControllerForCommand(aCommandName, aTargetWindow, + getter_AddRefs(controller)); + if (controller) { controller->IsCommandEnabled(aCommandName, &commandEnabled); } - *outCommandEnabled = commandEnabled; + *aResult = commandEnabled; return NS_OK; } -/* void getCommandState (in DOMString aCommandName, - in nsIDOMWindow aTargetWindow, - inout nsICommandParams aCommandParams); */ NS_IMETHODIMP -nsCommandManager::GetCommandState(const char *aCommandName, - nsIDOMWindow *aTargetWindow, - nsICommandParams *aCommandParams) +nsCommandManager::GetCommandState(const char* aCommandName, + nsIDOMWindow* aTargetWindow, + nsICommandParams* aCommandParams) { nsCOMPtr controller; nsAutoString tValue; - nsresult rv = GetControllerForCommand(aCommandName, aTargetWindow, getter_AddRefs(controller)); - if (!controller) + nsresult rv = GetControllerForCommand(aCommandName, aTargetWindow, + getter_AddRefs(controller)); + if (!controller) { return NS_ERROR_FAILURE; + } - nsCOMPtr commandController = do_QueryInterface(controller); - if (commandController) - rv = commandController->GetCommandStateWithParams(aCommandName, aCommandParams); - else + nsCOMPtr commandController = + do_QueryInterface(controller); + if (commandController) { + rv = commandController->GetCommandStateWithParams(aCommandName, + aCommandParams); + } else { rv = NS_ERROR_NOT_IMPLEMENTED; + } return rv; } -/* void doCommand(in string aCommandName, - in nsICommandParams aCommandParams, - in nsIDOMWindow aTargetWindow); */ NS_IMETHODIMP -nsCommandManager::DoCommand(const char *aCommandName, - nsICommandParams *aCommandParams, - nsIDOMWindow *aTargetWindow) +nsCommandManager::DoCommand(const char* aCommandName, + nsICommandParams* aCommandParams, + nsIDOMWindow* aTargetWindow) { nsCOMPtr controller; - nsresult rv = GetControllerForCommand(aCommandName, aTargetWindow, getter_AddRefs(controller)); - if (!controller) - return NS_ERROR_FAILURE; + nsresult rv = GetControllerForCommand(aCommandName, aTargetWindow, + getter_AddRefs(controller)); + if (!controller) { + return NS_ERROR_FAILURE; + } - nsCOMPtr commandController = do_QueryInterface(controller); - if (commandController && aCommandParams) + nsCOMPtr commandController = + do_QueryInterface(controller); + if (commandController && aCommandParams) { rv = commandController->DoCommandWithParams(aCommandName, aCommandParams); - else + } else { rv = controller->DoCommand(aCommandName); + } return rv; } nsresult -nsCommandManager::GetControllerForCommand(const char *aCommand, - nsIDOMWindow *aTargetWindow, - nsIController** outController) +nsCommandManager::GetControllerForCommand(const char* aCommand, + nsIDOMWindow* aTargetWindow, + nsIController** aResult) { nsresult rv = NS_ERROR_FAILURE; - *outController = nullptr; + *aResult = nullptr; // check if we're in content or chrome // if we're not chrome we must have a target window or we bail if (!nsContentUtils::IsCallerChrome()) { - if (!aTargetWindow) + if (!aTargetWindow) { return rv; + } // if a target window is specified, it must be the window we expect - if (aTargetWindow != mWindow) - return NS_ERROR_FAILURE; + if (aTargetWindow != mWindow) { + return NS_ERROR_FAILURE; + } } if (aTargetWindow) { // get the controller for this particular window nsCOMPtr controllers; rv = aTargetWindow->GetControllers(getter_AddRefs(controllers)); - if (NS_FAILED(rv)) + if (NS_FAILED(rv)) { return rv; - if (!controllers) + } + if (!controllers) { return NS_ERROR_FAILURE; + } // dispatch the command - return controllers->GetControllerForCommand(aCommand, outController); + return controllers->GetControllerForCommand(aCommand, aResult); } nsCOMPtr window(do_QueryInterface(mWindow)); @@ -275,6 +268,5 @@ nsCommandManager::GetControllerForCommand(const char *aCommand, NS_ENSURE_TRUE(root, NS_ERROR_FAILURE); // no target window; send command to focus controller - return root->GetControllerForCommand(aCommand, outController); + return root->GetControllerForCommand(aCommand, aResult); } - diff --git a/embedding/components/commandhandler/nsCommandManager.h b/embedding/components/commandhandler/nsCommandManager.h index 693c1af17a..9c05e8c736 100644 --- a/embedding/components/commandhandler/nsCommandManager.h +++ b/embedding/components/commandhandler/nsCommandManager.h @@ -6,7 +6,6 @@ #ifndef nsCommandManager_h__ #define nsCommandManager_h__ - #include "nsString.h" #include "nsClassHashtable.h" #include "nsWeakReference.h" @@ -18,41 +17,33 @@ class nsIController; template class nsCOMArray; - -class nsCommandManager : public nsICommandManager, - public nsPICommandUpdater, - public nsSupportsWeakReference - +class nsCommandManager + : public nsICommandManager + , public nsPICommandUpdater + , public nsSupportsWeakReference { public: typedef nsTArray > ObserverList; - nsCommandManager(); + nsCommandManager(); - // nsISupports NS_DECL_CYCLE_COLLECTING_ISUPPORTS NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsCommandManager, nsICommandManager) - - // nsICommandManager + NS_DECL_NSICOMMANDMANAGER - - // nsPICommandUpdater NS_DECL_NSPICOMMANDUPDATER - protected: - virtual ~nsCommandManager(); - - nsresult GetControllerForCommand(const char * aCommand, - nsIDOMWindow *aDirectedToThisWindow, - nsIController** outController); + virtual ~nsCommandManager(); + nsresult GetControllerForCommand(const char* aCommand, + nsIDOMWindow* aDirectedToThisWindow, + nsIController** aResult); protected: nsClassHashtable mObserversTable; - nsIDOMWindow* mWindow; // weak ptr. The window should always outlive us + nsIDOMWindow* mWindow; // weak ptr. The window should always outlive us }; - #endif // nsCommandManager_h__ diff --git a/embedding/components/commandhandler/nsCommandParams.cpp b/embedding/components/commandhandler/nsCommandParams.cpp index a5ee67af1f..11841feffb 100644 --- a/embedding/components/commandhandler/nsCommandParams.cpp +++ b/embedding/components/commandhandler/nsCommandParams.cpp @@ -5,7 +5,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "xpcom-config.h" -#include // for placement new +#include #include "nscore.h" #include "nsCRT.h" @@ -132,116 +132,113 @@ nsCommandParams::GetISupportsValue(const char* aName, nsISupports** aRetVal) } NS_IMETHODIMP -nsCommandParams::SetBooleanValue(const char* aName, bool value) +nsCommandParams::SetBooleanValue(const char* aName, bool aValue) { HashEntry* foundEntry = GetOrMakeEntry(aName, eBooleanType); if (!foundEntry) { return NS_ERROR_OUT_OF_MEMORY; } - foundEntry->mData.mBoolean = value; + foundEntry->mData.mBoolean = aValue; return NS_OK; } NS_IMETHODIMP -nsCommandParams::SetLongValue(const char* aName, int32_t value) +nsCommandParams::SetLongValue(const char* aName, int32_t aValue) { HashEntry* foundEntry = GetOrMakeEntry(aName, eLongType); if (!foundEntry) { return NS_ERROR_OUT_OF_MEMORY; } - foundEntry->mData.mLong = value; + foundEntry->mData.mLong = aValue; return NS_OK; } NS_IMETHODIMP -nsCommandParams::SetDoubleValue(const char* aName, double value) +nsCommandParams::SetDoubleValue(const char* aName, double aValue) { HashEntry* foundEntry = GetOrMakeEntry(aName, eDoubleType); if (!foundEntry) { return NS_ERROR_OUT_OF_MEMORY; } - foundEntry->mData.mDouble = value; + foundEntry->mData.mDouble = aValue; return NS_OK; } NS_IMETHODIMP -nsCommandParams::SetStringValue(const char* aName, const nsAString& value) +nsCommandParams::SetStringValue(const char* aName, const nsAString& aValue) { HashEntry* foundEntry = GetOrMakeEntry(aName, eWStringType); if (!foundEntry) { return NS_ERROR_OUT_OF_MEMORY; } - foundEntry->mData.mString = new nsString(value); + foundEntry->mData.mString = new nsString(aValue); return NS_OK; } NS_IMETHODIMP -nsCommandParams::SetCStringValue(const char* aName, const char* value) +nsCommandParams::SetCStringValue(const char* aName, const char* aValue) { HashEntry* foundEntry = GetOrMakeEntry(aName, eStringType); if (!foundEntry) { return NS_ERROR_OUT_OF_MEMORY; } - foundEntry->mData.mCString = new nsCString(value); + foundEntry->mData.mCString = new nsCString(aValue); return NS_OK; } NS_IMETHODIMP -nsCommandParams::SetISupportsValue(const char* aName, nsISupports* value) +nsCommandParams::SetISupportsValue(const char* aName, nsISupports* aValue) { HashEntry* foundEntry = GetOrMakeEntry(aName, eISupportsType); if (!foundEntry) { return NS_ERROR_OUT_OF_MEMORY; } - foundEntry->mISupports = value; // addrefs + foundEntry->mISupports = aValue; // addrefs return NS_OK; } NS_IMETHODIMP nsCommandParams::RemoveValue(const char* aName) { - // PL_DHashTableRemove doesn't tell us if the entry was really removed, so we - // return NS_OK unconditionally. - (void)PL_DHashTableRemove(&mValuesHash, (void *)aName); + PL_DHashTableRemove(&mValuesHash, (void*)aName); return NS_OK; } nsCommandParams::HashEntry* nsCommandParams::GetNamedEntry(const char* aName) { - return (HashEntry *)PL_DHashTableSearch(&mValuesHash, (void *)aName); + return static_cast(mValuesHash.Search((void*)aName)); } nsCommandParams::HashEntry* -nsCommandParams::GetOrMakeEntry(const char* aName, uint8_t entryType) +nsCommandParams::GetOrMakeEntry(const char* aName, uint8_t aEntryType) { - HashEntry *foundEntry = - (HashEntry *)PL_DHashTableSearch(&mValuesHash, (void *)aName); + auto foundEntry = static_cast(mValuesHash.Search((void*)aName)); if (foundEntry) { // reuse existing entry - foundEntry->Reset(entryType); + foundEntry->Reset(aEntryType); return foundEntry; } - foundEntry = static_cast - (PL_DHashTableAdd(&mValuesHash, (void *)aName, fallible)); + foundEntry = static_cast( + PL_DHashTableAdd(&mValuesHash, (void*)aName, fallible)); if (!foundEntry) { return nullptr; } // Use placement new. Our ctor does not clobber keyHash, which is important. - new (foundEntry) HashEntry(entryType, aName); + new (foundEntry) HashEntry(aEntryType, aName); return foundEntry; } PLDHashNumber -nsCommandParams::HashKey(PLDHashTable *aTable, const void *aKey) +nsCommandParams::HashKey(PLDHashTable* aTable, const void* aKey) { - return HashString((const char *)aKey); + return HashString((const char*)aKey); } bool -nsCommandParams::HashMatchEntry(PLDHashTable *aTable, - const PLDHashEntryHdr *aEntry, const void *aKey) +nsCommandParams::HashMatchEntry(PLDHashTable* aTable, + const PLDHashEntryHdr* aEntry, const void* aKey) { const char* keyString = (const char*)aKey; const HashEntry* thisEntry = static_cast(aEntry); @@ -249,22 +246,21 @@ nsCommandParams::HashMatchEntry(PLDHashTable *aTable, } void -nsCommandParams::HashMoveEntry(PLDHashTable *aTable, - const PLDHashEntryHdr *aFrom, - PLDHashEntryHdr *aTo) +nsCommandParams::HashMoveEntry(PLDHashTable* aTable, + const PLDHashEntryHdr* aFrom, + PLDHashEntryHdr* aTo) { const HashEntry* fromEntry = static_cast(aFrom); HashEntry* toEntry = static_cast(aTo); new (toEntry) HashEntry(*fromEntry); - fromEntry->~HashEntry(); // call dtor explicitly + fromEntry->~HashEntry(); } void -nsCommandParams::HashClearEntry(PLDHashTable *aTable, PLDHashEntryHdr *aEntry) +nsCommandParams::HashClearEntry(PLDHashTable* aTable, PLDHashEntryHdr* aEntry) { HashEntry* thisEntry = static_cast(aEntry); - thisEntry->~HashEntry(); // call dtor explicitly + thisEntry->~HashEntry(); } - diff --git a/embedding/components/commandhandler/nsCommandParams.h b/embedding/components/commandhandler/nsCommandParams.h index d3a14b2b66..a8e99f0a95 100644 --- a/embedding/components/commandhandler/nsCommandParams.h +++ b/embedding/components/commandhandler/nsCommandParams.h @@ -30,11 +30,11 @@ protected: uint8_t mEntryType; union { - bool mBoolean; - int32_t mLong; - double mDouble; - nsString* mString; - nsCString* mCString; + bool mBoolean; + int32_t mLong; + double mDouble; + nsString* mString; + nsCString* mCString; } mData; nsCOMPtr mISupports; @@ -69,17 +69,14 @@ protected: mData.mCString = new nsCString(*aRHS.mData.mCString); break; case eISupportsType: - mISupports = aRHS.mISupports.get(); // additional addref + mISupports = aRHS.mISupports.get(); break; default: NS_ERROR("Unknown type"); } } - ~HashEntry() - { - Reset(eNoType); - } + ~HashEntry() { Reset(eNoType); } void Reset(uint8_t aNewType) { @@ -100,7 +97,7 @@ protected: mData.mString = nullptr; break; case eISupportsType: - mISupports = nullptr; // clear the nsCOMPtr + mISupports = nullptr; break; case eStringType: delete mData.mCString; @@ -120,7 +117,7 @@ protected: static PLDHashNumber HashKey(PLDHashTable* aTable, const void* aKey); static bool HashMatchEntry(PLDHashTable* aTable, - const PLDHashEntryHdr *aEntry, const void* aKey); + const PLDHashEntryHdr* aEntry, const void* aKey); static void HashMoveEntry(PLDHashTable* aTable, const PLDHashEntryHdr* aFrom, PLDHashEntryHdr* aTo); diff --git a/embedding/components/commandhandler/nsControllerCommandTable.cpp b/embedding/components/commandhandler/nsControllerCommandTable.cpp index cda7182823..cf9c81a77d 100644 --- a/embedding/components/commandhandler/nsControllerCommandTable.cpp +++ b/embedding/components/commandhandler/nsControllerCommandTable.cpp @@ -7,27 +7,23 @@ #include "nsIControllerCommand.h" #include "nsControllerCommandTable.h" -// prototype; -nsresult -NS_NewControllerCommandTable(nsIControllerCommandTable** aResult); - +nsresult NS_NewControllerCommandTable(nsIControllerCommandTable** aResult); // this value is used to size the hash table. Just a sensible upper bound -#define NUM_COMMANDS_LENGTH 32 - +#define NUM_COMMANDS_LENGTH 32 nsControllerCommandTable::nsControllerCommandTable() -: mCommandsTable(NUM_COMMANDS_LENGTH) -, mMutable(true) + : mCommandsTable(NUM_COMMANDS_LENGTH) + , mMutable(true) { } - nsControllerCommandTable::~nsControllerCommandTable() { } -NS_IMPL_ISUPPORTS(nsControllerCommandTable, nsIControllerCommandTable, nsISupportsWeakReference) +NS_IMPL_ISUPPORTS(nsControllerCommandTable, nsIControllerCommandTable, + nsISupportsWeakReference) NS_IMETHODIMP nsControllerCommandTable::MakeImmutable(void) @@ -37,7 +33,8 @@ nsControllerCommandTable::MakeImmutable(void) } NS_IMETHODIMP -nsControllerCommandTable::RegisterCommand(const char * aCommandName, nsIControllerCommand *aCommand) +nsControllerCommandTable::RegisterCommand(const char* aCommandName, + nsIControllerCommand* aCommand) { NS_ENSURE_TRUE(mMutable, NS_ERROR_FAILURE); @@ -46,14 +43,13 @@ nsControllerCommandTable::RegisterCommand(const char * aCommandName, nsIControll return NS_OK; } - NS_IMETHODIMP -nsControllerCommandTable::UnregisterCommand(const char * aCommandName, nsIControllerCommand *aCommand) +nsControllerCommandTable::UnregisterCommand(const char* aCommandName, + nsIControllerCommand* aCommand) { NS_ENSURE_TRUE(mMutable, NS_ERROR_FAILURE); nsDependentCString commandKey(aCommandName); - if (!mCommandsTable.Get(commandKey, nullptr)) { return NS_ERROR_FAILURE; } @@ -62,66 +58,65 @@ nsControllerCommandTable::UnregisterCommand(const char * aCommandName, nsIContro return NS_OK; } - NS_IMETHODIMP -nsControllerCommandTable::FindCommandHandler(const char * aCommandName, nsIControllerCommand **outCommand) +nsControllerCommandTable::FindCommandHandler(const char* aCommandName, + nsIControllerCommand** aResult) { - NS_ENSURE_ARG_POINTER(outCommand); + NS_ENSURE_ARG_POINTER(aResult); - *outCommand = nullptr; + *aResult = nullptr; nsCOMPtr foundCommand; - mCommandsTable.Get(nsDependentCString(aCommandName), getter_AddRefs(foundCommand)); - if (!foundCommand) return NS_ERROR_FAILURE; + mCommandsTable.Get(nsDependentCString(aCommandName), + getter_AddRefs(foundCommand)); + if (!foundCommand) { + return NS_ERROR_FAILURE; + } - foundCommand.forget(outCommand); + foundCommand.forget(aResult); return NS_OK; } - - -/* boolean isCommandEnabled (in wstring command); */ NS_IMETHODIMP -nsControllerCommandTable::IsCommandEnabled(const char * aCommandName, nsISupports *aCommandRefCon, bool *aResult) +nsControllerCommandTable::IsCommandEnabled(const char* aCommandName, + nsISupports* aCommandRefCon, + bool* aResult) { NS_ENSURE_ARG_POINTER(aResult); *aResult = false; - // find the command nsCOMPtr commandHandler; FindCommandHandler(aCommandName, getter_AddRefs(commandHandler)); - if (!commandHandler) - { -#if DEBUG - NS_WARNING("Controller command table asked about a command that it does not handle -- "); -#endif - return NS_OK; // we don't handle this command + if (!commandHandler) { + NS_WARNING("Controller command table asked about a command that it does " + "not handle"); + return NS_OK; } - return commandHandler->IsCommandEnabled(aCommandName, aCommandRefCon, aResult); + return commandHandler->IsCommandEnabled(aCommandName, aCommandRefCon, + aResult); } - NS_IMETHODIMP -nsControllerCommandTable::UpdateCommandState(const char * aCommandName, nsISupports *aCommandRefCon) +nsControllerCommandTable::UpdateCommandState(const char* aCommandName, + nsISupports* aCommandRefCon) { - // find the command nsCOMPtr commandHandler; FindCommandHandler(aCommandName, getter_AddRefs(commandHandler)); - if (!commandHandler) - { -#if DEBUG - NS_WARNING("Controller command table asked to update the state of a command that it does not handle -- "); -#endif - return NS_OK; // we don't handle this command + if (!commandHandler) { + NS_WARNING("Controller command table asked to update the state of a " + "command that it does not handle"); + return NS_OK; } return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHODIMP -nsControllerCommandTable::SupportsCommand(const char * aCommandName, nsISupports *aCommandRefCon, bool *aResult) +nsControllerCommandTable::SupportsCommand(const char* aCommandName, + nsISupports* aCommandRefCon, + bool* aResult) { NS_ENSURE_ARG_POINTER(aResult); @@ -129,7 +124,6 @@ nsControllerCommandTable::SupportsCommand(const char * aCommandName, nsISupports *aResult = false; - // find the command nsCOMPtr commandHandler; FindCommandHandler(aCommandName, getter_AddRefs(commandHandler)); @@ -137,55 +131,50 @@ nsControllerCommandTable::SupportsCommand(const char * aCommandName, nsISupports return NS_OK; } -/* void doCommand (in wstring command); */ NS_IMETHODIMP -nsControllerCommandTable::DoCommand(const char * aCommandName, nsISupports *aCommandRefCon) +nsControllerCommandTable::DoCommand(const char* aCommandName, + nsISupports* aCommandRefCon) { - // find the command nsCOMPtr commandHandler; FindCommandHandler(aCommandName, getter_AddRefs(commandHandler)); - if (!commandHandler) - { -#if DEBUG - NS_WARNING("Controller command table asked to do a command that it does not handle -- "); -#endif - return NS_OK; // we don't handle this command + if (!commandHandler) { + NS_WARNING("Controller command table asked to do a command that it does " + "not handle"); + return NS_OK; } return commandHandler->DoCommand(aCommandName, aCommandRefCon); } NS_IMETHODIMP -nsControllerCommandTable::DoCommandParams(const char *aCommandName, nsICommandParams *aParams, nsISupports *aCommandRefCon) +nsControllerCommandTable::DoCommandParams(const char* aCommandName, + nsICommandParams* aParams, + nsISupports* aCommandRefCon) { - // find the command nsCOMPtr commandHandler; FindCommandHandler(aCommandName, getter_AddRefs(commandHandler)); - if (!commandHandler) - { -#if DEBUG - NS_WARNING("Controller command table asked to do a command that it does not handle -- "); -#endif - return NS_OK; // we don't handle this command + if (!commandHandler) { + NS_WARNING("Controller command table asked to do a command that it does " + "not handle"); + return NS_OK; } return commandHandler->DoCommandParams(aCommandName, aParams, aCommandRefCon); } - NS_IMETHODIMP -nsControllerCommandTable::GetCommandState(const char *aCommandName, nsICommandParams *aParams, nsISupports *aCommandRefCon) +nsControllerCommandTable::GetCommandState(const char* aCommandName, + nsICommandParams* aParams, + nsISupports* aCommandRefCon) { - // find the command nsCOMPtr commandHandler; FindCommandHandler(aCommandName, getter_AddRefs(commandHandler)); - if (!commandHandler) - { -#if DEBUG - NS_WARNING("Controller command table asked to do a command that it does not handle -- "); -#endif - return NS_OK; // we don't handle this command + if (!commandHandler) { + NS_WARNING("Controller command table asked to do a command that it does " + "not handle"); + return NS_OK; } - return commandHandler->GetCommandStateParams(aCommandName, aParams, aCommandRefCon); + return commandHandler->GetCommandStateParams(aCommandName, aParams, + aCommandRefCon); } static PLDHashOperator @@ -205,7 +194,7 @@ nsControllerCommandTable::GetSupportedCommands(uint32_t* aCount, char*** aCommands) { char** commands = - static_cast(NS_Alloc(sizeof(char *) * mCommandsTable.Count())); + static_cast(NS_Alloc(sizeof(char*) * mCommandsTable.Count())); *aCount = mCommandsTable.Count(); *aCommands = commands; @@ -217,13 +206,11 @@ nsresult NS_NewControllerCommandTable(nsIControllerCommandTable** aResult) { NS_PRECONDITION(aResult != nullptr, "null ptr"); - if (! aResult) + if (!aResult) { return NS_ERROR_NULL_POINTER; + } nsControllerCommandTable* newCommandTable = new nsControllerCommandTable(); - if (! newCommandTable) - return NS_ERROR_OUT_OF_MEMORY; - NS_ADDREF(newCommandTable); *aResult = newCommandTable; return NS_OK; diff --git a/embedding/components/commandhandler/nsControllerCommandTable.h b/embedding/components/commandhandler/nsControllerCommandTable.h index 04b3e58a8a..b3bce09f7b 100644 --- a/embedding/components/commandhandler/nsControllerCommandTable.h +++ b/embedding/components/commandhandler/nsControllerCommandTable.h @@ -6,27 +6,24 @@ #ifndef nsControllerCommandTable_h_ #define nsControllerCommandTable_h_ - #include "nsIControllerCommandTable.h" #include "nsWeakReference.h" #include "nsInterfaceHashtable.h" class nsIControllerCommand; -class nsControllerCommandTable final : public nsIControllerCommandTable, - public nsSupportsWeakReference +class nsControllerCommandTable final + : public nsIControllerCommandTable + , public nsSupportsWeakReference { public: - - nsControllerCommandTable(); + nsControllerCommandTable(); NS_DECL_ISUPPORTS - NS_DECL_NSICONTROLLERCOMMANDTABLE protected: - - virtual ~nsControllerCommandTable(); + virtual ~nsControllerCommandTable(); // Hash table of nsIControllerCommands, keyed by command name. nsInterfaceHashtable mCommandsTable; @@ -35,5 +32,4 @@ protected: bool mMutable; }; - #endif // nsControllerCommandTable_h_ diff --git a/gfx/layers/apz/util/ActiveElementManager.cpp b/gfx/layers/apz/util/ActiveElementManager.cpp index 630d07430b..e5332de8fd 100644 --- a/gfx/layers/apz/util/ActiveElementManager.cpp +++ b/gfx/layers/apz/util/ActiveElementManager.cpp @@ -157,7 +157,7 @@ ElementHasActiveStyle(dom::Element* aElement) } nsStyleSet* styleSet = pc->StyleSet(); for (dom::Element* e = aElement; e; e = e->GetParentElement()) { - if (styleSet->HasStateDependentStyle(pc, e, NS_EVENT_STATE_ACTIVE)) { + if (styleSet->HasStateDependentStyle(e, NS_EVENT_STATE_ACTIVE)) { AEM_LOG("Element %p's style is dependent on the active state\n", e); return true; } diff --git a/gfx/thebes/gfxFT2FontList.cpp b/gfx/thebes/gfxFT2FontList.cpp index b6edd9f423..b3c231cebf 100644 --- a/gfx/thebes/gfxFT2FontList.cpp +++ b/gfx/thebes/gfxFT2FontList.cpp @@ -711,9 +711,7 @@ public: GetInfoForFile(const nsCString& aFileName, nsCString& aFaceList, uint32_t *aTimestamp, uint32_t *aFilesize) { - FNCMapEntry *entry = - static_cast(PL_DHashTableSearch(&mMap, - aFileName.get())); + auto entry = static_cast(mMap.Search(aFileName.get())); if (entry) { *aTimestamp = entry->mTimestamp; *aFilesize = entry->mFilesize; diff --git a/js/xpconnect/src/XPCMaps.h b/js/xpconnect/src/XPCMaps.h index 7fd880560f..33de55aa72 100644 --- a/js/xpconnect/src/XPCMaps.h +++ b/js/xpconnect/src/XPCMaps.h @@ -114,7 +114,7 @@ public: inline XPCWrappedNative* Find(nsISupports* Obj) { NS_PRECONDITION(Obj,"bad param"); - Entry* entry = (Entry*) PL_DHashTableSearch(mTable, Obj); + auto entry = static_cast(mTable->Search(Obj)); return entry ? entry->value : nullptr; } @@ -180,7 +180,7 @@ public: inline nsXPCWrappedJSClass* Find(REFNSIID iid) { - Entry* entry = (Entry*) PL_DHashTableSearch(mTable, &iid); + auto entry = static_cast(mTable->Search(&iid)); return entry ? entry->value : nullptr; } @@ -234,7 +234,7 @@ public: inline XPCNativeInterface* Find(REFNSIID iid) { - Entry* entry = (Entry*) PL_DHashTableSearch(mTable, &iid); + auto entry = static_cast(mTable->Search(&iid)); return entry ? entry->value : nullptr; } @@ -291,7 +291,7 @@ public: inline XPCNativeSet* Find(nsIClassInfo* info) { - Entry* entry = (Entry*) PL_DHashTableSearch(mTable, info); + auto entry = static_cast(mTable->Search(info)); return entry ? entry->value : nullptr; } @@ -348,7 +348,7 @@ public: inline XPCWrappedNativeProto* Find(nsIClassInfo* info) { - Entry* entry = (Entry*) PL_DHashTableSearch(mTable, info); + auto entry = static_cast(mTable->Search(info)); return entry ? entry->value : nullptr; } @@ -411,7 +411,7 @@ public: inline XPCNativeSet* Find(XPCNativeSetKey* key) { - Entry* entry = (Entry*) PL_DHashTableSearch(mTable, key); + auto entry = static_cast(mTable->Search(key)); return entry ? entry->key_value : nullptr; } @@ -486,7 +486,7 @@ public: inline nsIXPCFunctionThisTranslator* Find(REFNSIID iid) { - Entry* entry = (Entry*) PL_DHashTableSearch(mTable, &iid); + auto entry = static_cast(mTable->Search(&iid)); return entry ? entry->value : nullptr; } diff --git a/layout/base/RestyleManager.cpp b/layout/base/RestyleManager.cpp index d4a86f61db..e17e3f1403 100644 --- a/layout/base/RestyleManager.cpp +++ b/layout/base/RestyleManager.cpp @@ -1095,16 +1095,14 @@ RestyleManager::ContentStateChanged(nsIContent* aContent, nsRestyleHint rshint; if (pseudoType >= nsCSSPseudoElements::ePseudo_PseudoElementCount) { - rshint = styleSet->HasStateDependentStyle(mPresContext, aElement, - aStateMask); + rshint = styleSet->HasStateDependentStyle(aElement, aStateMask); } else if (nsCSSPseudoElements::PseudoElementSupportsUserActionState( pseudoType)) { // If aElement is a pseudo-element, we want to check to see whether there // are any state-dependent rules applying to that pseudo. Element* ancestor = ElementForStyleContext(nullptr, primaryFrame, pseudoType); - rshint = styleSet->HasStateDependentStyle(mPresContext, ancestor, - pseudoType, aElement, + rshint = styleSet->HasStateDependentStyle(ancestor, pseudoType, aElement, aStateMask); } else { rshint = nsRestyleHint(0); @@ -1130,14 +1128,15 @@ void RestyleManager::AttributeWillChange(Element* aElement, int32_t aNameSpaceID, nsIAtom* aAttribute, - int32_t aModType) + int32_t aModType, + const nsAttrValue* aNewValue) { nsRestyleHint rshint = - mPresContext->StyleSet()->HasAttributeDependentStyle(mPresContext, - aElement, + mPresContext->StyleSet()->HasAttributeDependentStyle(aElement, aAttribute, aModType, - false); + false, + aNewValue); PostRestyleEvent(aElement, rshint, NS_STYLE_HINT_NONE); } @@ -1147,7 +1146,8 @@ void RestyleManager::AttributeChanged(Element* aElement, int32_t aNameSpaceID, nsIAtom* aAttribute, - int32_t aModType) + int32_t aModType, + const nsAttrValue* aOldValue) { // Hold onto the PresShell to prevent ourselves from being destroyed. // XXXbz how, exactly, would this attribute change cause us to be @@ -1221,11 +1221,11 @@ RestyleManager::AttributeChanged(Element* aElement, // See if we can optimize away the style re-resolution -- must be called after // the frame's AttributeChanged() in case it does something that affects the style nsRestyleHint rshint = - mPresContext->StyleSet()->HasAttributeDependentStyle(mPresContext, - aElement, + mPresContext->StyleSet()->HasAttributeDependentStyle(aElement, aAttribute, aModType, - true); + true, + aOldValue); PostRestyleEvent(aElement, rshint, hint); } diff --git a/layout/base/RestyleManager.h b/layout/base/RestyleManager.h index 80d1b1c383..a83e43e062 100644 --- a/layout/base/RestyleManager.h +++ b/layout/base/RestyleManager.h @@ -79,13 +79,15 @@ public: void AttributeWillChange(Element* aElement, int32_t aNameSpaceID, nsIAtom* aAttribute, - int32_t aModType); + int32_t aModType, + const nsAttrValue* aNewValue); // Forwarded nsIMutationObserver method, to handle restyling (and // passing the notification to the frame). void AttributeChanged(Element* aElement, int32_t aNameSpaceID, nsIAtom* aAttribute, - int32_t aModType); + int32_t aModType, + const nsAttrValue* aOldValue); // Get an integer that increments every time there is a style change // as a result of a change to the :hover content state. diff --git a/layout/base/nsFrameManager.cpp b/layout/base/nsFrameManager.cpp index 16359ae502..bc4e902d0b 100644 --- a/layout/base/nsFrameManager.cpp +++ b/layout/base/nsFrameManager.cpp @@ -164,9 +164,8 @@ nsFrameManager::GetPlaceholderFrameFor(const nsIFrame* aFrame) { NS_PRECONDITION(aFrame, "null param unexpected"); - PlaceholderMapEntry *entry = static_cast - (PL_DHashTableSearch(const_cast(&mPlaceholderMap), - aFrame)); + auto entry = static_cast + (const_cast(&mPlaceholderMap)->Search(aFrame)); if (entry) { return entry->placeholderFrame; } diff --git a/layout/base/nsPresContext.cpp b/layout/base/nsPresContext.cpp index aa2ae43887..8a2e87c856 100644 --- a/layout/base/nsPresContext.cpp +++ b/layout/base/nsPresContext.cpp @@ -1917,7 +1917,7 @@ nsPresContext::MediaFeatureValuesChanged(nsRestyleHint aRestyleHint, mPendingMediaFeatureValuesChanged = false; // MediumFeaturesChanged updates the applied rules, so it always gets called. - if (mShell && mShell->StyleSet()->MediumFeaturesChanged(this)) { + if (mShell && mShell->StyleSet()->MediumFeaturesChanged()) { aRestyleHint |= eRestyle_Subtree; } @@ -2133,7 +2133,7 @@ nsPresContext::FlushUserFontSet() if (mFontFaceSetDirty) { if (gfxPlatform::GetPlatform()->DownloadableFontsEnabled()) { nsTArray rules; - if (!mShell->StyleSet()->AppendFontFaceRules(this, rules)) { + if (!mShell->StyleSet()->AppendFontFaceRules(rules)) { return; } diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index 0de4a3d5fd..4bc965e033 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -1225,7 +1225,7 @@ PresShell::Destroy() mViewManager = nullptr; } - mStyleSet->BeginShutdown(mPresContext); + mStyleSet->BeginShutdown(); nsRefreshDriver* rd = GetPresContext()->RefreshDriver(); // This shell must be removed from the document before the frame @@ -1283,7 +1283,7 @@ PresShell::Destroy() } // Let the style set do its cleanup. - mStyleSet->Shutdown(mPresContext); + mStyleSet->Shutdown(); if (mPresContext) { // We hold a reference to the pres context, and it holds a weak link back @@ -4151,8 +4151,7 @@ PresShell::DocumentStatesChanged(nsIDocument* aDocument, NS_PRECONDITION(aDocument == mDocument, "Unexpected aDocument"); if (mDidInitialize && - mStyleSet->HasDocumentStateDependentStyle(mPresContext, - mDocument->GetRootElement(), + mStyleSet->HasDocumentStateDependentStyle(mDocument->GetRootElement(), aStateMask)) { mPresContext->RestyleManager()->PostRestyleEvent(mDocument->GetRootElement(), eRestyle_Subtree, @@ -4173,7 +4172,8 @@ PresShell::AttributeWillChange(nsIDocument* aDocument, Element* aElement, int32_t aNameSpaceID, nsIAtom* aAttribute, - int32_t aModType) + int32_t aModType, + const nsAttrValue* aNewValue) { NS_PRECONDITION(!mIsDocumentGone, "Unexpected AttributeWillChange"); NS_PRECONDITION(aDocument == mDocument, "Unexpected aDocument"); @@ -4184,7 +4184,8 @@ PresShell::AttributeWillChange(nsIDocument* aDocument, if (mDidInitialize) { nsAutoCauseReflowNotifier crNotifier(this); mPresContext->RestyleManager()->AttributeWillChange(aElement, aNameSpaceID, - aAttribute, aModType); + aAttribute, aModType, + aNewValue); VERIFY_STYLE_TREE; } } @@ -4194,7 +4195,8 @@ PresShell::AttributeChanged(nsIDocument* aDocument, Element* aElement, int32_t aNameSpaceID, nsIAtom* aAttribute, - int32_t aModType) + int32_t aModType, + const nsAttrValue* aOldValue) { NS_PRECONDITION(!mIsDocumentGone, "Unexpected AttributeChanged"); NS_PRECONDITION(aDocument == mDocument, "Unexpected aDocument"); @@ -4205,7 +4207,8 @@ PresShell::AttributeChanged(nsIDocument* aDocument, if (mDidInitialize) { nsAutoCauseReflowNotifier crNotifier(this); mPresContext->RestyleManager()->AttributeChanged(aElement, aNameSpaceID, - aAttribute, aModType); + aAttribute, aModType, + aOldValue); VERIFY_STYLE_TREE; } } diff --git a/layout/generic/nsFrameSetFrame.cpp b/layout/generic/nsFrameSetFrame.cpp index 747d694b47..d9c01a973b 100644 --- a/layout/generic/nsFrameSetFrame.cpp +++ b/layout/generic/nsFrameSetFrame.cpp @@ -109,7 +109,7 @@ public: const nsHTMLReflowState& aReflowState, nsReflowStatus& aStatus) override; - bool GetVisibility() { return mVisibility || mVisibilityOverride; } + bool GetVisibility() { return mVisibility; } void SetVisibility(bool aVisibility); void SetColor(nscolor aColor); @@ -129,7 +129,6 @@ protected: int32_t mWidth; bool mVertical; bool mVisibility; - bool mVisibilityOverride; bool mCanResize; friend class nsHTMLFramesetFrame; }; @@ -173,7 +172,6 @@ protected: * nsHTMLFramesetFrame ******************************************************************************/ bool nsHTMLFramesetFrame::gDragInProgress = false; -#define kFrameResizePref "layout.frames.force_resizability" #define DEFAULT_BORDER_WIDTH_PX 6 nsHTMLFramesetFrame::nsHTMLFramesetFrame(nsStyleContext* aContext) @@ -199,7 +197,6 @@ nsHTMLFramesetFrame::nsHTMLFramesetFrame(nsStyleContext* aContext) mHorBorders = nullptr; mChildFrameborder = nullptr; mChildBorderColors = nullptr; - mForceFrameResizability = false; } nsHTMLFramesetFrame::~nsHTMLFramesetFrame() @@ -210,43 +207,12 @@ nsHTMLFramesetFrame::~nsHTMLFramesetFrame() delete[] mHorBorders; delete[] mChildFrameborder; delete[] mChildBorderColors; - - Preferences::UnregisterCallback(FrameResizePrefCallback, - kFrameResizePref, this); } NS_QUERYFRAME_HEAD(nsHTMLFramesetFrame) NS_QUERYFRAME_ENTRY(nsHTMLFramesetFrame) NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame) -// static -void -nsHTMLFramesetFrame::FrameResizePrefCallback(const char* aPref, void* aClosure) -{ - nsHTMLFramesetFrame *frame = - reinterpret_cast(aClosure); - - nsIDocument* doc = frame->mContent->GetComposedDoc(); - mozAutoDocUpdate updateBatch(doc, UPDATE_CONTENT_MODEL, true); - if (doc) { - nsNodeUtils::AttributeWillChange(frame->GetContent()->AsElement(), - kNameSpaceID_None, - nsGkAtoms::frameborder, - nsIDOMMutationEvent::MODIFICATION); - } - - frame->mForceFrameResizability = - Preferences::GetBool(kFrameResizePref, frame->mForceFrameResizability); - - frame->RecalculateBorderResize(); - if (doc) { - nsNodeUtils::AttributeChanged(frame->GetContent()->AsElement(), - kNameSpaceID_None, - nsGkAtoms::frameborder, - nsIDOMMutationEvent::MODIFICATION); - } -} - void nsHTMLFramesetFrame::Init(nsIContent* aContent, nsContainerFrame* aParent, @@ -584,13 +550,9 @@ void nsHTMLFramesetFrame::GenerateRowCol(nsPresContext* aPresContext, int32_t nsHTMLFramesetFrame::GetBorderWidth(nsPresContext* aPresContext, bool aTakeForcingIntoAccount) { - bool forcing = mForceFrameResizability && aTakeForcingIntoAccount; - - if (!forcing) { - nsFrameborder frameborder = GetFrameBorder(); - if (frameborder == eFrameborder_No) { - return 0; - } + nsFrameborder frameborder = GetFrameBorder(); + if (frameborder == eFrameborder_No) { + return 0; } nsGenericHTMLElement *content = nsGenericHTMLElement::FromContent(mContent); @@ -605,15 +567,11 @@ int32_t nsHTMLFramesetFrame::GetBorderWidth(nsPresContext* aPresContext, } } - if (forcing && intVal == 0) { - intVal = DEFAULT_BORDER_WIDTH_PX; - } return nsPresContext::CSSPixelsToAppUnits(intVal); } } - if (mParentBorderWidth > 0 || - (mParentBorderWidth == 0 && !forcing)) { + if (mParentBorderWidth >= 0) { return mParentBorderWidth; } @@ -880,12 +838,6 @@ nsHTMLFramesetFrame::Reflow(nsPresContext* aPresContext, MOZ_ASSERT(!mChildFrameborder == !mChildBorderColors); bool firstTime = !!mChildFrameborder; - if (firstTime) { - Preferences::RegisterCallback(FrameResizePrefCallback, - kFrameResizePref, this); - mForceFrameResizability = Preferences::GetBool(kFrameResizePref); - } - // subtract out the width of all of the potential borders. There are // only borders between s. There are none on the edges (e.g the // leftmost has no left border). @@ -1121,11 +1073,7 @@ nsHTMLFramesetFrame::Reflow(nsPresContext* aPresContext, for (int verX = 0; verX < mNumCols-1; verX++) { if (mVerBorders[verX]) { mVerBorders[verX]->SetVisibility(verBordersVis[verX]); - if (mForceFrameResizability) { - mVerBorders[verX]->mVisibilityOverride = true; - } else { - SetBorderResize(mVerBorders[verX]); - } + SetBorderResize(mVerBorders[verX]); childColor = (NO_COLOR == verBorderColors[verX]) ? borderColor : verBorderColors[verX]; mVerBorders[verX]->SetColor(childColor); } @@ -1133,11 +1081,7 @@ nsHTMLFramesetFrame::Reflow(nsPresContext* aPresContext, for (int horX = 0; horX < mNumRows-1; horX++) { if (mHorBorders[horX]) { mHorBorders[horX]->SetVisibility(horBordersVis[horX]); - if (mForceFrameResizability) { - mHorBorders[horX]->mVisibilityOverride = true; - } else { - SetBorderResize(mHorBorders[horX]); - } + SetBorderResize(mHorBorders[horX]); childColor = (NO_COLOR == horBorderColors[horX]) ? borderColor : horBorderColors[horX]; mHorBorders[horX]->SetColor(childColor); } @@ -1238,24 +1182,14 @@ nsHTMLFramesetFrame::RecalculateBorderResize() for (verX = 0; verX < mNumCols-1; verX++) { if (mVerBorders[verX]) { mVerBorders[verX]->mCanResize = true; - if (mForceFrameResizability) { - mVerBorders[verX]->mVisibilityOverride = true; - } else { - mVerBorders[verX]->mVisibilityOverride = false; - SetBorderResize(mVerBorders[verX]); - } + SetBorderResize(mVerBorders[verX]); } } int32_t horX; for (horX = 0; horX < mNumRows-1; horX++) { if (mHorBorders[horX]) { mHorBorders[horX]->mCanResize = true; - if (mForceFrameResizability) { - mHorBorders[horX]->mVisibilityOverride = true; - } else { - mHorBorders[horX]->mVisibilityOverride = false; - SetBorderResize(mHorBorders[horX]); - } + SetBorderResize(mHorBorders[horX]); } } } @@ -1416,7 +1350,6 @@ nsHTMLFramesetBorderFrame::nsHTMLFramesetBorderFrame(nsStyleContext* aContext, bool aVisibility) : nsLeafFrame(aContext), mWidth(aWidth), mVertical(aVertical), mVisibility(aVisibility) { - mVisibilityOverride = false; mCanResize = true; mColor = NO_COLOR; mPrevNeighbor = 0; @@ -1537,7 +1470,7 @@ void nsHTMLFramesetBorderFrame::PaintBorder(DrawTarget* aDrawTarget, NS_RGB(128, 128, 128)))); ColorPattern color(ToDeviceColor(NS_RGB(255, 255, 255))); // default to white - if (mVisibility || mVisibilityOverride) { + if (mVisibility) { color = (NO_COLOR == mColor) ? bgColor : ColorPattern(ToDeviceColor(mColor)); } @@ -1566,7 +1499,7 @@ void nsHTMLFramesetBorderFrame::PaintBorder(DrawTarget* aDrawTarget, } } - if (!mVisibility && !mVisibilityOverride) + if (!mVisibility) return; if (widthInPixels >= 5) { diff --git a/layout/generic/nsFrameSetFrame.h b/layout/generic/nsFrameSetFrame.h index 186bb72b3e..673e1836ce 100644 --- a/layout/generic/nsFrameSetFrame.h +++ b/layout/generic/nsFrameSetFrame.h @@ -187,8 +187,6 @@ protected: void SetBorderResize(nsHTMLFramesetBorderFrame* aBorderFrame); - static void FrameResizePrefCallback(const char* aPref, void* aClosure); - nsFramesetDrag mDrag; nsBorderColor mEdgeColors; nsHTMLFramesetBorderFrame* mDragger; @@ -212,7 +210,6 @@ protected: int32_t mNextNeighborOrigSize; int32_t mMinDrag; int32_t mChildCount; - bool mForceFrameResizability; }; #endif diff --git a/layout/generic/nsImageMap.cpp b/layout/generic/nsImageMap.cpp index c9527b76fc..a816307c93 100644 --- a/layout/generic/nsImageMap.cpp +++ b/layout/generic/nsImageMap.cpp @@ -918,7 +918,8 @@ nsImageMap::AttributeChanged(nsIDocument* aDocument, dom::Element* aElement, int32_t aNameSpaceID, nsIAtom* aAttribute, - int32_t aModType) + int32_t aModType, + const nsAttrValue* aOldValue) { // If the parent of the changing content node is our map then update // the map. But only do this if the node is an HTML or diff --git a/layout/generic/nsLineBox.h b/layout/generic/nsLineBox.h index 64f2f59734..5c278978b7 100644 --- a/layout/generic/nsLineBox.h +++ b/layout/generic/nsLineBox.h @@ -343,7 +343,7 @@ private: uint32_t count = GetChildCount(); mFlags.mHasHashedFrames = 1; uint32_t minLength = std::max(kMinChildCountForHashtable, - uint32_t(PL_DHASH_DEFAULT_INITIAL_LENGTH)); + uint32_t(PLDHashTable::kDefaultInitialLength)); mFrames = new nsTHashtable< nsPtrHashKey >(std::max(count, minLength)); for (nsIFrame* f = mFirstChild; count-- > 0; f = f->GetNextSibling()) { mFrames->PutEntry(f); diff --git a/layout/inspector/inDOMView.cpp b/layout/inspector/inDOMView.cpp index 025be9911e..eee24ed6d9 100644 --- a/layout/inspector/inDOMView.cpp +++ b/layout/inspector/inDOMView.cpp @@ -632,7 +632,8 @@ inDOMView::NodeWillBeDestroyed(const nsINode* aNode) void inDOMView::AttributeChanged(nsIDocument* aDocument, dom::Element* aElement, int32_t aNameSpaceID, nsIAtom* aAttribute, - int32_t aModType) + int32_t aModType, + const nsAttrValue* aOldValue) { if (!mTree) { return; diff --git a/layout/reftests/bugs/1022481-1-ref.html b/layout/reftests/bugs/1022481-1-ref.html index 778b4de93c..256791bb16 100644 --- a/layout/reftests/bugs/1022481-1-ref.html +++ b/layout/reftests/bugs/1022481-1-ref.html @@ -20,16 +20,16 @@ p {

default font

-

serif

-

sans-serif

+

serif

+

sans-serif

monospace

-moz-fixed

-

unknown, serif

-

unknown, sans-serif

+

unknown, serif

+

unknown, sans-serif

unknown, monospace

unknown, -moz-fixed

-

unknown, serif, monospace

-

unknown, sans-serif, -moz-fixed

+

unknown, serif, monospace

+

unknown, sans-serif, -moz-fixed

unknown, monospace, serif

unknown, -moz-fixed, sans-serif

diff --git a/layout/style/CounterStyleManager.cpp b/layout/style/CounterStyleManager.cpp index 62c43f60f9..81d32317d3 100644 --- a/layout/style/CounterStyleManager.cpp +++ b/layout/style/CounterStyleManager.cpp @@ -2021,7 +2021,7 @@ CounterStyleManager::BuildCounterStyle(const nsSubstring& aName) // It is intentional that the predefined names are case-insensitive // but the user-defined names case-sensitive. nsCSSCounterStyleRule* rule = - mPresContext->StyleSet()->CounterStyleRuleForName(mPresContext, aName); + mPresContext->StyleSet()->CounterStyleRuleForName(aName); if (rule) { data = new (mPresContext) CustomCounterStyle(this, rule); } else { @@ -2074,7 +2074,7 @@ InvalidateOldStyle(const nsSubstring& aKey, bool toBeUpdated = false; bool toBeRemoved = false; nsCSSCounterStyleRule* newRule = data->mPresContext-> - StyleSet()->CounterStyleRuleForName(data->mPresContext, aKey); + StyleSet()->CounterStyleRuleForName(aKey); if (!newRule) { if (aStyle->IsCustomStyle()) { toBeRemoved = true; diff --git a/layout/style/StyleRule.cpp b/layout/style/StyleRule.cpp index ea4a783716..95eb154d96 100644 --- a/layout/style/StyleRule.cpp +++ b/layout/style/StyleRule.cpp @@ -1009,7 +1009,7 @@ public: NS_IMETHOD GetParentRule(nsIDOMCSSRule **aParent) override; void DropReference(void); - virtual css::Declaration* GetCSSDeclaration(bool aAllocate) override; + virtual css::Declaration* GetCSSDeclaration(Operation aOperation) override; virtual nsresult SetCSSDeclaration(css::Declaration* aDecl) override; virtual void GetCSSParsingEnvironment(CSSParsingEnvironment& aCSSParseEnv) override; virtual nsIDocument* DocToUpdate() override; @@ -1114,7 +1114,7 @@ DOMCSSDeclarationImpl::DropReference(void) } css::Declaration* -DOMCSSDeclarationImpl::GetCSSDeclaration(bool aAllocate) +DOMCSSDeclarationImpl::GetCSSDeclaration(Operation aOperation) { if (mRule) { return mRule->GetDeclaration(); diff --git a/layout/style/nsAnimationManager.cpp b/layout/style/nsAnimationManager.cpp index 1637d92423..d645f0ff28 100644 --- a/layout/style/nsAnimationManager.cpp +++ b/layout/style/nsAnimationManager.cpp @@ -510,8 +510,7 @@ nsAnimationManager::BuildAnimations(nsStyleContext* aStyleContext, nsCSSKeyframesRule* rule = src.GetName().IsEmpty() ? nullptr - : mPresContext->StyleSet()->KeyframesRuleForName(mPresContext, - src.GetName()); + : mPresContext->StyleSet()->KeyframesRuleForName(src.GetName()); if (!rule) { continue; } diff --git a/layout/style/nsCSSRuleProcessor.cpp b/layout/style/nsCSSRuleProcessor.cpp index 8fa751eae0..38b0c0ef97 100644 --- a/layout/style/nsCSSRuleProcessor.cpp +++ b/layout/style/nsCSSRuleProcessor.cpp @@ -55,6 +55,7 @@ #include "mozilla/Likely.h" #include "mozilla/TypedEnumBits.h" #include "RuleProcessorCache.h" +#include "nsIDOMMutationEvent.h" using namespace mozilla; using namespace mozilla::dom; @@ -671,24 +672,22 @@ void RuleHash::EnumerateAllRules(Element* aElement, ElementDependentRuleProcesso } // universal rules within the namespace if (kNameSpaceID_Unknown != nameSpace && mNameSpaceTable.EntryCount() > 0) { - RuleHashTableEntry *entry = static_cast - (PL_DHashTableSearch(&mNameSpaceTable, NS_INT32_TO_PTR(nameSpace))); + auto entry = static_cast + (mNameSpaceTable.Search(NS_INT32_TO_PTR(nameSpace))); if (entry) { mEnumList[valueCount++] = ToEnumData(entry->mRules); RULE_HASH_STAT_INCREMENT_LIST_COUNT(entry->mRules, mElementNameSpaceCalls); } } if (mTagTable.EntryCount() > 0) { - RuleHashTableEntry *entry = static_cast - (PL_DHashTableSearch(&mTagTable, tag)); + auto entry = static_cast(mTagTable.Search(tag)); if (entry) { mEnumList[valueCount++] = ToEnumData(entry->mRules); RULE_HASH_STAT_INCREMENT_LIST_COUNT(entry->mRules, mElementTagCalls); } } if (id && mIdTable.EntryCount() > 0) { - RuleHashTableEntry *entry = static_cast - (PL_DHashTableSearch(&mIdTable, id)); + auto entry = static_cast(mIdTable.Search(id)); if (entry) { mEnumList[valueCount++] = ToEnumData(entry->mRules); RULE_HASH_STAT_INCREMENT_LIST_COUNT(entry->mRules, mElementIdCalls); @@ -696,8 +695,8 @@ void RuleHash::EnumerateAllRules(Element* aElement, ElementDependentRuleProcesso } if (mClassTable.EntryCount() > 0) { for (int32_t index = 0; index < classCount; ++index) { - RuleHashTableEntry *entry = static_cast - (PL_DHashTableSearch(&mClassTable, classList->AtomAt(index))); + auto entry = static_cast + (mClassTable.Search(classList->AtomAt(index))); if (entry) { mEnumList[valueCount++] = ToEnumData(entry->mRules); RULE_HASH_STAT_INCREMENT_LIST_COUNT(entry->mRules, mElementClassCalls); @@ -2539,8 +2538,8 @@ nsCSSRuleProcessor::RulesMatching(AnonBoxRuleProcessorData* aData) RuleCascadeData* cascade = GetRuleCascade(aData->mPresContext); if (cascade && cascade->mAnonBoxRules.EntryCount()) { - RuleHashTagTableEntry* entry = static_cast - (PL_DHashTableSearch(&cascade->mAnonBoxRules, aData->mPseudoTag)); + auto entry = static_cast + (cascade->mAnonBoxRules.Search(aData->mPseudoTag)); if (entry) { nsTArray& rules = entry->mRules; for (RuleValue *value = rules.Elements(), *end = value + rules.Length(); @@ -2559,8 +2558,8 @@ nsCSSRuleProcessor::RulesMatching(XULTreeRuleProcessorData* aData) RuleCascadeData* cascade = GetRuleCascade(aData->mPresContext); if (cascade && cascade->mXULTreeRules.EntryCount()) { - RuleHashTagTableEntry* entry = static_cast - (PL_DHashTableSearch(&cascade->mXULTreeRules, aData->mPseudoTag)); + auto entry = static_cast + (cascade->mXULTreeRules.Search(aData->mPseudoTag)); if (entry) { NodeMatchContext nodeContext(EventStates(), nsCSSRuleProcessor::IsLink(aData->mElement)); @@ -2793,9 +2792,8 @@ nsCSSRuleProcessor::HasAttributeDependentStyle(AttributeRuleProcessorData* aData if (aData->mAttribute == nsGkAtoms::id) { nsIAtom* id = aData->mElement->GetID(); if (id) { - AtomSelectorEntry *entry = - static_cast - (PL_DHashTableSearch(&cascade->mIdSelectors, id)); + auto entry = + static_cast(cascade->mIdSelectors.Search(id)); if (entry) { EnumerateSelectors(entry->mSelectors, &data); } @@ -2805,17 +2803,38 @@ nsCSSRuleProcessor::HasAttributeDependentStyle(AttributeRuleProcessorData* aData } if (aData->mAttribute == nsGkAtoms::_class) { + const nsAttrValue* otherClasses = aData->mOtherValue; + NS_ASSERTION(otherClasses || + aData->mModType == nsIDOMMutationEvent::REMOVAL, + "All class values should be StoresOwnData and parsed" + "via Element::BeforeSetAttr, so available here"); + // For WillChange, enumerate classes that will be removed to see which + // rules apply before the change. + // For Changed, enumerate classes that have been added to see which rules + // apply after the change. + // In both cases we're interested in the classes that are currently on + // the element but not in mOtherValue. const nsAttrValue* elementClasses = aData->mElement->GetClasses(); if (elementClasses) { int32_t atomCount = elementClasses->GetAtomCount(); - for (int32_t i = 0; i < atomCount; ++i) { - nsIAtom* curClass = elementClasses->AtomAt(i); - AtomSelectorEntry *entry = - static_cast - (PL_DHashTableSearch(&cascade->mClassSelectors, - curClass)); - if (entry) { - EnumerateSelectors(entry->mSelectors, &data); + if (atomCount > 0) { + nsTHashtable> otherClassesTable; + if (otherClasses) { + int32_t otherClassesCount = otherClasses->GetAtomCount(); + for (int32_t i = 0; i < otherClassesCount; ++i) { + otherClassesTable.PutEntry(otherClasses->AtomAt(i)); + } + } + for (int32_t i = 0; i < atomCount; ++i) { + nsIAtom* curClass = elementClasses->AtomAt(i); + if (!otherClassesTable.Contains(curClass)) { + auto entry = + static_cast + (cascade->mClassSelectors.Search(curClass)); + if (entry) { + EnumerateSelectors(entry->mSelectors, &data); + } + } } } } @@ -2823,10 +2842,9 @@ nsCSSRuleProcessor::HasAttributeDependentStyle(AttributeRuleProcessorData* aData EnumerateSelectors(cascade->mPossiblyNegatedClassSelectors, &data); } - AtomSelectorEntry *entry = + auto entry = static_cast - (PL_DHashTableSearch(&cascade->mAttributeSelectors, - aData->mAttribute)); + (cascade->mAttributeSelectors.Search(aData->mAttribute)); if (entry) { EnumerateSelectors(entry->mSelectors, &data); } diff --git a/layout/style/nsCSSRules.cpp b/layout/style/nsCSSRules.cpp index d31c47d4a6..fcd788f5d9 100644 --- a/layout/style/nsCSSRules.cpp +++ b/layout/style/nsCSSRules.cpp @@ -2109,7 +2109,7 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsCSSKeyframeStyleDeclaration) NS_INTERFACE_MAP_END_INHERITING(nsDOMCSSDeclaration) css::Declaration* -nsCSSKeyframeStyleDeclaration::GetCSSDeclaration(bool aAllocate) +nsCSSKeyframeStyleDeclaration::GetCSSDeclaration(Operation aOperation) { if (mRule) { return mRule->Declaration(); @@ -2670,7 +2670,7 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsCSSPageStyleDeclaration) NS_INTERFACE_MAP_END_INHERITING(nsDOMCSSDeclaration) css::Declaration* -nsCSSPageStyleDeclaration::GetCSSDeclaration(bool aAllocate) +nsCSSPageStyleDeclaration::GetCSSDeclaration(Operation aOperation) { if (mRule) { return mRule->Declaration(); diff --git a/layout/style/nsCSSRules.h b/layout/style/nsCSSRules.h index a717c28a35..4203d225c9 100644 --- a/layout/style/nsCSSRules.h +++ b/layout/style/nsCSSRules.h @@ -410,7 +410,7 @@ public: NS_IMETHOD GetParentRule(nsIDOMCSSRule **aParent) override; void DropReference() { mRule = nullptr; } - virtual mozilla::css::Declaration* GetCSSDeclaration(bool aAllocate) override; + virtual mozilla::css::Declaration* GetCSSDeclaration(Operation aOperation) override; virtual nsresult SetCSSDeclaration(mozilla::css::Declaration* aDecl) override; virtual void GetCSSParsingEnvironment(CSSParsingEnvironment& aCSSParseEnv) override; virtual nsIDocument* DocToUpdate() override; @@ -543,7 +543,7 @@ public: NS_IMETHOD GetParentRule(nsIDOMCSSRule **aParent) override; void DropReference() { mRule = nullptr; } - virtual mozilla::css::Declaration* GetCSSDeclaration(bool aAllocate) override; + virtual mozilla::css::Declaration* GetCSSDeclaration(Operation aOperation) override; virtual nsresult SetCSSDeclaration(mozilla::css::Declaration* aDecl) override; virtual void GetCSSParsingEnvironment(CSSParsingEnvironment& aCSSParseEnv) override; virtual nsIDocument* DocToUpdate() override; diff --git a/layout/style/nsComputedDOMStyle.cpp b/layout/style/nsComputedDOMStyle.cpp index d831e8f23b..d63cd7b88f 100644 --- a/layout/style/nsComputedDOMStyle.cpp +++ b/layout/style/nsComputedDOMStyle.cpp @@ -544,7 +544,7 @@ nsComputedDOMStyle::GetPresShellForContent(nsIContent* aContent) // on a nsComputedDOMStyle object, but must be defined to avoid // compile errors. css::Declaration* -nsComputedDOMStyle::GetCSSDeclaration(bool) +nsComputedDOMStyle::GetCSSDeclaration(Operation) { NS_RUNTIMEABORT("called nsComputedDOMStyle::GetCSSDeclaration"); return nullptr; diff --git a/layout/style/nsComputedDOMStyle.h b/layout/style/nsComputedDOMStyle.h index 9515aef7dd..0c6ede7c89 100644 --- a/layout/style/nsComputedDOMStyle.h +++ b/layout/style/nsComputedDOMStyle.h @@ -98,7 +98,7 @@ public: // nsDOMCSSDeclaration abstract methods which should never be called // on a nsComputedDOMStyle object, but must be defined to avoid // compile errors. - virtual mozilla::css::Declaration* GetCSSDeclaration(bool) override; + virtual mozilla::css::Declaration* GetCSSDeclaration(Operation) override; virtual nsresult SetCSSDeclaration(mozilla::css::Declaration*) override; virtual nsIDocument* DocToUpdate() override; virtual void GetCSSParsingEnvironment(CSSParsingEnvironment& aCSSParseEnv) override; diff --git a/layout/style/nsDOMCSSAttrDeclaration.cpp b/layout/style/nsDOMCSSAttrDeclaration.cpp index 6701312be9..4496d038e8 100644 --- a/layout/style/nsDOMCSSAttrDeclaration.cpp +++ b/layout/style/nsDOMCSSAttrDeclaration.cpp @@ -91,23 +91,13 @@ nsDOMCSSAttributeDeclaration::SetCSSDeclaration(css::Declaration* aDecl) nsIDocument* nsDOMCSSAttributeDeclaration::DocToUpdate() { - // XXXbz this is a bit of a hack, especially doing it before the - // BeginUpdate(), but this is a good chokepoint where we know we - // plan to modify the CSSDeclaration, so need to notify - // AttributeWillChange if this is inline style. - if (!mIsSMILOverride) { - nsNodeUtils::AttributeWillChange(mElement, kNameSpaceID_None, - nsGkAtoms::style, - nsIDOMMutationEvent::MODIFICATION); - } - // We need OwnerDoc() rather than GetCurrentDoc() because it might // be the BeginUpdate call that inserts mElement into the document. return mElement->OwnerDoc(); } css::Declaration* -nsDOMCSSAttributeDeclaration::GetCSSDeclaration(bool aAllocate) +nsDOMCSSAttributeDeclaration::GetCSSDeclaration(Operation aOperation) { if (!mElement) return nullptr; @@ -118,10 +108,32 @@ nsDOMCSSAttributeDeclaration::GetCSSDeclaration(bool aAllocate) else cssRule = mElement->GetInlineStyleRule(); + // Notify observers that our style="" attribute is going to change + // unless: + // * this is a declaration that holds SMIL animation values (which + // aren't reflected in the DOM style="" attribute), or + // * we're getting the declaration for reading, or + // * we're getting it for property removal but we don't currently have + // a declaration. + + // XXXbz this is a bit of a hack, especially doing it before the + // BeginUpdate(), but this is a good chokepoint where we know we + // plan to modify the CSSDeclaration, so need to notify + // AttributeWillChange if this is inline style. + if (!mIsSMILOverride && + ((aOperation == eOperation_Modify) || + (aOperation == eOperation_RemoveProperty && cssRule))) { + nsNodeUtils::AttributeWillChange(mElement, kNameSpaceID_None, + nsGkAtoms::style, + nsIDOMMutationEvent::MODIFICATION, + nullptr); + } + if (cssRule) { return cssRule->GetDeclaration(); } - if (!aAllocate) { + + if (aOperation != eOperation_Modify) { return nullptr; } diff --git a/layout/style/nsDOMCSSAttrDeclaration.h b/layout/style/nsDOMCSSAttrDeclaration.h index 05134d7e5c..7efbbea090 100644 --- a/layout/style/nsDOMCSSAttrDeclaration.h +++ b/layout/style/nsDOMCSSAttrDeclaration.h @@ -31,7 +31,7 @@ public: // If GetCSSDeclaration returns non-null, then the decl it returns // is owned by our current style rule. - virtual mozilla::css::Declaration* GetCSSDeclaration(bool aAllocate) override; + virtual mozilla::css::Declaration* GetCSSDeclaration(Operation aOperation) override; virtual void GetCSSParsingEnvironment(CSSParsingEnvironment& aCSSParseEnv) override; NS_IMETHOD GetParentRule(nsIDOMCSSRule **aParent) override; diff --git a/layout/style/nsDOMCSSDeclaration.cpp b/layout/style/nsDOMCSSDeclaration.cpp index 4f3a2852fe..faa84d725c 100644 --- a/layout/style/nsDOMCSSDeclaration.cpp +++ b/layout/style/nsDOMCSSDeclaration.cpp @@ -46,7 +46,7 @@ nsDOMCSSDeclaration::GetPropertyValue(const nsCSSProperty aPropID, NS_PRECONDITION(aPropID != eCSSProperty_UNKNOWN, "Should never pass eCSSProperty_UNKNOWN around"); - css::Declaration* decl = GetCSSDeclaration(false); + css::Declaration* decl = GetCSSDeclaration(eOperation_Read); aValue.Truncate(); if (decl) { @@ -62,7 +62,7 @@ nsDOMCSSDeclaration::GetCustomPropertyValue(const nsAString& aPropertyName, MOZ_ASSERT(Substring(aPropertyName, 0, CSS_CUSTOM_NAME_PREFIX_LENGTH).EqualsLiteral("--")); - css::Declaration* decl = GetCSSDeclaration(false); + css::Declaration* decl = GetCSSDeclaration(eOperation_Read); if (!decl) { aValue.Truncate(); return; @@ -90,7 +90,7 @@ nsDOMCSSDeclaration::SetPropertyValue(const nsCSSProperty aPropID, NS_IMETHODIMP nsDOMCSSDeclaration::GetCssText(nsAString& aCssText) { - css::Declaration* decl = GetCSSDeclaration(false); + css::Declaration* decl = GetCSSDeclaration(eOperation_Read); aCssText.Truncate(); if (decl) { @@ -105,7 +105,7 @@ nsDOMCSSDeclaration::SetCssText(const nsAString& aCssText) { // We don't need to *do* anything with the old declaration, but we need // to ensure that it exists, or else SetCSSDeclaration may crash. - css::Declaration* olddecl = GetCSSDeclaration(true); + css::Declaration* olddecl = GetCSSDeclaration(eOperation_Modify); if (!olddecl) { return NS_ERROR_FAILURE; } @@ -140,7 +140,7 @@ nsDOMCSSDeclaration::SetCssText(const nsAString& aCssText) NS_IMETHODIMP nsDOMCSSDeclaration::GetLength(uint32_t* aLength) { - css::Declaration* decl = GetCSSDeclaration(false); + css::Declaration* decl = GetCSSDeclaration(eOperation_Read); if (decl) { *aLength = decl->Count(); @@ -162,7 +162,7 @@ nsDOMCSSDeclaration::GetPropertyCSSValue(const nsAString& aPropertyName, ErrorRe void nsDOMCSSDeclaration::IndexedGetter(uint32_t aIndex, bool& aFound, nsAString& aPropName) { - css::Declaration* decl = GetCSSDeclaration(false); + css::Declaration* decl = GetCSSDeclaration(eOperation_Read); aFound = decl && decl->GetNthProperty(aIndex, aPropName); } @@ -203,7 +203,7 @@ nsDOMCSSDeclaration::GetAuthoredPropertyValue(const nsAString& aPropertyName, return NS_OK; } - css::Declaration* decl = GetCSSDeclaration(false); + css::Declaration* decl = GetCSSDeclaration(eOperation_Read); if (!decl) { return NS_ERROR_FAILURE; } @@ -216,7 +216,7 @@ NS_IMETHODIMP nsDOMCSSDeclaration::GetPropertyPriority(const nsAString& aPropertyName, nsAString& aReturn) { - css::Declaration* decl = GetCSSDeclaration(false); + css::Declaration* decl = GetCSSDeclaration(eOperation_Read); aReturn.Truncate(); if (decl && decl->GetValueIsImportant(aPropertyName)) { @@ -311,7 +311,7 @@ nsDOMCSSDeclaration::ParsePropertyValue(const nsCSSProperty aPropID, const nsAString& aPropValue, bool aIsImportant) { - css::Declaration* olddecl = GetCSSDeclaration(true); + css::Declaration* olddecl = GetCSSDeclaration(eOperation_Modify); if (!olddecl) { return NS_ERROR_FAILURE; } @@ -352,7 +352,7 @@ nsDOMCSSDeclaration::ParseCustomPropertyValue(const nsAString& aPropertyName, { MOZ_ASSERT(nsCSSProps::IsCustomPropertyName(aPropertyName)); - css::Declaration* olddecl = GetCSSDeclaration(true); + css::Declaration* olddecl = GetCSSDeclaration(eOperation_Modify); if (!olddecl) { return NS_ERROR_FAILURE; } @@ -392,7 +392,7 @@ nsDOMCSSDeclaration::ParseCustomPropertyValue(const nsAString& aPropertyName, nsresult nsDOMCSSDeclaration::RemoveProperty(const nsCSSProperty aPropID) { - css::Declaration* decl = GetCSSDeclaration(false); + css::Declaration* decl = GetCSSDeclaration(eOperation_RemoveProperty); if (!decl) { return NS_OK; // no decl, so nothing to remove } @@ -415,7 +415,7 @@ nsDOMCSSDeclaration::RemoveCustomProperty(const nsAString& aPropertyName) MOZ_ASSERT(Substring(aPropertyName, 0, CSS_CUSTOM_NAME_PREFIX_LENGTH).EqualsLiteral("--")); - css::Declaration* decl = GetCSSDeclaration(false); + css::Declaration* decl = GetCSSDeclaration(eOperation_RemoveProperty); if (!decl) { return NS_OK; // no decl, so nothing to remove } diff --git a/layout/style/nsDOMCSSDeclaration.h b/layout/style/nsDOMCSSDeclaration.h index 1590e977ba..4f1bc88937 100644 --- a/layout/style/nsDOMCSSDeclaration.h +++ b/layout/style/nsDOMCSSDeclaration.h @@ -100,10 +100,26 @@ public: virtual JSObject* WrapObject(JSContext* aCx, JS::Handle aGivenProto) override; protected: - // This method can return null regardless of the value of aAllocate; - // however, a null return should only be considered a failure - // if aAllocate is true. - virtual mozilla::css::Declaration* GetCSSDeclaration(bool aAllocate) = 0; + // The reason for calling GetCSSDeclaration. + enum Operation { + // We are calling GetCSSDeclaration so that we can read from it. Does not + // allocate a new declaration if we don't have one yet; returns nullptr in + // this case. + eOperation_Read, + + // We are calling GetCSSDeclaration so that we can set a property on it + // or re-parse the whole declaration. Allocates a new declaration if we + // don't have one yet and calls AttributeWillChange. A nullptr return value + // indicates an error allocating the declaration. + eOperation_Modify, + + // We are calling GetCSSDeclaration so that we can remove a property from + // it. Does not allocates a new declaration if we don't have one yet; + // returns nullptr in this case. If we do have a declaration, calls + // AttributeWillChange. + eOperation_RemoveProperty + }; + virtual mozilla::css::Declaration* GetCSSDeclaration(Operation aOperation) = 0; virtual nsresult SetCSSDeclaration(mozilla::css::Declaration* aDecl) = 0; // Document that we must call BeginUpdate/EndUpdate on around the // calls to SetCSSDeclaration and the style rule mutation that leads diff --git a/layout/style/nsRuleProcessorData.h b/layout/style/nsRuleProcessorData.h index 67dbd9ad2c..b7f9cc3ea1 100644 --- a/layout/style/nsRuleProcessorData.h +++ b/layout/style/nsRuleProcessorData.h @@ -574,16 +574,20 @@ struct MOZ_STACK_CLASS AttributeRuleProcessorData : nsIAtom* aAttribute, int32_t aModType, bool aAttrHasChanged, + const nsAttrValue* aOtherValue, TreeMatchContext& aTreeMatchContext) : ElementDependentRuleProcessorData(aPresContext, aElement, nullptr, aTreeMatchContext), mAttribute(aAttribute), + mOtherValue(aOtherValue), mModType(aModType), mAttrHasChanged(aAttrHasChanged) { NS_PRECONDITION(!aTreeMatchContext.mForStyling, "Not styling here!"); } nsIAtom* mAttribute; // |HasAttributeDependentStyle| for which attribute? + // non-null if we have the value. + const nsAttrValue* mOtherValue; int32_t mModType; // The type of modification (see nsIDOMMutationEvent). bool mAttrHasChanged; // Whether the attribute has already changed. }; diff --git a/layout/style/nsStyleContext.cpp b/layout/style/nsStyleContext.cpp index 54e503777c..b08c702c7a 100644 --- a/layout/style/nsStyleContext.cpp +++ b/layout/style/nsStyleContext.cpp @@ -150,7 +150,7 @@ nsStyleContext::~nsStyleContext() mRuleNode->Release(); - styleSet->NotifyStyleContextDestroyed(presContext, this); + styleSet->NotifyStyleContextDestroyed(this); if (mParent) { mParent->RemoveChild(this); diff --git a/layout/style/nsStyleSet.cpp b/layout/style/nsStyleSet.cpp index d46b2c479d..46f0bf556f 100644 --- a/layout/style/nsStyleSet.cpp +++ b/layout/style/nsStyleSet.cpp @@ -1932,8 +1932,7 @@ nsStyleSet::ResolveAnonymousBoxStyle(nsIAtom* aPseudoTag, // Add any @page rules that are specified. nsTArray rules; nsTArray importantRules; - nsPresContext* presContext = PresContext(); - presContext->StyleSet()->AppendPageRules(presContext, rules); + PresContext()->StyleSet()->AppendPageRules(rules); for (uint32_t i = 0, i_end = rules.Length(); i != i_end; ++i) { ruleWalker.Forward(rules[i]); css::ImportantRule* importantRule = rules[i]->GetImportantRule(); @@ -1993,30 +1992,30 @@ nsStyleSet::ResolveXULTreePseudoStyle(Element* aParentElement, #endif bool -nsStyleSet::AppendFontFaceRules(nsPresContext* aPresContext, - nsTArray& aArray) +nsStyleSet::AppendFontFaceRules(nsTArray& aArray) { NS_ENSURE_FALSE(mInShutdown, false); NS_ASSERTION(mBatching == 0, "rule processors out of date"); + nsPresContext* presContext = PresContext(); for (uint32_t i = 0; i < ArrayLength(gCSSSheetTypes); ++i) { if (gCSSSheetTypes[i] == eScopedDocSheet) continue; nsCSSRuleProcessor *ruleProc = static_cast (mRuleProcessors[gCSSSheetTypes[i]].get()); - if (ruleProc && !ruleProc->AppendFontFaceRules(aPresContext, aArray)) + if (ruleProc && !ruleProc->AppendFontFaceRules(presContext, aArray)) return false; } return true; } nsCSSKeyframesRule* -nsStyleSet::KeyframesRuleForName(nsPresContext* aPresContext, - const nsString& aName) +nsStyleSet::KeyframesRuleForName(const nsString& aName) { NS_ENSURE_FALSE(mInShutdown, nullptr); NS_ASSERTION(mBatching == 0, "rule processors out of date"); + nsPresContext* presContext = PresContext(); for (uint32_t i = ArrayLength(gCSSSheetTypes); i-- != 0; ) { if (gCSSSheetTypes[i] == eScopedDocSheet) continue; @@ -2025,7 +2024,7 @@ nsStyleSet::KeyframesRuleForName(nsPresContext* aPresContext, if (!ruleProc) continue; nsCSSKeyframesRule* result = - ruleProc->KeyframesRuleForName(aPresContext, aName); + ruleProc->KeyframesRuleForName(presContext, aName); if (result) return result; } @@ -2033,12 +2032,12 @@ nsStyleSet::KeyframesRuleForName(nsPresContext* aPresContext, } nsCSSCounterStyleRule* -nsStyleSet::CounterStyleRuleForName(nsPresContext* aPresContext, - const nsAString& aName) +nsStyleSet::CounterStyleRuleForName(const nsAString& aName) { NS_ENSURE_FALSE(mInShutdown, nullptr); NS_ASSERTION(mBatching == 0, "rule processors out of date"); + nsPresContext* presContext = PresContext(); for (uint32_t i = ArrayLength(gCSSSheetTypes); i-- != 0; ) { if (gCSSSheetTypes[i] == eScopedDocSheet) continue; @@ -2047,7 +2046,7 @@ nsStyleSet::CounterStyleRuleForName(nsPresContext* aPresContext, if (!ruleProc) continue; nsCSSCounterStyleRule *result = - ruleProc->CounterStyleRuleForName(aPresContext, aName); + ruleProc->CounterStyleRuleForName(presContext, aName); if (result) return result; } @@ -2055,17 +2054,18 @@ nsStyleSet::CounterStyleRuleForName(nsPresContext* aPresContext, } bool -nsStyleSet::AppendFontFeatureValuesRules(nsPresContext* aPresContext, +nsStyleSet::AppendFontFeatureValuesRules( nsTArray& aArray) { NS_ENSURE_FALSE(mInShutdown, false); NS_ASSERTION(mBatching == 0, "rule processors out of date"); + nsPresContext* presContext = PresContext(); for (uint32_t i = 0; i < ArrayLength(gCSSSheetTypes); ++i) { nsCSSRuleProcessor *ruleProc = static_cast (mRuleProcessors[gCSSSheetTypes[i]].get()); if (ruleProc && - !ruleProc->AppendFontFeatureValuesRules(aPresContext, aArray)) + !ruleProc->AppendFontFeatureValuesRules(presContext, aArray)) { return false; } @@ -2080,7 +2080,7 @@ nsStyleSet::GetFontFeatureValuesLookup() mInitFontFeatureValuesLookup = false; nsTArray rules; - AppendFontFeatureValuesRules(PresContext(), rules); + AppendFontFeatureValuesRules(rules); mFontFeatureValuesLookup = new gfxFontFeatureValueSet(); @@ -2108,32 +2108,32 @@ nsStyleSet::GetFontFeatureValuesLookup() } bool -nsStyleSet::AppendPageRules(nsPresContext* aPresContext, - nsTArray& aArray) +nsStyleSet::AppendPageRules(nsTArray& aArray) { NS_ENSURE_FALSE(mInShutdown, false); NS_ASSERTION(mBatching == 0, "rule processors out of date"); + nsPresContext* presContext = PresContext(); for (uint32_t i = 0; i < ArrayLength(gCSSSheetTypes); ++i) { if (gCSSSheetTypes[i] == eScopedDocSheet) continue; nsCSSRuleProcessor* ruleProc = static_cast (mRuleProcessors[gCSSSheetTypes[i]].get()); - if (ruleProc && !ruleProc->AppendPageRules(aPresContext, aArray)) + if (ruleProc && !ruleProc->AppendPageRules(presContext, aArray)) return false; } return true; } void -nsStyleSet::BeginShutdown(nsPresContext* aPresContext) +nsStyleSet::BeginShutdown() { mInShutdown = 1; mRoots.Clear(); // no longer valid, since we won't keep it up to date } void -nsStyleSet::Shutdown(nsPresContext* aPresContext) +nsStyleSet::Shutdown() { mRuleTree->Destroy(); mRuleTree = nullptr; @@ -2151,8 +2151,7 @@ nsStyleSet::Shutdown(nsPresContext* aPresContext) static const uint32_t kGCInterval = 300; void -nsStyleSet::NotifyStyleContextDestroyed(nsPresContext* aPresContext, - nsStyleContext* aStyleContext) +nsStyleSet::NotifyStyleContextDestroyed(nsStyleContext* aStyleContext) { if (mInShutdown) return; @@ -2300,8 +2299,7 @@ static bool SheetHasDocumentStateStyle(nsIStyleRuleProcessor* aProcessor, // Test if style is dependent on a document state. bool -nsStyleSet::HasDocumentStateDependentStyle(nsPresContext* aPresContext, - nsIContent* aContent, +nsStyleSet::HasDocumentStateDependentStyle(nsIContent* aContent, EventStates aStateMask) { if (!aContent || !aContent->IsElement()) @@ -2310,7 +2308,7 @@ nsStyleSet::HasDocumentStateDependentStyle(nsPresContext* aPresContext, TreeMatchContext treeContext(false, nsRuleWalker::eLinksVisitedOrUnvisited, aContent->OwnerDoc()); InitStyleScopes(treeContext, aContent->AsElement()); - StatefulData data(aPresContext, aContent->AsElement(), aStateMask, + StatefulData data(PresContext(), aContent->AsElement(), aStateMask, treeContext); WalkRuleProcessors(SheetHasDocumentStateStyle, &data, true); return data.mHint != 0; @@ -2336,21 +2334,19 @@ static bool SheetHasStatefulPseudoElementStyle(nsIStyleRuleProcessor* aProcessor // Test if style is dependent on content state nsRestyleHint -nsStyleSet::HasStateDependentStyle(nsPresContext* aPresContext, - Element* aElement, +nsStyleSet::HasStateDependentStyle(Element* aElement, EventStates aStateMask) { TreeMatchContext treeContext(false, nsRuleWalker::eLinksVisitedOrUnvisited, aElement->OwnerDoc()); InitStyleScopes(treeContext, aElement); - StatefulData data(aPresContext, aElement, aStateMask, treeContext); + StatefulData data(PresContext(), aElement, aStateMask, treeContext); WalkRuleProcessors(SheetHasStatefulStyle, &data, false); return data.mHint; } nsRestyleHint -nsStyleSet::HasStateDependentStyle(nsPresContext* aPresContext, - Element* aElement, +nsStyleSet::HasStateDependentStyle(Element* aElement, nsCSSPseudoElements::Type aPseudoType, Element* aPseudoElement, EventStates aStateMask) @@ -2358,7 +2354,7 @@ nsStyleSet::HasStateDependentStyle(nsPresContext* aPresContext, TreeMatchContext treeContext(false, nsRuleWalker::eLinksVisitedOrUnvisited, aElement->OwnerDoc()); InitStyleScopes(treeContext, aElement); - StatefulPseudoElementData data(aPresContext, aElement, aStateMask, + StatefulPseudoElementData data(PresContext(), aElement, aStateMask, aPseudoType, treeContext, aPseudoElement); WalkRuleProcessors(SheetHasStatefulPseudoElementStyle, &data, false); return data.mHint; @@ -2367,9 +2363,10 @@ nsStyleSet::HasStateDependentStyle(nsPresContext* aPresContext, struct MOZ_STACK_CLASS AttributeData : public AttributeRuleProcessorData { AttributeData(nsPresContext* aPresContext, Element* aElement, nsIAtom* aAttribute, int32_t aModType, - bool aAttrHasChanged, TreeMatchContext& aTreeMatchContext) + bool aAttrHasChanged, const nsAttrValue* aOtherValue, + TreeMatchContext& aTreeMatchContext) : AttributeRuleProcessorData(aPresContext, aElement, aAttribute, aModType, - aAttrHasChanged, aTreeMatchContext), + aAttrHasChanged, aOtherValue, aTreeMatchContext), mHint(nsRestyleHint(0)) {} nsRestyleHint mHint; @@ -2386,45 +2383,46 @@ SheetHasAttributeStyle(nsIStyleRuleProcessor* aProcessor, void *aData) // Test if style is dependent on content state nsRestyleHint -nsStyleSet::HasAttributeDependentStyle(nsPresContext* aPresContext, - Element* aElement, +nsStyleSet::HasAttributeDependentStyle(Element* aElement, nsIAtom* aAttribute, int32_t aModType, - bool aAttrHasChanged) + bool aAttrHasChanged, + const nsAttrValue* aOtherValue) { TreeMatchContext treeContext(false, nsRuleWalker::eLinksVisitedOrUnvisited, aElement->OwnerDoc()); InitStyleScopes(treeContext, aElement); - AttributeData data(aPresContext, aElement, aAttribute, - aModType, aAttrHasChanged, treeContext); + AttributeData data(PresContext(), aElement, aAttribute, + aModType, aAttrHasChanged, aOtherValue, treeContext); WalkRuleProcessors(SheetHasAttributeStyle, &data, false); return data.mHint; } bool -nsStyleSet::MediumFeaturesChanged(nsPresContext* aPresContext) +nsStyleSet::MediumFeaturesChanged() { NS_ASSERTION(mBatching == 0, "rule processors out of date"); // We can't use WalkRuleProcessors without a content node. + nsPresContext* presContext = PresContext(); bool stylesChanged = false; for (uint32_t i = 0; i < ArrayLength(mRuleProcessors); ++i) { nsIStyleRuleProcessor *processor = mRuleProcessors[i]; if (!processor) { continue; } - bool thisChanged = processor->MediumFeaturesChanged(aPresContext); + bool thisChanged = processor->MediumFeaturesChanged(presContext); stylesChanged = stylesChanged || thisChanged; } for (uint32_t i = 0; i < mScopedDocSheetRuleProcessors.Length(); ++i) { nsIStyleRuleProcessor *processor = mScopedDocSheetRuleProcessors[i]; - bool thisChanged = processor->MediumFeaturesChanged(aPresContext); + bool thisChanged = processor->MediumFeaturesChanged(presContext); stylesChanged = stylesChanged || thisChanged; } if (mBindingManager) { bool thisChanged = false; - mBindingManager->MediumFeaturesChanged(aPresContext, &thisChanged); + mBindingManager->MediumFeaturesChanged(presContext, &thisChanged); stylesChanged = stylesChanged || thisChanged; } diff --git a/layout/style/nsStyleSet.h b/layout/style/nsStyleSet.h index 04a711b7fe..f21834d03d 100644 --- a/layout/style/nsStyleSet.h +++ b/layout/style/nsStyleSet.h @@ -228,40 +228,35 @@ class nsStyleSet final // Append all the currently-active font face rules to aArray. Return // true for success and false for failure. - bool AppendFontFaceRules(nsPresContext* aPresContext, - nsTArray& aArray); + bool AppendFontFaceRules(nsTArray& aArray); // Return the winning (in the cascade) @keyframes rule for the given name. - nsCSSKeyframesRule* KeyframesRuleForName(nsPresContext* aPresContext, - const nsString& aName); + nsCSSKeyframesRule* KeyframesRuleForName(const nsString& aName); // Return the winning (in the cascade) @counter-style rule for the given name. - nsCSSCounterStyleRule* CounterStyleRuleForName(nsPresContext* aPresContext, - const nsAString& aName); + nsCSSCounterStyleRule* CounterStyleRuleForName(const nsAString& aName); // Fetch object for looking up font feature values already_AddRefed GetFontFeatureValuesLookup(); // Append all the currently-active font feature values rules to aArray. // Return true for success and false for failure. - bool AppendFontFeatureValuesRules(nsPresContext* aPresContext, + bool AppendFontFeatureValuesRules( nsTArray& aArray); // Append all the currently-active page rules to aArray. Return // true for success and false for failure. - bool AppendPageRules(nsPresContext* aPresContext, - nsTArray& aArray); + bool AppendPageRules(nsTArray& aArray); // Begin ignoring style context destruction, to avoid lots of unnecessary // work on document teardown. - void BeginShutdown(nsPresContext* aPresContext); + void BeginShutdown(); // Free all of the data associated with this style set. - void Shutdown(nsPresContext* aPresContext); + void Shutdown(); // Notification that a style context is being destroyed. - void NotifyStyleContextDestroyed(nsPresContext* aPresContext, - nsStyleContext* aStyleContext); + void NotifyStyleContextDestroyed(nsStyleContext* aStyleContext); // Get a new style context that lives in a different parent // The new context will be the same as the old if the new parent is the @@ -275,33 +270,30 @@ class nsStyleSet final mozilla::dom::Element* aElement); // Test if style is dependent on a document state. - bool HasDocumentStateDependentStyle(nsPresContext* aPresContext, - nsIContent* aContent, + bool HasDocumentStateDependentStyle(nsIContent* aContent, mozilla::EventStates aStateMask); // Test if style is dependent on content state - nsRestyleHint HasStateDependentStyle(nsPresContext* aPresContext, - mozilla::dom::Element* aElement, + nsRestyleHint HasStateDependentStyle(mozilla::dom::Element* aElement, mozilla::EventStates aStateMask); - nsRestyleHint HasStateDependentStyle(nsPresContext* aPresContext, - mozilla::dom::Element* aElement, + nsRestyleHint HasStateDependentStyle(mozilla::dom::Element* aElement, nsCSSPseudoElements::Type aPseudoType, mozilla::dom::Element* aPseudoElement, mozilla::EventStates aStateMask); // Test if style is dependent on the presence of an attribute. - nsRestyleHint HasAttributeDependentStyle(nsPresContext* aPresContext, - mozilla::dom::Element* aElement, + nsRestyleHint HasAttributeDependentStyle(mozilla::dom::Element* aElement, nsIAtom* aAttribute, int32_t aModType, - bool aAttrHasChanged); + bool aAttrHasChanged, + const nsAttrValue* aOtherValue); /* * Do any processing that needs to happen as a result of a change in * the characteristics of the medium, and return whether style rules * may have changed as a result. */ - bool MediumFeaturesChanged(nsPresContext* aPresContext); + bool MediumFeaturesChanged(); // APIs for registering objects that can supply additional // rules during processing. diff --git a/layout/svg/SVGTextFrame.cpp b/layout/svg/SVGTextFrame.cpp index a06471f9ca..d51c82d10b 100644 --- a/layout/svg/SVGTextFrame.cpp +++ b/layout/svg/SVGTextFrame.cpp @@ -3417,7 +3417,8 @@ SVGTextFrame::MutationObserver::AttributeChanged( mozilla::dom::Element* aElement, int32_t aNameSpaceID, nsIAtom* aAttribute, - int32_t aModType) + int32_t aModType, + const nsAttrValue* aOldValue) { if (!aElement->IsSVGElement()) { return; diff --git a/layout/svg/nsSVGEffects.cpp b/layout/svg/nsSVGEffects.cpp index 5b3b1efdb9..de396176ad 100644 --- a/layout/svg/nsSVGEffects.cpp +++ b/layout/svg/nsSVGEffects.cpp @@ -115,7 +115,8 @@ nsSVGRenderingObserver::AttributeChanged(nsIDocument* aDocument, dom::Element* aElement, int32_t aNameSpaceID, nsIAtom* aAttribute, - int32_t aModType) + int32_t aModType, + const nsAttrValue* aOldValue) { // An attribute belonging to the element that we are observing *or one of its // descendants* has changed. diff --git a/layout/xul/tree/nsTreeContentView.cpp b/layout/xul/tree/nsTreeContentView.cpp index c1e93625f2..1730838d19 100644 --- a/layout/xul/tree/nsTreeContentView.cpp +++ b/layout/xul/tree/nsTreeContentView.cpp @@ -715,7 +715,8 @@ nsTreeContentView::AttributeChanged(nsIDocument* aDocument, dom::Element* aElement, int32_t aNameSpaceID, nsIAtom* aAttribute, - int32_t aModType) + int32_t aModType, + const nsAttrValue* aOldValue) { // Lots of codepaths under here that do all sorts of stuff, so be safe. nsCOMPtr kungFuDeathGrip(this); diff --git a/mfbt/ChaosMode.cpp b/mfbt/ChaosMode.cpp index d33258f5ce..48ed093e29 100644 --- a/mfbt/ChaosMode.cpp +++ b/mfbt/ChaosMode.cpp @@ -7,9 +7,11 @@ #include "mozilla/ChaosMode.h" namespace mozilla { + namespace detail { Atomic gChaosModeCounter(0); +ChaosFeature gChaosFeatures = None; } /* namespace detail */ } /* namespace mozilla */ diff --git a/mfbt/ChaosMode.h b/mfbt/ChaosMode.h index ca943a1e76..b5a0b65d0a 100644 --- a/mfbt/ChaosMode.h +++ b/mfbt/ChaosMode.h @@ -15,9 +15,25 @@ namespace mozilla { +enum ChaosFeature { + None = 0x0, + // Altering thread scheduling. + ThreadScheduling = 0x1, + // Altering network request scheduling. + NetworkScheduling = 0x2, + // Altering timer scheduling. + TimerScheduling = 0x4, + // Read and write less-than-requested amounts. + IOAmounts = 0x8, + // Iterate over hash tables in random order. + HashTableIteration = 0x10, + Any = 0xffffffff, +}; + namespace detail { extern MFBT_DATA Atomic gChaosModeCounter; -} +extern MFBT_DATA ChaosFeature gChaosFeatures; +} // namespace detail /** * When "chaos mode" is activated, code that makes implicitly nondeterministic @@ -27,32 +43,17 @@ extern MFBT_DATA Atomic gChaosModeCounter; class ChaosMode { public: - enum ChaosFeature { - None = 0x0, - // Altering thread scheduling. - ThreadScheduling = 0x1, - // Altering network request scheduling. - NetworkScheduling = 0x2, - // Altering timer scheduling. - TimerScheduling = 0x4, - // Read and write less-than-requested amounts. - IOAmounts = 0x8, - // Iterate over hash tables in random order. - HashTableIteration = 0x10, - Any = 0xffffffff, - }; + static void SetChaosFeature(ChaosFeature aChaosFeature) + { + detail::gChaosFeatures = aChaosFeature; + } -private: - // Change this to any non-None value to activate ChaosMode. - static const ChaosFeature sChaosFeatures = None; - -public: static bool isActive(ChaosFeature aFeature) { if (detail::gChaosModeCounter > 0) { return true; } - return sChaosFeatures & aFeature; + return detail::gChaosFeatures & aFeature; } /** diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index b814dbf809..0d211f241f 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -2427,9 +2427,6 @@ pref("layout.word_select.stop_at_punctuation", true); // Windows default is 1 for word delete behavior, the rest as for 2. pref("layout.selection.caret_style", 0); -// pref to force frames to be resizable -pref("layout.frames.force_resizability", false); - // pref to report CSS errors to the error console pref("layout.css.report_errors", true); diff --git a/modules/libpref/prefapi.cpp b/modules/libpref/prefapi.cpp index 6fec760839..75ad6468e8 100644 --- a/modules/libpref/prefapi.cpp +++ b/modules/libpref/prefapi.cpp @@ -585,7 +585,7 @@ PREF_ClearUserPref(const char *pref_name) pref->flags &= ~PREF_USERSET; if (!(pref->flags & PREF_HAS_DEFAULT)) { - PL_DHashTableRemove(gHashTable, pref_name); + gHashTable->RemoveEntry(pref); } pref_DoCallback(pref_name); @@ -699,7 +699,7 @@ PrefHashEntry* pref_HashTableLookup(const void *key) MOZ_ASSERT(NS_IsMainThread()); #endif - return static_cast(PL_DHashTableSearch(gHashTable, key)); + return static_cast(gHashTable->Search(key)); } nsresult pref_HashPref(const char *key, PrefValue value, PrefType type, uint32_t flags) diff --git a/netwerk/base/nsLoadGroup.cpp b/netwerk/base/nsLoadGroup.cpp index 4e00aebe10..12dfbbc590 100644 --- a/netwerk/base/nsLoadGroup.cpp +++ b/netwerk/base/nsLoadGroup.cpp @@ -299,7 +299,7 @@ nsLoadGroup::Cancel(nsresult status) NS_ASSERTION(request, "NULL request found in list."); - if (!PL_DHashTableSearch(&mRequests, request)) { + if (!mRequests.Search(request)) { // |request| was removed already NS_RELEASE(request); continue; @@ -507,7 +507,7 @@ nsLoadGroup::AddRequest(nsIRequest *request, nsISupports* ctxt) this, request, nameStr.get(), mRequests.EntryCount())); } - NS_ASSERTION(!PL_DHashTableSearch(&mRequests, request), + NS_ASSERTION(!mRequests.Search(request), "Entry added to loadgroup twice, don't do that"); // @@ -614,9 +614,7 @@ nsLoadGroup::RemoveRequest(nsIRequest *request, nsISupports* ctxt, // the request was *not* in the group so do not update the foreground // count or it will get messed up... // - RequestMapEntry *entry = - static_cast - (PL_DHashTableSearch(&mRequests, request)); + auto entry = static_cast(mRequests.Search(request)); if (!entry) { LOG(("LOADGROUP [%x]: Unable to remove request %x. Not in group!\n", @@ -625,7 +623,7 @@ nsLoadGroup::RemoveRequest(nsIRequest *request, nsISupports* ctxt, return NS_ERROR_FAILURE; } - PL_DHashTableRawRemove(&mRequests, entry); + mRequests.RemoveEntry(entry); // Undo any group priority delta... if (mPriority != 0) diff --git a/netwerk/base/nsSocketTransportService2.cpp b/netwerk/base/nsSocketTransportService2.cpp index ef613ec19e..1c36fe9a32 100644 --- a/netwerk/base/nsSocketTransportService2.cpp +++ b/netwerk/base/nsSocketTransportService2.cpp @@ -227,7 +227,7 @@ nsSocketTransportService::AddToPollList(SocketContext *sock) } uint32_t newSocketIndex = mActiveCount; - if (ChaosMode::isActive(ChaosMode::NetworkScheduling)) { + if (ChaosMode::isActive(ChaosFeature::NetworkScheduling)) { newSocketIndex = ChaosMode::randomUint32LessThan(mActiveCount + 1); PodMove(mActiveList + newSocketIndex + 1, mActiveList + newSocketIndex, mActiveCount - newSocketIndex); diff --git a/netwerk/cache/nsCacheEntry.cpp b/netwerk/cache/nsCacheEntry.cpp index e3d32cad13..31b2c3faf4 100644 --- a/netwerk/cache/nsCacheEntry.cpp +++ b/netwerk/cache/nsCacheEntry.cpp @@ -420,7 +420,7 @@ nsCacheEntryHashTable::GetEntry( const nsCString * key) NS_ASSERTION(initialized, "nsCacheEntryHashTable not initialized"); if (!initialized) return nullptr; - PLDHashEntryHdr *hashEntry = PL_DHashTableSearch(&table, key); + PLDHashEntryHdr *hashEntry = table.Search(key); return hashEntry ? ((nsCacheEntryHashTableEntry *)hashEntry)->cacheEntry : nullptr; } diff --git a/netwerk/cache/nsDiskCacheBinding.cpp b/netwerk/cache/nsDiskCacheBinding.cpp index 61776a5cc2..b1eb204eb8 100644 --- a/netwerk/cache/nsDiskCacheBinding.cpp +++ b/netwerk/cache/nsDiskCacheBinding.cpp @@ -197,10 +197,8 @@ nsDiskCacheBindery::FindActiveBinding(uint32_t hashNumber) { NS_ASSERTION(initialized, "nsDiskCacheBindery not initialized"); // find hash entry for key - HashTableEntry * hashEntry; - hashEntry = - (HashTableEntry *) PL_DHashTableSearch(&table, - (void*)(uintptr_t) hashNumber); + auto hashEntry = static_cast + (table.Search((void*)(uintptr_t)hashNumber)); if (!hashEntry) return nullptr; // walk list looking for active entry @@ -294,11 +292,9 @@ nsDiskCacheBindery::RemoveBinding(nsDiskCacheBinding * binding) NS_ASSERTION(initialized, "nsDiskCacheBindery not initialized"); if (!initialized) return; - HashTableEntry * hashEntry; - void * key = (void *)(uintptr_t)binding->mRecord.HashNumber(); - - hashEntry = (HashTableEntry*) PL_DHashTableSearch(&table, - (void*)(uintptr_t) key); + void* key = (void *)(uintptr_t)binding->mRecord.HashNumber(); + auto hashEntry = + static_cast(table.Search((void*)(uintptr_t) key)); if (!hashEntry) { NS_WARNING("### disk cache: binding not in hashtable!"); return; diff --git a/netwerk/dns/nsHostResolver.cpp b/netwerk/dns/nsHostResolver.cpp index 30e61276f3..b5c123bf9f 100644 --- a/netwerk/dns/nsHostResolver.cpp +++ b/netwerk/dns/nsHostResolver.cpp @@ -827,8 +827,8 @@ nsHostResolver::ResolveHost(const char *host, // First, search for an entry with AF_UNSPEC const nsHostKey unspecKey = { host, flags, PR_AF_UNSPEC, netInterface }; - nsHostDBEnt *unspecHe = static_cast - (PL_DHashTableSearch(&mDB, &unspecKey)); + auto unspecHe = + static_cast(mDB.Search(&unspecKey)); NS_ASSERTION(!unspecHe || (unspecHe && unspecHe->rec), "Valid host entries should contain a record"); @@ -958,8 +958,7 @@ nsHostResolver::DetachCallback(const char *host, MutexAutoLock lock(mLock); nsHostKey key = { host, flags, af, netInterface }; - nsHostDBEnt *he = static_cast - (PL_DHashTableSearch(&mDB, &key)); + auto he = static_cast(mDB.Search(&key)); if (he) { // walk list looking for |callback|... we cannot assume // that it will be there! @@ -1292,8 +1291,7 @@ nsHostResolver::CancelAsyncRequest(const char *host, // Lookup the host record associated with host, flags & address family nsHostKey key = { host, flags, af, netInterface }; - nsHostDBEnt *he = static_cast - (PL_DHashTableSearch(&mDB, &key)); + auto he = static_cast(mDB.Search(&key)); if (he) { nsHostRecord* recPtr = nullptr; PRCList *node = he->rec->callbacks.next; diff --git a/netwerk/protocol/http/nsHttpConnection.cpp b/netwerk/protocol/http/nsHttpConnection.cpp index dd448dad7e..76853ca70d 100644 --- a/netwerk/protocol/http/nsHttpConnection.cpp +++ b/netwerk/protocol/http/nsHttpConnection.cpp @@ -1731,7 +1731,7 @@ nsHttpConnection::OnWriteSegment(char *buf, return NS_ERROR_FAILURE; // stop iterating } - if (ChaosMode::isActive(ChaosMode::IOAmounts) && + if (ChaosMode::isActive(ChaosFeature::IOAmounts) && ChaosMode::randomUint32LessThan(2)) { // read 1...count bytes count = ChaosMode::randomUint32LessThan(count) + 1; diff --git a/netwerk/protocol/http/nsHttpConnectionMgr.cpp b/netwerk/protocol/http/nsHttpConnectionMgr.cpp index 0907ab6bf3..090a4dced1 100644 --- a/netwerk/protocol/http/nsHttpConnectionMgr.cpp +++ b/netwerk/protocol/http/nsHttpConnectionMgr.cpp @@ -53,7 +53,7 @@ InsertTransactionSorted(nsTArray &pendingQ, nsHttpTransactio for (int32_t i=pendingQ.Length()-1; i>=0; --i) { nsHttpTransaction *t = pendingQ[i]; if (trans->Priority() >= t->Priority()) { - if (ChaosMode::isActive(ChaosMode::NetworkScheduling)) { + if (ChaosMode::isActive(ChaosFeature::NetworkScheduling)) { int32_t samePriorityCount; for (samePriorityCount = 0; i - samePriorityCount >= 0; ++samePriorityCount) { if (pendingQ[i - samePriorityCount]->Priority() != trans->Priority()) { diff --git a/parser/htmlparser/nsHTMLEntities.cpp b/parser/htmlparser/nsHTMLEntities.cpp index 7ac587b0ed..06db92ea92 100644 --- a/parser/htmlparser/nsHTMLEntities.cpp +++ b/parser/htmlparser/nsHTMLEntities.cpp @@ -147,9 +147,8 @@ nsHTMLEntities::EntityToUnicode(const nsCString& aEntity) return EntityToUnicode(temp); } - EntityNodeEntry* entry = - static_cast - (PL_DHashTableSearch(gEntityToUnicode, aEntity.get())); + auto entry = + static_cast(gEntityToUnicode->Search(aEntity.get())); return entry ? entry->node->mUnicode : -1; } @@ -170,9 +169,9 @@ const char* nsHTMLEntities::UnicodeToEntity(int32_t aUnicode) { NS_ASSERTION(gUnicodeToEntity, "no lookup table, needs addref"); - EntityNodeEntry* entry = + auto entry = static_cast - (PL_DHashTableSearch(gUnicodeToEntity, NS_INT32_TO_PTR(aUnicode))); + (gUnicodeToEntity->Search(NS_INT32_TO_PTR(aUnicode))); return entry ? entry->node->mStr : nullptr; } diff --git a/rdf/base/nsInMemoryDataSource.cpp b/rdf/base/nsInMemoryDataSource.cpp index bf36645cef..70739051ac 100644 --- a/rdf/base/nsInMemoryDataSource.cpp +++ b/rdf/base/nsInMemoryDataSource.cpp @@ -302,13 +302,13 @@ public: // Implementation methods Assertion* GetForwardArcs(nsIRDFResource* u) { - PLDHashEntryHdr* hdr = PL_DHashTableSearch(&mForwardArcs, u); + PLDHashEntryHdr* hdr = mForwardArcs.Search(u); return hdr ? static_cast(hdr)->mAssertions : nullptr; } Assertion* GetReverseArcs(nsIRDFNode* v) { - PLDHashEntryHdr* hdr = PL_DHashTableSearch(&mReverseArcs, v); + PLDHashEntryHdr* hdr = mReverseArcs.Search(v); return hdr ? static_cast(hdr)->mAssertions : nullptr; } @@ -421,8 +421,7 @@ InMemoryAssertionEnumeratorImpl::InMemoryAssertionEnumeratorImpl( if (mNextAssertion && mNextAssertion->mHashEntry) { // its our magical HASH_ENTRY forward hash for assertions PLDHashEntryHdr* hdr = - PL_DHashTableSearch(mNextAssertion->u.hash.mPropertyHash, - aProperty); + mNextAssertion->u.hash.mPropertyHash->Search(aProperty); mNextAssertion = hdr ? static_cast(hdr)->mAssertions : nullptr; } @@ -917,8 +916,7 @@ InMemoryDataSource::GetTarget(nsIRDFResource* source, Assertion *as = GetForwardArcs(source); if (as && as->mHashEntry) { - PLDHashEntryHdr* hdr = - PL_DHashTableSearch(as->u.hash.mPropertyHash, property); + PLDHashEntryHdr* hdr = as->u.hash.mPropertyHash->Search(property); Assertion* val = hdr ? static_cast(hdr)->mAssertions : nullptr; while (val) { if (tv == val->u.as.mTruthValue) { @@ -962,8 +960,7 @@ InMemoryDataSource::HasAssertion(nsIRDFResource* source, Assertion *as = GetForwardArcs(source); if (as && as->mHashEntry) { - PLDHashEntryHdr* hdr = - PL_DHashTableSearch(as->u.hash.mPropertyHash, property); + PLDHashEntryHdr* hdr = as->u.hash.mPropertyHash->Search(property); Assertion* val = hdr ? static_cast(hdr)->mAssertions : nullptr; while (val) { if ((val->u.as.mTarget == target) && (tv == (val->u.as.mTruthValue))) { @@ -1072,8 +1069,7 @@ InMemoryDataSource::LockedAssert(nsIRDFResource* aSource, bool haveHash = (next) ? next->mHashEntry : false; if (haveHash) { - PLDHashEntryHdr* hdr = - PL_DHashTableSearch(next->u.hash.mPropertyHash, aProperty); + PLDHashEntryHdr* hdr = next->u.hash.mPropertyHash->Search(aProperty); Assertion* val = hdr ? static_cast(hdr)->mAssertions : nullptr; while (val) { if (val->u.as.mTarget == aTarget) { @@ -1112,8 +1108,7 @@ InMemoryDataSource::LockedAssert(nsIRDFResource* aSource, if (haveHash) { - PLDHashEntryHdr* hdr = - PL_DHashTableSearch(next->u.hash.mPropertyHash, aProperty); + PLDHashEntryHdr* hdr = next->u.hash.mPropertyHash->Search(aProperty); Assertion *asRef = hdr ? static_cast(hdr)->mAssertions : nullptr; if (asRef) @@ -1211,8 +1206,7 @@ InMemoryDataSource::LockedUnassert(nsIRDFResource* aSource, bool haveHash = (next) ? next->mHashEntry : false; if (haveHash) { - PLDHashEntryHdr* hdr = - PL_DHashTableSearch(next->u.hash.mPropertyHash, aProperty); + PLDHashEntryHdr* hdr = next->u.hash.mPropertyHash->Search(aProperty); prev = next = hdr ? static_cast(hdr)->mAssertions : nullptr; bool first = true; while (next) { @@ -1513,8 +1507,7 @@ InMemoryDataSource::HasArcOut(nsIRDFResource *aSource, nsIRDFResource *aArc, boo { Assertion* ass = GetForwardArcs(aSource); if (ass && ass->mHashEntry) { - PLDHashEntryHdr* hdr = - PL_DHashTableSearch(ass->u.hash.mPropertyHash, aArc); + PLDHashEntryHdr* hdr = ass->u.hash.mPropertyHash->Search(aArc); Assertion* val = hdr ? static_cast(hdr)->mAssertions : nullptr; if (val) { *result = true; @@ -1664,7 +1657,7 @@ InMemoryDataSource::EnsureFastContainment(nsIRDFResource* aSource) nextRef = first->mNext; nsIRDFResource *prop = first->u.as.mProperty; - PLDHashEntryHdr* hdr = PL_DHashTableSearch(table, prop); + PLDHashEntryHdr* hdr = table->Search(prop); Assertion* val = hdr ? static_cast(hdr)->mAssertions : nullptr; if (val) { first->mNext = val->mNext; @@ -1727,8 +1720,7 @@ InMemoryDataSource::Mark(nsIRDFResource* aSource, Assertion *as = GetForwardArcs(aSource); if (as && as->mHashEntry) { - PLDHashEntryHdr* hdr = - PL_DHashTableSearch(as->u.hash.mPropertyHash, aProperty); + PLDHashEntryHdr* hdr = as->u.hash.mPropertyHash->Search(aProperty); Assertion* val = hdr ? static_cast(hdr)->mAssertions : nullptr; while (val) { if ((val->u.as.mTarget == aTarget) && @@ -1844,7 +1836,7 @@ InMemoryDataSource::SweepForwardArcsEntries(PLDHashTable* aTable, // remove from the reverse arcs PLDHashEntryHdr* hdr = - PL_DHashTableSearch(aInfo->mReverseArcs, as->u.as.mTarget); + aInfo->mReverseArcs->Search(as->u.as.mTarget); NS_ASSERTION(hdr, "no assertion in reverse arcs"); Entry* rentry = static_cast(hdr); diff --git a/rdf/base/nsRDFService.cpp b/rdf/base/nsRDFService.cpp index ee7401eeec..a054ae1ae2 100644 --- a/rdf/base/nsRDFService.cpp +++ b/rdf/base/nsRDFService.cpp @@ -838,7 +838,7 @@ RDFServiceImpl::GetResource(const nsACString& aURI, nsIRDFResource** aResource) // First, check the cache to see if we've already created and // registered this thing. - PLDHashEntryHdr *hdr = PL_DHashTableSearch(&mResources, flatURI.get()); + PLDHashEntryHdr *hdr = mResources.Search(flatURI.get()); if (hdr) { ResourceHashEntry *entry = static_cast(hdr); NS_ADDREF(*aResource = entry->mResource); @@ -1006,7 +1006,7 @@ RDFServiceImpl::GetLiteral(const char16_t* aValue, nsIRDFLiteral** aLiteral) return NS_ERROR_NULL_POINTER; // See if we have one already cached - PLDHashEntryHdr *hdr = PL_DHashTableSearch(&mLiterals, aValue); + PLDHashEntryHdr *hdr = mLiterals.Search(aValue); if (hdr) { LiteralHashEntry *entry = static_cast(hdr); NS_ADDREF(*aLiteral = entry->mLiteral); @@ -1021,7 +1021,7 @@ NS_IMETHODIMP RDFServiceImpl::GetDateLiteral(PRTime aTime, nsIRDFDate** aResult) { // See if we have one already cached - PLDHashEntryHdr *hdr = PL_DHashTableSearch(&mDates, &aTime); + PLDHashEntryHdr *hdr = mDates.Search(&aTime); if (hdr) { DateHashEntry *entry = static_cast(hdr); NS_ADDREF(*aResult = entry->mDate); @@ -1040,7 +1040,7 @@ NS_IMETHODIMP RDFServiceImpl::GetIntLiteral(int32_t aInt, nsIRDFInt** aResult) { // See if we have one already cached - PLDHashEntryHdr *hdr = PL_DHashTableSearch(&mInts, &aInt); + PLDHashEntryHdr *hdr = mInts.Search(&aInt); if (hdr) { IntHashEntry *entry = static_cast(hdr); NS_ADDREF(*aResult = entry->mInt); @@ -1061,7 +1061,7 @@ RDFServiceImpl::GetBlobLiteral(const uint8_t *aBytes, int32_t aLength, { BlobImpl::Data key = { aLength, const_cast(aBytes) }; - PLDHashEntryHdr *hdr = PL_DHashTableSearch(&mBlobs, &key); + PLDHashEntryHdr *hdr = mBlobs.Search(&key); if (hdr) { BlobHashEntry *entry = static_cast(hdr); NS_ADDREF(*aResult = entry->mBlob); @@ -1122,7 +1122,7 @@ RDFServiceImpl::RegisterResource(nsIRDFResource* aResource, bool aReplace) if (! uri) return NS_ERROR_NULL_POINTER; - PLDHashEntryHdr *hdr = PL_DHashTableSearch(&mResources, uri); + PLDHashEntryHdr *hdr = mResources.Search(uri); if (hdr) { if (!aReplace) { NS_WARNING("resource already registered, and replace not specified"); @@ -1181,7 +1181,7 @@ RDFServiceImpl::UnregisterResource(nsIRDFResource* aResource) aResource, (const char*) uri)); #ifdef DEBUG - if (!PL_DHashTableSearch(&mResources, uri)) + if (!mResources.Search(uri)) NS_WARNING("resource was never registered"); #endif @@ -1373,8 +1373,7 @@ RDFServiceImpl::RegisterLiteral(nsIRDFLiteral* aLiteral) const char16_t* value; aLiteral->GetValueConst(&value); - NS_ASSERTION(!PL_DHashTableSearch(&mLiterals, value), - "literal already registered"); + NS_ASSERTION(!mLiterals.Search(value), "literal already registered"); PLDHashEntryHdr *hdr = PL_DHashTableAdd(&mLiterals, value, fallible); if (! hdr) @@ -1403,8 +1402,7 @@ RDFServiceImpl::UnregisterLiteral(nsIRDFLiteral* aLiteral) const char16_t* value; aLiteral->GetValueConst(&value); - NS_ASSERTION(PL_DHashTableSearch(&mLiterals, value), - "literal was never registered"); + NS_ASSERTION(mLiterals.Search(value), "literal was never registered"); PL_DHashTableRemove(&mLiterals, value); @@ -1425,8 +1423,7 @@ RDFServiceImpl::RegisterInt(nsIRDFInt* aInt) int32_t value; aInt->GetValue(&value); - NS_ASSERTION(!PL_DHashTableSearch(&mInts, &value), - "int already registered"); + NS_ASSERTION(!mInts.Search(&value), "int already registered"); PLDHashEntryHdr *hdr = PL_DHashTableAdd(&mInts, &value, fallible); if (! hdr) @@ -1455,8 +1452,7 @@ RDFServiceImpl::UnregisterInt(nsIRDFInt* aInt) int32_t value; aInt->GetValue(&value); - NS_ASSERTION(PL_DHashTableSearch(&mInts, &value), - "int was never registered"); + NS_ASSERTION(mInts.Search(&value), "int was never registered"); PL_DHashTableRemove(&mInts, &value); @@ -1477,8 +1473,7 @@ RDFServiceImpl::RegisterDate(nsIRDFDate* aDate) PRTime value; aDate->GetValue(&value); - NS_ASSERTION(!PL_DHashTableSearch(&mDates, &value), - "date already registered"); + NS_ASSERTION(!mDates.Search(&value), "date already registered"); PLDHashEntryHdr *hdr = PL_DHashTableAdd(&mDates, &value, fallible); if (! hdr) @@ -1507,8 +1502,7 @@ RDFServiceImpl::UnregisterDate(nsIRDFDate* aDate) PRTime value; aDate->GetValue(&value); - NS_ASSERTION(PL_DHashTableSearch(&mDates, &value), - "date was never registered"); + NS_ASSERTION(mDates.Search(&value), "date was never registered"); PL_DHashTableRemove(&mDates, &value); @@ -1524,8 +1518,7 @@ RDFServiceImpl::UnregisterDate(nsIRDFDate* aDate) nsresult RDFServiceImpl::RegisterBlob(BlobImpl *aBlob) { - NS_ASSERTION(!PL_DHashTableSearch(&mBlobs, &aBlob->mData), - "blob already registered"); + NS_ASSERTION(!mBlobs.Search(&aBlob->mData), "blob already registered"); PLDHashEntryHdr *hdr = PL_DHashTableAdd(&mBlobs, &aBlob->mData, fallible); if (! hdr) @@ -1549,8 +1542,7 @@ RDFServiceImpl::RegisterBlob(BlobImpl *aBlob) nsresult RDFServiceImpl::UnregisterBlob(BlobImpl *aBlob) { - NS_ASSERTION(PL_DHashTableSearch(&mBlobs, &aBlob->mData), - "blob was never registered"); + NS_ASSERTION(mBlobs.Search(&aBlob->mData), "blob was never registered"); PL_DHashTableRemove(&mBlobs, &aBlob->mData); diff --git a/security/manager/ssl/nsSecureBrowserUIImpl.cpp b/security/manager/ssl/nsSecureBrowserUIImpl.cpp index bfeca26293..e6b2ce3d2d 100644 --- a/security/manager/ssl/nsSecureBrowserUIImpl.cpp +++ b/security/manager/ssl/nsSecureBrowserUIImpl.cpp @@ -865,8 +865,9 @@ nsSecureBrowserUIImpl::OnStateChange(nsIWebProgress* aWebProgress, { { /* scope for the ReentrantMonitorAutoEnter */ ReentrantMonitorAutoEnter lock(mReentrantMonitor); - if (PL_DHashTableSearch(&mTransferringRequests, aRequest)) { - PL_DHashTableRemove(&mTransferringRequests, aRequest); + PLDHashEntryHdr* entry = mTransferringRequests.Search(aRequest); + if (entry) { + mTransferringRequests.RemoveEntry(entry); requestHasTransferedData = true; } } diff --git a/toolkit/components/satchel/nsFormFillController.cpp b/toolkit/components/satchel/nsFormFillController.cpp index 16472df7ca..befb535e02 100644 --- a/toolkit/components/satchel/nsFormFillController.cpp +++ b/toolkit/components/satchel/nsFormFillController.cpp @@ -114,7 +114,8 @@ void nsFormFillController::AttributeChanged(nsIDocument* aDocument, mozilla::dom::Element* aElement, int32_t aNameSpaceID, - nsIAtom* aAttribute, int32_t aModType) + nsIAtom* aAttribute, int32_t aModType, + const nsAttrValue* aOldValue) { if ((aAttribute == nsGkAtoms::type || aAttribute == nsGkAtoms::readonly || aAttribute == nsGkAtoms::autocomplete) && @@ -188,7 +189,8 @@ void nsFormFillController::AttributeWillChange(nsIDocument* aDocument, mozilla::dom::Element* aElement, int32_t aNameSpaceID, - nsIAtom* aAttribute, int32_t aModType) + nsIAtom* aAttribute, int32_t aModType, + const nsAttrValue* aNewValue) { } diff --git a/toolkit/components/telemetry/Telemetry.cpp b/toolkit/components/telemetry/Telemetry.cpp index c00d4165c0..4c5f20ca17 100644 --- a/toolkit/components/telemetry/Telemetry.cpp +++ b/toolkit/components/telemetry/Telemetry.cpp @@ -102,7 +102,8 @@ template class AutoHashtable : public nsTHashtable { public: - explicit AutoHashtable(uint32_t initLength = PL_DHASH_DEFAULT_INITIAL_LENGTH); + explicit AutoHashtable(uint32_t initLength = + PLDHashTable::kDefaultInitialLength); typedef bool (*ReflectEntryFunc)(EntryType *entry, JSContext *cx, JS::Handle obj); bool ReflectIntoJS(ReflectEntryFunc entryFunc, JSContext *cx, JS::Handle obj); private: diff --git a/toolkit/content/widgets/notification.xml b/toolkit/content/widgets/notification.xml index caa3a94cb2..0db112993c 100644 --- a/toolkit/content/widgets/notification.xml +++ b/toolkit/content/widgets/notification.xml @@ -496,12 +496,6 @@ - - - diff --git a/toolkit/xre/nsAppRunner.cpp b/toolkit/xre/nsAppRunner.cpp index de23484a7b..92f40064dc 100644 --- a/toolkit/xre/nsAppRunner.cpp +++ b/toolkit/xre/nsAppRunner.cpp @@ -2754,7 +2754,17 @@ XREMain::XRE_mainInit(bool* aExitFlag) StartupTimeline::Record(StartupTimeline::MAIN); - if (ChaosMode::isActive(ChaosMode::Any)) { + if (PR_GetEnv("MOZ_CHAOSMODE")) { + ChaosFeature feature = ChaosFeature::Any; + long featureInt = strtol(PR_GetEnv("MOZ_CHAOSMODE"), nullptr, 16); + if (featureInt) { + // NOTE: MOZ_CHAOSMODE=0 or a non-hex value maps to Any feature. + feature = static_cast(featureInt); + } + ChaosMode::SetChaosFeature(feature); + } + + if (ChaosMode::isActive(ChaosFeature::Any)) { printf_stderr("*** You are running in chaos test mode. See ChaosMode.h. ***\n"); } diff --git a/toolkit/xre/nsSigHandlers.cpp b/toolkit/xre/nsSigHandlers.cpp index d6846afbe9..26aa9ef573 100644 --- a/toolkit/xre/nsSigHandlers.cpp +++ b/toolkit/xre/nsSigHandlers.cpp @@ -38,7 +38,9 @@ #endif static char _progname[1024] = "huh?"; -static unsigned int _gdb_sleep_duration = 300; + +// Note: some tests manipulate this value. +unsigned int _gdb_sleep_duration = 300; #if defined(LINUX) && defined(DEBUG) && \ (defined(__i386) || defined(__x86_64) || defined(PPC)) diff --git a/uriloader/base/nsDocLoader.cpp b/uriloader/base/nsDocLoader.cpp index 0dfb64cb8d..506a5198dc 100644 --- a/uriloader/base/nsDocLoader.cpp +++ b/uriloader/base/nsDocLoader.cpp @@ -1336,8 +1336,7 @@ void nsDocLoader::RemoveRequestInfo(nsIRequest *aRequest) nsDocLoader::nsRequestInfo* nsDocLoader::GetRequestInfo(nsIRequest* aRequest) { - return static_cast - (PL_DHashTableSearch(&mRequestInfoHash, aRequest)); + return static_cast(mRequestInfoHash.Search(aRequest)); } void nsDocLoader::ClearRequestInfoHash(void) diff --git a/widget/cocoa/nsMenuGroupOwnerX.mm b/widget/cocoa/nsMenuGroupOwnerX.mm index 3afde7221b..c8a70ce56c 100644 --- a/widget/cocoa/nsMenuGroupOwnerX.mm +++ b/widget/cocoa/nsMenuGroupOwnerX.mm @@ -91,7 +91,8 @@ void nsMenuGroupOwnerX::AttributeWillChange(nsIDocument* aDocument, dom::Element* aContent, int32_t aNameSpaceID, nsIAtom* aAttribute, - int32_t aModType) + int32_t aModType, + const nsAttrValue* aNewValue) { } @@ -100,7 +101,8 @@ void nsMenuGroupOwnerX::AttributeChanged(nsIDocument* aDocument, dom::Element* aElement, int32_t aNameSpaceID, nsIAtom* aAttribute, - int32_t aModType) + int32_t aModType, + const nsAttrValue* aOldValue) { nsCOMPtr kungFuDeathGrip(this); nsChangeObserver* obs = LookupContentChangeObserver(aElement); diff --git a/widget/nsBaseAppShell.cpp b/widget/nsBaseAppShell.cpp index 8e5ddaa428..2bd7b92e1f 100644 --- a/widget/nsBaseAppShell.cpp +++ b/widget/nsBaseAppShell.cpp @@ -14,7 +14,7 @@ // When processing the next thread event, the appshell may process native // events (if not in performance mode), which can result in suppressing the // next thread event for at most this many ticks: -#define THREAD_EVENT_STARVATION_LIMIT PR_MillisecondsToInterval(20) +#define THREAD_EVENT_STARVATION_LIMIT PR_MillisecondsToInterval(10) NS_IMPL_ISUPPORTS(nsBaseAppShell, nsIAppShell, nsIThreadObserver, nsIObserver) diff --git a/xpcom/base/nsCycleCollector.cpp b/xpcom/base/nsCycleCollector.cpp index 48266186b2..07556be5bc 100644 --- a/xpcom/base/nsCycleCollector.cpp +++ b/xpcom/base/nsCycleCollector.cpp @@ -858,9 +858,10 @@ public: } #endif + PtrToNodeEntry* FindNodeEntry(void* aPtr); PtrInfo* FindNode(void* aPtr); PtrToNodeEntry* AddNodeToMap(void* aPtr); - void RemoveNodeFromMap(void* aPtr); + void RemoveNodeFromMap(PtrToNodeEntry* aPtr); uint32_t MapCount() const { @@ -880,11 +881,17 @@ public: } }; +PtrToNodeEntry* +CCGraph::FindNodeEntry(void* aPtr) +{ + return + static_cast(mPtrToNodeMap.Search(aPtr)); +} + PtrInfo* CCGraph::FindNode(void* aPtr) { - PtrToNodeEntry* e = - static_cast(PL_DHashTableSearch(&mPtrToNodeMap, aPtr)); + PtrToNodeEntry* e = FindNodeEntry(aPtr); return e ? e->mNode : nullptr; } @@ -907,9 +914,9 @@ CCGraph::AddNodeToMap(void* aPtr) } void -CCGraph::RemoveNodeFromMap(void* aPtr) +CCGraph::RemoveNodeFromMap(PtrToNodeEntry* aEntry) { - PL_DHashTableRemove(&mPtrToNodeMap, aPtr); + mPtrToNodeMap.RemoveEntry(aEntry); } @@ -3846,8 +3853,10 @@ nsCycleCollector::RemoveObjectFromGraph(void* aObj) return; } - if (PtrInfo* pinfo = mGraph.FindNode(aObj)) { - mGraph.RemoveNodeFromMap(aObj); + PtrToNodeEntry* e = mGraph.FindNodeEntry(aObj); + PtrInfo* pinfo = e ? e->mNode : nullptr; + if (pinfo) { + mGraph.RemoveNodeFromMap(e); pinfo->mPointer = nullptr; pinfo->mParticipant = nullptr; diff --git a/xpcom/ds/nsPersistentProperties.cpp b/xpcom/ds/nsPersistentProperties.cpp index b2e7838c86..80fd07dcf3 100644 --- a/xpcom/ds/nsPersistentProperties.cpp +++ b/xpcom/ds/nsPersistentProperties.cpp @@ -551,9 +551,7 @@ nsPersistentProperties::GetStringProperty(const nsACString& aKey, { const nsAFlatCString& flatKey = PromiseFlatCString(aKey); - PropertyTableEntry* entry = static_cast( - PL_DHashTableSearch(&mTable, flatKey.get())); - + auto entry = static_cast(mTable.Search(flatKey.get())); if (!entry) { return NS_ERROR_FAILURE; } @@ -611,7 +609,7 @@ nsPersistentProperties::Undefine(const char* aProp) NS_IMETHODIMP nsPersistentProperties::Has(const char* aProp, bool* aResult) { - *aResult = !!PL_DHashTableSearch(&mTable, aProp); + *aResult = !!mTable.Search(aProp); return NS_OK; } diff --git a/xpcom/ds/nsStaticNameTable.cpp b/xpcom/ds/nsStaticNameTable.cpp index c4fc1ee319..cec5613931 100644 --- a/xpcom/ds/nsStaticNameTable.cpp +++ b/xpcom/ds/nsStaticNameTable.cpp @@ -170,8 +170,7 @@ nsStaticCaseInsensitiveNameTable::Lookup(const nsACString& aName) const nsAFlatCString& str = PromiseFlatCString(aName); NameTableKey key(&str); - NameTableEntry* entry = - static_cast(PL_DHashTableSearch(&mNameTable, &key)); + auto entry = static_cast(mNameTable.Search(&key)); return entry ? entry->mIndex : nsStaticCaseInsensitiveNameTable::NOT_FOUND; } @@ -184,8 +183,7 @@ nsStaticCaseInsensitiveNameTable::Lookup(const nsAString& aName) const nsAFlatString& str = PromiseFlatString(aName); NameTableKey key(&str); - NameTableEntry* entry = - static_cast(PL_DHashTableSearch(&mNameTable, &key)); + auto entry = static_cast(mNameTable.Search(&key)); return entry ? entry->mIndex : nsStaticCaseInsensitiveNameTable::NOT_FOUND; } diff --git a/xpcom/glue/nsTHashtable.cpp b/xpcom/glue/nsTHashtable.cpp deleted file mode 100644 index e02cd7d871..0000000000 --- a/xpcom/glue/nsTHashtable.cpp +++ /dev/null @@ -1,16 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "nsTHashtable.h" - -PLDHashOperator -PL_DHashStubEnumRemove(PLDHashTable* aTable, - PLDHashEntryHdr* aEntry, - uint32_t aOrdinal, - void* aUserarg) -{ - return PL_DHASH_REMOVE; -} diff --git a/xpcom/glue/nsTHashtable.h b/xpcom/glue/nsTHashtable.h index d588e295f6..046a8e05b6 100644 --- a/xpcom/glue/nsTHashtable.h +++ b/xpcom/glue/nsTHashtable.h @@ -20,13 +20,6 @@ #include -// helper function for nsTHashtable::Clear() -PLDHashOperator PL_DHashStubEnumRemove(PLDHashTable* aTable, - PLDHashEntryHdr* aEntry, - uint32_t aOrdinal, - void* aUserArg); - - /** * a base class for templated hashtables. * @@ -79,6 +72,16 @@ PLDHashOperator PL_DHashStubEnumRemove(PLDHashTable* aTable, * @author "Benjamin Smedberg " */ +// These are the codes returned by |Enumerator| functions, which control +// EnumerateEntry()'s behavior. The PLD/PL_D prefix is because they originated +// in PLDHashTable, but that class no longer uses them. +enum PLDHashOperator +{ + PL_DHASH_NEXT = 0, // enumerator says continue + PL_DHASH_STOP = 1, // enumerator says stop + PL_DHASH_REMOVE = 2 // enumerator says remove +}; + template class MOZ_NEEDS_NO_VTABLE_TYPE nsTHashtable { @@ -88,7 +91,7 @@ public: // Separate constructors instead of default aInitLength parameter since // otherwise the default no-arg constructor isn't found. nsTHashtable() - : mTable(Ops(), sizeof(EntryType), PL_DHASH_DEFAULT_INITIAL_LENGTH) + : mTable(Ops(), sizeof(EntryType), PLDHashTable::kDefaultInitialLength) {} explicit nsTHashtable(uint32_t aInitLength) : mTable(Ops(), sizeof(EntryType), aInitLength) @@ -132,8 +135,7 @@ public: EntryType* GetEntry(KeyType aKey) const { return static_cast( - PL_DHashTableSearch(const_cast(&mTable), - EntryType::KeyToPointer(aKey))); + const_cast(&mTable)->Search(EntryType::KeyToPointer(aKey))); } /** @@ -199,7 +201,10 @@ public: typedef PLDHashOperator (*Enumerator)(EntryType* aEntry, void* userArg); /** - * Enumerate all the entries of the function. + * Enumerate all the entries of the function. If any entries are removed via + * a PL_DHASH_REMOVE return value from |aEnumFunc|, the table may be shrunk + * at the end. Use RawRemoveEntry() instead if you wish to remove an entry + * without possibly shrinking the table. * @param enumFunc the Enumerator function to call * @param userArg a pointer to pass to the * Enumerator function @@ -223,11 +228,13 @@ public: } /** - * remove all entries, return hashtable to "pristine" state ;) + * Remove all entries, return hashtable to "pristine" state. It's + * conceptually the same as calling the destructor and then re-calling the + * constructor. */ void Clear() { - PL_DHashTableEnumerate(&mTable, PL_DHashStubEnumRemove, nullptr); + mTable.Clear(); } /** diff --git a/xpcom/glue/objs.mozbuild b/xpcom/glue/objs.mozbuild index 0b21f405e4..3c4f0d2172 100644 --- a/xpcom/glue/objs.mozbuild +++ b/xpcom/glue/objs.mozbuild @@ -25,7 +25,6 @@ xpcom_glue_src_lcppsrcs = [ 'nsMemory.cpp', 'nsQuickSort.cpp', 'nsTArray.cpp', - 'nsTHashtable.cpp', 'nsThreadUtils.cpp', 'nsTObserverArray.cpp', 'nsVersionComparator.cpp', diff --git a/xpcom/glue/pldhash.cpp b/xpcom/glue/pldhash.cpp index 74f49207a7..eb24d3f99c 100644 --- a/xpcom/glue/pldhash.cpp +++ b/xpcom/glue/pldhash.cpp @@ -4,9 +4,6 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -/* - * Double hashing implementation. - */ #include #include #include @@ -14,7 +11,6 @@ #include "pldhash.h" #include "mozilla/HashFunctions.h" #include "mozilla/MathAlgorithms.h" -#include "nsDebug.h" /* for PR_ASSERT */ #include "nsAlgorithm.h" #include "mozilla/Likely.h" #include "mozilla/MemoryReporting.h" @@ -95,7 +91,7 @@ PL_DHashMatchStringKey(PLDHashTable* aTable, { const PLDHashEntryStub* stub = (const PLDHashEntryStub*)aEntry; - /* XXX tolerate null keys on account of sloppy Mozilla callers. */ + // XXX tolerate null keys on account of sloppy Mozilla callers. return stub->key == aKey || (stub->key && aKey && strcmp((const char*)stub->key, (const char*)aKey) == 0); @@ -150,13 +146,11 @@ SizeOfEntryStore(uint32_t aCapacity, uint32_t aEntrySize, uint32_t* aNbytes) return uint64_t(*aNbytes) == nbytes64; // returns false on overflow } -/* - * Compute max and min load numbers (entry counts). We have a secondary max - * that allows us to overload a table reasonably if it cannot be grown further - * (i.e. if ChangeTable() fails). The table slows down drastically if the - * secondary max is too close to 1, but 0.96875 gives only a slight slowdown - * while allowing 1.3x more elements. - */ +// Compute max and min load numbers (entry counts). We have a secondary max +// that allows us to overload a table reasonably if it cannot be grown further +// (i.e. if ChangeTable() fails). The table slows down drastically if the +// secondary max is too close to 1, but 0.96875 gives only a slight slowdown +// while allowing 1.3x more elements. static inline uint32_t MaxLoad(uint32_t aCapacity) { @@ -185,23 +179,23 @@ BestCapacity(uint32_t aLength, uint32_t* aCapacityOut, // Compute the smallest capacity allowing |aLength| elements to be inserted // without rehashing. uint32_t capacity = (aLength * 4 + (3 - 1)) / 3; // == ceil(aLength * 4 / 3) - if (capacity < PL_DHASH_MIN_CAPACITY) { - capacity = PL_DHASH_MIN_CAPACITY; + if (capacity < PLDHashTable::kMinCapacity) { + capacity = PLDHashTable::kMinCapacity; } // Round up capacity to next power-of-two. uint32_t log2 = CeilingLog2(capacity); capacity = 1u << log2; - MOZ_ASSERT(capacity <= PL_DHASH_MAX_CAPACITY); + MOZ_ASSERT(capacity <= PLDHashTable::kMaxCapacity); *aCapacityOut = capacity; *aLog2CapacityOut = log2; } -static MOZ_ALWAYS_INLINE uint32_t -HashShift(uint32_t aEntrySize, uint32_t aLength) +/* static */ MOZ_ALWAYS_INLINE uint32_t +PLDHashTable::HashShift(uint32_t aEntrySize, uint32_t aLength) { - if (aLength > PL_DHASH_MAX_INITIAL_LENGTH) { + if (aLength > kMaxInitialLength) { MOZ_CRASH("Initial length is too large"); } @@ -214,7 +208,7 @@ HashShift(uint32_t aEntrySize, uint32_t aLength) } // Compute the hashShift value. - return PL_DHASH_BITS - log2; + return kHashBits - log2; } PLDHashTable::PLDHashTable(const PLDHashTableOps* aOps, uint32_t aEntrySize, @@ -271,41 +265,70 @@ PLDHashTable::operator=(PLDHashTable&& aOther) return *this; } -/* - * Double hashing needs the second hash code to be relatively prime to table - * size, so we simply make hash2 odd. - */ -#define HASH1(hash0, shift) ((hash0) >> (shift)) -#define HASH2(hash0,log2,shift) ((((hash0) << (log2)) >> (shift)) | 1) +PLDHashNumber +PLDHashTable::Hash1(PLDHashNumber aHash0) +{ + return aHash0 >> mHashShift; +} -/* - * Reserve mKeyHash 0 for free entries and 1 for removed-entry sentinels. Note - * that a removed-entry sentinel need be stored only if the removed entry had - * a colliding entry added after it. Therefore we can use 1 as the collision - * flag in addition to the removed-entry sentinel value. Multiplicative hash - * uses the high order bits of mKeyHash, so this least-significant reservation - * should not hurt the hash function's effectiveness much. - */ -#define COLLISION_FLAG ((PLDHashNumber) 1) -#define MARK_ENTRY_FREE(entry) ((entry)->mKeyHash = 0) -#define MARK_ENTRY_REMOVED(entry) ((entry)->mKeyHash = 1) -#define ENTRY_IS_REMOVED(entry) ((entry)->mKeyHash == 1) -#define ENTRY_IS_LIVE(entry) ((entry)->mKeyHash >= 2) -#define ENSURE_LIVE_KEYHASH(hash0) if (hash0 < 2) hash0 -= 2; else (void)0 +// Double hashing needs the second hash code to be relatively prime to table +// size, so we simply make hash2 odd. +void +PLDHashTable::Hash2(PLDHashNumber aHash, + uint32_t& aHash2Out, uint32_t& aSizeMaskOut) +{ + uint32_t sizeLog2 = kHashBits - mHashShift; + aHash2Out = ((aHash << sizeLog2) >> mHashShift) | 1; + aSizeMaskOut = (PLDHashNumber(1) << sizeLog2) - 1; +} -/* Match an entry's mKeyHash against an unstored one computed from a key. */ -#define MATCH_ENTRY_KEYHASH(entry,hash0) \ - (((entry)->mKeyHash & ~COLLISION_FLAG) == (hash0)) - -/* Compute the address of the indexed entry in table. */ -#define ADDRESS_ENTRY(table, index) \ - ((PLDHashEntryHdr *)((table)->mEntryStore + (index) * (table)->mEntrySize)) +// Reserve mKeyHash 0 for free entries and 1 for removed-entry sentinels. Note +// that a removed-entry sentinel need be stored only if the removed entry had +// a colliding entry added after it. Therefore we can use 1 as the collision +// flag in addition to the removed-entry sentinel value. Multiplicative hash +// uses the high order bits of mKeyHash, so this least-significant reservation +// should not hurt the hash function's effectiveness much. /* static */ MOZ_ALWAYS_INLINE bool PLDHashTable::EntryIsFree(PLDHashEntryHdr* aEntry) { return aEntry->mKeyHash == 0; } +/* static */ MOZ_ALWAYS_INLINE bool +PLDHashTable::EntryIsRemoved(PLDHashEntryHdr* aEntry) +{ + return aEntry->mKeyHash == 1; +} +/* static */ MOZ_ALWAYS_INLINE bool +PLDHashTable::EntryIsLive(PLDHashEntryHdr* aEntry) +{ + return aEntry->mKeyHash >= 2; +} + +/* static */ MOZ_ALWAYS_INLINE void +PLDHashTable::MarkEntryFree(PLDHashEntryHdr* aEntry) +{ + aEntry->mKeyHash = 0; +} +/* static */ MOZ_ALWAYS_INLINE void +PLDHashTable::MarkEntryRemoved(PLDHashEntryHdr* aEntry) +{ + aEntry->mKeyHash = 1; +} + +// Match an entry's mKeyHash against an unstored one computed from a key. +/* static */ bool +PLDHashTable::MatchEntryKeyhash(PLDHashEntryHdr* aEntry, PLDHashNumber aKeyHash) +{ + return (aEntry->mKeyHash & ~kCollisionFlag) == aKeyHash; +} + +// Compute the address of the indexed entry in table. +PLDHashEntryHdr* +PLDHashTable::AddressEntry(uint32_t aIndex) +{ + return reinterpret_cast(mEntryStore + aIndex * mEntrySize); +} PLDHashTable::~PLDHashTable() { @@ -317,18 +340,18 @@ PLDHashTable::~PLDHashTable() return; } - /* Clear any remaining live entries. */ + // Clear any remaining live entries. char* entryAddr = mEntryStore; char* entryLimit = entryAddr + Capacity() * mEntrySize; while (entryAddr < entryLimit) { PLDHashEntryHdr* entry = (PLDHashEntryHdr*)entryAddr; - if (ENTRY_IS_LIVE(entry)) { + if (EntryIsLive(entry)) { mOps->clearEntry(this, entry); } entryAddr += mEntrySize; } - /* Free entry storage last. */ + // Free entry storage last. free(mEntryStore); mEntryStore = nullptr; } @@ -347,7 +370,7 @@ PLDHashTable::ClearAndPrepareForLength(uint32_t aLength) void PLDHashTable::Clear() { - ClearAndPrepareForLength(PL_DHASH_DEFAULT_INITIAL_LENGTH); + ClearAndPrepareForLength(kDefaultInitialLength); } // If |IsAdd| is true, the return value is always non-null and it may be a @@ -360,112 +383,107 @@ PLDHashEntryHdr* PL_DHASH_FASTCALL PLDHashTable::SearchTable(const void* aKey, PLDHashNumber aKeyHash) { MOZ_ASSERT(mEntryStore); - NS_ASSERTION(!(aKeyHash & COLLISION_FLAG), - "!(aKeyHash & COLLISION_FLAG)"); + NS_ASSERTION(!(aKeyHash & kCollisionFlag), + "!(aKeyHash & kCollisionFlag)"); - /* Compute the primary hash address. */ - PLDHashNumber hash1 = HASH1(aKeyHash, mHashShift); - PLDHashEntryHdr* entry = ADDRESS_ENTRY(this, hash1); + // Compute the primary hash address. + PLDHashNumber hash1 = Hash1(aKeyHash); + PLDHashEntryHdr* entry = AddressEntry(hash1); - /* Miss: return space for a new entry. */ + // Miss: return space for a new entry. if (EntryIsFree(entry)) { return (Reason == ForAdd) ? entry : nullptr; } - /* Hit: return entry. */ + // Hit: return entry. PLDHashMatchEntry matchEntry = mOps->matchEntry; - if (MATCH_ENTRY_KEYHASH(entry, aKeyHash) && + if (MatchEntryKeyhash(entry, aKeyHash) && matchEntry(this, entry, aKey)) { return entry; } - /* Collision: double hash. */ - int sizeLog2 = PL_DHASH_BITS - mHashShift; - PLDHashNumber hash2 = HASH2(aKeyHash, sizeLog2, mHashShift); - uint32_t sizeMask = (1u << sizeLog2) - 1; + // Collision: double hash. + PLDHashNumber hash2; + uint32_t sizeMask; + Hash2(aKeyHash, hash2, sizeMask); - /* - * Save the first removed entry pointer so Add() can recycle it. (Only used - * if Reason==ForAdd.) - */ + // Save the first removed entry pointer so Add() can recycle it. (Only used + // if Reason==ForAdd.) PLDHashEntryHdr* firstRemoved = nullptr; for (;;) { if (Reason == ForAdd) { - if (MOZ_UNLIKELY(ENTRY_IS_REMOVED(entry))) { + if (MOZ_UNLIKELY(EntryIsRemoved(entry))) { if (!firstRemoved) { firstRemoved = entry; } } else { - entry->mKeyHash |= COLLISION_FLAG; + entry->mKeyHash |= kCollisionFlag; } } hash1 -= hash2; hash1 &= sizeMask; - entry = ADDRESS_ENTRY(this, hash1); + entry = AddressEntry(hash1); if (EntryIsFree(entry)) { return (Reason == ForAdd) ? (firstRemoved ? firstRemoved : entry) : nullptr; } - if (MATCH_ENTRY_KEYHASH(entry, aKeyHash) && + if (MatchEntryKeyhash(entry, aKeyHash) && matchEntry(this, entry, aKey)) { return entry; } } - /* NOTREACHED */ + // NOTREACHED return nullptr; } -/* - * This is a copy of SearchTable, used by ChangeTable, hardcoded to - * 1. assume |aIsAdd| is true, - * 2. assume that |aKey| will never match an existing entry, and - * 3. assume that no entries have been removed from the current table - * structure. - * Avoiding the need for |aKey| means we can avoid needing a way to map - * entries to keys, which means callers can use complex key types more - * easily. - */ +// This is a copy of SearchTable(), used by ChangeTable(), hardcoded to +// 1. assume |aIsAdd| is true, +// 2. assume that |aKey| will never match an existing entry, and +// 3. assume that no entries have been removed from the current table +// structure. +// Avoiding the need for |aKey| means we can avoid needing a way to map entries +// to keys, which means callers can use complex key types more easily. PLDHashEntryHdr* PL_DHASH_FASTCALL PLDHashTable::FindFreeEntry(PLDHashNumber aKeyHash) { MOZ_ASSERT(mEntryStore); - NS_ASSERTION(!(aKeyHash & COLLISION_FLAG), - "!(aKeyHash & COLLISION_FLAG)"); + NS_ASSERTION(!(aKeyHash & kCollisionFlag), + "!(aKeyHash & kCollisionFlag)"); - /* Compute the primary hash address. */ - PLDHashNumber hash1 = HASH1(aKeyHash, mHashShift); - PLDHashEntryHdr* entry = ADDRESS_ENTRY(this, hash1); + // Compute the primary hash address. + PLDHashNumber hash1 = Hash1(aKeyHash); + PLDHashEntryHdr* entry = AddressEntry(hash1); - /* Miss: return space for a new entry. */ + // Miss: return space for a new entry. if (EntryIsFree(entry)) { return entry; } - /* Collision: double hash. */ - int sizeLog2 = PL_DHASH_BITS - mHashShift; - PLDHashNumber hash2 = HASH2(aKeyHash, sizeLog2, mHashShift); - uint32_t sizeMask = (1u << sizeLog2) - 1; + // Collision: double hash. + PLDHashNumber hash2; + uint32_t sizeMask; + Hash2(aKeyHash, hash2, sizeMask); for (;;) { - NS_ASSERTION(!ENTRY_IS_REMOVED(entry), - "!ENTRY_IS_REMOVED(entry)"); - entry->mKeyHash |= COLLISION_FLAG; + NS_ASSERTION(!EntryIsRemoved(entry), + "!EntryIsRemoved(entry)"); + entry->mKeyHash |= kCollisionFlag; hash1 -= hash2; hash1 &= sizeMask; - entry = ADDRESS_ENTRY(this, hash1); + entry = AddressEntry(hash1); if (EntryIsFree(entry)) { return entry; } } - /* NOTREACHED */ + // NOTREACHED return nullptr; } @@ -474,11 +492,11 @@ PLDHashTable::ChangeTable(int32_t aDeltaLog2) { MOZ_ASSERT(mEntryStore); - /* Look, but don't touch, until we succeed in getting new entry store. */ - int32_t oldLog2 = PL_DHASH_BITS - mHashShift; + // Look, but don't touch, until we succeed in getting new entry store. + int32_t oldLog2 = kHashBits - mHashShift; int32_t newLog2 = oldLog2 + aDeltaLog2; uint32_t newCapacity = 1u << newLog2; - if (newCapacity > PL_DHASH_MAX_CAPACITY) { + if (newCapacity > kMaxCapacity) { return false; } @@ -492,12 +510,12 @@ PLDHashTable::ChangeTable(int32_t aDeltaLog2) return false; } - /* We can't fail from here on, so update table parameters. */ - mHashShift = PL_DHASH_BITS - newLog2; + // We can't fail from here on, so update table parameters. + mHashShift = kHashBits - newLog2; mRemovedCount = 0; mGeneration++; - /* Assign the new entry store to table. */ + // Assign the new entry store to table. memset(newEntryStore, 0, nbytes); char* oldEntryStore; char* oldEntryAddr; @@ -505,12 +523,12 @@ PLDHashTable::ChangeTable(int32_t aDeltaLog2) mEntryStore = newEntryStore; PLDHashMoveEntry moveEntry = mOps->moveEntry; - /* Copy only live entries, leaving removed ones behind. */ + // Copy only live entries, leaving removed ones behind. uint32_t oldCapacity = 1u << oldLog2; for (uint32_t i = 0; i < oldCapacity; ++i) { PLDHashEntryHdr* oldEntry = (PLDHashEntryHdr*)oldEntryAddr; - if (ENTRY_IS_LIVE(oldEntry)) { - oldEntry->mKeyHash &= ~COLLISION_FLAG; + if (EntryIsLive(oldEntry)) { + oldEntry->mKeyHash &= ~kCollisionFlag; PLDHashEntryHdr* newEntry = FindFreeEntry(oldEntry->mKeyHash); NS_ASSERTION(EntryIsFree(newEntry), "EntryIsFree(newEntry)"); moveEntry(this, oldEntry, newEntry); @@ -529,16 +547,18 @@ PLDHashTable::ComputeKeyHash(const void* aKey) MOZ_ASSERT(mEntryStore); PLDHashNumber keyHash = mOps->hashKey(this, aKey); - keyHash *= PL_DHASH_GOLDEN_RATIO; + keyHash *= kGoldenRatio; - /* Avoid 0 and 1 hash codes, they indicate free and removed entries. */ - ENSURE_LIVE_KEYHASH(keyHash); - keyHash &= ~COLLISION_FLAG; + // Avoid 0 and 1 hash codes, they indicate free and removed entries. + if (keyHash < 2) { + keyHash -= 2; + } + keyHash &= ~kCollisionFlag; return keyHash; } -MOZ_ALWAYS_INLINE PLDHashEntryHdr* +PLDHashEntryHdr* PLDHashTable::Search(const void* aKey) { #ifdef DEBUG @@ -572,14 +592,12 @@ PLDHashTable::Add(const void* aKey, const mozilla::fallible_t&) memset(mEntryStore, 0, nbytes); } - /* - * If alpha is >= .75, grow or compress the table. If aKey is already - * in the table, we may grow once more than necessary, but only if we - * are on the edge of being overloaded. - */ + // If alpha is >= .75, grow or compress the table. If aKey is already in the + // table, we may grow once more than necessary, but only if we are on the + // edge of being overloaded. uint32_t capacity = Capacity(); if (mEntryCount + mRemovedCount >= MaxLoad(capacity)) { - /* Compress if a quarter or more of all entries are removed. */ + // Compress if a quarter or more of all entries are removed. int deltaLog2; if (mRemovedCount >= capacity >> 2) { deltaLog2 = 0; @@ -587,28 +605,23 @@ PLDHashTable::Add(const void* aKey, const mozilla::fallible_t&) deltaLog2 = 1; } - /* - * Grow or compress the table. If ChangeTable() fails, allow - * overloading up to the secondary max. Once we hit the secondary - * max, return null. - */ + // Grow or compress the table. If ChangeTable() fails, allow overloading up + // to the secondary max. Once we hit the secondary max, return null. if (!ChangeTable(deltaLog2) && mEntryCount + mRemovedCount >= MaxLoadOnGrowthFailure(capacity)) { return nullptr; } } - /* - * Look for entry after possibly growing, so we don't have to add it, - * then skip it while growing the table and re-add it after. - */ + // Look for entry after possibly growing, so we don't have to add it, + // then skip it while growing the table and re-add it after. PLDHashNumber keyHash = ComputeKeyHash(aKey); PLDHashEntryHdr* entry = SearchTable(aKey, keyHash); - if (!ENTRY_IS_LIVE(entry)) { - /* Initialize the entry, indicating that it's no longer free. */ - if (ENTRY_IS_REMOVED(entry)) { + if (!EntryIsLive(entry)) { + // Initialize the entry, indicating that it's no longer free. + if (EntryIsRemoved(entry)) { mRemovedCount--; - keyHash |= COLLISION_FLAG; + keyHash |= kCollisionFlag; } if (mOps->initEntry) { mOps->initEntry(entry, aKey); @@ -652,22 +665,20 @@ PLDHashTable::Remove(const void* aKey) mEntryStore ? SearchTable(aKey, ComputeKeyHash(aKey)) : nullptr; if (entry) { - /* Clear this entry and mark it as "removed". */ - PL_DHashTableRawRemove(this, entry); - - /* Shrink if alpha is <= .25 and the table isn't too small already. */ - uint32_t capacity = Capacity(); - if (capacity > PL_DHASH_MIN_CAPACITY && - mEntryCount <= MinLoad(capacity)) { - (void) ChangeTable(-1); - } + RawRemove(entry); + ShrinkIfAppropriate(); } } -PLDHashEntryHdr* PL_DHASH_FASTCALL -PL_DHashTableSearch(PLDHashTable* aTable, const void* aKey) +void +PLDHashTable::RemoveEntry(PLDHashEntryHdr* aEntry) { - return aTable->Search(aKey); +#ifdef DEBUG + AutoWriteOp op(mChecker); +#endif + + RawRemove(aEntry); + ShrinkIfAppropriate(); } PLDHashEntryHdr* PL_DHASH_FASTCALL @@ -699,16 +710,16 @@ PLDHashTable::RawRemove(PLDHashEntryHdr* aEntry) MOZ_ASSERT(mEntryStore); - NS_ASSERTION(ENTRY_IS_LIVE(aEntry), "ENTRY_IS_LIVE(aEntry)"); + MOZ_ASSERT(EntryIsLive(aEntry), "EntryIsLive(aEntry)"); - /* Load keyHash first in case clearEntry() goofs it. */ + // Load keyHash first in case clearEntry() goofs it. PLDHashNumber keyHash = aEntry->mKeyHash; mOps->clearEntry(this, aEntry); - if (keyHash & COLLISION_FLAG) { - MARK_ENTRY_REMOVED(aEntry); + if (keyHash & kCollisionFlag) { + MarkEntryRemoved(aEntry); mRemovedCount++; } else { - MARK_ENTRY_FREE(aEntry); + MarkEntryFree(aEntry); } mEntryCount--; } @@ -727,91 +738,17 @@ PLDHashTable::ShrinkIfAppropriate() { uint32_t capacity = Capacity(); if (mRemovedCount >= capacity >> 2 || - (capacity > PL_DHASH_MIN_CAPACITY && mEntryCount <= MinLoad(capacity))) { - + (capacity > kMinCapacity && mEntryCount <= MinLoad(capacity))) { uint32_t log2; BestCapacity(mEntryCount, &capacity, &log2); - int32_t deltaLog2 = log2 - (PL_DHASH_BITS - mHashShift); + int32_t deltaLog2 = log2 - (kHashBits - mHashShift); MOZ_ASSERT(deltaLog2 <= 0); (void) ChangeTable(deltaLog2); } } -MOZ_ALWAYS_INLINE uint32_t -PLDHashTable::Enumerate(PLDHashEnumerator aEtor, void* aArg) -{ -#ifdef DEBUG - // Enumerate() can be a read operation or a write operation, depending on - // whether PL_DHASH_REMOVE is used. Assume for now it's a read; once the - // enumeration is done we'll know if that is false, and if so, - // retrospectively check it as a write. - bool wasIdleAndWritableAtStart = mChecker.IsIdle() && mChecker.IsWritable(); - AutoReadOp op(mChecker); -#endif - - if (!mEntryStore) { - return 0; - } - - char* entryAddr = mEntryStore; - uint32_t capacity = Capacity(); - uint32_t tableSize = capacity * mEntrySize; - char* entryLimit = mEntryStore + tableSize; - uint32_t i = 0; - bool didRemove = false; - - if (ChaosMode::isActive(ChaosMode::HashTableIteration)) { - // Start iterating at a random point in the hashtable. It would be - // even more chaotic to iterate in fully random order, but that's a lot - // more work. - entryAddr += ChaosMode::randomUint32LessThan(capacity) * mEntrySize; - } - - for (uint32_t e = 0; e < capacity; ++e) { - PLDHashEntryHdr* entry = (PLDHashEntryHdr*)entryAddr; - if (ENTRY_IS_LIVE(entry)) { - PLDHashOperator op = aEtor(this, entry, i++, aArg); - if (op & PL_DHASH_REMOVE) { - PL_DHashTableRawRemove(this, entry); - didRemove = true; - } - if (op & PL_DHASH_STOP) { - break; - } - } - entryAddr += mEntrySize; - if (entryAddr >= entryLimit) { - entryAddr -= tableSize; - } - } - - // This is the retrospective check mentioned above. If we removed anything, - // then the table should have been idle and writable before we did so. - MOZ_ASSERT_IF(didRemove, wasIdleAndWritableAtStart); - - // Shrink the table if appropriate. Do this only if we removed above, so - // non-removing enumerations can count on stable |mEntryStore| until the next - // Add, Remove, or removing-Enumerate. - if (didRemove) { - ShrinkIfAppropriate(); - } - - return i; -} - -uint32_t -PL_DHashTableEnumerate(PLDHashTable* aTable, PLDHashEnumerator aEtor, - void* aArg) -{ - MOZ_ASSERT(aTable != nullptr, "aTable must not be null"); - if (!aTable) { - return 0; - } - return aTable->Enumerate(aEtor, aArg); -} - MOZ_ALWAYS_INLINE size_t PLDHashTable::SizeOfExcludingThis( PLDHashSizeOfEntryExcludingThisFun aSizeOfEntryExcludingThis, @@ -866,30 +803,49 @@ PL_DHashTableSizeOfIncludingThis( PLDHashTable::Iterator::Iterator(Iterator&& aOther) : mTable(aOther.mTable) - , mCurrent(aOther.mCurrent) + , mStart(aOther.mStart) , mLimit(aOther.mLimit) + , mCurrent(aOther.mCurrent) + , mNexts(aOther.mNexts) + , mNextsLimit(aOther.mNextsLimit) , mHaveRemoved(aOther.mHaveRemoved) { // No need to change |mChecker| here. aOther.mTable = nullptr; - aOther.mCurrent = nullptr; + aOther.mStart = nullptr; aOther.mLimit = nullptr; + aOther.mCurrent = nullptr; + aOther.mNexts = 0; + aOther.mNextsLimit = 0; aOther.mHaveRemoved = false; } PLDHashTable::Iterator::Iterator(PLDHashTable* aTable) : mTable(aTable) - , mCurrent(mTable->mEntryStore) + , mStart(mTable->mEntryStore) , mLimit(mTable->mEntryStore + mTable->Capacity() * mTable->mEntrySize) + , mCurrent(mTable->mEntryStore) + , mNexts(0) + , mNextsLimit(mTable->EntryCount()) , mHaveRemoved(false) { #ifdef DEBUG mTable->mChecker.StartReadOp(); #endif - // Advance to the first live entry, or to the end if there are none. - while (IsOnNonLiveEntry()) { - mCurrent += mTable->mEntrySize; + if (ChaosMode::isActive(ChaosFeature::HashTableIteration) && + mTable->Capacity() > 0) { + // Start iterating at a random entry. It would be even more chaotic to + // iterate in fully random order, but that's harder. + mCurrent += ChaosMode::randomUint32LessThan(mTable->Capacity()) * + mTable->mEntrySize; + } + + // Advance to the first live entry, if there is one. + if (!Done()) { + while (IsOnNonLiveEntry()) { + MoveToNextEntry(); + } } } @@ -908,13 +864,23 @@ PLDHashTable::Iterator::~Iterator() bool PLDHashTable::Iterator::Done() const { - return mCurrent == mLimit; + return mNexts == mNextsLimit; } MOZ_ALWAYS_INLINE bool PLDHashTable::Iterator::IsOnNonLiveEntry() const { - return !Done() && !ENTRY_IS_LIVE(reinterpret_cast(mCurrent)); + MOZ_ASSERT(!Done()); + return !EntryIsLive(reinterpret_cast(mCurrent)); +} + +MOZ_ALWAYS_INLINE void +PLDHashTable::Iterator::MoveToNextEntry() +{ + mCurrent += mTable->mEntrySize; + if (mCurrent == mLimit) { + mCurrent = mStart; // Wrap-around. Possible due to Chaos Mode. + } } PLDHashEntryHdr* @@ -923,7 +889,7 @@ PLDHashTable::Iterator::Get() const MOZ_ASSERT(!Done()); PLDHashEntryHdr* entry = reinterpret_cast(mCurrent); - MOZ_ASSERT(ENTRY_IS_LIVE(entry)); + MOZ_ASSERT(EntryIsLive(entry)); return entry; } @@ -932,9 +898,14 @@ PLDHashTable::Iterator::Next() { MOZ_ASSERT(!Done()); - do { - mCurrent += mTable->mEntrySize; - } while (IsOnNonLiveEntry()); + mNexts++; + + // Advance to the next live entry, if there is one. + if (!Done()) { + do { + MoveToNextEntry(); + } while (IsOnNonLiveEntry()); + } } void diff --git a/xpcom/glue/pldhash.h b/xpcom/glue/pldhash.h index 0a81410a3c..5bc1fbe042 100644 --- a/xpcom/glue/pldhash.h +++ b/xpcom/glue/pldhash.h @@ -6,9 +6,7 @@ #ifndef pldhash_h___ #define pldhash_h___ -/* - * Double hashing, a la Knuth 6. - */ + #include "mozilla/Atomics.h" #include "mozilla/Attributes.h" // for MOZ_ALWAYS_INLINE #include "mozilla/fallible.h" @@ -25,56 +23,27 @@ #define PL_DHASH_FASTCALL #endif -/* - * Table capacity limit; do not exceed. The max capacity used to be 1<<23 but - * that occasionally that wasn't enough. Making it much bigger than 1<<26 - * probably isn't worthwhile -- tables that big are kind of ridiculous. Also, - * the growth operation will (deliberately) fail if |capacity * mEntrySize| - * overflows a uint32_t, and mEntrySize is always at least 8 bytes. - */ -#define PL_DHASH_MAX_CAPACITY ((uint32_t)1 << 26) - -#define PL_DHASH_MIN_CAPACITY 8 - -/* - * Making this half of the max capacity ensures it'll fit. Nobody should need - * an initial length anywhere nearly this large, anyway. - */ -#define PL_DHASH_MAX_INITIAL_LENGTH (PL_DHASH_MAX_CAPACITY / 2) - -/* This gives a default initial capacity of 8. */ -#define PL_DHASH_DEFAULT_INITIAL_LENGTH 4 - -/* - * Multiplicative hash uses an unsigned 32 bit integer and the golden ratio, - * expressed as a fixed-point 32-bit fraction. - */ -#define PL_DHASH_BITS 32 -#define PL_DHASH_GOLDEN_RATIO 0x9E3779B9U - typedef uint32_t PLDHashNumber; class PLDHashTable; struct PLDHashTableOps; -/* - * Table entry header structure. - * - * In order to allow in-line allocation of key and value, we do not declare - * either here. Instead, the API uses const void *key as a formal parameter. - * The key need not be stored in the entry; it may be part of the value, but - * need not be stored at all. - * - * Callback types are defined below and grouped into the PLDHashTableOps - * structure, for single static initialization per hash table sub-type. - * - * Each hash table sub-type should make its entry type a subclass of - * PLDHashEntryHdr. The mKeyHash member contains the result of multiplying the - * hash code returned from the hashKey callback (see below) by - * PL_DHASH_GOLDEN_RATIO, then constraining the result to avoid the magic 0 and - * 1 values. The stored mKeyHash value is table size invariant, and it is - * maintained automatically -- users need never access it. - */ +// Table entry header structure. +// +// In order to allow in-line allocation of key and value, we do not declare +// either here. Instead, the API uses const void *key as a formal parameter. +// The key need not be stored in the entry; it may be part of the value, but +// need not be stored at all. +// +// Callback types are defined below and grouped into the PLDHashTableOps +// structure, for single static initialization per hash table sub-type. +// +// Each hash table sub-type should make its entry type a subclass of +// PLDHashEntryHdr. The mKeyHash member contains the result of multiplying the +// hash code returned from the hashKey callback (see below) by kGoldenRatio, +// then constraining the result to avoid the magic 0 and 1 values. The stored +// mKeyHash value is table size invariant, and it is maintained automatically +// -- users need never access it. struct PLDHashEntryHdr { private: @@ -83,60 +52,6 @@ private: PLDHashNumber mKeyHash; }; -/* - * These are the codes returned by PLDHashEnumerator functions, which control - * PL_DHashTableEnumerate's behavior. - */ -enum PLDHashOperator -{ - PL_DHASH_NEXT = 0, /* enumerator says continue */ - PL_DHASH_STOP = 1, /* enumerator says stop */ - PL_DHASH_REMOVE = 2 /* enumerator says remove */ -}; - -/* - * Enumerate entries in table using etor: - * - * count = PL_DHashTableEnumerate(table, etor, arg); - * - * PL_DHashTableEnumerate calls etor like so: - * - * op = etor(table, entry, number, arg); - * - * where number is a zero-based ordinal assigned to live entries according to - * their order in aTable->mEntryStore. - * - * The return value, op, is treated as a set of flags. If op is PL_DHASH_NEXT, - * then continue enumerating. If op contains PL_DHASH_REMOVE, then clear (via - * aTable->mOps->clearEntry) and free entry. Then we check whether op contains - * PL_DHASH_STOP; if so, stop enumerating and return the number of live entries - * that were enumerated so far. Return the total number of live entries when - * enumeration completes normally. - * - * If etor calls PL_DHashTableAdd or PL_DHashTableRemove on table, it must - * return PL_DHASH_STOP; otherwise undefined behavior results. - * - * If any enumerator returns PL_DHASH_REMOVE, aTable->mEntryStore may be shrunk - * or compressed after enumeration, but before PL_DHashTableEnumerate returns. - * Such an enumerator therefore can't safely set aside entry pointers, but an - * enumerator that never returns PL_DHASH_REMOVE can set pointers to entries - * aside, e.g., to avoid copying live entries into an array of the entry type. - * Copying entry pointers is cheaper, and safe so long as the caller of such a - * "stable" Enumerate doesn't use the set-aside pointers after any call either - * to PL_DHashTableAdd or PL_DHashTableRemove, or to an "unstable" form of - * Enumerate, which might grow or shrink mEntryStore. - * - * If your enumerator wants to remove certain entries, but set aside pointers - * to other entries that it retains, it can use PL_DHashTableRawRemove on the - * entries to be removed, returning PL_DHASH_NEXT to skip them. Likewise, if - * you want to remove entries, but for some reason you do not want mEntryStore - * to be shrunk or compressed, you can call PL_DHashTableRawRemove safely on - * the entry being enumerated, rather than returning PL_DHASH_REMOVE. - */ -typedef PLDHashOperator (*PLDHashEnumerator)(PLDHashTable* aTable, - PLDHashEntryHdr* aHdr, - uint32_t aNumber, void* aArg); - typedef size_t (*PLDHashSizeOfEntryExcludingThisFun)( PLDHashEntryHdr* aHdr, mozilla::MallocSizeOf aMallocSizeOf, void* aArg); @@ -287,37 +202,52 @@ private: }; #endif -/* - * A PLDHashTable may be allocated on the stack or within another structure or - * class. No entry storage is allocated until the first element is added. This - * means that empty hash tables are cheap, which is good because they are - * common. - * - * There used to be a long, math-heavy comment here about the merits of - * double hashing vs. chaining; it was removed in bug 1058335. In short, double - * hashing is more space-efficient unless the element size gets large (in which - * case you should keep using double hashing but switch to using pointer - * elements). Also, with double hashing, you can't safely hold an entry pointer - * and use it after an ADD or REMOVE operation, unless you sample - * aTable->mGeneration before adding or removing, and compare the sample after, - * dereferencing the entry pointer only if aTable->mGeneration has not changed. - */ +// A PLDHashTable may be allocated on the stack or within another structure or +// class. No entry storage is allocated until the first element is added. This +// means that empty hash tables are cheap, which is good because they are +// common. +// +// There used to be a long, math-heavy comment here about the merits of +// double hashing vs. chaining; it was removed in bug 1058335. In short, double +// hashing is more space-efficient unless the element size gets large (in which +// case you should keep using double hashing but switch to using pointer +// elements). Also, with double hashing, you can't safely hold an entry pointer +// and use it after an ADD or REMOVE operation, unless you sample +// aTable->mGeneration before adding or removing, and compare the sample after, +// dereferencing the entry pointer only if aTable->mGeneration has not changed. class PLDHashTable { private: - const PLDHashTableOps* const mOps; /* Virtual operations; see below. */ - int16_t mHashShift; /* multiplicative hash shift */ - const uint32_t mEntrySize; /* number of bytes in an entry */ - uint32_t mEntryCount; /* number of entries in table */ - uint32_t mRemovedCount; /* removed entry sentinels in table */ - uint32_t mGeneration; /* entry storage generation number */ - char* mEntryStore; /* entry storage; allocated lazily */ + const PLDHashTableOps* const mOps; // Virtual operations; see below. + int16_t mHashShift; // Multiplicative hash shift. + const uint32_t mEntrySize; // Number of bytes in an entry. + uint32_t mEntryCount; // Number of entries in table. + uint32_t mRemovedCount; // Removed entry sentinels in table. + uint32_t mGeneration; // Entry storage generation number. + char* mEntryStore; // Entry storage; allocated lazily. #ifdef DEBUG mutable Checker mChecker; #endif public: + // Table capacity limit; do not exceed. The max capacity used to be 1<<23 but + // that occasionally that wasn't enough. Making it much bigger than 1<<26 + // probably isn't worthwhile -- tables that big are kind of ridiculous. + // Also, the growth operation will (deliberately) fail if |capacity * + // mEntrySize| overflows a uint32_t, and mEntrySize is always at least 8 + // bytes. + static const uint32_t kMaxCapacity = ((uint32_t)1 << 26); + + static const uint32_t kMinCapacity = 8; + + // Making this half of kMaxCapacity ensures it'll fit. Nobody should need an + // initial length anywhere nearly this large, anyway. + static const uint32_t kMaxInitialLength = kMaxCapacity / 2; + + // This gives a default initial capacity of 8. + static const uint32_t kDefaultInitialLength = 4; + // Initialize the table with |aOps| and |aEntrySize|. The table's initial // capacity is chosen such that |aLength| elements can be inserted without // rehashing; if |aLength| is a power-of-two, this capacity will be @@ -327,7 +257,7 @@ public: // // This will crash if |aEntrySize| and/or |aLength| are too large. PLDHashTable(const PLDHashTableOps* aOps, uint32_t aEntrySize, - uint32_t aLength = PL_DHASH_DEFAULT_INITIAL_LENGTH); + uint32_t aLength = kDefaultInitialLength); PLDHashTable(PLDHashTable&& aOther) // These two fields are |const|. Initialize them here because the @@ -351,11 +281,9 @@ public: // This should be used rarely. const PLDHashTableOps* const Ops() { return mOps; } - /* - * Size in entries (gross, not net of free and removed sentinels) for table. - * This can be zero if no elements have been added yet, in which case the - * entry storage will not have yet been allocated. - */ + // Size in entries (gross, not net of free and removed sentinels) for table. + // This can be zero if no elements have been added yet, in which case the + // entry storage will not have yet been allocated. uint32_t Capacity() const { return mEntryStore ? CapacityFromHashShift() : 0; @@ -365,17 +293,58 @@ public: uint32_t EntryCount() const { return mEntryCount; } uint32_t Generation() const { return mGeneration; } + // To search for a |key| in |table|, call: + // + // entry = table.Search(key); + // + // If |entry| is non-null, |key| was found. If |entry| is null, key was not + // found. PLDHashEntryHdr* Search(const void* aKey); + + // To add an entry identified by |key| to table, call: + // + // entry = table.Add(key, mozilla::fallible); + // + // If |entry| is null upon return, then the table is severely overloaded and + // memory can't be allocated for entry storage. + // + // Otherwise, |aEntry->mKeyHash| has been set so that + // PLDHashTable::EntryIsFree(entry) is false, and it is up to the caller to + // initialize the key and value parts of the entry sub-type, if they have not + // been set already (i.e. if entry was not already in the table, and if the + // optional initEntry hook was not used). PLDHashEntryHdr* Add(const void* aKey, const mozilla::fallible_t&); + + // This is like the other Add() function, but infallible, and so never + // returns null. PLDHashEntryHdr* Add(const void* aKey); + + // To remove an entry identified by |key| from table, call: + // + // table.Remove(key); + // + // If |key|'s entry is found, it is cleared (via table->mOps->clearEntry). + // The table's capacity may be reduced afterwards. void Remove(const void* aKey); + // To remove an entry found by a prior search, call: + // + // table.RemoveEntry(entry); + // + // The entry, which must be present and in use, is cleared (via + // table->mOps->clearEntry). The table's capacity may be reduced afterwards. + void RemoveEntry(PLDHashEntryHdr* aEntry); + + // Remove an entry already accessed via Search() or Add(). + // + // NB: this is a "raw" or low-level method. It does not shrink the table if + // it is underloaded. Don't use it unless necessary and you know what you are + // doing, and if so, please explain in a comment why it is necessary instead + // of RemoveEntry(). void RawRemove(PLDHashEntryHdr* aEntry); - uint32_t Enumerate(PLDHashEnumerator aEtor, void* aArg); - // This function is equivalent to - // ClearAndPrepareForLength(PL_DHASH_DEFAULT_INITIAL_LENGTH). + // ClearAndPrepareForLength(kDefaultInitialLength). void Clear(); // This function clears the table's contents and frees its entry storage, @@ -388,15 +357,22 @@ public: // a new |aLength| argument. void ClearAndPrepareForLength(uint32_t aLength); + // Measure the size of the table's entry storage, and if + // |aSizeOfEntryExcludingThis| is non-nullptr, measure the size of things + // pointed to by entries. size_t SizeOfIncludingThis( PLDHashSizeOfEntryExcludingThisFun aSizeOfEntryExcludingThis, mozilla::MallocSizeOf aMallocSizeOf, void* aArg = nullptr) const; + // Like SizeOfExcludingThis(), but includes sizeof(*this). size_t SizeOfExcludingThis( PLDHashSizeOfEntryExcludingThisFun aSizeOfEntryExcludingThis, mozilla::MallocSizeOf aMallocSizeOf, void* aArg = nullptr) const; #ifdef DEBUG + // Mark a table as immutable for the remainder of its lifetime. This + // changes the implementation from asserting one set of invariants to + // asserting a different set. void MarkImmutable(); #endif @@ -449,12 +425,16 @@ public: PLDHashTable* mTable; // Main table pointer. private: - char* mCurrent; // Pointer to the current entry. + char* mStart; // The first entry. char* mLimit; // One past the last entry. + char* mCurrent; // Pointer to the current entry. + uint32_t mNexts; // Number of Next() calls. + uint32_t mNextsLimit; // Next() call limit. bool mHaveRemoved; // Have any elements been removed? bool IsOnNonLiveEntry() const; + void MoveToNextEntry(); Iterator() = delete; Iterator(const Iterator&) = delete; @@ -472,13 +452,32 @@ public: } private: + // Multiplicative hash uses an unsigned 32 bit integer and the golden ratio, + // expressed as a fixed-point 32-bit fraction. + static const uint32_t kHashBits = 32; + static const uint32_t kGoldenRatio = 0x9E3779B9U; + + static uint32_t HashShift(uint32_t aEntrySize, uint32_t aLength); + + static const PLDHashNumber kCollisionFlag = 1; + static bool EntryIsFree(PLDHashEntryHdr* aEntry); + static bool EntryIsRemoved(PLDHashEntryHdr* aEntry); + static bool EntryIsLive(PLDHashEntryHdr* aEntry); + static void MarkEntryFree(PLDHashEntryHdr* aEntry); + static void MarkEntryRemoved(PLDHashEntryHdr* aEntry); + + PLDHashNumber Hash1(PLDHashNumber aHash0); + void Hash2(PLDHashNumber aHash, uint32_t& aHash2Out, uint32_t& aSizeMaskOut); + + static bool MatchEntryKeyhash(PLDHashEntryHdr* aEntry, PLDHashNumber aHash); + PLDHashEntryHdr* AddressEntry(uint32_t aIndex); // We store mHashShift rather than sizeLog2 to optimize the collision-free // case in SearchTable. uint32_t CapacityFromHashShift() const { - return ((uint32_t)1 << (PL_DHASH_BITS - mHashShift)); + return ((uint32_t)1 << (kHashBits - mHashShift)); } PLDHashNumber ComputeKeyHash(const void* aKey); @@ -499,212 +498,134 @@ private: PLDHashTable& operator=(const PLDHashTable& aOther) = delete; }; -/* - * Compute the hash code for a given key to be looked up, added, or removed - * from aTable. A hash code may have any PLDHashNumber value. - */ +// Compute the hash code for a given key to be looked up, added, or removed +// from aTable. A hash code may have any PLDHashNumber value. typedef PLDHashNumber (*PLDHashHashKey)(PLDHashTable* aTable, const void* aKey); -/* - * Compare the key identifying aEntry in aTable with the provided key parameter. - * Return true if keys match, false otherwise. - */ +// Compare the key identifying aEntry in aTable with the provided key parameter. +// Return true if keys match, false otherwise. typedef bool (*PLDHashMatchEntry)(PLDHashTable* aTable, const PLDHashEntryHdr* aEntry, const void* aKey); -/* - * Copy the data starting at aFrom to the new entry storage at aTo. Do not add - * reference counts for any strong references in the entry, however, as this - * is a "move" operation: the old entry storage at from will be freed without - * any reference-decrementing callback shortly. - */ +// Copy the data starting at aFrom to the new entry storage at aTo. Do not add +// reference counts for any strong references in the entry, however, as this +// is a "move" operation: the old entry storage at from will be freed without +// any reference-decrementing callback shortly. typedef void (*PLDHashMoveEntry)(PLDHashTable* aTable, const PLDHashEntryHdr* aFrom, PLDHashEntryHdr* aTo); -/* - * Clear the entry and drop any strong references it holds. This callback is - * invoked by PL_DHashTableRemove(), but only if the given key is found in the - * table. - */ +// Clear the entry and drop any strong references it holds. This callback is +// invoked by Remove(), but only if the given key is found in the table. typedef void (*PLDHashClearEntry)(PLDHashTable* aTable, PLDHashEntryHdr* aEntry); -/* - * Initialize a new entry, apart from mKeyHash. This function is called when - * PL_DHashTableAdd finds no existing entry for the given key, and must add a - * new one. At that point, aEntry->mKeyHash is not set yet, to avoid claiming - * the last free entry in a severely overloaded table. - */ +// Initialize a new entry, apart from mKeyHash. This function is called when +// Add() finds no existing entry for the given key, and must add a new one. At +// that point, |aEntry->mKeyHash| is not set yet, to avoid claiming the last +// free entry in a severely overloaded table. typedef void (*PLDHashInitEntry)(PLDHashEntryHdr* aEntry, const void* aKey); -/* - * Finally, the "vtable" structure for PLDHashTable. The first four hooks - * must be provided by implementations; they're called unconditionally by the - * generic pldhash.c code. Hooks after these may be null. - * - * Summary of allocation-related hook usage with C++ placement new emphasis: - * initEntry Call placement new using default key-based ctor. - * moveEntry Call placement new using copy ctor, run dtor on old - * entry storage. - * clearEntry Run dtor on entry. - * - * Note the reason why initEntry is optional: the default hooks (stubs) clear - * entry storage: On successful PL_DHashTableAdd(tbl, key), the returned entry - * pointer addresses an entry struct whose mKeyHash member has been set - * non-zero, but all other entry members are still clear (null). - * PL_DHashTableAdd callers can test such members to see whether the entry was - * newly created by the PL_DHashTableAdd call that just succeeded. If - * placement new or similar initialization is required, define an initEntry - * hook. Of course, the clearEntry hook must zero or null appropriately. - * - * XXX assumes 0 is null for pointer types. - */ +// Finally, the "vtable" structure for PLDHashTable. The first four hooks +// must be provided by implementations; they're called unconditionally by the +// generic pldhash.c code. Hooks after these may be null. +// +// Summary of allocation-related hook usage with C++ placement new emphasis: +// initEntry Call placement new using default key-based ctor. +// moveEntry Call placement new using copy ctor, run dtor on old +// entry storage. +// clearEntry Run dtor on entry. +// +// Note the reason why initEntry is optional: the default hooks (stubs) clear +// entry storage: On successful Add(tbl, key), the returned entry pointer +// addresses an entry struct whose mKeyHash member has been set non-zero, but +// all other entry members are still clear (null). Add() callers can test such +// members to see whether the entry was newly created by the Add() call that +// just succeeded. If placement new or similar initialization is required, +// define an |initEntry| hook. Of course, the |clearEntry| hook must zero or +// null appropriately. +// +// XXX assumes 0 is null for pointer types. struct PLDHashTableOps { - /* Mandatory hooks. All implementations must provide these. */ + // Mandatory hooks. All implementations must provide these. PLDHashHashKey hashKey; PLDHashMatchEntry matchEntry; PLDHashMoveEntry moveEntry; PLDHashClearEntry clearEntry; - /* Optional hooks start here. If null, these are not called. */ + // Optional hooks start here. If null, these are not called. PLDHashInitEntry initEntry; }; -/* - * Default implementations for the above mOps. - */ +// Default implementations for the above mOps. -PLDHashNumber PL_DHashStringKey(PLDHashTable* aTable, const void* aKey); +PLDHashNumber +PL_DHashStringKey(PLDHashTable* aTable, const void* aKey); -/* A minimal entry is a subclass of PLDHashEntryHdr and has void key pointer. */ +// A minimal entry is a subclass of PLDHashEntryHdr and has void key pointer. struct PLDHashEntryStub : public PLDHashEntryHdr { const void* key; }; -PLDHashNumber PL_DHashVoidPtrKeyStub(PLDHashTable* aTable, const void* aKey); +PLDHashNumber +PL_DHashVoidPtrKeyStub(PLDHashTable* aTable, const void* aKey); -bool PL_DHashMatchEntryStub(PLDHashTable* aTable, - const PLDHashEntryHdr* aEntry, - const void* aKey); +bool +PL_DHashMatchEntryStub(PLDHashTable* aTable, + const PLDHashEntryHdr* aEntry, + const void* aKey); -bool PL_DHashMatchStringKey(PLDHashTable* aTable, - const PLDHashEntryHdr* aEntry, - const void* aKey); +bool +PL_DHashMatchStringKey(PLDHashTable* aTable, + const PLDHashEntryHdr* aEntry, + const void* aKey); void PL_DHashMoveEntryStub(PLDHashTable* aTable, const PLDHashEntryHdr* aFrom, PLDHashEntryHdr* aTo); -void PL_DHashClearEntryStub(PLDHashTable* aTable, PLDHashEntryHdr* aEntry); +void +PL_DHashClearEntryStub(PLDHashTable* aTable, PLDHashEntryHdr* aEntry); -/* - * If you use PLDHashEntryStub or a subclass of it as your entry struct, and - * if your entries move via memcpy and clear via memset(0), you can use these - * stub operations. - */ -const PLDHashTableOps* PL_DHashGetStubOps(void); +// If you use PLDHashEntryStub or a subclass of it as your entry struct, and +// if your entries move via memcpy and clear via memset(0), you can use these +// stub operations. +const PLDHashTableOps* +PL_DHashGetStubOps(void); -/* - * To search for a key in |table|, call: - * - * entry = PL_DHashTableSearch(table, key); - * - * If |entry| is non-null, |key| was found. If |entry| is null, key was not - * found. - */ -PLDHashEntryHdr* PL_DHASH_FASTCALL -PL_DHashTableSearch(PLDHashTable* aTable, const void* aKey); - -/* - * To add an entry identified by key to table, call: - * - * entry = PL_DHashTableAdd(table, key, mozilla::fallible); - * - * If entry is null upon return, then the table is severely overloaded and - * memory can't be allocated for entry storage. - * - * Otherwise, aEntry->mKeyHash has been set so that - * PLDHashTable::EntryIsFree(entry) is false, and it is up to the caller to - * initialize the key and value parts of the entry sub-type, if they have not - * been set already (i.e. if entry was not already in the table, and if the - * optional initEntry hook was not used). - */ PLDHashEntryHdr* PL_DHASH_FASTCALL PL_DHashTableAdd(PLDHashTable* aTable, const void* aKey, const mozilla::fallible_t&); -/* - * This is like the other PL_DHashTableAdd() function, but infallible, and so - * never returns null. - */ PLDHashEntryHdr* PL_DHASH_FASTCALL PL_DHashTableAdd(PLDHashTable* aTable, const void* aKey); -/* - * To remove an entry identified by key from table, call: - * - * PL_DHashTableRemove(table, key); - * - * If key's entry is found, it is cleared (via table->mOps->clearEntry). - */ void PL_DHASH_FASTCALL PL_DHashTableRemove(PLDHashTable* aTable, const void* aKey); -/* - * Remove an entry already accessed via PL_DHashTableSearch or PL_DHashTableAdd. - * - * NB: this is a "raw" or low-level routine, intended to be used only where - * the inefficiency of a full PL_DHashTableRemove (which rehashes in order - * to find the entry given its key) is not tolerable. This function does not - * shrink the table if it is underloaded. - */ -void PL_DHashTableRawRemove(PLDHashTable* aTable, PLDHashEntryHdr* aEntry); +void +PL_DHashTableRawRemove(PLDHashTable* aTable, PLDHashEntryHdr* aEntry); -uint32_t -PL_DHashTableEnumerate(PLDHashTable* aTable, PLDHashEnumerator aEtor, - void* aArg); - -/** - * Measure the size of the table's entry storage, and if - * |aSizeOfEntryExcludingThis| is non-nullptr, measure the size of things - * pointed to by entries. Doesn't measure |mOps| because it's often shared - * between tables. - */ -size_t PL_DHashTableSizeOfExcludingThis( +size_t +PL_DHashTableSizeOfExcludingThis( const PLDHashTable* aTable, PLDHashSizeOfEntryExcludingThisFun aSizeOfEntryExcludingThis, mozilla::MallocSizeOf aMallocSizeOf, void* aArg = nullptr); -/** - * Like PL_DHashTableSizeOfExcludingThis, but includes sizeof(*this). - */ -size_t PL_DHashTableSizeOfIncludingThis( +size_t +PL_DHashTableSizeOfIncludingThis( const PLDHashTable* aTable, PLDHashSizeOfEntryExcludingThisFun aSizeOfEntryExcludingThis, mozilla::MallocSizeOf aMallocSizeOf, void* aArg = nullptr); #ifdef DEBUG -/** - * Mark a table as immutable for the remainder of its lifetime. This - * changes the implementation from ASSERTing one set of invariants to - * ASSERTing a different set. - * - * When a table is NOT marked as immutable, the table implementation - * asserts that the table is not mutated from its own callbacks. It - * assumes the caller protects the table from being accessed on multiple - * threads simultaneously. - * - * When the table is marked as immutable, the re-entry assertions will - * no longer trigger erroneously due to multi-threaded access. Instead, - * mutations will cause assertions. - */ -void PL_DHashMarkTableImmutable(PLDHashTable* aTable); +void +PL_DHashMarkTableImmutable(PLDHashTable* aTable); #endif #endif /* pldhash_h___ */ diff --git a/xpcom/libxpcomrt/moz.build b/xpcom/libxpcomrt/moz.build index 4179c3238b..4de8bb0eb0 100644 --- a/xpcom/libxpcomrt/moz.build +++ b/xpcom/libxpcomrt/moz.build @@ -77,7 +77,6 @@ xpcom_glue_src = [ 'nsProxyRelease.cpp', 'nsQuickSort.cpp', 'nsTArray.cpp', - 'nsTHashtable.cpp', 'nsTObserverArray.cpp', 'nsThreadUtils.cpp', 'nsWeakReference.cpp', diff --git a/xpcom/tests/gtest/TestPLDHash.cpp b/xpcom/tests/gtest/TestPLDHash.cpp index 33fc6819a0..0db4cbe529 100644 --- a/xpcom/tests/gtest/TestPLDHash.cpp +++ b/xpcom/tests/gtest/TestPLDHash.cpp @@ -10,23 +10,109 @@ // This test mostly focuses on edge cases. But more coverage of normal // operations wouldn't be a bad thing. +#ifdef XP_UNIX +#include +#include +#include + +// This global variable is defined in toolkit/xre/nsSigHandlers.cpp. +extern unsigned int _gdb_sleep_duration; +#endif + +// We can test that certain operations cause expected aborts by forking +// and then checking that the child aborted in the expected way (i.e. via +// MOZ_CRASH). We skip this for the following configurations. +// - On Windows, because it doesn't have fork(). +// - On non-DEBUG builds, because the crashes cause the crash reporter to pop +// up when running this test locally, which is surprising and annoying. +// - On ASAN builds, because ASAN alters the way a MOZ_CRASHing process +// terminates, which makes it harder to test if the right thing has occurred. +void +TestCrashyOperation(void (*aCrashyOperation)()) +{ +#if defined(XP_UNIX) && defined(DEBUG) && !defined(MOZ_ASAN) + // We're about to trigger a crash. When it happens don't pause to allow GDB + // to be attached. + unsigned int old_gdb_sleep_duration = _gdb_sleep_duration; + _gdb_sleep_duration = 0; + + int pid = fork(); + ASSERT_NE(pid, -1); + + if (pid == 0) { + // Child: perform the crashy operation. + aCrashyOperation(); + fprintf(stderr, "TestCrashyOperation: didn't crash?!\n"); + ASSERT_TRUE(false); // shouldn't reach here + } + + // Parent: check that child crashed as expected. + int status; + ASSERT_NE(waitpid(pid, &status, 0), -1); + + // The path taken here depends on the platform and configuration. + ASSERT_TRUE(WIFEXITED(status) || WTERMSIG(status)); + if (WIFEXITED(status)) { + // This occurs if the ah_crap_handler() is run, i.e. we caught the crash. + // It returns the number of the caught signal. + int signum = WEXITSTATUS(status); + if (signum != SIGSEGV && signum != SIGBUS) { + fprintf(stderr, "TestCrashyOperation 'exited' failure: %d\n", signum); + ASSERT_TRUE(false); + } + } else if (WIFSIGNALED(status)) { + // This one occurs if we didn't catch the crash. The exit code is the + // number of the terminating signal. + int signum = WTERMSIG(status); + if (signum != SIGSEGV && signum != SIGBUS) { + fprintf(stderr, "TestCrashyOperation 'signaled' failure: %d\n", signum); + ASSERT_TRUE(false); + } + } + + _gdb_sleep_duration = old_gdb_sleep_duration; +#endif +} + +void +InitCapacityOk_InitialLengthTooBig() +{ + PLDHashTable t(PL_DHashGetStubOps(), sizeof(PLDHashEntryStub), + PLDHashTable::kMaxInitialLength + 1); +} + +void +InitCapacityOk_InitialEntryStoreTooBig() +{ + // Try the smallest disallowed power-of-two entry store size, which is 2^32 + // bytes (which overflows to 0). (Note that the 2^23 *length* gets converted + // to a 2^24 *capacity*.) + PLDHashTable t(PL_DHashGetStubOps(), (uint32_t)1 << 23, (uint32_t)1 << 8); +} + TEST(PLDHashTableTest, InitCapacityOk) { - // Try the largest allowed capacity. With PL_DHASH_MAX_CAPACITY==1<<26, this + // Try the largest allowed capacity. With kMaxCapacity==1<<26, this // would allocate (if we added an element) 0.5GB of entry store on 32-bit // platforms and 1GB on 64-bit platforms. - // - // Ideally we'd also try (a) a too-large capacity, and (b) a large capacity - // combined with a large entry size that when multipled overflow. But those - // cases would cause the test to abort immediately. - // - // Furthermore, ideally we'd also try a large-but-ok capacity that almost but - // doesn't quite overflow, but that would result in allocating just under 4GB - // of entry storage. That's very likely to fail on 32-bit platforms, so such - // a test wouldn't be reliable. - // - PLDHashTable t(PL_DHashGetStubOps(), sizeof(PLDHashEntryStub), - PL_DHASH_MAX_INITIAL_LENGTH); + PLDHashTable t1(PL_DHashGetStubOps(), sizeof(PLDHashEntryStub), + PLDHashTable::kMaxInitialLength); + + // Try the largest allowed power-of-two entry store size, which is 2^31 bytes + // (Note that the 2^23 *length* gets converted to a 2^24 *capacity*.) + PLDHashTable t2(PL_DHashGetStubOps(), (uint32_t)1 << 23, (uint32_t)1 << 7); + + // Try a too-large capacity (which aborts). + TestCrashyOperation(InitCapacityOk_InitialLengthTooBig); + + // Try a large capacity combined with a large entry size that when multiplied + // overflow (causing abort). + TestCrashyOperation(InitCapacityOk_InitialEntryStoreTooBig); + + // Ideally we'd also try a large-but-ok capacity that almost but doesn't + // quite overflow, but that would result in allocating slightly less than 4 + // GiB of entry storage. That would be very likely to fail on 32-bit + // platforms, so such a test wouldn't be reliable. } TEST(PLDHashTableTest, LazyStorage) @@ -42,7 +128,7 @@ TEST(PLDHashTableTest, LazyStorage) ASSERT_EQ(t.EntryCount(), 0u); ASSERT_EQ(t.Generation(), 0u); - ASSERT_TRUE(!PL_DHashTableSearch(&t, (const void*)1)); + ASSERT_TRUE(!t.Search((const void*)1)); // No result to check here, but call it to make sure it doesn't crash. PL_DHashTableRemove(&t, (const void*)2); @@ -141,7 +227,7 @@ TEST(PLDHashTableTest, Clear) ASSERT_EQ(t1.EntryCount(), 0u); } -TEST(PLDHashTableIterator, Iterator) +TEST(PLDHashTableTest, Iterator) { PLDHashTable t(&trivialOps, sizeof(PLDHashEntryStub)); @@ -228,7 +314,7 @@ TEST(PLDHashTableIterator, Iterator) iter.Remove(); } ASSERT_EQ(t.EntryCount(), 0u); - ASSERT_EQ(t.Capacity(), unsigned(PL_DHASH_MIN_CAPACITY)); + ASSERT_EQ(t.Capacity(), unsigned(PLDHashTable::kMinCapacity)); } // See bug 931062, we skip this test on Android due to OOM. Also, it's slow, @@ -251,7 +337,8 @@ TEST(PLDHashTableTest, GrowToMaxCapacity) // We stop when the element count is 96.875% of PL_DHASH_MAX_SIZE (see // MaxLoadOnGrowthFailure()). - if (numInserted != PL_DHASH_MAX_CAPACITY - (PL_DHASH_MAX_CAPACITY >> 5)) { + if (numInserted != + PLDHashTable::kMaxCapacity - (PLDHashTable::kMaxCapacity >> 5)) { delete t; ASSERT_TRUE(false); } diff --git a/xpcom/threads/TimerThread.cpp b/xpcom/threads/TimerThread.cpp index 3d2b376d99..ce20dd0b5e 100644 --- a/xpcom/threads/TimerThread.cpp +++ b/xpcom/threads/TimerThread.cpp @@ -236,7 +236,7 @@ TimerThread::Run() if (mSleeping) { // Sleep for 0.1 seconds while not firing timers. uint32_t milliseconds = 100; - if (ChaosMode::isActive(ChaosMode::TimerScheduling)) { + if (ChaosMode::isActive(ChaosFeature::TimerScheduling)) { milliseconds = ChaosMode::randomUint32LessThan(200); } waitFor = PR_MillisecondsToInterval(milliseconds); @@ -319,7 +319,7 @@ TimerThread::Run() // interval is so small we should not wait at all). double microseconds = (timeout - now).ToMilliseconds() * 1000; - if (ChaosMode::isActive(ChaosMode::TimerScheduling)) { + if (ChaosMode::isActive(ChaosFeature::TimerScheduling)) { // The mean value of sFractions must be 1 to ensure that // the average of a long sequence of timeouts converges to the // actual sum of their times. diff --git a/xpcom/threads/nsEventQueue.cpp b/xpcom/threads/nsEventQueue.cpp index b858a7c512..5f6893b66d 100644 --- a/xpcom/threads/nsEventQueue.cpp +++ b/xpcom/threads/nsEventQueue.cpp @@ -88,7 +88,7 @@ nsEventQueue::PutEvent(nsIRunnable* aRunnable) // Avoid calling AddRef+Release while holding our monitor. nsCOMPtr event(aRunnable); - if (ChaosMode::isActive(ChaosMode::ThreadScheduling)) { + if (ChaosMode::isActive(ChaosFeature::ThreadScheduling)) { // With probability 0.5, yield so other threads have a chance to // dispatch events to this queue first. if (ChaosMode::randomUint32LessThan(2)) { diff --git a/xpcom/threads/nsThread.cpp b/xpcom/threads/nsThread.cpp index bf2a666c7c..421c8b7bdd 100644 --- a/xpcom/threads/nsThread.cpp +++ b/xpcom/threads/nsThread.cpp @@ -277,7 +277,7 @@ private: static void SetupCurrentThreadForChaosMode() { - if (!ChaosMode::isActive(ChaosMode::ThreadScheduling)) { + if (!ChaosMode::isActive(ChaosFeature::ThreadScheduling)) { return; } @@ -889,7 +889,7 @@ nsThread::SetPriority(int32_t aPriority) pri = PR_PRIORITY_NORMAL; } // If chaos mode is active, retain the randomly chosen priority - if (!ChaosMode::isActive(ChaosMode::ThreadScheduling)) { + if (!ChaosMode::isActive(ChaosFeature::ThreadScheduling)) { PR_SetThreadPriority(mThread, pri); }