Changeset 81092 in webkit


Ignore:
Timestamp:
Mar 14, 2011 6:19:14 PM (13 years ago)
Author:
antonm@chromium.org
Message:

2011-03-14 Anton Muhin <antonm@chromium.org>

Reviewed by Adam Barth.

[v8] Rework object group building.
https://bugs.webkit.org/show_bug.cgi?id=55399

Instead of going top-down (from owner to owned elements), go up---from objects
to their group ids. That fits better to v8's object grouping model and guarantees
that each wrapper belongs to the single group.

Alas, this cannot be implemented for one kind of objects---CSSProperties.

Part of core GC algorithm and tested extensively by exisiting layout tests.

  • platform/chromium/test_expectations.txt: Temporary suppress text differences.

2011-03-14 Anton Muhin <antonm@chromium.org>

Reviewed by Adam Barth.

[v8] Rework object group building.
https://bugs.webkit.org/show_bug.cgi?id=55399

Instead of going top-down (from owner to owned elements), go up---from objects
to their group ids. That fits better to v8's object grouping model and guarantees
that each wrapper belongs to the single group.

Alas, this cannot be implemented for one kind of objects---CSSProperties.

Part of core GC algorithm and tested extensively by exisiting layout tests.

  • bindings/scripts/CodeGeneratorV8.pm:
  • bindings/scripts/test/V8/V8TestInterface.cpp:
  • bindings/scripts/test/V8/V8TestMediaQueryListListener.cpp:
  • bindings/scripts/test/V8/V8TestObj.cpp:
  • bindings/v8/V8GCController.cpp: (WebCore::calculateGroupId): (WebCore::calculateRootStyleSheet): (WebCore::GrouperVisitor::visitDOMWrapper): (WebCore::GrouperVisitor::applyGrouping): (WebCore::V8GCController::gcPrologue):
  • bindings/v8/WrapperTypeInfo.h: (WebCore::WrapperTypeInfo::isSubclass):
  • css/CSSRuleList.h: (WebCore::CSSRuleList::styleList):
  • css/StyleSheetList.h: (WebCore::StyleSheetList::document):
Location:
trunk
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r81091 r81092  
     12011-03-14  Anton Muhin  <antonm@chromium.org>
     2
     3        Reviewed by Adam Barth.
     4
     5        [v8] Rework object group building.
     6        https://bugs.webkit.org/show_bug.cgi?id=55399
     7
     8        Instead of going top-down (from owner to owned elements), go up---from objects
     9        to their group ids.  That fits better to v8's object grouping model and guarantees
     10        that each wrapper belongs to the single group.
     11
     12        Alas, this cannot be implemented for one kind of objects---CSSProperties.
     13
     14        Part of core GC algorithm and tested extensively by exisiting layout tests.
     15
     16        * platform/chromium/test_expectations.txt: Temporary suppress text differences.
     17
    1182011-03-14  Ryosuke Niwa  <rniwa@webkit.org>
    219
  • trunk/LayoutTests/platform/chromium/test_expectations.txt

    r81083 r81092  
    33913391BUGCR75639 MAC LEOPARD : fast/canvas/webgl/uninitialized-test.html = TIMEOUT
    33923392
     3393// I (antonm) am working on proper fix for it.  Temporary suppressing text differences.
     3394BUGWK55399 : fast/dom/StyleSheet/gc-inline-style-cssvalues.html = TEXT
     3395
    33933396// Test changed in Wk r80743, throws an exception rather than returning 'true'
    33943397BUGCR75740 : fast/js/regexp-test-null-string.html = FAIL
  • trunk/Source/WebCore/ChangeLog

    r81088 r81092  
     12011-03-14  Anton Muhin  <antonm@chromium.org>
     2
     3        Reviewed by Adam Barth.
     4
     5        [v8] Rework object group building.
     6        https://bugs.webkit.org/show_bug.cgi?id=55399
     7
     8        Instead of going top-down (from owner to owned elements), go up---from objects
     9        to their group ids.  That fits better to v8's object grouping model and guarantees
     10        that each wrapper belongs to the single group.
     11
     12        Alas, this cannot be implemented for one kind of objects---CSSProperties.
     13
     14        Part of core GC algorithm and tested extensively by exisiting layout tests.
     15
     16        * bindings/scripts/CodeGeneratorV8.pm:
     17        * bindings/scripts/test/V8/V8TestInterface.cpp:
     18        * bindings/scripts/test/V8/V8TestMediaQueryListListener.cpp:
     19        * bindings/scripts/test/V8/V8TestObj.cpp:
     20        * bindings/v8/V8GCController.cpp:
     21        (WebCore::calculateGroupId):
     22        (WebCore::calculateRootStyleSheet):
     23        (WebCore::GrouperVisitor::visitDOMWrapper):
     24        (WebCore::GrouperVisitor::applyGrouping):
     25        (WebCore::V8GCController::gcPrologue):
     26        * bindings/v8/WrapperTypeInfo.h:
     27        (WebCore::WrapperTypeInfo::isSubclass):
     28        * css/CSSRuleList.h:
     29        (WebCore::CSSRuleList::styleList):
     30        * css/StyleSheetList.h:
     31        (WebCore::StyleSheetList::document):
     32
    1332011-03-14  Kent Tamura  <tkent@chromium.org>
    234
  • trunk/Source/WebCore/bindings/scripts/CodeGeneratorV8.pm

    r80536 r81092  
    17171717    my $toActive = IsActiveDomType($interfaceName) ? "${className}::toActiveDOMObject" : "0";
    17181718
     1719    # Find the super descriptor.
     1720    my $parentClass = "";
     1721    my $parentClassTemplate = "";
     1722    foreach (@{$dataNode->parents}) {
     1723        my $parent = $codeGenerator->StripModule($_);
     1724        if ($parent eq "EventTarget") {
     1725            next;
     1726        }
     1727        $implIncludes{"V8${parent}.h"} = 1;
     1728        $parentClass = "V8" . $parent;
     1729        $parentClassTemplate = $parentClass . "::GetTemplate()";
     1730        last;
     1731    }
    17191732    push(@implContentDecls, "namespace WebCore {\n\n");
    1720     push(@implContentDecls, "WrapperTypeInfo ${className}::info = { ${className}::GetTemplate, ${className}::derefObject, ${toActive} };\n\n");   
     1733    my $parentClassInfo = $parentClass ? "&${parentClass}::info" : "0";
     1734    push(@implContentDecls, "WrapperTypeInfo ${className}::info = { ${className}::GetTemplate, ${className}::derefObject, ${toActive}, ${parentClassInfo} };\n\n");   
    17211735    push(@implContentDecls, "namespace ${interfaceName}Internal {\n\n");
    17221736    push(@implContentDecls, "template <typename T> void V8_USE(T) { }\n\n");
     
    19421956    }
    19431957
    1944     # find the super descriptor
    1945     my $parentClassTemplate = "";
    1946     foreach (@{$dataNode->parents}) {
    1947         my $parent = $codeGenerator->StripModule($_);
    1948         if ($parent eq "EventTarget") { next; }
    1949         $implIncludes{"V8${parent}.h"} = 1;
    1950         $parentClassTemplate = "V8" . $parent . "::GetTemplate()";
    1951         last;
    1952     }
    19531958    if (!$parentClassTemplate) {
    19541959        $parentClassTemplate = "v8::Persistent<v8::FunctionTemplate>()";
  • trunk/Source/WebCore/bindings/scripts/test/V8/V8TestInterface.cpp

    r80072 r81092  
    3434namespace WebCore {
    3535
    36 WrapperTypeInfo V8TestInterface::info = { V8TestInterface::GetTemplate, V8TestInterface::derefObject, 0 };
     36WrapperTypeInfo V8TestInterface::info = { V8TestInterface::GetTemplate, V8TestInterface::derefObject, 0, 0 };
    3737
    3838namespace TestInterfaceInternal {
  • trunk/Source/WebCore/bindings/scripts/test/V8/V8TestMediaQueryListListener.cpp

    r72728 r81092  
    3434namespace WebCore {
    3535
    36 WrapperTypeInfo V8TestMediaQueryListListener::info = { V8TestMediaQueryListListener::GetTemplate, V8TestMediaQueryListListener::derefObject, 0 };
     36WrapperTypeInfo V8TestMediaQueryListListener::info = { V8TestMediaQueryListListener::GetTemplate, V8TestMediaQueryListListener::derefObject, 0, 0 };
    3737
    3838namespace TestMediaQueryListListenerInternal {
  • trunk/Source/WebCore/bindings/scripts/test/V8/V8TestObj.cpp

    r76277 r81092  
    4747namespace WebCore {
    4848
    49 WrapperTypeInfo V8TestObj::info = { V8TestObj::GetTemplate, V8TestObj::derefObject, 0 };
     49WrapperTypeInfo V8TestObj::info = { V8TestObj::GetTemplate, V8TestObj::derefObject, 0, 0 };
    5050
    5151namespace TestObjInternal {
  • trunk/Source/WebCore/bindings/v8/V8GCController.cpp

    r80842 r81092  
    3535#include "Attr.h"
    3636#include "DOMDataStore.h"
    37 #include "Frame.h"
     37#include "DOMImplementation.h"
    3838#include "HTMLImageElement.h"
    3939#include "HTMLNames.h"
    4040#include "MessagePort.h"
    4141#include "PlatformBridge.h"
    42 #include "SVGElement.h"
    4342#include "V8Binding.h"
    44 #include "V8CSSCharsetRule.h"
    45 #include "V8CSSFontFaceRule.h"
    46 #include "V8CSSImportRule.h"
    47 #include "V8CSSMediaRule.h"
     43#include "V8CSSRule.h"
    4844#include "V8CSSRuleList.h"
    4945#include "V8CSSStyleDeclaration.h"
    50 #include "V8CSSStyleRule.h"
    51 #include "V8CSSStyleSheet.h"
    52 #include "V8DOMMap.h"
    53 #include "V8HTMLLinkElement.h"
    54 #include "V8HTMLStyleElement.h"
     46#include "V8DOMImplementation.h"
    5547#include "V8MessagePort.h"
    56 #include "V8ProcessingInstruction.h"
    57 #include "V8Proxy.h"
     48#include "V8StyleSheet.h"
    5849#include "V8StyleSheetList.h"
    5950#include "WrapperTypeInfo.h"
     
    199190typedef Vector<GrouperItem> GrouperList;
    200191
    201 void makeV8ObjectGroups(GrouperList& grouper)
    202 {
    203     // Group by sorting by the group id.
    204     std::sort(grouper.begin(), grouper.end());
    205 
    206     // FIXME Should probably work in iterators here, but indexes were easier for my simple mind.
    207     for (size_t i = 0; i < grouper.size(); ) {
    208         // Seek to the next key (or the end of the list).
    209         size_t nextKeyIndex = grouper.size();
    210         for (size_t j = i; j < grouper.size(); ++j) {
    211             if (grouper[i].groupId() != grouper[j].groupId()) {
    212                 nextKeyIndex = j;
    213                 break;
    214             }
    215         }
    216 
    217         ASSERT(nextKeyIndex > i);
    218 
    219         // We only care about a group if it has more than one object. If it only
    220         // has one object, it has nothing else that needs to be kept alive.
    221         if (nextKeyIndex - i <= 1) {
    222             i = nextKeyIndex;
    223             continue;
    224         }
    225 
    226         Vector<v8::Persistent<v8::Value> > group;
    227         group.reserveCapacity(nextKeyIndex - i);
    228         for (; i < nextKeyIndex; ++i) {
    229             v8::Persistent<v8::Value> wrapper = grouper[i].wrapper();
    230             if (!wrapper.IsEmpty())
    231                 group.append(wrapper);
    232         }
    233 
    234         if (group.size() > 1)
    235             v8::V8::AddObjectGroup(&group[0], group.size());
    236 
    237         ASSERT(i == nextKeyIndex);
    238     }
    239 }
    240 
    241 class NodeGrouperVisitor : public DOMWrapperMap<Node>::Visitor {
    242 public:
    243     NodeGrouperVisitor()
    244     {
    245         // FIXME: grouper_.reserveCapacity(node_map.size());  ?
    246     }
    247 
    248     void visitDOMWrapper(DOMDataStore* store, Node* node, v8::Persistent<v8::Object> wrapper)
    249     {
    250         // If the node is in document, put it in the ownerDocument's object group.
    251         //
    252         // If an image element was created by JavaScript "new Image",
    253         // it is not in a document. However, if the load event has not
    254         // been fired (still onloading), it is treated as in the document.
    255         //
    256         // Otherwise, the node is put in an object group identified by the root
    257         // element of the tree to which it belongs.
    258         uintptr_t groupId;
    259         if (node->inDocument() || (node->hasTagName(HTMLNames::imgTag) && !static_cast<HTMLImageElement*>(node)->haveFiredLoadEvent()))
    260             groupId = reinterpret_cast<uintptr_t>(node->document());
    261         else {
    262             Node* root = node;
    263             if (node->isAttributeNode()) {
    264                 root = static_cast<Attr*>(node)->ownerElement();
    265                 // If the attribute has no element, no need to put it in the group,
    266                 // because it'll always be a group of 1.
    267                 if (!root)
    268                     return;
    269             } else {
    270                 while (root->parentNode())
    271                     root = root->parentNode();
    272 
    273                 // If the node is alone in its DOM tree (doesn't have a parent or any
    274                 // children) then the group will be filtered out later anyway.
    275                 if (root == node && !node->hasChildNodes() && !node->hasAttributes())
    276                     return;
    277             }
    278             groupId = reinterpret_cast<uintptr_t>(root);
    279         }
    280         m_grouper.append(GrouperItem(groupId, wrapper));
    281 
    282         // If the node is styled and there is a wrapper for the inline
    283         // style declaration, we need to keep that style declaration
    284         // wrapper alive as well, so we add it to the object group.
    285         if (node->isStyledElement()) {
    286             StyledElement* element = reinterpret_cast<StyledElement*>(node);
    287             addDOMObjectToGroup(store, groupId, element->inlineStyleDecl());
    288         }
    289 
    290         if (node->isDocumentNode()) {
    291             Document* document = reinterpret_cast<Document*>(node);
    292             addDOMObjectToGroup(store, groupId, document->styleSheets());
    293             addDOMObjectToGroup(store, groupId, document->implementation());
    294         }
    295 
    296         WrapperTypeInfo* typeInfo = V8DOMWrapper::domWrapperType(wrapper);
    297 
    298         if (V8HTMLLinkElement::info.equals(typeInfo)) {
    299             HTMLLinkElement* htmlLinkElement = static_cast<HTMLLinkElement*>(node);
    300             addDOMObjectToGroup(store, groupId, htmlLinkElement->sheet());
    301         }
    302 
    303         if (V8HTMLStyleElement::info.equals(typeInfo)) {
    304             HTMLStyleElement* htmlStyleElement = static_cast<HTMLStyleElement*>(node);
    305             addDOMObjectToGroup(store, groupId, htmlStyleElement->sheet());
    306         }
    307 
    308         if (V8ProcessingInstruction::info.equals(typeInfo)) {
    309             ProcessingInstruction* processingInstruction = static_cast<ProcessingInstruction*>(node);
    310             addDOMObjectToGroup(store, groupId, processingInstruction->sheet());
    311         }
    312     }
    313 
    314     void applyGrouping()
    315     {
    316         makeV8ObjectGroups(m_grouper);
    317     }
    318 
    319 private:
    320     GrouperList m_grouper;
    321 
    322     void addDOMObjectToGroup(DOMDataStore* store, uintptr_t groupId, void* object)
    323     {
    324         if (!object)
    325             return;
    326         v8::Persistent<v8::Object> wrapper = store->domObjectMap().get(object);
    327         if (!wrapper.IsEmpty())
    328             m_grouper.append(GrouperItem(groupId, wrapper));
    329     }
    330 };
     192// If the node is in document, put it in the ownerDocument's object group.
     193//
     194// If an image element was created by JavaScript "new Image",
     195// it is not in a document. However, if the load event has not
     196// been fired (still onloading), it is treated as in the document.
     197//
     198// Otherwise, the node is put in an object group identified by the root
     199// element of the tree to which it belongs.
     200static uintptr_t calculateGroupId(Node* node)
     201{
     202    if (node->inDocument() || (node->hasTagName(HTMLNames::imgTag) && !static_cast<HTMLImageElement*>(node)->haveFiredLoadEvent()))
     203        return reinterpret_cast<uintptr_t>(node->document());
     204
     205    Node* root = node;
     206    if (node->isAttributeNode()) {
     207        root = static_cast<Attr*>(node)->ownerElement();
     208        // If the attribute has no element, no need to put it in the group,
     209        // because it'll always be a group of 1.
     210        if (!root)
     211            return 0;
     212    } else {
     213        while (Node* parent = root->parentNode())
     214            root = parent;
     215    }
     216
     217    return reinterpret_cast<uintptr_t>(root);
     218}
    331219
    332220static uintptr_t calculateGroupId(StyleBase* styleBase)
     
    336224    StyleSheet* styleSheet = 0;
    337225    while (true) {
    338         // Special case: CSSStyleDeclarations should have CSSRule as a parent
    339         // to proceed with parent traversal, otherwise they are coming from
    340         // inlined style declaration and should be treated as a root.
     226        // Special case: CSSStyleDeclarations might be either inline and in this case
     227        // we need to group them with their node or regular ones.
    341228        if (current->isMutableStyleDeclaration()) {
    342229            CSSMutableStyleDeclaration* cssMutableStyleDeclaration = static_cast<CSSMutableStyleDeclaration*>(current);
    343             if (CSSRule* parentRule = cssMutableStyleDeclaration->parentRule())
    344                 current = parentRule;
    345             else
    346                 return reinterpret_cast<uintptr_t>(cssMutableStyleDeclaration);
     230            if (cssMutableStyleDeclaration->isInlineStyleDeclaration()) {
     231                ASSERT(cssMutableStyleDeclaration->parent()->isStyleSheet());
     232                return calculateGroupId(cssMutableStyleDeclaration->node());
     233            }
     234            // Either we have no parent, or this parent is a CSSRule.
     235            ASSERT(cssMutableStyleDeclaration->parent() == cssMutableStyleDeclaration->parentRule());
    347236        }
    348237
     
    356245    }
    357246
    358     if (styleSheet)
     247    if (styleSheet) {
     248        if (Node* ownerNode = styleSheet->ownerNode())
     249            return calculateGroupId(ownerNode);
    359250        return reinterpret_cast<uintptr_t>(styleSheet);
     251    }
    360252
    361253    return reinterpret_cast<uintptr_t>(current);
    362254}
    363255
    364 class DOMObjectGrouperVisitor : public DOMWrapperMap<void>::Visitor {
    365 public:
    366     DOMObjectGrouperVisitor()
    367     {
    368     }
    369 
    370     void startMap()
    371     {
    372         m_grouper.shrink(0);
    373     }
    374 
    375     void endMap()
    376     {
    377         makeV8ObjectGroups(m_grouper);
     256class GrouperVisitor : public DOMWrapperMap<Node>::Visitor, public DOMWrapperMap<void>::Visitor {
     257public:
     258    void visitDOMWrapper(DOMDataStore* store, Node* node, v8::Persistent<v8::Object> wrapper)
     259    {
     260        uintptr_t groupId = calculateGroupId(node);
     261        if (!groupId)
     262            return;
     263        m_grouper.append(GrouperItem(groupId, wrapper));
    378264    }
    379265
     
    381267    {
    382268        WrapperTypeInfo* typeInfo = V8DOMWrapper::domWrapperType(wrapper);
    383         // FIXME: extend WrapperTypeInfo with isStyle to simplify the check below or consider
    384         // adding a virtual method to WrapperTypeInfo which would know how to group objects.
    385         // FIXME: check if there are other StyleBase wrappers we should care of.
    386         if (V8CSSStyleSheet::info.equals(typeInfo)
    387             || V8CSSStyleDeclaration::info.equals(typeInfo)
    388             || V8CSSCharsetRule::info.equals(typeInfo)
    389             || V8CSSFontFaceRule::info.equals(typeInfo)
    390             || V8CSSStyleRule::info.equals(typeInfo)
    391             || V8CSSImportRule::info.equals(typeInfo)
    392             || V8CSSMediaRule::info.equals(typeInfo)) {
    393             StyleBase* styleBase = static_cast<StyleBase*>(object);
    394 
    395             uintptr_t groupId = calculateGroupId(styleBase);
     269
     270        if (typeInfo->isSubclass(&V8StyleSheetList::info)) {
     271            StyleSheetList* styleSheetList = static_cast<StyleSheetList*>(object);
     272            uintptr_t groupId = reinterpret_cast<uintptr_t>(styleSheetList);
     273            if (Document* document = styleSheetList->document())
     274                groupId = reinterpret_cast<uintptr_t>(document);
    396275            m_grouper.append(GrouperItem(groupId, wrapper));
    397276
    398             if (V8CSSStyleDeclaration::info.equals(typeInfo)) {
    399                 CSSStyleDeclaration* cssStyleDeclaration = static_cast<CSSStyleDeclaration*>(styleBase);
    400                 if (cssStyleDeclaration->isMutableStyleDeclaration()) {
    401                     CSSMutableStyleDeclaration* cssMutableStyleDeclaration = static_cast<CSSMutableStyleDeclaration*>(cssStyleDeclaration);
    402                     CSSMutableStyleDeclaration::const_iterator end = cssMutableStyleDeclaration->end();
    403                     for (CSSMutableStyleDeclaration::const_iterator it = cssMutableStyleDeclaration->begin(); it != end; ++it) {
    404                         wrapper = store->domObjectMap().get(it->value());
    405                         if (!wrapper.IsEmpty())
    406                             m_grouper.append(GrouperItem(groupId, wrapper));
    407                     }
     277        } else if (typeInfo->isSubclass(&V8DOMImplementation::info)) {
     278            DOMImplementation* domImplementation = static_cast<DOMImplementation*>(object);
     279            uintptr_t groupId = reinterpret_cast<uintptr_t>(domImplementation);
     280            if (Document* document = domImplementation->ownerDocument())
     281                groupId = reinterpret_cast<uintptr_t>(document);
     282            m_grouper.append(GrouperItem(groupId, wrapper));
     283
     284        } else if (typeInfo->isSubclass(&V8StyleSheet::info) || typeInfo->isSubclass(&V8CSSRule::info)) {
     285            m_grouper.append(GrouperItem(calculateGroupId(static_cast<StyleBase*>(object)), wrapper));
     286
     287        } else if (typeInfo->isSubclass(&V8CSSStyleDeclaration::info)) {
     288            CSSStyleDeclaration* cssStyleDeclaration = static_cast<CSSStyleDeclaration*>(object);
     289
     290            uintptr_t groupId = calculateGroupId(cssStyleDeclaration);
     291            m_grouper.append(GrouperItem(groupId, wrapper));
     292
     293        } else if (typeInfo->isSubclass(&V8CSSRuleList::info)) {
     294            CSSRuleList* cssRuleList = static_cast<CSSRuleList*>(object);
     295            uintptr_t groupId = reinterpret_cast<uintptr_t>(cssRuleList);
     296            StyleList* styleList = cssRuleList->styleList();
     297            if (styleList)
     298                groupId = calculateGroupId(styleList);
     299            m_grouper.append(GrouperItem(groupId, wrapper));
     300        }
     301    }
     302
     303    void applyGrouping()
     304    {
     305        // Group by sorting by the group id.
     306        std::sort(m_grouper.begin(), m_grouper.end());
     307
     308        for (size_t i = 0; i < m_grouper.size(); ) {
     309            // Seek to the next key (or the end of the list).
     310            size_t nextKeyIndex = m_grouper.size();
     311            for (size_t j = i; j < m_grouper.size(); ++j) {
     312                if (m_grouper[i].groupId() != m_grouper[j].groupId()) {
     313                    nextKeyIndex = j;
     314                    break;
    408315                }
    409316            }
    410         } else if (V8StyleSheetList::info.equals(typeInfo)) {
    411             addAllItems(store, static_cast<StyleSheetList*>(object), wrapper);
    412         } else if (V8CSSRuleList::info.equals(typeInfo)) {
    413             addAllItems(store, static_cast<CSSRuleList*>(object), wrapper);
     317
     318            ASSERT(nextKeyIndex > i);
     319
     320            // We only care about a group if it has more than one object. If it only
     321            // has one object, it has nothing else that needs to be kept alive.
     322            if (nextKeyIndex - i <= 1) {
     323                i = nextKeyIndex;
     324                continue;
     325            }
     326
     327            Vector<v8::Persistent<v8::Value> > group;
     328            group.reserveCapacity(nextKeyIndex - i);
     329            for (; i < nextKeyIndex; ++i) {
     330                v8::Persistent<v8::Value> wrapper = m_grouper[i].wrapper();
     331                if (!wrapper.IsEmpty())
     332                    group.append(wrapper);
     333            }
     334
     335            if (group.size() > 1)
     336                v8::V8::AddObjectGroup(&group[0], group.size());
     337
     338            ASSERT(i == nextKeyIndex);
    414339        }
    415340    }
     
    417342private:
    418343    GrouperList m_grouper;
    419 
    420     template <class C>
    421     void addAllItems(DOMDataStore* store, C* collection, v8::Persistent<v8::Object> wrapper)
    422     {
    423         uintptr_t groupId = reinterpret_cast<uintptr_t>(collection);
    424         m_grouper.append(GrouperItem(groupId, wrapper));
    425         for (unsigned i = 0; i < collection->length(); i++) {
    426             wrapper = store->domObjectMap().get(collection->item(i));
    427             if (!wrapper.IsEmpty())
    428                 m_grouper.append(GrouperItem(groupId, wrapper));
    429         }
    430     }
    431344};
    432345
     
    447360
    448361    // Create object groups.
    449     NodeGrouperVisitor nodeGrouperVisitor;
    450     visitDOMNodesInCurrentThread(&nodeGrouperVisitor);
    451     nodeGrouperVisitor.applyGrouping();
    452 
    453     DOMObjectGrouperVisitor domObjectGrouperVisitor;
    454     visitDOMObjectsInCurrentThread(&domObjectGrouperVisitor);
     362    GrouperVisitor grouperVisitor;
     363    visitDOMNodesInCurrentThread(&grouperVisitor);
     364    visitDOMObjectsInCurrentThread(&grouperVisitor);
     365    grouperVisitor.applyGrouping();
    455366
    456367    // Clean single element cache for string conversions.
  • trunk/Source/WebCore/bindings/v8/WrapperTypeInfo.h

    r57004 r81092  
    6262            return this == that;
    6363        }
     64
     65        bool isSubclass(const WrapperTypeInfo* that) const
     66        {
     67            for (const WrapperTypeInfo* current = this; current; current = current->parentClass) {
     68                if (current == that)
     69                    return true;
     70            }
     71
     72            return false;
     73        }
    6474       
    6575        v8::Persistent<v8::FunctionTemplate> getTemplate() { return getTemplateFunction(); }
     
    8191        const DerefObjectFunction derefObjectFunction;
    8292        const ToActiveDOMObjectFunction toActiveDOMObjectFunction;
     93        const WrapperTypeInfo* parentClass;
    8394    };
    8495}
  • trunk/Source/WebCore/css/CSSMutableStyleDeclaration.cpp

    r80963 r81092  
    499499}
    500500
     501bool CSSMutableStyleDeclaration::isInlineStyleDeclaration()
     502{
     503    // FIXME: Ideally, this should be factored better and there
     504    // should be a subclass of CSSMutableStyleDeclaration just
     505    // for inline style declarations that handles this
     506    return m_node && m_node->isStyledElement() && static_cast<StyledElement*>(m_node)->inlineStyleDecl() == this;
     507}
     508
    501509void CSSMutableStyleDeclaration::setNeedsStyleRecalc()
    502510{
    503511    if (m_node) {
    504         // FIXME: Ideally, this should be factored better and there
    505         // should be a subclass of CSSMutableStyleDeclaration just
    506         // for inline style declarations that handles this
    507         bool isInlineStyleDeclaration = m_node->isStyledElement() && this == static_cast<StyledElement*>(m_node)->inlineStyleDecl();
    508         if (isInlineStyleDeclaration) {
     512        if (isInlineStyleDeclaration()) {
    509513            m_node->setNeedsStyleRecalc(InlineStyleChange);
    510514            static_cast<StyledElement*>(m_node)->invalidateStyleAttribute();
  • trunk/Source/WebCore/css/CSSMutableStyleDeclaration.h

    r80620 r81092  
    141141    bool propertiesEqual(const CSSMutableStyleDeclaration* o) const { return m_properties == o->m_properties; }
    142142
     143    bool isInlineStyleDeclaration();
     144
    143145protected:
    144146    CSSMutableStyleDeclaration(CSSRule* parentRule);
  • trunk/Source/WebCore/css/CSSRuleList.h

    r50583 r81092  
    5454    void append(CSSRule*);
    5555
     56    StyleList* styleList()
     57    {
     58        return m_list.get();
     59    }
     60
    5661private:
    5762    CSSRuleList();
  • trunk/Source/WebCore/css/StyleSheetList.h

    r65021 r81092  
    5151        m_sheets.swap(sheets);
    5252    }
     53
     54    Document* document()
     55    {
     56        return m_doc;
     57    }
    5358   
    5459private:
Note: See TracChangeset for help on using the changeset viewer.