addFldFastPath.js 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. function testMonoInlineSlots() {
  6. var iterations = 10;
  7. var a = new Array(iterations);
  8. for (var i = 0; i < iterations; i++) {
  9. // This object will have 4 inlined slots
  10. var o = { a: 0 };
  11. WScript.Echo("...");
  12. // This is the field add we want the fast path for.
  13. o.p = 1;
  14. WScript.Echo("...");
  15. // Use o to verify the type got written correctly to the object.
  16. o.z = -1;
  17. a[i] = o;
  18. }
  19. for (var i = 0; i < iterations; i++) {
  20. WScript.Echo("{ a: " + a[i].a + ", p: " + a[i].p + ", z: " + a[i].z + "}");
  21. }
  22. }
  23. WScript.Echo("testMonoInlineSlots: ");
  24. testMonoInlineSlots();
  25. testMonoInlineSlots();
  26. WScript.Echo();
  27. function testMonoInlineSlotsSetOrAdd() {
  28. var iterations = 10;
  29. var a = new Array(iterations);
  30. for (var i = 0; i < iterations; i++) {
  31. // This object will have 4 inlined slots
  32. var o = { a: 0 };
  33. // This adds a property ahead of time for every other object, so the profile indicates we either set or add a property.
  34. if (i % 2 == 0) {
  35. o.p = 1;
  36. }
  37. WScript.Echo("...");
  38. // This is the field add we want the fast path for.
  39. o.p = 1;
  40. WScript.Echo("...");
  41. // Use o to verify the type got written correctly to the object.
  42. o.z = -1;
  43. a[i] = o;
  44. }
  45. for (var i = 0; i < iterations; i++) {
  46. WScript.Echo("{ a: " + a[i].a + ", p: " + a[i].p + ", z: " + a[i].z + "}");
  47. }
  48. }
  49. WScript.Echo("testMonoInlineSlotsSetOrAdd: ");
  50. testMonoInlineSlotsSetOrAdd();
  51. testMonoInlineSlotsSetOrAdd();
  52. WScript.Echo();
  53. function testMonoAuxSlots() {
  54. var iterations = 10;
  55. var a = new Array(iterations);
  56. for (var i = 0; i < iterations; i++) {
  57. // This object will have 0 inlined slots.
  58. var o = {};
  59. // This will add aux slot array.
  60. o.a = 1;
  61. WScript.Echo("...");
  62. // This is the field add we want the fast path for.
  63. // Adding property now will stick it into an aux slot but won't require slot array re-allocation.
  64. o.p = 1;
  65. WScript.Echo("...");
  66. // Use o to verify the type got written correctly to the object.
  67. o.z = -1;
  68. a[i] = o;
  69. }
  70. for (var i = 0; i < iterations; i++) {
  71. WScript.Echo("{ a: " + a[i].a + ", p: " + a[i].p + ", z: " + a[i].z + "}");
  72. }
  73. }
  74. WScript.Echo("testMonoAuxSlots: ");
  75. testMonoAuxSlots();
  76. testMonoAuxSlots();
  77. WScript.Echo();
  78. function testMonoAuxSlotsAdjustmentRequired1() {
  79. var iterations = 10;
  80. var a = new Array(iterations);
  81. for (var i = 0; i < iterations; i++) {
  82. // This object will have 0 inlined slots.
  83. var o = {};
  84. WScript.Echo("...");
  85. // This is the field add we want the fast path for.
  86. // Adding property now will require slot array allocation and then will stick it into an aux slot.
  87. o.p = 1;
  88. WScript.Echo("...");
  89. // Use o to verify the type got written correctly to the object.
  90. o.z = -1;
  91. a[i] = o;
  92. }
  93. for (var i = 0; i < iterations; i++) {
  94. WScript.Echo("{ p: " + a[i].p + ", z: " + a[i].z + "}");
  95. }
  96. }
  97. WScript.Echo("testMonoAuxSlotsAdjustmentRequired1: ");
  98. testMonoAuxSlotsAdjustmentRequired1();
  99. testMonoAuxSlotsAdjustmentRequired1();
  100. WScript.Echo();
  101. function testMonoAuxSlotsAdjustmentRequired2() {
  102. var iterations = 10;
  103. var a = new Array(iterations);
  104. for (var i = 0; i < iterations; i++) {
  105. // This object will have 0 inlined slots.
  106. var o = {};
  107. // This will add aux slot array of size 4, but it will fill every slot.
  108. o.a = 0;
  109. o.b = 1;
  110. o.c = 2;
  111. o.d = 3;
  112. WScript.Echo("...");
  113. // This is the field add we want the fast path for.
  114. // Adding property now will require slot array allocation and then will stick it into an aux slot.
  115. o.p = 1;
  116. WScript.Echo("...");
  117. // Use o to verify the type got written correctly to the object.
  118. o.z = -1;
  119. a[i] = o;
  120. }
  121. for (var i = 0; i < iterations; i++) {
  122. WScript.Echo("{ a: " + a[i].a + ", b: " + a[i].b + ", c: " + a[i].c + ", d: " + a[i].d + ", p: " + a[i].p + ", z: " + a[i].z + "}");
  123. }
  124. }
  125. WScript.Echo("testMonoAuxSlotsAdjustmentRequired2: ");
  126. testMonoAuxSlotsAdjustmentRequired2();
  127. testMonoAuxSlotsAdjustmentRequired2();
  128. WScript.Echo();
  129. function testPoly() {
  130. var iterations = 25;
  131. var a = new Array(iterations);
  132. for (var i = 0; i < iterations; i++) {
  133. var o;
  134. switch (i % 3) {
  135. case 0:
  136. o = {};
  137. break;
  138. case 1:
  139. o = { a: 0 };
  140. break;
  141. case 2:
  142. o = { b: 0 };
  143. break;
  144. }
  145. if (i % 6 >= 3) {
  146. o.p = 0;
  147. }
  148. WScript.Echo("...");
  149. // This is the field add we want the fast path for.
  150. o.p = 1;
  151. WScript.Echo("...");
  152. o.z = -1;
  153. a[i] = o;
  154. }
  155. for (var i = 0; i < iterations; i++) {
  156. WScript.Echo("{ a: " + a[i].a + ", b: " + a[i].b + ", p: " + a[i].p + ", z: " + a[i].z + "}");
  157. }
  158. }
  159. WScript.Echo("testPoly: ");
  160. testPoly();
  161. testPoly();
  162. WScript.Echo();
  163. (function () {
  164. var Blank = function () {
  165. }
  166. Blank.prototype = { a: 0, b: 0, c: 0 }
  167. function setUpMonoStoreFieldCacheInvalidation() {
  168. // Make sure properties a, b, and c are not marked as fixed on Blank's type handler, so that
  169. // add property inline caches can be populated.
  170. var o = new Blank();
  171. o.a = 1;
  172. o.b = 2;
  173. o.c = 3;
  174. var o = new Blank();
  175. o.a = 1;
  176. o.b = 2;
  177. o.c = 3;
  178. }
  179. function testMonoStoreFieldCacheInvalidation(o, isNative) {
  180. // Do this only for the JIT-ed iteration to be sure caches aren't populated and we don't do
  181. // object type spec.
  182. if (isNative) {
  183. o.a = 1;
  184. o.b = 2;
  185. o.c = 3;
  186. }
  187. }
  188. WScript.Echo("testMonoStoreFieldCacheInvalidation: ");
  189. setUpMonoStoreFieldCacheInvalidation();
  190. var o = new Blank();
  191. testMonoStoreFieldCacheInvalidation(o, false);
  192. WScript.Echo("{ a: " + o.a + ", b: " + o.b + ", c: " + o.c + "}");
  193. var o = new Blank();
  194. testMonoStoreFieldCacheInvalidation(o, true);
  195. WScript.Echo("{ a: " + o.a + ", b: " + o.b + ", c: " + o.c + "}");
  196. // Change the writable attribute without actually adding or deleting any properties.
  197. // This should invalidate all inline caches for property b.
  198. Object.defineProperty(Blank.prototype, "b", { writable: false });
  199. var o = new Blank();
  200. testMonoStoreFieldCacheInvalidation(o, true);
  201. WScript.Echo("{ a: " + o.a + ", b: " + o.b + ", c: " + o.c + "}");
  202. })();
  203. WScript.Echo();
  204. (function () {
  205. var Blank = function () {
  206. }
  207. Blank.prototype = { a: 0, b: 0, c: 0 }
  208. function setUpPolyStoreFieldCacheInvalidation() {
  209. // Make sure properties a, b, and c are not marked as fixed on Blank's type handler, so that
  210. // add property inline caches can be populated.
  211. var o = new Blank();
  212. o.a = 1;
  213. o.b = 2;
  214. o.c = 3;
  215. o.d = 4;
  216. var o = new Blank();
  217. o.a = 1;
  218. o.b = 2;
  219. o.c = 3;
  220. o.d = 4;
  221. }
  222. function testPolyStoreFieldCacheInvalidation(objects, isNative) {
  223. // This loop ensures that inline caches for a and b become polymorphic on the second iteration.
  224. // That's because the type encountered the second time around is the final type with all properties present.
  225. var o;
  226. for (var i = 0; i < 2; i++) {
  227. o = objects[i];
  228. o.a = 1;
  229. o.b = 2;
  230. o.c = 3;
  231. }
  232. }
  233. function reportResults(objects) {
  234. for (var i = 0; i < 2; i++) {
  235. var o = objects[i];
  236. WScript.Echo("{ a: " + o.a + ", b: " + o.b + ", c: " + o.c + "}");
  237. }
  238. }
  239. WScript.Echo("testPolyStoreFieldCacheInvalidation: ");
  240. setUpPolyStoreFieldCacheInvalidation();
  241. var warmUpObjects = new Array(2);
  242. warmUpObjects[0] = new Blank();
  243. var o = new Blank();
  244. o.a = 1;
  245. o.b = 2;
  246. o.c = 3;
  247. warmUpObjects[1] = o;
  248. testPolyStoreFieldCacheInvalidation(warmUpObjects, false);
  249. reportResults(warmUpObjects);
  250. // Change the writable attribute without actually adding or deleting any properties.
  251. // This should invalidate all inline caches for property b, including those that are part of a
  252. // polymorphic inline cache - provided they got registered for invalidation properly.
  253. Object.defineProperty(Blank.prototype, "b", { writable: false });
  254. var testObjects = new Array(2);
  255. testObjects[0] = new Blank();
  256. testObjects[1] = new Blank();
  257. testPolyStoreFieldCacheInvalidation(testObjects, true);
  258. reportResults(testObjects);
  259. })();