typed-array-memory.html 8.2 KB

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