From 1eb02fae6c6c60cf8a228aa9825a571e0504b542 Mon Sep 17 00:00:00 2001 From: Cameron McCormack Date: Sun, 30 Apr 2017 14:45:32 +0800 Subject: [PATCH] Bug 1356103 - Part 4: Add a mechanism for C++ functions to perform post-Servo traversal tasks. r=bholley MozReview-Commit-ID: 5Gx1qZzQxAK --HG-- extra : rebase_source : af569f460fb7039faf481e393a34c04bc4c36bb9 --- layout/style/PostTraversalTask.cpp | 16 +++++++++++ layout/style/PostTraversalTask.h | 45 ++++++++++++++++++++++++++++++ layout/style/ServoStyleSet.cpp | 17 +++++++++++ layout/style/ServoStyleSet.h | 30 ++++++++++++++++++++ layout/style/moz.build | 2 ++ 5 files changed, 110 insertions(+) create mode 100644 layout/style/PostTraversalTask.cpp create mode 100644 layout/style/PostTraversalTask.h diff --git a/layout/style/PostTraversalTask.cpp b/layout/style/PostTraversalTask.cpp new file mode 100644 index 000000000000..0dd7aeb190c7 --- /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 diff --git a/layout/style/PostTraversalTask.h b/layout/style/PostTraversalTask.h new file mode 100644 index 000000000000..80ccc036b887 --- /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 diff --git a/layout/style/ServoStyleSet.cpp b/layout/style/ServoStyleSet.cpp index f7a04c28c8c8..e1f8284eafc5 100644 --- a/layout/style/ServoStyleSet.cpp +++ b/layout/style/ServoStyleSet.cpp @@ -1106,4 +1106,21 @@ ServoStyleSet::RemoveSheetOfType(SheetType aType, return 0; } +void +ServoStyleSet::RunPostTraversalTasks() +{ + MOZ_ASSERT(!IsInServoTraversal()); + + if (mPostTraversalTasks.IsEmpty()) { + return; + } + + nsTArray tasks; + tasks.SwapElements(mPostTraversalTasks); + + for (auto& task : tasks) { + task.Run(); + } +} + ServoStyleSet* ServoStyleSet::sInServoTraversal = nullptr; diff --git a/layout/style/ServoStyleSet.h b/layout/style/ServoStyleSet.h index b57be3168c3e..18822f0e304e 100644 --- a/layout/style/ServoStyleSet.h +++ b/layout/style/ServoStyleSet.h @@ -9,8 +9,10 @@ #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" @@ -313,11 +315,27 @@ public: 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); @@ -328,7 +346,11 @@ private: { MOZ_ASSERT(sInServoTraversal); sInServoTraversal = nullptr; + mSet->RunPostTraversalTasks(); } + + private: + ServoStyleSet* mSet; }; already_AddRefed GetContext(already_AddRefed, @@ -378,6 +400,8 @@ private: already_AddRefed ResolveStyleLazily(dom::Element* aElement, nsIAtom* aPseudoTag); + void RunPostTraversalTasks(); + uint32_t FindSheetOfType(SheetType aType, ServoStyleSheet* aSheet); @@ -421,6 +445,12 @@ private: nsCSSAnonBoxes::NonInheriting::_Count, RefPtr> 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 mPostTraversalTasks; + static ServoStyleSet* sInServoTraversal; }; diff --git a/layout/style/moz.build b/layout/style/moz.build index 9557a46dde19..ec913c0500d1 100644 --- a/layout/style/moz.build +++ b/layout/style/moz.build @@ -93,6 +93,7 @@ EXPORTS.mozilla += [ 'HandleRefPtr.h', 'IncrementalClearCOMRuleArray.h', 'LayerAnimationInfo.h', + 'PostTraversalTask.h', 'PreloadedStyleSheet.h', 'RuleNodeCacheConditions.h', 'RuleProcessorCache.h', @@ -219,6 +220,7 @@ UNIFIED_SOURCES += [ 'nsStyleTransformMatrix.cpp', 'nsStyleUtil.cpp', 'nsTransitionManager.cpp', + 'PostTraversalTask.cpp', 'PreloadedStyleSheet.cpp', 'RuleNodeCacheConditions.cpp', 'RuleProcessorCache.cpp',