[Chromium] Implementing a global limit on memory consumed by deferred 2D canvases
https://bugs.webkit.org/show_bug.cgi?id=94386

Patch by Justin Novosad <junov@chromium.org> on 2012-08-24
Reviewed by Stephen White.

Source/WebCore:

Before this change, there was no global bound on memory that could be
consumed for the purpose of recording 2d canvas deferred draw commands.
There was only a per canvas limit. It is possible for canvases to get
dereferenced without flushing pending draw commands, which may lock
resources until the canvas element is garbage collected. This makes
it possible to grow memory consumption indefinitely by hitting reload
successively on some canvas-intensive web pages.

The solution implemented in this change consists in maintaining a
global registry of deferred canvas layers and tracking the sum of
memory allocated by all canvases for the purpose of storing deferred
draw commands. When memory consumption reaches the allowed limit,
caches are cleared and draw operations are flushed on one or several
canvases, starting with the least recently used, until memory
consumption is below a target level.

New tests: webkit_unit_tests DeferredLayerManagerTest*

* WebCore.gypi:
* platform/graphics/chromium/Canvas2DLayerBridge.cpp:
(WebCore::Canvas2DLayerBridge::Canvas2DLayerBridge):
(WebCore::Canvas2DLayerBridge::~Canvas2DLayerBridge):
(WebCore::Canvas2DLayerBridge::storageAllocatedForRecordingChanged):
Overloaded from SkDeferredCanvas::NotificationClient. Called when
there is a change in the number of bytes allocated by the deferred
canvas.
(WebCore):
(WebCore::Canvas2DLayerBridge::flushedDrawCommands):
Overloaded from SkDeferredCanvas::NotificationClient. Called when
pending draw commands are flush by the deferred canvas.
(WebCore::Canvas2DLayerBridge::freeMemoryIfPossible):
Called by the Canvas2DLayerManager to request the release of unlocked
memory resources (caches). Request is relayed to SkDeferredCanvas.
returns number of bytes freed.
(WebCore::Canvas2DLayerBridge::flush):
Requests that pending draw commands be flushed immediately from the
deferred canvas queue. Request is relayed to SkDeferredCanvas.
(WebCore::Canvas2DLayerBridge::contextAcquired):
* platform/graphics/chromium/Canvas2DLayerBridge.h:
(Canvas2DLayerBridge):
(WebCore::Canvas2DLayerBridge::bytesAllocated):
(WebCore::Canvas2DLayerBridge::updateBytesAllocated):
* platform/graphics/chromium/Canvas2DLayerManager.cpp: Added.
(WebCore):
(WebCore::Canvas2DLayerManager::Canvas2DLayerManager):
(WebCore::Canvas2DLayerManager::~Canvas2DLayerManager):
(WebCore::Canvas2DLayerManager::init):
Sets the global limit for the maximum total number of bytes allocated
by deferred layers.
(WebCore::Canvas2DLayerManager::get):
Singleton accessor
(WebCore::Canvas2DLayerManager::layerDidDraw):
Called by Canvas2DLayerBridge to indicate that the layer was drawn to.
(WebCore::Canvas2DLayerManager::addLayerToList):
(WebCore::Canvas2DLayerManager::layerAllocatedStorageChanged):
Called by Canvas2DLayerBridge to indicate thet the memory consumed by
the layer has changed.
(WebCore::Canvas2DLayerManager::layerDidFlush):
Called by Canvas2DLayerBridge to indicated that the pending draw
commands of the layer were flushed.
(WebCore::Canvas2DLayerManager::layerToBeDestroyed):
Called by Canvas2DLayerBridge upon destruction.
(WebCore::Canvas2DLayerManager::freeMemoryIfNecessary):
Called internally. Check that current memory consumption is below
the tolerated limit.  If check fails, intiates resource releases.
(WebCore::Canvas2DLayerManager::removeLayerFromList):
(WebCore::Canvas2DLayerManager::isInList):
(WebCore::Canvas2DLayerManager::updateBytesAllocated):
* platform/graphics/chromium/Canvas2DLayerManager.h: Added.
(WebCore):
(Canvas2DLayerManager):

Source/WebKit/chromium:

Adding unit tests for WebCore::Canvas2DLayerManager

* WebKit.gypi:
* tests/Canvas2DLayerManagerTest.cpp: Added.
(FakeCanvas2DLayerBridge):
(FakeCanvas2DLayerBridge::FakeCanvas2DLayerBridge):
(FakeCanvas2DLayerBridge::fakeFreeableBytes):
(Canvas2DLayerManagerTest):
(Canvas2DLayerManagerTest::storageAllocationTrackingTest):
(Canvas2DLayerManagerTest::evictionTest):
(Canvas2DLayerManagerTest::flushEvictionTest):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@126620 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Source/WebCore: Update comment regarding root node handling in XPath for detached trees.
https://bugs.webkit.org/show_bug.cgi?id=36427

Reviewed by Alexey Proskuryakov.

* xml/XPathPath.cpp:
(WebCore::XPath::LocationPath::evaluate): Update XPath root node comment.

LayoutTests: Improve xpath-detached-nodes.html test.
https://bugs.webkit.org/show_bug.cgi?id=36427

Reviewed by Alexey Proskuryakov.

* fast/xpath/xpath-detached-nodes-expected.txt:
* fast/xpath/xpath-detached-nodes.html: Increase coverage and improve log messages.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@126621 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Unreviewed Chromium gardening.

Rebaselined a bunch of repaint tests on Mac. The failures or differences fell in
the following categories:
- small alpha difference on the repaint tests' background. This issue has been known for
some time now but is not being worked on AFAICT.
- Chromium unions the invalidation rects when Mac doesn't.
- font difference.

* platform/chromium-mac-snowleopard/fast/repaint/box-shadow-dynamic-expected.png: Added.
* platform/chromium-mac/fast/repaint/box-shadow-dynamic-expected.png: Added.
This test was using Mac's expectation which is wrong (they have some beige rectangles that
are not in the page). Those new baselines matches the other ports and the expected result.

* platform/chromium-mac-snowleopard/fast/repaint/4774354-expected.png: Added.
* platform/chromium-mac-snowleopard/fast/repaint/4776765-expected.png: Added.
* platform/chromium-mac-snowleopard/fast/repaint/border-fit-lines-expected.png: Added.
* platform/chromium-mac-snowleopard/fast/repaint/border-repaint-glitch-expected.png: Added.
* platform/chromium-mac-snowleopard/fast/repaint/bugzilla-3509-expected.png: Added.
* platform/chromium-mac-snowleopard/fast/repaint/bugzilla-6388-expected.png: Added.
* platform/chromium-mac-snowleopard/fast/repaint/bugzilla-7235-expected.png: Added.
* platform/chromium-mac-snowleopard/fast/repaint/change-transform-expected.png: Added.
* platform/chromium-mac-snowleopard/fast/repaint/containing-block-position-change-expected.png: Added.
* platform/chromium-mac-snowleopard/fast/repaint/dynamic-table-vertical-alignment-change-expected.png: Added.
* platform/chromium-mac-snowleopard/fast/repaint/fixed-child-move-after-scroll-expected.png: Added.
* platform/chromium-mac-snowleopard/fast/repaint/fixed-child-of-fixed-move-after-scroll-expected.png: Added.
* platform/chromium-mac-snowleopard/fast/repaint/fixed-child-of-transformed-move-after-scroll-expected.png: Added.
* platform/chromium-mac-snowleopard/fast/repaint/fixed-move-after-scroll-expected.png: Added.
* platform/chromium-mac-snowleopard/fast/repaint/float-move-during-layout-expected.png: Added.
* platform/chromium-mac-snowleopard/fast/repaint/inline-color-change-expected.png: Added.
* platform/chromium-mac-snowleopard/fast/repaint/layout-state-relative-expected.png: Added.
* platform/chromium-mac-snowleopard/fast/repaint/outline-shrinking-expected.png: Added.
* platform/chromium-mac/fast/repaint/4774354-expected.png: Added.
* platform/chromium-mac/fast/repaint/4776765-expected.png: Added.
* platform/chromium-mac/fast/repaint/block-selection-gap-in-table-cell-expected.png: Added.
* platform/chromium-mac/fast/repaint/border-fit-lines-expected.png: Added.
* platform/chromium-mac/fast/repaint/border-repaint-glitch-expected.png: Added.
* platform/chromium-mac/fast/repaint/bugzilla-3509-expected.png: Added.
* platform/chromium-mac/fast/repaint/bugzilla-6388-expected.png: Added.
* platform/chromium-mac/fast/repaint/bugzilla-7235-expected.png: Added.
* platform/chromium-mac/fast/repaint/button-spurious-layout-hint-expected.png: Added.
* platform/chromium-mac/fast/repaint/change-transform-expected.png: Added.
* platform/chromium-mac/fast/repaint/clip-with-layout-delta-expected.png: Added.
* platform/chromium-mac/fast/repaint/containing-block-position-change-expected.png: Added.
* platform/chromium-mac/fast/repaint/delete-into-nested-block-expected.png:
* platform/chromium-mac/fast/repaint/dynamic-table-vertical-alignment-change-expected.png: Added.
* platform/chromium-mac/fast/repaint/erase-overflow-expected.png: Added.
* platform/chromium-mac/fast/repaint/fixed-child-move-after-scroll-expected.png: Added.
* platform/chromium-mac/fast/repaint/fixed-child-of-fixed-move-after-scroll-expected.png: Added.
* platform/chromium-mac/fast/repaint/fixed-child-of-transformed-move-after-scroll-expected.png: Added.
* platform/chromium-mac/fast/repaint/fixed-move-after-scroll-expected.png: Added.
* platform/chromium-mac/fast/repaint/float-in-new-block-with-layout-delta-expected.png: Added.
* platform/chromium-mac/fast/repaint/float-move-during-layout-expected.png: Added.
* platform/chromium-mac/fast/repaint/inline-block-resize-expected.png: Added.
* platform/chromium-mac/fast/repaint/inline-color-change-expected.png: Added.
* platform/chromium-mac/fast/repaint/inline-overflow-expected.png: Added.
* platform/chromium-mac/fast/repaint/layer-full-repaint-expected.png: Added.
* platform/chromium-mac/fast/repaint/layer-hide-when-needs-layout-expected.png: Added.
* platform/chromium-mac/fast/repaint/layer-visibility-expected.png: Added.
* platform/chromium-mac/fast/repaint/layout-state-relative-expected.png: Added.
* platform/chromium-mac/fast/repaint/outline-shrinking-expected.png: Added.
* platform/chromium/TestExpectations:


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@126622 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Always null check cells before marking
https://bugs.webkit.org/show_bug.cgi?id=94968

Reviewed by Geoffrey Garen.

Originally we tried to minimise null checks by only null checking values
that we knew could be null, however given that we can't ever guarantee
when a GC will happen, we're better off just always assuming that a null
check will be necessary.  This results in a much less fragile code base
as we can add GC allocations to object initialisers without having to
subsequently worry about whether the object we are initialising will need
to add a bunch of null checks in its visitChildren implementation.

* heap/MarkStack.cpp:
(JSC::MarkStack::internalAppend):
* heap/MarkStackInlineMethods.h:
(JSC::MarkStack::append):
(JSC::MarkStack::appendUnbarrieredPointer):
* runtime/Structure.h:
(JSC::MarkStack::internalAppend):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@126624 268f45cc-cd09-0410-ab3c-d52691b4dbfc