void DOMObjectCache::forget(void* objectHandle) { DOMObjectCacheData* cacheData = domObjects().get(objectHandle); ASSERT(cacheData); g_slice_free(DOMObjectCacheData, cacheData); domObjects().take(objectHandle); }
void* DOMObjectCache::put(void* objectHandle, void* wrapper) { if (domObjects().get(objectHandle)) return wrapper; DOMObjectCacheData* data = g_slice_new(DOMObjectCacheData); data->object = static_cast<GObject*>(wrapper); data->frame = 0; data->timesReturned = 1; domObjects().set(objectHandle, data); return wrapper; }
void ScriptInterpreter::mark(bool currentThreadIsMainThread) { if (!currentThreadIsMainThread) { // On alternate threads, DOMObjects remain in the cache because they're not collected. // So, they need an opportunity to mark their children. DOMObjectMap::iterator objectEnd = domObjects().end(); for (DOMObjectMap::iterator objectIt = domObjects().begin(); objectIt != objectEnd; ++objectIt) { DOMObject* object = objectIt->second; if (!object->marked()) object->mark(); } } Interpreter::mark(currentThreadIsMainThread); }
DOMNode* ScriptInterpreter::getDOMNodeForDocument(Document* document, Node* node) { if (!document) return static_cast<DOMNode*>(domObjects().get(node)); NodeMap* documentDict = domNodesPerDocument().get(document); if (documentDict) return documentDict->get(node); return NULL; }
void DOMObjectCache::put(WebCore::Node* objectHandle, void* wrapper) { DOMObjectMap::AddResult result = domObjects().add(objectHandle, nullptr); if (!result.isNewEntry) return; result.iterator->value = std::make_unique<DOMObjectCacheData>(G_OBJECT(wrapper)); if (WebCore::Frame* frame = objectHandle->document().frame()) getOrCreateDOMObjectCacheFrameObserver(*frame).addObjectCacheData(*result.iterator->value); }
void ScriptInterpreter::forgetDOMNodeForDocument(Document* document, Node* node) { REMOVE_WRAPPER(getDOMNodeForDocument(document, node)); if (!document) { domObjects().remove(node); return; } NodeMap* documentDict = domNodesPerDocument().get(document); if (documentDict) documentDict->remove(node); }
void* DOMObjectCache::get(void* objectHandle) { DOMObjectCacheData* data = domObjects().get(objectHandle); if (!data) return 0; // We want to add one ref each time a wrapper is returned, so that // the user can manually unref them if he chooses to. ASSERT(data->object); data->timesReturned++; return g_object_ref(data->object); }
void DOMObjectCache::clearByFrame(WebCore::Frame* frame) { Vector<DOMObjectCacheData*> toUnref; // Unreffing the objects removes them from the cache in their // finalize method, so just save them to do that while we are not // iterating the cache itself. DOMObjectMap::iterator end = domObjects().end(); for (DOMObjectMap::iterator iter = domObjects().begin(); iter != end; ++iter) { DOMObjectCacheData* data = iter->second; ASSERT(data); if ((!frame || data->frame == frame) && data->timesReturned) toUnref.append(data); } Vector<DOMObjectCacheData*>::iterator last = toUnref.end(); for (Vector<DOMObjectCacheData*>::iterator it = toUnref.begin(); it != last; ++it) { DOMObjectCacheData* data = *it; // We can't really know what the user has done with the DOM // objects, so in case any of the external references to them // were unreffed (but not all, otherwise the object would be // dead and out of the cache) we'll add a weak ref before we // start to get rid of the cache's own references; if the // object dies in the middle of the process, we'll just stop. gboolean objectDead = FALSE; g_object_weak_ref(data->object, weakRefNotify, &objectDead); // We need to check objectDead first, otherwise the cache data // might be garbage already. while (!objectDead && data->timesReturned > 0) { // If this is the last unref we are going to do, // disconnect the weak ref. We cannot do it afterwards // because the object might be dead at that point. if (data->timesReturned == 1) g_object_weak_unref(data->object, weakRefNotify, &objectDead); data->timesReturned--; g_object_unref(data->object); } } }
void* DOMObjectCache::put(WebCore::Node* objectHandle, void* wrapper) { // call the ::put version that takes void* to do the basic cache // insertion work put(static_cast<void*>(objectHandle), wrapper); DOMObjectCacheData* data = domObjects().get(objectHandle); ASSERT(data); data->frame = getFrameFromHandle(objectHandle); return wrapper; }
void ScriptInterpreter::putDOMNodeForDocument(Document* document, Node* node, DOMNode* wrapper) { ADD_WRAPPER(wrapper); if (!document) { domObjects().set(node, wrapper); return; } NodeMap* documentDict = domNodesPerDocument().get(document); if (!documentDict) { documentDict = new NodeMap; domNodesPerDocument().set(document, documentDict); } documentDict->set(node, wrapper); }
void DOMObjectCache::put(void* objectHandle, void* wrapper) { DOMObjectMap::AddResult result = domObjects().add(objectHandle, nullptr); if (result.isNewEntry) result.iterator->value = std::make_unique<DOMObjectCacheData>(G_OBJECT(wrapper)); }
void* DOMObjectCache::get(void* objectHandle) { DOMObjectCacheData* data = domObjects().get(objectHandle); return data ? data->refObject() : nullptr; }
void DOMObjectCache::forget(void* objectHandle) { ASSERT(domObjects().contains(objectHandle)); domObjects().remove(objectHandle); }
void ScriptInterpreter::forgetDOMObject(void* objectHandle) { REMOVE_WRAPPER(domObjects().get(objectHandle)); domObjects().remove(objectHandle); }
void ScriptInterpreter::putDOMObject(void* objectHandle, DOMObject* wrapper) { ADD_WRAPPER(wrapper); domObjects().set(objectHandle, wrapper); }
DOMObject* ScriptInterpreter::getDOMObject(void* objectHandle) { return domObjects().get(objectHandle); }