diff options
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.cpp | 49 |
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, |