summaryrefslogtreecommitdiffstats
path: root/chromium/third_party/WebKit/Source/bindings/core/v8/V8GCController.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/WebKit/Source/bindings/core/v8/V8GCController.cpp')
-rw-r--r--chromium/third_party/WebKit/Source/bindings/core/v8/V8GCController.cpp49
1 files changed, 42 insertions, 7 deletions
diff --git a/chromium/third_party/WebKit/Source/bindings/core/v8/V8GCController.cpp b/chromium/third_party/WebKit/Source/bindings/core/v8/V8GCController.cpp
index 7dc184828cd..096baa7a937 100644
--- a/chromium/third_party/WebKit/Source/bindings/core/v8/V8GCController.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/core/v8/V8GCController.cpp
@@ -477,34 +477,69 @@ void V8GCController::CollectAllGarbageForTesting(v8::Isolate* isolate) {
v8::Isolate::kFullGarbageCollection);
}
-class DOMWrapperTracer : public v8::PersistentHandleVisitor {
+namespace {
+
+// Traces all DOM persistent handles using the provided visitor.
+class DOMWrapperTracer final : public v8::PersistentHandleVisitor {
public:
explicit DOMWrapperTracer(Visitor* visitor) : visitor_(visitor) {
DCHECK(visitor_);
}
void VisitPersistentHandle(v8::Persistent<v8::Value>* value,
- uint16_t class_id) override {
+ uint16_t class_id) final {
if (class_id != WrapperTypeInfo::kNodeClassId &&
class_id != WrapperTypeInfo::kObjectClassId)
return;
+ visitor_->Trace(
+ ToScriptWrappable(v8::Persistent<v8::Object>::Cast(*value)));
+ }
+
+ private:
+ Visitor* const visitor_;
+};
- const v8::Persistent<v8::Object>& wrapper =
- v8::Persistent<v8::Object>::Cast(*value);
+// Purges all DOM persistent handles.
+class DOMWrapperPurger final : public v8::PersistentHandleVisitor {
+ public:
+ explicit DOMWrapperPurger(v8::Isolate* isolate)
+ : isolate_(isolate), scope_(isolate) {}
- if (ScriptWrappable* script_wrappable = ToScriptWrappable(wrapper))
- ToWrapperTypeInfo(wrapper)->Trace(visitor_, script_wrappable);
+ void VisitPersistentHandle(v8::Persistent<v8::Value>* value,
+ uint16_t class_id) final {
+ if (class_id != WrapperTypeInfo::kNodeClassId &&
+ class_id != WrapperTypeInfo::kObjectClassId)
+ return;
+
+ // Clear out wrapper type information, essentially disconnecting the Blink
+ // wrappable from the V8 wrapper. This way, V8 cannot find the C++ object
+ // anymore.
+
+ int indices[] = {kV8DOMWrapperObjectIndex, kV8DOMWrapperTypeIndex};
+ void* values[] = {nullptr, nullptr};
+ v8::Local<v8::Object> wrapper = v8::Local<v8::Object>::New(
+ isolate_, v8::Persistent<v8::Object>::Cast(*value));
+ wrapper->SetAlignedPointerInInternalFields(arraysize(indices), indices,
+ values);
+ value->Reset();
}
private:
- Visitor* visitor_;
+ v8::Isolate* isolate_;
+ v8::HandleScope scope_;
};
+} // namespace
void V8GCController::TraceDOMWrappers(v8::Isolate* isolate, Visitor* visitor) {
DOMWrapperTracer tracer(visitor);
isolate->VisitHandlesWithClassIds(&tracer);
}
+void V8GCController::ClearDOMWrappers(v8::Isolate* isolate) {
+ DOMWrapperPurger purger(isolate);
+ isolate->VisitHandlesWithClassIds(&purger);
+}
+
class PendingActivityVisitor : public v8::PersistentHandleVisitor {
public:
PendingActivityVisitor(v8::Isolate* isolate,