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 : d3c119e2a71833462d67bb373674bbd38a7aa47d
This commit is contained in:
Cameron McCormack 2017-04-30 14:45:32 +08:00
parent 64ee30fc47
commit b3951ab999
5 changed files with 110 additions and 0 deletions

View File

@ -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

View File

@ -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,
};
PostTraversalTask(Type aType)
: mType(aType)
, mTarget(nullptr)
{
}
Type mType;
void* mTarget;
};
} // namespace mozilla
#endif // mozilla_PostTraversalTask_h

View File

@ -1106,4 +1106,21 @@ ServoStyleSet::RemoveSheetOfType(SheetType aType,
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;

View File

@ -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:
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<nsStyleContext> GetContext(already_AddRefed<ServoComputedValues>,
@ -378,6 +400,8 @@ private:
already_AddRefed<ServoComputedValues> ResolveStyleLazily(dom::Element* aElement,
nsIAtom* aPseudoTag);
void RunPostTraversalTasks();
uint32_t FindSheetOfType(SheetType aType,
ServoStyleSheet* aSheet);
@ -421,6 +445,12 @@ private:
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;
};

View File

@ -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',