SVN commit 1197123 by carewolf: Use less memory by sharing more RenderStyle sub-objects between elements. M +44 -1 css/cssstyleselector.cpp M +2 -0 css/cssstyleselector.h M +22 -0 rendering/render_style.cpp M +1 -0 rendering/render_style.h --- trunk/KDE/kdelibs/khtml/css/cssstyleselector.cpp #1197122:1197123 @@ -3,7 +3,7 @@ * * Copyright 1999-2003 Lars Knoll (knoll@kde.org) * Copyright 2003-2004 Apple Computer, Inc. - * Copyright 2004-2006 Allan Sandfeld Jensen (kde@carewolf.com) + * Copyright 2004-2010 Allan Sandfeld Jensen (kde@carewolf.com) * Copyright 2004-2008 Germain Garand (germain@ebooksfrance.org) * Copyright 2008 Vyacheslav Tokarev (tsjoker@gmail.com) * (C) 2005, 2006, 2008 Apple Computer, Inc. @@ -543,6 +543,44 @@ #undef MAXFONTSIZES +RenderStyle* CSSStyleSelector::locateSimilarStyle() +{ + ElementImpl *s=0, *t=0, *c=0; + if (!element) return 0; + // Check previous siblings. + unsigned count = 0; + NodeImpl* n; + do { + for (n = element->previousSibling(); n && !n->isElementNode(); n = n->previousSibling()); + if (!n) break; + ElementImpl *e = static_cast(n); + if (++count > 10) break; + if (!s) s = e; // sibling match + if (e->id() != element->id()) continue; + if (!t) t = e; // tag match + if (element->hasClass()) { + if (!e->hasClass()) continue; + const DOMString& class1 = element->getAttribute(ATTR_CLASS); + const DOMString& class2 = e->getAttribute(ATTR_CLASS); + if (class1 != class2) continue; + } + if (!c) c = e; // class match + break; + } while(true); + + // if possible return sibling that matches tag and class + if (c && c->renderer() && c->renderer()->style()) return c->renderer()->style(); + // second best: return sibling that matches tag + if (t && t->renderer() && t->renderer()->style()) return t->renderer()->style(); + // third best: return sibling element + if (s && s->renderer() && s->renderer()->style()) return s->renderer()->style(); + // last attempt: return parent element + NodeImpl* p = element->parentNode(); + if (p && p->renderer()) return p->renderer()->style(); + + return 0; +} + static inline void bubbleSort( CSSOrderedProperty **b, CSSOrderedProperty **e ) { while( b < e ) { @@ -774,6 +812,11 @@ pseudoStyle = pseudoStyle->pseudoStyle; } + // Try and share or partially share the style with our siblings + RenderStyle *commonStyle = locateSimilarStyle(); + if (commonStyle) + style->compactWith(commonStyle); + // Now return the style. return style; } --- trunk/KDE/kdelibs/khtml/css/cssstyleselector.h #1197122:1197123 @@ -227,6 +227,8 @@ current generic font family has changed. -dwh */ void checkForGenericFamilyChange(RenderStyle* aStyle, RenderStyle* aParentStyle); #endif + // locates potentially similar style + RenderStyle* locateSimilarStyle(); /* builds up the selectors and properties lists from the CSSStyleSelectorList's */ void buildLists(); --- trunk/KDE/kdelibs/khtml/rendering/render_style.cpp #1197122:1197123 @@ -618,6 +618,28 @@ setWhiteSpace(PRE_LINE); } +void RenderStyle::compactWith(const RenderStyle* similarStyle) +{ + if (this == similarStyle) return; + + if (box.get() != similarStyle->box.get() && box == similarStyle->box) + box = similarStyle->box; + if (visual.get() != similarStyle->visual.get() && visual == similarStyle->visual) + visual = similarStyle->visual; + if (background.get() != similarStyle->background.get() && background == similarStyle->background) + background = similarStyle->background; + if (surround.get() != similarStyle->surround.get() && surround == similarStyle->surround) + surround = similarStyle->surround; + if (generated.get() != similarStyle->generated.get() && generated == similarStyle->generated) + generated = similarStyle->generated; + if (css3NonInheritedData.get() != similarStyle->css3NonInheritedData.get() && css3NonInheritedData == similarStyle->css3NonInheritedData) + css3NonInheritedData = similarStyle->css3NonInheritedData; + if (css3InheritedData.get() != similarStyle->css3InheritedData.get() && css3InheritedData == similarStyle->css3InheritedData) + css3InheritedData = similarStyle->css3InheritedData; + if (inherited.get() != similarStyle->inherited.get() && inherited == similarStyle->inherited) + inherited = similarStyle->inherited; +} + RenderStyle::~RenderStyle() { RenderStyle *ps = pseudoStyle; --- trunk/KDE/kdelibs/khtml/rendering/render_style.h #1197122:1197123 @@ -983,6 +983,7 @@ ~RenderStyle(); void inheritFrom(const RenderStyle* inheritParent); + void compactWith(const RenderStyle* similarStyle); PseudoId styleType() const { return KDE_CAST_BF_ENUM(PseudoId, noninherited_flags.f._styleType); } void setStyleType(PseudoId pi) { noninherited_flags.f._styleType = pi; }