Skip to content
Permalink
Browse files
[chromium] Hint garbage collector to run if page uses Canvas contexts
https://bugs.webkit.org/show_bug.cgi?id=76225

Reviewed by Kentaro Hara.

Source/WebCore:

Upon creating a canvas context, set a hint in the current isolate
indicating that a full GC should be done upon the next page
navigation.

This improves Chrome's robustness on some WebGL stress tests which
simulate real-world behavior by repeatedly navigating among
several samples. More general measures are being investigated, but
this change makes V8 behave the same as JSC on these stress tests.
JSC doesn't currently use generational garbage collection, so it
has more opportunities to discover unreferenced canvas contexts.

Test: fast/canvas/webgl/context-creation-and-destruction.html

* bindings/v8/V8Binding.cpp:
(WebCore::V8BindingPerIsolateData::V8BindingPerIsolateData):
    Initialize per-isolate low memory hint.
* bindings/v8/V8Binding.h:
(V8BindingPerIsolateData):
(WebCore::V8BindingPerIsolateData::setLowMemoryNotificationHint):
    Set a per-isolate hint to signal a low memory condition upon the next page navigation.
(WebCore::V8BindingPerIsolateData::clearLowMemoryNotificationHint):
    Clear the previously set hint.
(WebCore::V8BindingPerIsolateData::isLowMemoryNotificationHint):
    Get the previously set hint.
* bindings/v8/V8Proxy.cpp:
(WebCore::V8Proxy::hintForGCIfNecessary):
    If necessary, send V8 a hint that it should GC.
(WebCore):
(WebCore::V8Proxy::clearForClose):
(WebCore::V8Proxy::clearForNavigation):
    Call hintForGCIfNecessary.
* bindings/v8/V8Proxy.h:
(V8Proxy):
* bindings/v8/custom/V8HTMLCanvasElementCustom.cpp:
(WebCore::V8HTMLCanvasElement::getContextCallback):
    Set a hint that we should GC upon the next page navigation.

LayoutTests:

This test doesn't directly exercise this code path yet, but it
needs to work regardless and also needs to be expanded.

* fast/canvas/webgl/context-creation-and-destruction-expected.txt: Added.
* fast/canvas/webgl/context-creation-and-destruction.html: Added.


Canonical link: https://commits.webkit.org/109996@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@123556 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
kenrussell committed Jul 25, 2012
1 parent 2394842 commit 6898408d217795ea2a2cd75a250f65c459de8ce4
Showing 9 changed files with 171 additions and 0 deletions.
@@ -1,3 +1,16 @@
2012-07-24 Kenneth Russell <kbr@google.com>

[chromium] Hint garbage collector to run if page uses Canvas contexts
https://bugs.webkit.org/show_bug.cgi?id=76225

Reviewed by Kentaro Hara.

This test doesn't directly exercise this code path yet, but it
needs to work regardless and also needs to be expanded.

* fast/canvas/webgl/context-creation-and-destruction-expected.txt: Added.
* fast/canvas/webgl/context-creation-and-destruction.html: Added.

2012-07-24 Alexis Menard <alexis.menard@openbossa.org>

[Qt] svg/as-background-image rebaseline after new test fonts
@@ -0,0 +1,25 @@
Test that contexts are freed and garbage collected reasonably

On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".


test 1 of 8
PASS getError was expected value: NO_ERROR : Should be no errors
test 2 of 8
PASS getError was expected value: NO_ERROR : Should be no errors
test 3 of 8
PASS getError was expected value: NO_ERROR : Should be no errors
test 4 of 8
PASS getError was expected value: NO_ERROR : Should be no errors
test 5 of 8
PASS getError was expected value: NO_ERROR : Should be no errors
test 6 of 8
PASS getError was expected value: NO_ERROR : Should be no errors
test 7 of 8
PASS getError was expected value: NO_ERROR : Should be no errors
test 8 of 8
PASS getError was expected value: NO_ERROR : Should be no errors
PASS successfullyParsed is true

TEST COMPLETE

@@ -0,0 +1,58 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="../../js/resources/js-test-style.css"/>
<script src="../../js/resources/js-test-pre.js"></script>
<script src="resources/webgl-test.js"> </script>
<script src="resources/webgl-test-utils.js"> </script>
</head>
<body>
<script>
var wtu = WebGLTestUtils;
// Ideally we would make this test run far longer, but we need to keep
// it within a reasonable per-test timeout.
var target = 8;
var count = 0;

if (window.initNonKhronosFramework) {
window.initNonKhronosFramework(true);
}

description('Test that contexts are freed and garbage collected reasonably');
doNextTest();

// Creates a canvas and some textures then exits. There are
// no references to either so all should be garbage collected.
function test() {
var canvas = document.createElement("canvas");
// This is safe for any device. See drawingBufferWidth in spec.
canvas.width = 2048;
canvas.height = 2048;
var gl = wtu.create3DContext(canvas);
var maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE);
var size = Math.min(1024, maxTextureSize);
for (var jj = 0; jj < 5; ++jj) {
var tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, size, size, 0, gl.RGBA, gl.UNSIGNED_BYTE,
new Uint8Array(size * size * 4));
}
gl.clear(gl.COLOR_BUFFER_BIT);
glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors");
}

function doNextTest() {
++count;
debug("test " + count + " of " + target);
test();
if (count < target) {
setTimeout(doNextTest, 100);
} else {
finishTest();
}
}
</script>

</body>
</html>
@@ -1,3 +1,47 @@
2012-07-24 Kenneth Russell <kbr@google.com>

[chromium] Hint garbage collector to run if page uses Canvas contexts
https://bugs.webkit.org/show_bug.cgi?id=76225

Reviewed by Kentaro Hara.

Upon creating a canvas context, set a hint in the current isolate
indicating that a full GC should be done upon the next page
navigation.

This improves Chrome's robustness on some WebGL stress tests which
simulate real-world behavior by repeatedly navigating among
several samples. More general measures are being investigated, but
this change makes V8 behave the same as JSC on these stress tests.
JSC doesn't currently use generational garbage collection, so it
has more opportunities to discover unreferenced canvas contexts.

Test: fast/canvas/webgl/context-creation-and-destruction.html

* bindings/v8/V8Binding.cpp:
(WebCore::V8BindingPerIsolateData::V8BindingPerIsolateData):
Initialize per-isolate low memory hint.
* bindings/v8/V8Binding.h:
(V8BindingPerIsolateData):
(WebCore::V8BindingPerIsolateData::setLowMemoryNotificationHint):
Set a per-isolate hint to signal a low memory condition upon the next page navigation.
(WebCore::V8BindingPerIsolateData::clearLowMemoryNotificationHint):
Clear the previously set hint.
(WebCore::V8BindingPerIsolateData::isLowMemoryNotificationHint):
Get the previously set hint.
* bindings/v8/V8Proxy.cpp:
(WebCore::V8Proxy::hintForGCIfNecessary):
If necessary, send V8 a hint that it should GC.
(WebCore):
(WebCore::V8Proxy::clearForClose):
(WebCore::V8Proxy::clearForNavigation):
Call hintForGCIfNecessary.
* bindings/v8/V8Proxy.h:
(V8Proxy):
* bindings/v8/custom/V8HTMLCanvasElementCustom.cpp:
(WebCore::V8HTMLCanvasElement::getContextCallback):
Set a hint that we should GC upon the next page navigation.

2012-07-24 Dave Tu <dtu@chromium.org>

[chromium] Add time spent painting to GPU benchmarking renderingStats() API.
@@ -60,6 +60,7 @@ V8BindingPerIsolateData::V8BindingPerIsolateData(v8::Isolate* isolate)
#ifndef NDEBUG
, m_internalScriptRecursionLevel(0)
#endif
, m_lowMemoryNotificationHint(false)
{
}

@@ -220,6 +220,14 @@ namespace WebCore {

void reportMemoryUsage(MemoryObjectInfo*) const;

// Gives the system a hint that we should send a low memory
// notification upon the next close or navigation event,
// because some expensive objects have been allocated that we
// want to take every opportunity to collect.
void setLowMemoryNotificationHint() { m_lowMemoryNotificationHint = true; }
void clearLowMemoryNotificationHint() { m_lowMemoryNotificationHint = false; }
bool isLowMemoryNotificationHint() const { return m_lowMemoryNotificationHint; }

private:
explicit V8BindingPerIsolateData(v8::Isolate*);
~V8BindingPerIsolateData();
@@ -248,6 +256,8 @@ namespace WebCore {
int m_internalScriptRecursionLevel;
#endif
GCEventData m_gcEventData;

bool m_lowMemoryNotificationHint;
};

class ConstructorMode {
@@ -559,15 +559,26 @@ void V8Proxy::resetIsolatedWorlds()
m_isolatedWorldSecurityOrigins.clear();
}

void V8Proxy::hintForGCIfNecessary()
{
V8BindingPerIsolateData* data = V8BindingPerIsolateData::current();
if (data->isLowMemoryNotificationHint()) {
data->clearLowMemoryNotificationHint();
v8::V8::LowMemoryNotification();
}
}

void V8Proxy::clearForClose()
{
resetIsolatedWorlds();
hintForGCIfNecessary();
windowShell()->clearForClose();
}

void V8Proxy::clearForNavigation()
{
resetIsolatedWorlds();
hintForGCIfNecessary();
windowShell()->clearForNavigation();
}

@@ -271,6 +271,8 @@ namespace WebCore {
private:
void resetIsolatedWorlds();

void hintForGCIfNecessary();

PassOwnPtr<v8::ScriptData> precompileScript(v8::Handle<v8::String>, CachedScript*);

static const char* rangeExceptionName(int exceptionCode);
@@ -86,6 +86,13 @@ v8::Handle<v8::Value> V8HTMLCanvasElement::getContextCallback(const v8::Argument
CanvasRenderingContext* result = imp->getContext(contextId, attrs.get());
if (!result)
return v8::Null(args.GetIsolate());

// Both 2D and 3D canvas contexts can hold on to lots of GPU resources, and we
// want to take an opportunity to get rid of them as soon as possible when we
// navigate away from pages using them.
V8BindingPerIsolateData* perIsolateData = V8BindingPerIsolateData::current(args.GetIsolate());
perIsolateData->setLowMemoryNotificationHint();

if (result->is2d())
return toV8(static_cast<CanvasRenderingContext2D*>(result), args.GetIsolate());
#if ENABLE(WEBGL)

0 comments on commit 6898408

Please sign in to comment.