PageRenderTime 47ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/hphp/test/slow/objprof/heapgraph.php

http://github.com/facebook/hiphop-php
PHP | 254 lines | 203 code | 38 blank | 13 comment | 30 complexity | 3cc8853aa2b030d427499c337b3ee1c8 MD5 | raw file
Possible License(s): LGPL-2.1, BSD-2-Clause, BSD-3-Clause, MPL-2.0-no-copyleft-exception, MIT, LGPL-2.0, Apache-2.0
  1. <?hh
  2. class RootClass {
  3. public darray<string, mixed> $children = darray[];
  4. <<__Memoize>>
  5. public static function getInstance() {
  6. return new RootClass();
  7. }
  8. }
  9. $r = RootClass::getInstance();
  10. class ChildWithClosureMember {
  11. public $closure;
  12. public function doWork() {
  13. json_encode($this->closure);
  14. }
  15. }
  16. class ParentWithClosureTarget {
  17. public $someval = 20151012;
  18. public $somestring = "";
  19. public $child;
  20. public function __construct() {
  21. $this->somestring = json_encode(varray[1,2,3]);
  22. $this->child = new ChildWithClosureMember();
  23. $this->child->closure = $this->createClosure();
  24. }
  25. public function createClosure() {
  26. return function() {
  27. return $this->someval;
  28. };
  29. }
  30. }
  31. $r->children['MemoizedSingleton'] = new ParentWithClosureTarget();
  32. $r->children['MemoizedSingleton']->child->doWork();
  33. class ClassForSecondCapture { }
  34. // We do some consolidation here because the behavior when testing
  35. // is really non-deterministic. Both on order of scans and also
  36. // whether things are in CPP or PHP (based on mode of test)
  37. ObjprofHeapgraphPhp::$echobuf = varray[];
  38. function echo_buffer($str) {
  39. // new root names
  40. $str = str_replace('HPHP::CppStack', 'onsome-stack', $str);
  41. $str = str_replace('HPHP::PhpStack', 'onsome-stack', $str);
  42. $str = str_replace('HPHP::RdsLocal', 'rds-local', $str);
  43. ObjprofHeapgraphPhp::$echobuf[] = $str;
  44. }
  45. function echo_flush() {
  46. $echobuf_uniq = array_unique(ObjprofHeapgraphPhp::$echobuf);
  47. sort(inout $echobuf_uniq);
  48. foreach ($echobuf_uniq as $str) {
  49. echo $str;
  50. }
  51. ObjprofHeapgraphPhp::$echobuf = varray[];
  52. }
  53. ObjprofHeapgraphPhp::$hg_for_closure = null;
  54. ObjprofHeapgraphPhp::$id_of_rootclass = null;
  55. function showTestClasses($node) {
  56. $classname = idx($node, 'class', 'no class...');
  57. $kind = $node['kind'];
  58. $testclasses = darray[
  59. ChildWithClosureMember::class => 1,
  60. ParentWithClosureTarget::class => 1,
  61. RootClass::class => 1,
  62. ClassForSecondCapture::class => 1,
  63. ];
  64. if ($kind === "Object" && idx($testclasses, $classname)) {
  65. echo_buffer("$classname\n");
  66. $same_node = heapgraph_node(ObjprofHeapgraphPhp::$hg_for_closure, $node['index']);
  67. $same_class = idx($same_node, 'class', 'null');
  68. if ($same_class != $classname) {
  69. echo "heapgraph_node broken: $classname != $same_class\n";
  70. }
  71. if ($classname == "RootClass") {
  72. ObjprofHeapgraphPhp::$id_of_rootclass = $node['index'];
  73. }
  74. }
  75. }
  76. function edgeName($hg, $edge) {
  77. $from = $edge['from'];
  78. $n = heapgraph_node($hg, $from);
  79. $kind = $n['kind'];
  80. if ($kind === 'Root') {
  81. $ty = $n['type'];
  82. if ($ty === 'HPHP::CppStack') return 'onsome-stack';
  83. if ($ty === 'HPHP::PhpStack') return 'onsome-stack';
  84. if ($ty === 'HPHP::StaticPropData') {
  85. return "StaticProperty:".$n['class']."::".$n['prop'];
  86. }
  87. }
  88. if (isset($edge['key'])) return "Key:".$edge['key'];
  89. if (isset($edge['value'])) return "Value:".$edge['value'];
  90. if (isset($edge['prop'])) return "Property:".$edge['prop'];
  91. if (isset($edge['offset'])) return "Offset:".$edge['offset'];
  92. return "";
  93. }
  94. function showTestEdge($edge) {
  95. $testedges = darray[
  96. 'ArrayKey:MemoizedSingleton' => 1,
  97. 'Property:somestring' => 1,
  98. 'Property:child' => 1,
  99. 'Property:closure' => 1,
  100. 'Property:children' => 1,
  101. ];
  102. $name = edgeName(ObjprofHeapgraphPhp::$hg_for_closure, $edge);
  103. if (idx($testedges, $name)) {
  104. echo_buffer("$name\n");
  105. $same_edge = heapgraph_edge(ObjprofHeapgraphPhp::$hg_for_closure, $edge['index']);
  106. if ($same_edge != $edge) {
  107. echo"heapgraph_edge broken: $edge != $same_edge\n";
  108. }
  109. }
  110. }
  111. function showAllEdges($hg, $edges) {
  112. foreach ($edges as $edge) {
  113. echo_buffer(edgeName($hg, $edge)."\n");
  114. }
  115. }
  116. function showClassOnly($node) {
  117. if (idx($node, 'class')) {
  118. echo_buffer($node['class']."\n");
  119. }
  120. }
  121. function showClass($node) {
  122. if (idx($node, 'class')) {
  123. echo_buffer($node['class']."\n");
  124. } else {
  125. echo_buffer($node['kind']."\n");
  126. }
  127. }
  128. function printNode($node) {
  129. echo "node ".$node['index']." ".$node['kind']." ";
  130. if (isset($node['class'])) echo $node['class']." ";
  131. if (isset($node['func'])) echo $node['func']." ";
  132. if (isset($node['local'])) echo $node['local']." ";
  133. if (isset($node['prop'])) echo $node['prop']." ";
  134. echo "\n";
  135. }
  136. function printEdge($edge) {
  137. echo 'edge '.$edge['name'].' ';
  138. echo $edge['kind'].' '.$edge['from']."->".$edge['to'];
  139. echo "\n";
  140. }
  141. ObjprofHeapgraphPhp::$visited = varray[];
  142. function dfsPrintNode($hg, $node) {
  143. $id = $node['index'];
  144. ObjprofHeapgraphPhp::$visited[$id] = true;
  145. printNode($node);
  146. $in_edges = heapgraph_node_in_edges($hg, $id);
  147. foreach ($in_edges as $edge) {
  148. printEdge($edge);
  149. }
  150. foreach ($in_edges as $edge) {
  151. $from = $edge['from'];
  152. if (!isset(ObjprofHeapgraphPhp::$visited[$from])) {
  153. dfsPrintNode($hg, heapgraph_node($hg, $from));
  154. }
  155. }
  156. }
  157. ////////////////////////////////////////////////////
  158. // Test starts here:
  159. echo "Capturing two snapshots...\n";
  160. // FIRST CAPTURE
  161. $hg = heapgraph_create();
  162. var_dump($hg);
  163. // SECOND CAPTURE
  164. $b = new ClassForSecondCapture();
  165. $hg2 = heapgraph_create();
  166. var_dump($hg2);
  167. // STATS
  168. echo "Stats for first capture:\n";
  169. $stats = heapgraph_stats($hg);
  170. var_dump($stats);
  171. // OUT OF BOUNDS
  172. echo "Getting invalid nodes and edges:\n";
  173. $inv_edge = heapgraph_edge($hg, -1) ?: heapgraph_edge($hg, 999999);
  174. $inv_node = heapgraph_node($hg, -1) ?: heapgraph_node($hg, 999999);
  175. echo $inv_edge ?: $inv_node ?: "Invalid nodes and edges work OK.\n";
  176. echo_flush();
  177. // TRAVERSAL
  178. echo "\nTraversing second capture:\n";
  179. ObjprofHeapgraphPhp::$hg_for_closure = $hg2;
  180. heapgraph_foreach_node($hg2, 'showTestClasses');
  181. echo_flush();
  182. echo "\nTraversing first capture:\n";
  183. ObjprofHeapgraphPhp::$hg_for_closure = $hg;
  184. heapgraph_foreach_node($hg, 'showTestClasses');
  185. echo_flush();
  186. echo "\nTraversing edges for first capture:\n";
  187. ObjprofHeapgraphPhp::$hg_for_closure = $hg;
  188. heapgraph_foreach_edge($hg, 'showTestEdge');
  189. echo_flush();
  190. echo "\nTraversing roots for first capture:\n";
  191. heapgraph_foreach_root($hg, 'showTestEdge');
  192. echo_flush();
  193. // CHILDREN / PARENTS
  194. echo "\nGetting in edges of root class:\n";
  195. $in_edges = heapgraph_node_in_edges($hg, ObjprofHeapgraphPhp::$id_of_rootclass);
  196. showAllEdges($hg, $in_edges);
  197. echo_flush();
  198. echo "\nGetting out edges of root class:\n";
  199. $out_edges = heapgraph_node_out_edges($hg, ObjprofHeapgraphPhp::$id_of_rootclass);
  200. showAllEdges($hg, $out_edges);
  201. echo_flush();
  202. // DFS NODES
  203. echo "\nDoing DFS from root class on nodes:\n";
  204. heapgraph_dfs_nodes($hg, varray[ObjprofHeapgraphPhp::$id_of_rootclass], varray[], 'showClassOnly');
  205. echo_flush();
  206. echo "\nDoing DFS from root class on nodes (skipping root):\n";
  207. heapgraph_dfs_nodes(
  208. $hg, varray[ObjprofHeapgraphPhp::$id_of_rootclass], varray[ObjprofHeapgraphPhp::$id_of_rootclass], 'showClass'
  209. );
  210. echo_flush();
  211. abstract final class ObjprofHeapgraphPhp {
  212. public static $echobuf;
  213. public static $hg_for_closure;
  214. public static $id_of_rootclass;
  215. public static $visited;
  216. }