Commit b0dc3da9 authored by Yuki Shiino's avatar Yuki Shiino Committed by Commit Bot

v8binding: Supports wrapper-tracing for pending IntersectionObservers.

IntersectionObservers are usually made alive through the observation
target elements (ElementIntersectionObserverData).  However, it's
possible that the target element gets detached from the document
while an observation event is being scheduled (while it's pending).

Considering this corner case, IntersectionObserverController should
take responsibility to make the sheduled IntersectionObservers alive.

Bug: 792604
Change-Id: I63a435173d51025dcd4fd4276bc7cc1788e9a2bf
Reviewed-on: https://chromium-review.googlesource.com/836575Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Commit-Queue: Yuki Shiino <yukishiino@chromium.org>
Cr-Commit-Position: refs/heads/master@{#525324}
parent 6a6a07a4
......@@ -7316,6 +7316,7 @@ void Document::TraceWrappers(const ScriptWrappableVisitor* visitor) const {
visitor->TraceWrappers(script_runner_);
visitor->TraceWrappers(scripted_animation_controller_);
visitor->TraceWrappers(scripted_idle_task_controller_);
visitor->TraceWrappers(intersection_observer_controller_);
ContainerNode::TraceWrappers(visitor);
Supplementable<Document>::TraceWrappers(visitor);
}
......
......@@ -1765,7 +1765,8 @@ class CORE_EXPORT Document : public ContainerNode,
Member<CanvasFontCache> canvas_font_cache_;
Member<IntersectionObserverController> intersection_observer_controller_;
TraceWrapperMember<IntersectionObserverController>
intersection_observer_controller_;
Member<ResizeObserverController> resize_observer_controller_;
int node_count_;
......
......@@ -64,10 +64,10 @@ void IntersectionObserverController::DeliverIntersectionObservations() {
callback_fired_while_suspended_ = true;
return;
}
HeapHashSet<Member<IntersectionObserver>> observers;
pending_intersection_observers_.swap(observers);
for (auto& observer : observers)
pending_intersection_observers_.swap(intersection_observers_being_invoked_);
for (auto& observer : intersection_observers_being_invoked_)
observer->Deliver();
intersection_observers_being_invoked_.clear();
}
void IntersectionObserverController::ComputeTrackedIntersectionObservations() {
......@@ -98,7 +98,16 @@ void IntersectionObserverController::RemoveTrackedObserversForRoot(
void IntersectionObserverController::Trace(blink::Visitor* visitor) {
visitor->Trace(tracked_intersection_observers_);
visitor->Trace(pending_intersection_observers_);
visitor->Trace(intersection_observers_being_invoked_);
PausableObject::Trace(visitor);
}
void IntersectionObserverController::TraceWrappers(
const ScriptWrappableVisitor* visitor) const {
for (const auto& observer : pending_intersection_observers_)
visitor->TraceWrappers(observer);
for (const auto& observer : intersection_observers_being_invoked_)
visitor->TraceWrappers(observer);
}
} // namespace blink
......@@ -7,6 +7,7 @@
#include "core/dom/PausableObject.h"
#include "core/intersection_observer/IntersectionObserver.h"
#include "platform/bindings/TraceWrapperMember.h"
#include "platform/heap/Handle.h"
#include "platform/wtf/HashSet.h"
......@@ -19,7 +20,8 @@ class Document;
class IntersectionObserverController
: public GarbageCollectedFinalized<IntersectionObserverController>,
public PausableObject {
public PausableObject,
public TraceWrapperBase {
USING_GARBAGE_COLLECTED_MIXIN(IntersectionObserverController);
public:
......@@ -35,6 +37,7 @@ class IntersectionObserverController
void RemoveTrackedObserversForRoot(const Node&);
void Trace(blink::Visitor*);
void TraceWrappers(const ScriptWrappableVisitor*) const override;
private:
explicit IntersectionObserverController(Document*);
......@@ -45,7 +48,12 @@ class IntersectionObserverController
HeapHashSet<WeakMember<IntersectionObserver>> tracked_intersection_observers_;
// IntersectionObservers for which this is the execution context of the
// callback.
HeapHashSet<Member<IntersectionObserver>> pending_intersection_observers_;
HeapHashSet<TraceWrapperMember<IntersectionObserver>>
pending_intersection_observers_;
// TODO(https://crbug.com/796145): Remove this hack once on-stack objects
// get supported by either of wrapper-tracing or unified GC.
HeapHashSet<TraceWrapperMember<IntersectionObserver>>
intersection_observers_being_invoked_;
bool callback_fired_while_suspended_;
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment