virtual void visitDOMWrapper(DOMDataStore*, void* impl, v8::Persistent<v8::Object> v8Object) { WrapperTypeInfo* type = V8DOMWrapper::domWrapperType(v8Object); if (!type->isSubclass(&V8ArrayBufferView::info)) return; ArrayBufferView* arrayBufferView = V8ArrayBufferView::toNative(v8Object); m_visitor->visitJSExternalArray(arrayBufferView); }
void visitDOMWrapper(DOMDataStore* store, T* object, v8::Persistent<v8::Object> wrapper) { WrapperTypeInfo* typeInfo = V8DOMWrapper::domWrapperType(wrapper); if (!S::process(object, wrapper, typeInfo)) { ActiveDOMObject* activeDOMObject = typeInfo->toActiveDOMObject(wrapper); if (activeDOMObject && activeDOMObject->hasPendingActivity()) wrapper.ClearWeak(); } }
void ScriptWrappableVisitor::traceWrappersFrom(std::pair<void*, void*> internalFields) { WrapperTypeInfo* wrapperTypeInfo = reinterpret_cast<WrapperTypeInfo*>(internalFields.first); if (wrapperTypeInfo->ginEmbedder != gin::GinEmbedder::kEmbedderBlink) return; ScriptWrappable* scriptWrappable = reinterpret_cast<ScriptWrappable*>(internalFields.second); ASSERT(wrapperTypeInfo->wrapperClassId == WrapperTypeInfo::NodeClassId || wrapperTypeInfo->wrapperClassId == WrapperTypeInfo::ObjectClassId); wrapperTypeInfo->traceWrappers(this, scriptWrappable); }
void visitDOMWrapper(DOMDataStore* store, T* object, v8::Persistent<v8::Object> wrapper) { WrapperTypeInfo* typeInfo = V8DOMWrapper::domWrapperType(wrapper); if (!S::process(object, wrapper, typeInfo)) { ActiveDOMObject* activeDOMObject = typeInfo->toActiveDOMObject(wrapper); if (activeDOMObject && activeDOMObject->hasPendingActivity()) { ASSERT(!wrapper.IsWeak()); // NOTE: To re-enable weak status of the active object we use // |object| from the map and not |activeDOMObject|. The latter // may be a different pointer (in case ActiveDOMObject is not // the main base class of the object's class) and pointer // identity is required by DOM map functions. wrapper.MakeWeak(object, callback); } } }
void visitDOMWrapper(DOMDataStore* store, void* object, v8::Persistent<v8::Object> wrapper) { WrapperTypeInfo* typeInfo = V8DOMWrapper::domWrapperType(wrapper); if (typeInfo->isSubclass(&V8StyleSheetList::info)) { StyleSheetList* styleSheetList = static_cast<StyleSheetList*>(object); GroupId groupId(styleSheetList); if (Document* document = styleSheetList->document()) groupId = GroupId(document); m_grouper.append(GrouperItem(groupId, wrapper)); } else if (typeInfo->isSubclass(&V8DOMImplementation::info)) { DOMImplementation* domImplementation = static_cast<DOMImplementation*>(object); GroupId groupId(domImplementation); if (Document* document = domImplementation->document()) groupId = GroupId(document); m_grouper.append(GrouperItem(groupId, wrapper)); } else if (typeInfo->isSubclass(&V8StyleSheet::info) || typeInfo->isSubclass(&V8CSSRule::info)) { m_grouper.append(GrouperItem(calculateGroupId(static_cast<StyleBase*>(object)), wrapper)); #if 0 //CMP_ERROR_UNCLEAR CSSMutableStyleDeclaration } else if (typeInfo->isSubclass(&V8CSSStyleDeclaration::info)) { CSSStyleDeclaration* cssStyleDeclaration = static_cast<CSSStyleDeclaration*>(object); GroupId groupId = calculateGroupId(cssStyleDeclaration); m_grouper.append(GrouperItem(groupId, wrapper)); // Keep alive "dirty" primitive values (i.e. the ones that // have user-added properties) by creating implicit // references between the style declaration and the values // in it. if (cssStyleDeclaration->isMutableStyleDeclaration()) { CSSMutableStyleDeclaration* cssMutableStyleDeclaration = static_cast<CSSMutableStyleDeclaration*>(cssStyleDeclaration); Vector<v8::Persistent<v8::Value> > values; values.reserveCapacity(cssMutableStyleDeclaration->length()); CSSMutableStyleDeclaration::const_iterator end = cssMutableStyleDeclaration->end(); for (CSSMutableStyleDeclaration::const_iterator it = cssMutableStyleDeclaration->begin(); it != end; ++it) { v8::Persistent<v8::Object> value = store->domObjectMap().get(it->value()); if (!value.IsEmpty() && value->IsDirty()) values.append(value); } if (!values.isEmpty()) v8::V8::AddImplicitReferences(wrapper, values.data(), values.size()); } } else if (typeInfo->isSubclass(&V8CSSRuleList::info)) { CSSRuleList* cssRuleList = static_cast<CSSRuleList*>(object); GroupId groupId(cssRuleList); StyleList* styleList = cssRuleList->styleList(); if (styleList) groupId = calculateGroupId(styleList); m_grouper.append(GrouperItem(groupId, wrapper)); #endif } }
void visitDOMWrapper(DOMDataStore* store, void* object, v8::Persistent<v8::Object> wrapper) { WrapperTypeInfo* typeInfo = V8DOMWrapper::domWrapperType(wrapper); // Additional handling of message port ensuring that entangled ports also // have their wrappers entangled. This should ideally be handled when the // ports are actually entangled in MessagePort::entangle, but to avoid // forking MessagePort.* this is postponed to GC time. Having this postponed // has the drawback that the wrappers are "entangled/unentangled" for each // GC even though their entaglement most likely is still the same. if (V8MessagePort::info.equals(typeInfo)) { // Mark each port as in-use if it's entangled. For simplicity's sake, we assume all ports are remotely entangled, // since the Chromium port implementation can't tell the difference. MessagePort* port1 = static_cast<MessagePort*>(object); if (port1->isEntangled() || port1->hasPendingActivity()) wrapper.ClearWeak(); } else { ActiveDOMObject* activeDOMObject = typeInfo->toActiveDOMObject(wrapper); if (activeDOMObject && activeDOMObject->hasPendingActivity()) wrapper.ClearWeak(); } }
void visitDOMWrapper(DOMDataStore* store, void* object, v8::Persistent<v8::Object> wrapper) { WrapperTypeInfo* typeInfo = V8DOMWrapper::domWrapperType(wrapper); if (V8MessagePort::info.equals(typeInfo)) { MessagePort* port1 = static_cast<MessagePort*>(object); // We marked this port as reachable in GCPrologueVisitor. Undo this now since the // port could be not reachable in the future if it gets disentangled (and also // GCPrologueVisitor expects to see all handles marked as weak). if ((!wrapper.IsWeak() && !wrapper.IsNearDeath()) || port1->hasPendingActivity()) wrapper.MakeWeak(port1, &DOMDataStore::weakActiveDOMObjectCallback); } else { ActiveDOMObject* activeDOMObject = typeInfo->toActiveDOMObject(wrapper); if (activeDOMObject && activeDOMObject->hasPendingActivity()) { ASSERT(!wrapper.IsWeak()); // NOTE: To re-enable weak status of the active object we use // |object| from the map and not |activeDOMObject|. The latter // may be a different pointer (in case ActiveDOMObject is not // the main base class of the object's class) and pointer // identity is required by DOM map functions. wrapper.MakeWeak(object, &DOMDataStore::weakActiveDOMObjectCallback); } } }