Bug 1335319 - Add a global flag indicating that we're in the servo traversal. r=bz

This commit is contained in:
Bobby Holley 2017-02-02 11:48:28 -08:00
parent 5a4e484266
commit f5bde33979
3 changed files with 25 additions and 4 deletions

View File

@ -6,6 +6,7 @@
#include "FramePropertyTable.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/ServoStyleSet.h"
#include "nsThreadUtils.h"
namespace mozilla {
@ -74,12 +75,9 @@ FramePropertyTable::GetInternal(
// We can end up here during parallel style traversal, in which case the main
// thread is blocked. Reading from the cache is fine on any thread, but we
// only want to write to it in the main-thread case.
//
// We order things such that we only need to check TLS in the case of a cache
// miss.
bool cacheHit = mLastFrame == aFrame;
Entry* entry = cacheHit ? mLastEntry : mEntries.GetEntry(aFrame);
if (!cacheHit && NS_IsMainThread()) {
if (!cacheHit && !ServoStyleSet::IsInServoTraversal()) {
mLastFrame = aFrame;
mLastEntry = entry;
}

View File

@ -191,7 +191,11 @@ void
ServoStyleSet::PrepareAndTraverseSubtree(RawGeckoElementBorrowed aRoot,
mozilla::TraversalRootBehavior aRootBehavior) {
ResolveMappedAttrDeclarationBlocks();
MOZ_ASSERT(!sInServoTraversal);
sInServoTraversal = true;
Servo_TraverseSubtree(aRoot, mRawSet.get(), aRootBehavior);
sInServoTraversal = false;
}
already_AddRefed<nsStyleContext>
@ -628,3 +632,5 @@ ServoStyleSet::ResolveServoStyle(Element* aElement)
{
return Servo_ResolveStyle(aElement, mRawSet.get()).Consume();
}
bool ServoStyleSet::sInServoTraversal = false;

View File

@ -44,6 +44,21 @@ class ServoStyleSet
{
friend class ServoRestyleManager;
public:
static bool IsInServoTraversal(bool aAssertServoTraversalOrMainThread = true)
{
// The callers of this function are generally main-thread-only _except_
// for potentially running during the Servo traversal, in which case they may
// take special paths that avoid writing to caches and the like. In order
// to allow those callers to branch efficiently without checking TLS, we
// maintain this static boolean. However, the danger is that those callers
// are generally unprepared to deal with non-Servo-but-also-non-main-thread
// callers, and are likely to take the main-thread codepath if this function
// returns false. So we assert against other non-main-thread callers here.
MOZ_ASSERT_IF(aAssertServoTraversalOrMainThread,
sInServoTraversal || NS_IsMainThread());
return sInServoTraversal;
}
ServoStyleSet();
void Init(nsPresContext* aPresContext);
@ -218,6 +233,8 @@ private:
EnumeratedArray<SheetType, SheetType::Count,
nsTArray<RefPtr<ServoStyleSheet>>> mSheets;
int32_t mBatching;
static bool sInServoTraversal;
};
} // namespace mozilla