1<html> 2<head> 3<title>ArrayBuffer External Memory test</title> 4<script> 5 6var log; 7function print(message, color) 8{ 9 var paragraph = document.createElement("div"); 10 paragraph.appendChild(document.createTextNode(message)); 11 paragraph.style.fontFamily = "monospace"; 12 if (color) 13 paragraph.style.color = color; 14 log.appendChild(paragraph); 15} 16 17function pass(msg) 18{ 19 print("PASS: " + msg, "green"); 20} 21 22function fail(msg) 23{ 24 print("FAIL: " + msg, "red"); 25} 26 27var KB = 1024; 28var MB = KB * KB; 29var noise = KB; 30 31function externalMemory() { 32 return getV8Statistics().amount_of_external_allocated_memory; 33} 34 35function collectGarbage() { 36 for (var i = 0; i < 10; i++) gc(); 37} 38 39function allocationsThatIncreaseExternalMemory() { 40 function test(expression) { 41 var before = externalMemory(); 42 (function () { eval(expression); }) (); 43 var now = externalMemory(); 44 if (now < before + MB - noise) { 45 fail(expression + " did not increase the amount of external memory (" + 46 before + ", " + now + ")."); 47 } else { 48 pass(expression + " increased the amount of external memory."); 49 } 50 collectGarbage(); 51 var after = externalMemory(); 52 if (after > now + noise) { 53 fail("Garbage collection after " + expression + 54 " did not return the amount of external memory to the initial value (" + 55 now + ", " + after + ")."); 56 } else { 57 pass("Garbage collection after " + expression + 58 " returned the amount of external memory to the initial value."); 59 } 60 } 61 62 test("(new ArrayBuffer(MB))"); 63 test("(new Float32Array(MB))"); 64 test("(new Float64Array(MB))"); 65 test("(new Int8Array(MB))"); 66 test("(new Int16Array(MB))"); 67 test("(new Int32Array(MB))"); 68 test("(new Uint8Array(MB))"); 69 test("(new Uint16Array(MB))"); 70 test("(new Uint32Array(MB))"); 71 var largeJSArray = []; 72 for (var i = 0; i < MB; i++) largeJSArray.push(i); 73 test("(new Float32Array(largeJSArray))"); 74 test("(new Float64Array(largeJSArray))"); 75 test("(new Int8Array(largeJSArray))"); 76 test("(new Int16Array(largeJSArray))"); 77 test("(new Int32Array(largeJSArray))"); 78 test("(new Uint8Array(largeJSArray))"); 79 test("(new Uint16Array(largeJSArray))"); 80 test("(new Uint32Array(largeJSArray))"); 81 var int8Array = new Int8Array(MB); 82 test("(new Float32Array(int8Array))"); 83 test("(new Float64Array(int8Array))"); 84 test("(new Int8Array(int8Array))"); 85 test("(new Int16Array(int8Array))"); 86 test("(new Int32Array(int8Array))"); 87 test("(new Uint8Array(int8Array))"); 88 test("(new Uint16Array(int8Array))"); 89 test("(new Uint32Array(int8Array))"); 90} 91 92 93function allocationsThatDoNotChangeExternalMemory() { 94 function test(expression) { 95 var before = externalMemory(); 96 (function () { eval(expression); }) (); 97 var now = externalMemory(); 98 if (now > before + noise) { 99 fail(expression + " increased the amount of external memory (" + before + ", " + now + ")."); 100 } else { 101 pass(expression + " did not increase the amount of external memory."); 102 } 103 collectGarbage(); 104 var after = externalMemory(); 105 if (after < now - noise) { 106 fail("Garbage collection after " + expression + " decreased the amount of external memory (" + 107 now + ", " + after + ")."); 108 } else { 109 pass("Garbage collection after " + expression + 110 " did not decrease the amount of external memory."); 111 } 112 } 113 var arrayBuffer = new ArrayBuffer(MB); 114 test("(new Float32Array(arrayBuffer))"); 115 test("(new Float64Array(arrayBuffer))"); 116 test("(new Int8Array(arrayBuffer))"); 117 test("(new Int16Array(arrayBuffer))"); 118 test("(new Int32Array(arrayBuffer))"); 119 test("(new Uint8Array(arrayBuffer))"); 120 test("(new Uint16Array(arrayBuffer))"); 121 test("(new Uint32Array(arrayBuffer))"); 122 var int8Array = new Int8Array(MB); 123 test("(new Float32Array(int8Array.buffer))"); 124 test("(new Float64Array(int8Array.buffer))"); 125 test("(new Int8Array(int8Array.buffer))"); 126 test("(new Int16Array(int8Array.buffer))"); 127 test("(new Int32Array(int8Array.buffer))"); 128 test("(new Uint8Array(int8Array.buffer))"); 129 test("(new Uint16Array(int8Array.buffer))"); 130 test("(new Uint32Array(int8Array.buffer))"); 131} 132 133 134function transfersThatDecreaseExternalMemory() { 135 var workerSource = 136"function externalMemory() {\n" + 137" return getV8Statistics().amount_of_external_allocated_memory;\n" + 138"}\n" + 139"var KB = 1024;\n" + 140"var MB = KB * KB;\n" + 141"var noise = KB;\n" + 142"self.onmessage = function(e) {\n" + 143" var before = externalMemory();\n" + 144" e.data;\n" + 145" var after = externalMemory();\n" + 146" if (after > before + MB - noise) {\n" + 147" self.postMessage('PASS: Amount of external memory increased.');\n" + 148" } else {\n" + 149" self.postMessage('FAIL: Amount of external memory did not increase.');\n" + 150" }\n" + 151"}\n"; 152 153 var blob = new Blob([workerSource]); 154 var worker = new Worker(window.webkitURL.createObjectURL(blob)); 155 worker.onmessage = function (e) { 156 print("message from worker: " + e.data, "blue"); 157 } 158 function test(expression) 159 { 160 var buffer = eval(expression); 161 try { 162 var before = externalMemory(); 163 worker.postMessage(buffer, [buffer]); 164 var now = externalMemory(); 165 if (now > before - MB + noise) { 166 fail("Transfer of " + expression + " did not decrease the amount of external memory (" + 167 before + ", " + now + ")."); 168 } else { 169 pass("Transfer of " + expression + " decreased the amount of external memory."); 170 } 171 collectGarbage(); 172 var after = externalMemory(); 173 if (after < now - noise) { 174 fail("Garbage collection after transfer of " + expression + 175 " decreased the amount of external memory (" + now + ", " + after + ")."); 176 } else { 177 pass("Garbage collection after transfer of " + expression + 178 " did not decrease the amount of external memory."); 179 } 180 } catch (e) { 181 fail("Transfer of " + name + ": could not webkitPostMessage: " + e); 182 return false; 183 } 184 return true; 185 } 186 test("(new ArrayBuffer(MB))"); 187 test("(new Float32Array(MB)).buffer"); 188 test("(new Float64Array(MB)).buffer"); 189 test("(new Int8Array(MB)).buffer"); 190 test("(new Int16Array(MB)).buffer"); 191 test("(new Int32Array(MB)).buffer"); 192 test("(new Uint8Array(MB)).buffer"); 193 test("(new Uint16Array(MB)).buffer"); 194 test("(new Uint32Array(MB)).buffer"); 195} 196 197 198function runAll() { 199 log = document.getElementById("log1"); 200 if (typeof gc == "undefined" || typeof getV8Statistics == "undefined") { 201 print("Run chrome browser with --js-flags='--expose_gc --track_gc_object_stats'", "red"); 202 } else { 203 allocationsThatIncreaseExternalMemory(); 204 collectGarbage(); 205 allocationsThatDoNotChangeExternalMemory(); 206 collectGarbage(); 207 log = document.getElementById("log2"); 208 transfersThatDecreaseExternalMemory(); 209 collectGarbage(); 210 } 211} 212 213</script> 214</head> 215<body onload="runAll()"> 216<p>This test checks that allocation and deallocation of typed arrays correctly 217adjusts the amount of external memory in V8.</p> 218<div id='log1'></div> 219<p>This test checks that transfer of an array buffer to worker decreases amount of 220external memory in the main V8 isolate.</p> 221<div id='log2'></div> 222</body> 223</html> 224