Bug 1356103 - Part 4: Add a mechanism for C++ functions to perform post-Servo traversal tasks. r=bholley
MozReview-Commit-ID: 5Gx1qZzQxAK
new file mode 100644
--- /dev/null
+++ b/layout/style/PostTraversalTask.cpp
@@ -0,0 +1,16 @@
+/* -*- 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 "PostTraversalTask.h"
+
+namespace mozilla {
+
+void
+PostTraversalTask::Run()
+{
+}
+
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/layout/style/PostTraversalTask.h
@@ -0,0 +1,45 @@
+/* -*- 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/. */
+
+#ifndef mozilla_PostTraversalTask_h
+#define mozilla_PostTraversalTask_h
+
+/* a task to be performed immediately after a Servo traversal */
+
+namespace mozilla {
+
+/**
+ * A PostTraversalTask is a task to be performed immediately after a Servo
+ * traversal. There are just a few tasks we need to perform, so we use this
+ * class rather than Runnables, to avoid virtual calls and some allocations.
+ *
+ * A PostTraversalTask is only safe to run immediately after the Servo
+ * traversal, since it can hold raw pointers to DOM objects.
+ */
+class PostTraversalTask
+{
+public:
+ void Run();
+
+private:
+ enum class Type
+ {
+ Dummy,
+ };
+
+ explicit PostTraversalTask(Type aType)
+ : mType(aType)
+ , mTarget(nullptr)
+ {
+ }
+
+ Type mType;
+ void* mTarget;
+};
+
+} // namespace mozilla
+
+#endif // mozilla_PostTraversalTask_h
--- a/layout/style/ServoStyleSet.cpp
+++ b/layout/style/ServoStyleSet.cpp
@@ -1101,9 +1101,26 @@ ServoStyleSet::RemoveSheetOfType(SheetTy
uint32_t uniqueID = mEntries[aType][i].uniqueID;
mEntries[aType].RemoveElementAt(i);
return uniqueID;
}
}
return 0;
}
+void
+ServoStyleSet::RunPostTraversalTasks()
+{
+ MOZ_ASSERT(!IsInServoTraversal());
+
+ if (mPostTraversalTasks.IsEmpty()) {
+ return;
+ }
+
+ nsTArray<PostTraversalTask> tasks;
+ tasks.SwapElements(mPostTraversalTasks);
+
+ for (auto& task : tasks) {
+ task.Run();
+ }
+}
+
ServoStyleSet* ServoStyleSet::sInServoTraversal = nullptr;
--- a/layout/style/ServoStyleSet.h
+++ b/layout/style/ServoStyleSet.h
@@ -4,18 +4,20 @@
* 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/. */
#ifndef mozilla_ServoStyleSet_h
#define mozilla_ServoStyleSet_h
#include "mozilla/EnumeratedArray.h"
#include "mozilla/EventStates.h"
+#include "mozilla/PostTraversalTask.h"
#include "mozilla/ServoBindingTypes.h"
#include "mozilla/ServoElementSnapshot.h"
+#include "mozilla/ServoUtils.h"
#include "mozilla/StyleSheetInlines.h"
#include "mozilla/SheetType.h"
#include "mozilla/UniquePtr.h"
#include "MainThreadUtils.h"
#include "nsCSSPseudoElements.h"
#include "nsCSSAnonBoxes.h"
#include "nsChangeHint.h"
#include "nsIAtom.h"
@@ -308,32 +310,52 @@ public:
already_AddRefed<ServoComputedValues>
ResolveForDeclarations(ServoComputedValuesBorrowedOrNull aParentOrNull,
RawServoDeclarationBlockBorrowed aDeclarations);
already_AddRefed<RawServoAnimationValue>
ComputeAnimationValue(RawServoDeclarationBlock* aDeclaration,
const ServoComputedValuesWithParent& aComputedValues);
+ void AppendTask(PostTraversalTask aTask)
+ {
+ MOZ_ASSERT(IsInServoTraversal());
+
+ // We currently only use PostTraversalTasks while the Servo font metrics
+ // mutex is locked. If we need to use them in other situations during
+ // a traversal, we should assert that we've taken appropriate
+ // synchronization measures.
+ AssertIsMainThreadOrServoFontMetricsLocked();
+
+ mPostTraversalTasks.AppendElement(aTask);
+ }
+
private:
+ // On construction, sets sInServoTraversal to the given ServoStyleSet.
+ // On destruction, clears sInServoTraversal and calls RunPostTraversalTasks.
class MOZ_STACK_CLASS AutoSetInServoTraversal
{
public:
explicit AutoSetInServoTraversal(ServoStyleSet* aSet)
+ : mSet(aSet)
{
MOZ_ASSERT(!sInServoTraversal);
MOZ_ASSERT(aSet);
sInServoTraversal = aSet;
}
~AutoSetInServoTraversal()
{
MOZ_ASSERT(sInServoTraversal);
sInServoTraversal = nullptr;
+ mSet->RunPostTraversalTasks();
}
+
+ private:
+ ServoStyleSet* mSet;
};
already_AddRefed<nsStyleContext> GetContext(already_AddRefed<ServoComputedValues>,
nsStyleContext* aParentContext,
nsIAtom* aPseudoTag,
CSSPseudoElementType aPseudoType,
dom::Element* aElementForAnimation);
@@ -373,16 +395,18 @@ private:
*/
void PreTraverse(dom::Element* aRoot = nullptr);
// Subset of the pre-traverse steps that involve syncing up data
void PreTraverseSync();
already_AddRefed<ServoComputedValues> ResolveStyleLazily(dom::Element* aElement,
nsIAtom* aPseudoTag);
+ void RunPostTraversalTasks();
+
uint32_t FindSheetOfType(SheetType aType,
ServoStyleSheet* aSheet);
uint32_t PrependSheetOfType(SheetType aType,
ServoStyleSheet* aSheet,
uint32_t aReuseUniqueID = 0);
uint32_t AppendSheetOfType(SheetType aType,
@@ -416,14 +440,20 @@ private:
bool mAuthorStyleDisabled;
// Stores pointers to our cached style contexts for non-inheriting anonymous
// boxes.
EnumeratedArray<nsCSSAnonBoxes::NonInheriting,
nsCSSAnonBoxes::NonInheriting::_Count,
RefPtr<nsStyleContext>> mNonInheritingStyleContexts;
+ // Tasks to perform after a traversal, back on the main thread.
+ //
+ // These are similar to Servo's SequentialTasks, except that they are
+ // posted by C++ code running on style worker threads.
+ nsTArray<PostTraversalTask> mPostTraversalTasks;
+
static ServoStyleSet* sInServoTraversal;
};
} // namespace mozilla
#endif // mozilla_ServoStyleSet_h
--- a/layout/style/moz.build
+++ b/layout/style/moz.build
@@ -88,16 +88,17 @@ EXPORTS.mozilla += [
'DeclarationBlock.h',
'DeclarationBlockInlines.h',
'DocumentStyleRootIterator.h',
'GenericSpecifiedValues.h',
'GenericSpecifiedValuesInlines.h',
'HandleRefPtr.h',
'IncrementalClearCOMRuleArray.h',
'LayerAnimationInfo.h',
+ 'PostTraversalTask.h',
'PreloadedStyleSheet.h',
'RuleNodeCacheConditions.h',
'RuleProcessorCache.h',
'ServoArcTypeList.h',
'ServoBindingList.h',
'ServoBindings.h',
'ServoBindingTypes.h',
'ServoCSSRuleList.h',
@@ -214,16 +215,17 @@ UNIFIED_SOURCES += [
'nsRuleNode.cpp',
'nsStyleContext.cpp',
'nsStyleCoord.cpp',
'nsStyleSet.cpp',
'nsStyleStruct.cpp',
'nsStyleTransformMatrix.cpp',
'nsStyleUtil.cpp',
'nsTransitionManager.cpp',
+ 'PostTraversalTask.cpp',
'PreloadedStyleSheet.cpp',
'RuleNodeCacheConditions.cpp',
'RuleProcessorCache.cpp',
'ServoBindings.cpp',
'ServoCSSRuleList.cpp',
'ServoDeclarationBlock.cpp',
'ServoElementSnapshot.cpp',
'ServoMediaList.cpp',