mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-08-15 00:43:07 +09:00
Refactor PerformanceObserver to use hash tables for entry type validation and improve ThrottleInputStream state management
This commit is contained in:
parent
cd020e380d
commit
a2a4c62a9b
4 changed files with 55 additions and 12 deletions
|
|
@ -10,9 +10,11 @@
|
|||
#include "mozilla/dom/PerformanceEntryBinding.h"
|
||||
#include "mozilla/dom/PerformanceObserverBinding.h"
|
||||
#include "nsIScriptError.h"
|
||||
#include "nsHashKeys.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsQueryObject.h"
|
||||
#include "nsString.h"
|
||||
#include "nsTHashtable.h"
|
||||
#include "PerformanceEntry.h"
|
||||
#include "PerformanceObserverEntryList.h"
|
||||
#include "WorkerPrivate.h"
|
||||
|
|
@ -225,19 +227,28 @@ void PerformanceObserver::Observe(const PerformanceObserverInit& aOptions,
|
|||
}
|
||||
|
||||
/* 3.3.1.5.2 */
|
||||
nsTHashtable<nsStringHashKey> requestedTypes(entryTypes.Length());
|
||||
for (const auto& type : entryTypes) {
|
||||
requestedTypes.PutEntry(type);
|
||||
}
|
||||
|
||||
nsTArray<nsString> validEntryTypes;
|
||||
for (const char16_t* name : sValidTypeNames) {
|
||||
nsDependentString validTypeName(name);
|
||||
if (entryTypes.Contains<nsString>(validTypeName) &&
|
||||
!validEntryTypes.Contains<nsString>(validTypeName)) {
|
||||
if (requestedTypes.GetEntry(validTypeName)) {
|
||||
validEntryTypes.AppendElement(validTypeName);
|
||||
}
|
||||
}
|
||||
|
||||
nsTHashtable<nsStringHashKey> validTypeSet(validEntryTypes.Length());
|
||||
for (const auto& validType : validEntryTypes) {
|
||||
validTypeSet.PutEntry(validType);
|
||||
}
|
||||
|
||||
nsAutoString invalidTypesJoined;
|
||||
bool addComma = false;
|
||||
for (const auto& type : entryTypes) {
|
||||
if (!validEntryTypes.Contains<nsString>(type)) {
|
||||
if (!validTypeSet.GetEntry(type)) {
|
||||
if (addComma) {
|
||||
invalidTypesJoined.AppendLiteral(", ");
|
||||
}
|
||||
|
|
@ -289,13 +300,13 @@ void PerformanceObserver::Observe(const PerformanceObserverInit& aOptions,
|
|||
|
||||
/* 3.3.1.6.4, 3.3.1.6.4 */
|
||||
bool didUpdateOptionsList = false;
|
||||
nsTArray<PerformanceObserverInit> updatedOptionsList;
|
||||
nsTArray<PerformanceObserverInit> updatedOptionsList(mOptions.Length() + 1);
|
||||
for (auto& option : mOptions) {
|
||||
if (option.mType.WasPassed() && option.mType.Value() == type) {
|
||||
updatedOptionsList.AppendElement(aOptions);
|
||||
didUpdateOptionsList = true;
|
||||
} else {
|
||||
updatedOptionsList.AppendElement(option);
|
||||
updatedOptionsList.AppendElement(Move(option));
|
||||
}
|
||||
}
|
||||
if (!didUpdateOptionsList) {
|
||||
|
|
|
|||
|
|
@ -103,13 +103,23 @@ static LayerSortOrder CompareDepth(Layer* aOne, Layer* aTwo) {
|
|||
// Could we just check Contains() on the bounds rects. ie, is it possible
|
||||
// for layers to overlap without intersections (in 2d space) and yet still
|
||||
// have their bounds rects not completely enclose each other?
|
||||
nsTArray<gfxPoint> points;
|
||||
AutoTArray<gfxPoint, 24> points;
|
||||
auto appendUniquePoint = [&points](const gfxPoint& aPoint) {
|
||||
static const gfxFloat kDuplicateEpsilon = 0.01;
|
||||
for (const auto& point : points) {
|
||||
if (fabs(point.x - aPoint.x) < kDuplicateEpsilon &&
|
||||
fabs(point.y - aPoint.y) < kDuplicateEpsilon) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
points.AppendElement(aPoint);
|
||||
};
|
||||
for (uint32_t i = 0; i < 4; i++) {
|
||||
if (ourTransformedRect.Contains(otherTransformedRect.mPoints[i])) {
|
||||
points.AppendElement(otherTransformedRect.mPoints[i]);
|
||||
appendUniquePoint(otherTransformedRect.mPoints[i]);
|
||||
}
|
||||
if (otherTransformedRect.Contains(ourTransformedRect.mPoints[i])) {
|
||||
points.AppendElement(ourTransformedRect.mPoints[i]);
|
||||
appendUniquePoint(ourTransformedRect.mPoints[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -123,7 +133,7 @@ static LayerSortOrder CompareDepth(Layer* aOne, Layer* aTwo) {
|
|||
gfxLineSegment two(otherTransformedRect.mPoints[j],
|
||||
otherTransformedRect.mPoints[(j + 1) % 4]);
|
||||
if (one.Intersects(two, intersection)) {
|
||||
points.AppendElement(intersection);
|
||||
appendUniquePoint(intersection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@ public:
|
|||
NS_DECL_NSIASYNCINPUTSTREAM
|
||||
|
||||
void AllowInput();
|
||||
bool IsQueued() const;
|
||||
void SetQueued(bool aQueued);
|
||||
|
||||
private:
|
||||
|
||||
|
|
@ -41,6 +43,7 @@ private:
|
|||
|
||||
nsCOMPtr<nsIInputStreamCallback> mCallback;
|
||||
nsCOMPtr<nsIEventTarget> mEventTarget;
|
||||
bool mIsQueued;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(ThrottleInputStream, nsIAsyncInputStream, nsIInputStream, nsISeekableStream)
|
||||
|
|
@ -49,6 +52,7 @@ ThrottleInputStream::ThrottleInputStream(nsIInputStream *aStream, ThrottleQueue*
|
|||
: mStream(aStream)
|
||||
, mQueue(aQueue)
|
||||
, mClosedStatus(NS_OK)
|
||||
, mIsQueued(false)
|
||||
{
|
||||
MOZ_ASSERT(aQueue != nullptr);
|
||||
}
|
||||
|
|
@ -233,6 +237,18 @@ ThrottleInputStream::AllowInput()
|
|||
callbackEvent->OnInputStreamReady(this);
|
||||
}
|
||||
|
||||
bool
|
||||
ThrottleInputStream::IsQueued() const
|
||||
{
|
||||
return mIsQueued;
|
||||
}
|
||||
|
||||
void
|
||||
ThrottleInputStream::SetQueued(bool aQueued)
|
||||
{
|
||||
mIsQueued = aQueued;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NS_IMPL_ISUPPORTS(ThrottleQueue, nsIInputChannelThrottleQueue, nsITimerCallback)
|
||||
|
|
@ -348,6 +364,7 @@ ThrottleQueue::Notify(nsITimer* aTimer)
|
|||
// Optimistically notify all the waiting readers, and then let them
|
||||
// requeue if there isn't enough bandwidth.
|
||||
for (size_t i = 0; i < events.Length(); ++i) {
|
||||
events[i]->SetQueued(false);
|
||||
events[i]->AllowInput();
|
||||
}
|
||||
|
||||
|
|
@ -359,7 +376,8 @@ void
|
|||
ThrottleQueue::QueueStream(ThrottleInputStream* aStream)
|
||||
{
|
||||
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
||||
if (mAsyncEvents.IndexOf(aStream) == mAsyncEvents.NoIndex) {
|
||||
if (!aStream->IsQueued()) {
|
||||
aStream->SetQueued(true);
|
||||
mAsyncEvents.AppendElement(aStream);
|
||||
|
||||
if (!mTimerArmed) {
|
||||
|
|
@ -386,7 +404,12 @@ void
|
|||
ThrottleQueue::DequeueStream(ThrottleInputStream* aStream)
|
||||
{
|
||||
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
||||
if (!aStream->IsQueued()) {
|
||||
return;
|
||||
}
|
||||
|
||||
mAsyncEvents.RemoveElement(aStream);
|
||||
aStream->SetQueued(false);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -354,8 +354,7 @@ TimerThread::Shutdown()
|
|||
// might potentially call some code reentering the same lock
|
||||
// that leads to unexpected behavior or deadlock.
|
||||
// See bug 422472.
|
||||
timers.AppendElements(mTimers);
|
||||
mTimers.Clear();
|
||||
timers.SwapElements(mTimers);
|
||||
}
|
||||
|
||||
uint32_t timersCount = timers.Length();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue