test_tree-model-06.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. /* Any copyright is dedicated to the Public Domain.
  2. http://creativecommons.org/publicdomain/zero/1.0/ */
  3. "use strict";
  4. /**
  5. * Tests that when constructing FrameNodes, if optimization data is available,
  6. * the FrameNodes have the correct optimization data after iterating over samples,
  7. * and only youngest frames capture optimization data.
  8. */
  9. function run_test() {
  10. run_next_test();
  11. }
  12. add_task(function test() {
  13. let { ThreadNode } = require("devtools/client/performance/modules/logic/tree-model");
  14. let root = getFrameNodePath(new ThreadNode(gThread, { startTime: 0,
  15. endTime: 30 }), "(root)");
  16. let A = getFrameNodePath(root, "A");
  17. let B = getFrameNodePath(A, "B");
  18. let C = getFrameNodePath(B, "C");
  19. let Aopts = A.getOptimizations();
  20. let Bopts = B.getOptimizations();
  21. let Copts = C.getOptimizations();
  22. ok(!Aopts, "A() was never youngest frame, so should not have optimization data");
  23. equal(Bopts.length, 2, "B() only has optimization data when it was a youngest frame");
  24. // Check a few properties on the OptimizationSites.
  25. let optSitesObserved = new Set();
  26. for (let opt of Bopts) {
  27. if (opt.data.line === 12) {
  28. equal(opt.samples, 2, "Correct amount of samples for B()'s first opt site");
  29. equal(opt.data.attempts.length, 3, "First opt site has 3 attempts");
  30. equal(opt.data.attempts[0].strategy, "SomeGetter1", "inflated strategy name");
  31. equal(opt.data.attempts[0].outcome, "Failure1", "inflated outcome name");
  32. equal(opt.data.types[0].typeset[0].keyedBy, "constructor", "inflates type info");
  33. optSitesObserved.add("first");
  34. } else {
  35. equal(opt.samples, 1, "Correct amount of samples for B()'s second opt site");
  36. optSitesObserved.add("second");
  37. }
  38. }
  39. ok(optSitesObserved.has("first"), "first opt site for B() was checked");
  40. ok(optSitesObserved.has("second"), "second opt site for B() was checked");
  41. equal(Copts.length, 1, "C() always youngest frame, so has optimization data");
  42. });
  43. var gUniqueStacks = new RecordingUtils.UniqueStacks();
  44. function uniqStr(s) {
  45. return gUniqueStacks.getOrAddStringIndex(s);
  46. }
  47. var gThread = RecordingUtils.deflateThread({
  48. samples: [{
  49. time: 0,
  50. frames: [
  51. { location: "(root)" }
  52. ]
  53. }, {
  54. time: 10,
  55. frames: [
  56. { location: "(root)" },
  57. { location: "A" },
  58. { location: "B_LEAF_1" }
  59. ]
  60. }, {
  61. time: 15,
  62. frames: [
  63. { location: "(root)" },
  64. { location: "A" },
  65. { location: "B_NOTLEAF" },
  66. { location: "C" },
  67. ]
  68. }, {
  69. time: 20,
  70. frames: [
  71. { location: "(root)" },
  72. { location: "A" },
  73. { location: "B_LEAF_2" }
  74. ]
  75. }, {
  76. time: 25,
  77. frames: [
  78. { location: "(root)" },
  79. { location: "A" },
  80. { location: "B_LEAF_2" }
  81. ]
  82. }],
  83. markers: []
  84. }, gUniqueStacks);
  85. var gRawSite1 = {
  86. line: 12,
  87. column: 2,
  88. types: [{
  89. mirType: uniqStr("Object"),
  90. site: uniqStr("B (http://foo/bar:10)"),
  91. typeset: [{
  92. keyedBy: uniqStr("constructor"),
  93. name: uniqStr("Foo"),
  94. location: uniqStr("B (http://foo/bar:10)")
  95. }, {
  96. keyedBy: uniqStr("primitive"),
  97. location: uniqStr("self-hosted")
  98. }]
  99. }],
  100. attempts: {
  101. schema: {
  102. outcome: 0,
  103. strategy: 1
  104. },
  105. data: [
  106. [uniqStr("Failure1"), uniqStr("SomeGetter1")],
  107. [uniqStr("Failure2"), uniqStr("SomeGetter2")],
  108. [uniqStr("Inlined"), uniqStr("SomeGetter3")]
  109. ]
  110. }
  111. };
  112. var gRawSite2 = {
  113. line: 22,
  114. types: [{
  115. mirType: uniqStr("Int32"),
  116. site: uniqStr("Receiver")
  117. }],
  118. attempts: {
  119. schema: {
  120. outcome: 0,
  121. strategy: 1
  122. },
  123. data: [
  124. [uniqStr("Failure1"), uniqStr("SomeGetter1")],
  125. [uniqStr("Failure2"), uniqStr("SomeGetter2")],
  126. [uniqStr("Failure3"), uniqStr("SomeGetter3")]
  127. ]
  128. }
  129. };
  130. function serialize(x) {
  131. return JSON.parse(JSON.stringify(x));
  132. }
  133. gThread.frameTable.data.forEach((frame) => {
  134. const LOCATION_SLOT = gThread.frameTable.schema.location;
  135. const OPTIMIZATIONS_SLOT = gThread.frameTable.schema.optimizations;
  136. let l = gThread.stringTable[frame[LOCATION_SLOT]];
  137. switch (l) {
  138. case "A":
  139. frame[OPTIMIZATIONS_SLOT] = serialize(gRawSite1);
  140. break;
  141. // Rename some of the location sites so we can register different
  142. // frames with different opt sites
  143. case "B_LEAF_1":
  144. frame[OPTIMIZATIONS_SLOT] = serialize(gRawSite2);
  145. frame[LOCATION_SLOT] = uniqStr("B");
  146. break;
  147. case "B_LEAF_2":
  148. frame[OPTIMIZATIONS_SLOT] = serialize(gRawSite1);
  149. frame[LOCATION_SLOT] = uniqStr("B");
  150. break;
  151. case "B_NOTLEAF":
  152. frame[OPTIMIZATIONS_SLOT] = serialize(gRawSite1);
  153. frame[LOCATION_SLOT] = uniqStr("B");
  154. break;
  155. case "C":
  156. frame[OPTIMIZATIONS_SLOT] = serialize(gRawSite1);
  157. break;
  158. }
  159. });