libv8-sgonyea 3.3.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (500) hide show
  1. data/.gitignore +8 -0
  2. data/.gitmodules +3 -0
  3. data/Gemfile +4 -0
  4. data/README.md +76 -0
  5. data/Rakefile +113 -0
  6. data/ext/libv8/extconf.rb +28 -0
  7. data/lib/libv8.rb +15 -0
  8. data/lib/libv8/Makefile +30 -0
  9. data/lib/libv8/detect_cpu.rb +27 -0
  10. data/lib/libv8/fpic-on-linux-amd64.patch +13 -0
  11. data/lib/libv8/v8/.gitignore +35 -0
  12. data/lib/libv8/v8/AUTHORS +44 -0
  13. data/lib/libv8/v8/ChangeLog +2839 -0
  14. data/lib/libv8/v8/LICENSE +52 -0
  15. data/lib/libv8/v8/LICENSE.strongtalk +29 -0
  16. data/lib/libv8/v8/LICENSE.v8 +26 -0
  17. data/lib/libv8/v8/LICENSE.valgrind +45 -0
  18. data/lib/libv8/v8/SConstruct +1478 -0
  19. data/lib/libv8/v8/build/README.txt +49 -0
  20. data/lib/libv8/v8/build/all.gyp +18 -0
  21. data/lib/libv8/v8/build/armu.gypi +32 -0
  22. data/lib/libv8/v8/build/common.gypi +144 -0
  23. data/lib/libv8/v8/build/gyp_v8 +145 -0
  24. data/lib/libv8/v8/include/v8-debug.h +395 -0
  25. data/lib/libv8/v8/include/v8-preparser.h +117 -0
  26. data/lib/libv8/v8/include/v8-profiler.h +505 -0
  27. data/lib/libv8/v8/include/v8-testing.h +104 -0
  28. data/lib/libv8/v8/include/v8.h +4124 -0
  29. data/lib/libv8/v8/include/v8stdint.h +53 -0
  30. data/lib/libv8/v8/preparser/SConscript +38 -0
  31. data/lib/libv8/v8/preparser/preparser-process.cc +379 -0
  32. data/lib/libv8/v8/src/SConscript +368 -0
  33. data/lib/libv8/v8/src/accessors.cc +767 -0
  34. data/lib/libv8/v8/src/accessors.h +123 -0
  35. data/lib/libv8/v8/src/allocation-inl.h +49 -0
  36. data/lib/libv8/v8/src/allocation.cc +122 -0
  37. data/lib/libv8/v8/src/allocation.h +143 -0
  38. data/lib/libv8/v8/src/api.cc +5845 -0
  39. data/lib/libv8/v8/src/api.h +574 -0
  40. data/lib/libv8/v8/src/apinatives.js +110 -0
  41. data/lib/libv8/v8/src/apiutils.h +73 -0
  42. data/lib/libv8/v8/src/arguments.h +118 -0
  43. data/lib/libv8/v8/src/arm/assembler-arm-inl.h +353 -0
  44. data/lib/libv8/v8/src/arm/assembler-arm.cc +2661 -0
  45. data/lib/libv8/v8/src/arm/assembler-arm.h +1375 -0
  46. data/lib/libv8/v8/src/arm/builtins-arm.cc +1658 -0
  47. data/lib/libv8/v8/src/arm/code-stubs-arm.cc +6398 -0
  48. data/lib/libv8/v8/src/arm/code-stubs-arm.h +673 -0
  49. data/lib/libv8/v8/src/arm/codegen-arm.cc +52 -0
  50. data/lib/libv8/v8/src/arm/codegen-arm.h +91 -0
  51. data/lib/libv8/v8/src/arm/constants-arm.cc +152 -0
  52. data/lib/libv8/v8/src/arm/constants-arm.h +775 -0
  53. data/lib/libv8/v8/src/arm/cpu-arm.cc +120 -0
  54. data/lib/libv8/v8/src/arm/debug-arm.cc +317 -0
  55. data/lib/libv8/v8/src/arm/deoptimizer-arm.cc +754 -0
  56. data/lib/libv8/v8/src/arm/disasm-arm.cc +1506 -0
  57. data/lib/libv8/v8/src/arm/frames-arm.cc +45 -0
  58. data/lib/libv8/v8/src/arm/frames-arm.h +168 -0
  59. data/lib/libv8/v8/src/arm/full-codegen-arm.cc +4375 -0
  60. data/lib/libv8/v8/src/arm/ic-arm.cc +1562 -0
  61. data/lib/libv8/v8/src/arm/lithium-arm.cc +2206 -0
  62. data/lib/libv8/v8/src/arm/lithium-arm.h +2348 -0
  63. data/lib/libv8/v8/src/arm/lithium-codegen-arm.cc +4526 -0
  64. data/lib/libv8/v8/src/arm/lithium-codegen-arm.h +403 -0
  65. data/lib/libv8/v8/src/arm/lithium-gap-resolver-arm.cc +305 -0
  66. data/lib/libv8/v8/src/arm/lithium-gap-resolver-arm.h +84 -0
  67. data/lib/libv8/v8/src/arm/macro-assembler-arm.cc +3163 -0
  68. data/lib/libv8/v8/src/arm/macro-assembler-arm.h +1126 -0
  69. data/lib/libv8/v8/src/arm/regexp-macro-assembler-arm.cc +1287 -0
  70. data/lib/libv8/v8/src/arm/regexp-macro-assembler-arm.h +253 -0
  71. data/lib/libv8/v8/src/arm/simulator-arm.cc +3424 -0
  72. data/lib/libv8/v8/src/arm/simulator-arm.h +431 -0
  73. data/lib/libv8/v8/src/arm/stub-cache-arm.cc +4243 -0
  74. data/lib/libv8/v8/src/array.js +1366 -0
  75. data/lib/libv8/v8/src/assembler.cc +1207 -0
  76. data/lib/libv8/v8/src/assembler.h +858 -0
  77. data/lib/libv8/v8/src/ast-inl.h +112 -0
  78. data/lib/libv8/v8/src/ast.cc +1146 -0
  79. data/lib/libv8/v8/src/ast.h +2188 -0
  80. data/lib/libv8/v8/src/atomicops.h +167 -0
  81. data/lib/libv8/v8/src/atomicops_internals_arm_gcc.h +145 -0
  82. data/lib/libv8/v8/src/atomicops_internals_mips_gcc.h +169 -0
  83. data/lib/libv8/v8/src/atomicops_internals_x86_gcc.cc +133 -0
  84. data/lib/libv8/v8/src/atomicops_internals_x86_gcc.h +287 -0
  85. data/lib/libv8/v8/src/atomicops_internals_x86_macosx.h +301 -0
  86. data/lib/libv8/v8/src/atomicops_internals_x86_msvc.h +203 -0
  87. data/lib/libv8/v8/src/bignum-dtoa.cc +655 -0
  88. data/lib/libv8/v8/src/bignum-dtoa.h +81 -0
  89. data/lib/libv8/v8/src/bignum.cc +768 -0
  90. data/lib/libv8/v8/src/bignum.h +140 -0
  91. data/lib/libv8/v8/src/bootstrapper.cc +2184 -0
  92. data/lib/libv8/v8/src/bootstrapper.h +188 -0
  93. data/lib/libv8/v8/src/builtins.cc +1707 -0
  94. data/lib/libv8/v8/src/builtins.h +371 -0
  95. data/lib/libv8/v8/src/bytecodes-irregexp.h +105 -0
  96. data/lib/libv8/v8/src/cached-powers.cc +177 -0
  97. data/lib/libv8/v8/src/cached-powers.h +65 -0
  98. data/lib/libv8/v8/src/char-predicates-inl.h +94 -0
  99. data/lib/libv8/v8/src/char-predicates.h +67 -0
  100. data/lib/libv8/v8/src/checks.cc +110 -0
  101. data/lib/libv8/v8/src/checks.h +296 -0
  102. data/lib/libv8/v8/src/circular-queue-inl.h +53 -0
  103. data/lib/libv8/v8/src/circular-queue.cc +122 -0
  104. data/lib/libv8/v8/src/circular-queue.h +103 -0
  105. data/lib/libv8/v8/src/code-stubs.cc +267 -0
  106. data/lib/libv8/v8/src/code-stubs.h +1011 -0
  107. data/lib/libv8/v8/src/code.h +70 -0
  108. data/lib/libv8/v8/src/codegen.cc +231 -0
  109. data/lib/libv8/v8/src/codegen.h +84 -0
  110. data/lib/libv8/v8/src/compilation-cache.cc +540 -0
  111. data/lib/libv8/v8/src/compilation-cache.h +287 -0
  112. data/lib/libv8/v8/src/compiler.cc +786 -0
  113. data/lib/libv8/v8/src/compiler.h +312 -0
  114. data/lib/libv8/v8/src/contexts.cc +347 -0
  115. data/lib/libv8/v8/src/contexts.h +391 -0
  116. data/lib/libv8/v8/src/conversions-inl.h +106 -0
  117. data/lib/libv8/v8/src/conversions.cc +1131 -0
  118. data/lib/libv8/v8/src/conversions.h +135 -0
  119. data/lib/libv8/v8/src/counters.cc +93 -0
  120. data/lib/libv8/v8/src/counters.h +254 -0
  121. data/lib/libv8/v8/src/cpu-profiler-inl.h +101 -0
  122. data/lib/libv8/v8/src/cpu-profiler.cc +609 -0
  123. data/lib/libv8/v8/src/cpu-profiler.h +302 -0
  124. data/lib/libv8/v8/src/cpu.h +69 -0
  125. data/lib/libv8/v8/src/d8-debug.cc +367 -0
  126. data/lib/libv8/v8/src/d8-debug.h +158 -0
  127. data/lib/libv8/v8/src/d8-posix.cc +695 -0
  128. data/lib/libv8/v8/src/d8-readline.cc +130 -0
  129. data/lib/libv8/v8/src/d8-windows.cc +42 -0
  130. data/lib/libv8/v8/src/d8.cc +803 -0
  131. data/lib/libv8/v8/src/d8.gyp +91 -0
  132. data/lib/libv8/v8/src/d8.h +235 -0
  133. data/lib/libv8/v8/src/d8.js +2798 -0
  134. data/lib/libv8/v8/src/data-flow.cc +66 -0
  135. data/lib/libv8/v8/src/data-flow.h +205 -0
  136. data/lib/libv8/v8/src/date.js +1103 -0
  137. data/lib/libv8/v8/src/dateparser-inl.h +127 -0
  138. data/lib/libv8/v8/src/dateparser.cc +178 -0
  139. data/lib/libv8/v8/src/dateparser.h +266 -0
  140. data/lib/libv8/v8/src/debug-agent.cc +447 -0
  141. data/lib/libv8/v8/src/debug-agent.h +129 -0
  142. data/lib/libv8/v8/src/debug-debugger.js +2569 -0
  143. data/lib/libv8/v8/src/debug.cc +3165 -0
  144. data/lib/libv8/v8/src/debug.h +1057 -0
  145. data/lib/libv8/v8/src/deoptimizer.cc +1256 -0
  146. data/lib/libv8/v8/src/deoptimizer.h +602 -0
  147. data/lib/libv8/v8/src/disasm.h +80 -0
  148. data/lib/libv8/v8/src/disassembler.cc +343 -0
  149. data/lib/libv8/v8/src/disassembler.h +58 -0
  150. data/lib/libv8/v8/src/diy-fp.cc +58 -0
  151. data/lib/libv8/v8/src/diy-fp.h +117 -0
  152. data/lib/libv8/v8/src/double.h +238 -0
  153. data/lib/libv8/v8/src/dtoa.cc +103 -0
  154. data/lib/libv8/v8/src/dtoa.h +85 -0
  155. data/lib/libv8/v8/src/execution.cc +849 -0
  156. data/lib/libv8/v8/src/execution.h +297 -0
  157. data/lib/libv8/v8/src/extensions/experimental/break-iterator.cc +250 -0
  158. data/lib/libv8/v8/src/extensions/experimental/break-iterator.h +89 -0
  159. data/lib/libv8/v8/src/extensions/experimental/collator.cc +218 -0
  160. data/lib/libv8/v8/src/extensions/experimental/collator.h +69 -0
  161. data/lib/libv8/v8/src/extensions/experimental/experimental.gyp +94 -0
  162. data/lib/libv8/v8/src/extensions/experimental/i18n-extension.cc +78 -0
  163. data/lib/libv8/v8/src/extensions/experimental/i18n-extension.h +54 -0
  164. data/lib/libv8/v8/src/extensions/experimental/i18n-locale.cc +112 -0
  165. data/lib/libv8/v8/src/extensions/experimental/i18n-locale.h +60 -0
  166. data/lib/libv8/v8/src/extensions/experimental/i18n-utils.cc +43 -0
  167. data/lib/libv8/v8/src/extensions/experimental/i18n-utils.h +49 -0
  168. data/lib/libv8/v8/src/extensions/experimental/i18n.js +180 -0
  169. data/lib/libv8/v8/src/extensions/experimental/language-matcher.cc +251 -0
  170. data/lib/libv8/v8/src/extensions/experimental/language-matcher.h +95 -0
  171. data/lib/libv8/v8/src/extensions/externalize-string-extension.cc +141 -0
  172. data/lib/libv8/v8/src/extensions/externalize-string-extension.h +50 -0
  173. data/lib/libv8/v8/src/extensions/gc-extension.cc +58 -0
  174. data/lib/libv8/v8/src/extensions/gc-extension.h +49 -0
  175. data/lib/libv8/v8/src/factory.cc +1222 -0
  176. data/lib/libv8/v8/src/factory.h +442 -0
  177. data/lib/libv8/v8/src/fast-dtoa.cc +736 -0
  178. data/lib/libv8/v8/src/fast-dtoa.h +83 -0
  179. data/lib/libv8/v8/src/fixed-dtoa.cc +405 -0
  180. data/lib/libv8/v8/src/fixed-dtoa.h +55 -0
  181. data/lib/libv8/v8/src/flag-definitions.h +560 -0
  182. data/lib/libv8/v8/src/flags.cc +551 -0
  183. data/lib/libv8/v8/src/flags.h +79 -0
  184. data/lib/libv8/v8/src/frames-inl.h +247 -0
  185. data/lib/libv8/v8/src/frames.cc +1243 -0
  186. data/lib/libv8/v8/src/frames.h +870 -0
  187. data/lib/libv8/v8/src/full-codegen.cc +1374 -0
  188. data/lib/libv8/v8/src/full-codegen.h +771 -0
  189. data/lib/libv8/v8/src/func-name-inferrer.cc +92 -0
  190. data/lib/libv8/v8/src/func-name-inferrer.h +111 -0
  191. data/lib/libv8/v8/src/gdb-jit.cc +1555 -0
  192. data/lib/libv8/v8/src/gdb-jit.h +143 -0
  193. data/lib/libv8/v8/src/global-handles.cc +665 -0
  194. data/lib/libv8/v8/src/global-handles.h +284 -0
  195. data/lib/libv8/v8/src/globals.h +325 -0
  196. data/lib/libv8/v8/src/handles-inl.h +177 -0
  197. data/lib/libv8/v8/src/handles.cc +987 -0
  198. data/lib/libv8/v8/src/handles.h +382 -0
  199. data/lib/libv8/v8/src/hashmap.cc +230 -0
  200. data/lib/libv8/v8/src/hashmap.h +123 -0
  201. data/lib/libv8/v8/src/heap-inl.h +704 -0
  202. data/lib/libv8/v8/src/heap-profiler.cc +1173 -0
  203. data/lib/libv8/v8/src/heap-profiler.h +397 -0
  204. data/lib/libv8/v8/src/heap.cc +5930 -0
  205. data/lib/libv8/v8/src/heap.h +2268 -0
  206. data/lib/libv8/v8/src/hydrogen-instructions.cc +1769 -0
  207. data/lib/libv8/v8/src/hydrogen-instructions.h +3971 -0
  208. data/lib/libv8/v8/src/hydrogen.cc +6239 -0
  209. data/lib/libv8/v8/src/hydrogen.h +1202 -0
  210. data/lib/libv8/v8/src/ia32/assembler-ia32-inl.h +446 -0
  211. data/lib/libv8/v8/src/ia32/assembler-ia32.cc +2487 -0
  212. data/lib/libv8/v8/src/ia32/assembler-ia32.h +1144 -0
  213. data/lib/libv8/v8/src/ia32/builtins-ia32.cc +1621 -0
  214. data/lib/libv8/v8/src/ia32/code-stubs-ia32.cc +6198 -0
  215. data/lib/libv8/v8/src/ia32/code-stubs-ia32.h +517 -0
  216. data/lib/libv8/v8/src/ia32/codegen-ia32.cc +265 -0
  217. data/lib/libv8/v8/src/ia32/codegen-ia32.h +79 -0
  218. data/lib/libv8/v8/src/ia32/cpu-ia32.cc +88 -0
  219. data/lib/libv8/v8/src/ia32/debug-ia32.cc +312 -0
  220. data/lib/libv8/v8/src/ia32/deoptimizer-ia32.cc +774 -0
  221. data/lib/libv8/v8/src/ia32/disasm-ia32.cc +1628 -0
  222. data/lib/libv8/v8/src/ia32/frames-ia32.cc +45 -0
  223. data/lib/libv8/v8/src/ia32/frames-ia32.h +142 -0
  224. data/lib/libv8/v8/src/ia32/full-codegen-ia32.cc +4338 -0
  225. data/lib/libv8/v8/src/ia32/ic-ia32.cc +1597 -0
  226. data/lib/libv8/v8/src/ia32/lithium-codegen-ia32.cc +4461 -0
  227. data/lib/libv8/v8/src/ia32/lithium-codegen-ia32.h +375 -0
  228. data/lib/libv8/v8/src/ia32/lithium-gap-resolver-ia32.cc +475 -0
  229. data/lib/libv8/v8/src/ia32/lithium-gap-resolver-ia32.h +110 -0
  230. data/lib/libv8/v8/src/ia32/lithium-ia32.cc +2261 -0
  231. data/lib/libv8/v8/src/ia32/lithium-ia32.h +2396 -0
  232. data/lib/libv8/v8/src/ia32/macro-assembler-ia32.cc +2136 -0
  233. data/lib/libv8/v8/src/ia32/macro-assembler-ia32.h +775 -0
  234. data/lib/libv8/v8/src/ia32/regexp-macro-assembler-ia32.cc +1263 -0
  235. data/lib/libv8/v8/src/ia32/regexp-macro-assembler-ia32.h +216 -0
  236. data/lib/libv8/v8/src/ia32/simulator-ia32.cc +30 -0
  237. data/lib/libv8/v8/src/ia32/simulator-ia32.h +74 -0
  238. data/lib/libv8/v8/src/ia32/stub-cache-ia32.cc +3847 -0
  239. data/lib/libv8/v8/src/ic-inl.h +130 -0
  240. data/lib/libv8/v8/src/ic.cc +2577 -0
  241. data/lib/libv8/v8/src/ic.h +736 -0
  242. data/lib/libv8/v8/src/inspector.cc +63 -0
  243. data/lib/libv8/v8/src/inspector.h +62 -0
  244. data/lib/libv8/v8/src/interpreter-irregexp.cc +659 -0
  245. data/lib/libv8/v8/src/interpreter-irregexp.h +49 -0
  246. data/lib/libv8/v8/src/isolate-inl.h +50 -0
  247. data/lib/libv8/v8/src/isolate.cc +1869 -0
  248. data/lib/libv8/v8/src/isolate.h +1382 -0
  249. data/lib/libv8/v8/src/json-parser.cc +504 -0
  250. data/lib/libv8/v8/src/json-parser.h +161 -0
  251. data/lib/libv8/v8/src/json.js +342 -0
  252. data/lib/libv8/v8/src/jsregexp.cc +5385 -0
  253. data/lib/libv8/v8/src/jsregexp.h +1492 -0
  254. data/lib/libv8/v8/src/list-inl.h +212 -0
  255. data/lib/libv8/v8/src/list.h +174 -0
  256. data/lib/libv8/v8/src/lithium-allocator-inl.h +142 -0
  257. data/lib/libv8/v8/src/lithium-allocator.cc +2123 -0
  258. data/lib/libv8/v8/src/lithium-allocator.h +630 -0
  259. data/lib/libv8/v8/src/lithium.cc +190 -0
  260. data/lib/libv8/v8/src/lithium.h +597 -0
  261. data/lib/libv8/v8/src/liveedit-debugger.js +1082 -0
  262. data/lib/libv8/v8/src/liveedit.cc +1691 -0
  263. data/lib/libv8/v8/src/liveedit.h +180 -0
  264. data/lib/libv8/v8/src/liveobjectlist-inl.h +126 -0
  265. data/lib/libv8/v8/src/liveobjectlist.cc +2589 -0
  266. data/lib/libv8/v8/src/liveobjectlist.h +322 -0
  267. data/lib/libv8/v8/src/log-inl.h +59 -0
  268. data/lib/libv8/v8/src/log-utils.cc +428 -0
  269. data/lib/libv8/v8/src/log-utils.h +231 -0
  270. data/lib/libv8/v8/src/log.cc +1993 -0
  271. data/lib/libv8/v8/src/log.h +476 -0
  272. data/lib/libv8/v8/src/macro-assembler.h +120 -0
  273. data/lib/libv8/v8/src/macros.py +178 -0
  274. data/lib/libv8/v8/src/mark-compact.cc +3143 -0
  275. data/lib/libv8/v8/src/mark-compact.h +506 -0
  276. data/lib/libv8/v8/src/math.js +264 -0
  277. data/lib/libv8/v8/src/messages.cc +179 -0
  278. data/lib/libv8/v8/src/messages.h +113 -0
  279. data/lib/libv8/v8/src/messages.js +1096 -0
  280. data/lib/libv8/v8/src/mips/assembler-mips-inl.h +312 -0
  281. data/lib/libv8/v8/src/mips/assembler-mips.cc +1960 -0
  282. data/lib/libv8/v8/src/mips/assembler-mips.h +1138 -0
  283. data/lib/libv8/v8/src/mips/builtins-mips.cc +1628 -0
  284. data/lib/libv8/v8/src/mips/code-stubs-mips.cc +6656 -0
  285. data/lib/libv8/v8/src/mips/code-stubs-mips.h +682 -0
  286. data/lib/libv8/v8/src/mips/codegen-mips.cc +52 -0
  287. data/lib/libv8/v8/src/mips/codegen-mips.h +98 -0
  288. data/lib/libv8/v8/src/mips/constants-mips.cc +352 -0
  289. data/lib/libv8/v8/src/mips/constants-mips.h +739 -0
  290. data/lib/libv8/v8/src/mips/cpu-mips.cc +96 -0
  291. data/lib/libv8/v8/src/mips/debug-mips.cc +308 -0
  292. data/lib/libv8/v8/src/mips/deoptimizer-mips.cc +91 -0
  293. data/lib/libv8/v8/src/mips/disasm-mips.cc +1050 -0
  294. data/lib/libv8/v8/src/mips/frames-mips.cc +47 -0
  295. data/lib/libv8/v8/src/mips/frames-mips.h +219 -0
  296. data/lib/libv8/v8/src/mips/full-codegen-mips.cc +4388 -0
  297. data/lib/libv8/v8/src/mips/ic-mips.cc +1580 -0
  298. data/lib/libv8/v8/src/mips/lithium-codegen-mips.h +65 -0
  299. data/lib/libv8/v8/src/mips/lithium-mips.h +307 -0
  300. data/lib/libv8/v8/src/mips/macro-assembler-mips.cc +4056 -0
  301. data/lib/libv8/v8/src/mips/macro-assembler-mips.h +1214 -0
  302. data/lib/libv8/v8/src/mips/regexp-macro-assembler-mips.cc +1251 -0
  303. data/lib/libv8/v8/src/mips/regexp-macro-assembler-mips.h +252 -0
  304. data/lib/libv8/v8/src/mips/simulator-mips.cc +2621 -0
  305. data/lib/libv8/v8/src/mips/simulator-mips.h +401 -0
  306. data/lib/libv8/v8/src/mips/stub-cache-mips.cc +4285 -0
  307. data/lib/libv8/v8/src/mirror-debugger.js +2382 -0
  308. data/lib/libv8/v8/src/mksnapshot.cc +328 -0
  309. data/lib/libv8/v8/src/natives.h +64 -0
  310. data/lib/libv8/v8/src/objects-debug.cc +738 -0
  311. data/lib/libv8/v8/src/objects-inl.h +4323 -0
  312. data/lib/libv8/v8/src/objects-printer.cc +829 -0
  313. data/lib/libv8/v8/src/objects-visiting.cc +148 -0
  314. data/lib/libv8/v8/src/objects-visiting.h +424 -0
  315. data/lib/libv8/v8/src/objects.cc +10585 -0
  316. data/lib/libv8/v8/src/objects.h +6838 -0
  317. data/lib/libv8/v8/src/parser.cc +4997 -0
  318. data/lib/libv8/v8/src/parser.h +765 -0
  319. data/lib/libv8/v8/src/platform-cygwin.cc +779 -0
  320. data/lib/libv8/v8/src/platform-freebsd.cc +826 -0
  321. data/lib/libv8/v8/src/platform-linux.cc +1149 -0
  322. data/lib/libv8/v8/src/platform-macos.cc +830 -0
  323. data/lib/libv8/v8/src/platform-nullos.cc +479 -0
  324. data/lib/libv8/v8/src/platform-openbsd.cc +640 -0
  325. data/lib/libv8/v8/src/platform-posix.cc +424 -0
  326. data/lib/libv8/v8/src/platform-solaris.cc +762 -0
  327. data/lib/libv8/v8/src/platform-tls-mac.h +62 -0
  328. data/lib/libv8/v8/src/platform-tls-win32.h +62 -0
  329. data/lib/libv8/v8/src/platform-tls.h +50 -0
  330. data/lib/libv8/v8/src/platform-win32.cc +2021 -0
  331. data/lib/libv8/v8/src/platform.h +667 -0
  332. data/lib/libv8/v8/src/preparse-data-format.h +62 -0
  333. data/lib/libv8/v8/src/preparse-data.cc +183 -0
  334. data/lib/libv8/v8/src/preparse-data.h +225 -0
  335. data/lib/libv8/v8/src/preparser-api.cc +220 -0
  336. data/lib/libv8/v8/src/preparser.cc +1450 -0
  337. data/lib/libv8/v8/src/preparser.h +493 -0
  338. data/lib/libv8/v8/src/prettyprinter.cc +1493 -0
  339. data/lib/libv8/v8/src/prettyprinter.h +223 -0
  340. data/lib/libv8/v8/src/profile-generator-inl.h +128 -0
  341. data/lib/libv8/v8/src/profile-generator.cc +3098 -0
  342. data/lib/libv8/v8/src/profile-generator.h +1126 -0
  343. data/lib/libv8/v8/src/property.cc +105 -0
  344. data/lib/libv8/v8/src/property.h +365 -0
  345. data/lib/libv8/v8/src/proxy.js +83 -0
  346. data/lib/libv8/v8/src/regexp-macro-assembler-irregexp-inl.h +78 -0
  347. data/lib/libv8/v8/src/regexp-macro-assembler-irregexp.cc +471 -0
  348. data/lib/libv8/v8/src/regexp-macro-assembler-irregexp.h +142 -0
  349. data/lib/libv8/v8/src/regexp-macro-assembler-tracer.cc +373 -0
  350. data/lib/libv8/v8/src/regexp-macro-assembler-tracer.h +104 -0
  351. data/lib/libv8/v8/src/regexp-macro-assembler.cc +267 -0
  352. data/lib/libv8/v8/src/regexp-macro-assembler.h +243 -0
  353. data/lib/libv8/v8/src/regexp-stack.cc +111 -0
  354. data/lib/libv8/v8/src/regexp-stack.h +147 -0
  355. data/lib/libv8/v8/src/regexp.js +483 -0
  356. data/lib/libv8/v8/src/rewriter.cc +360 -0
  357. data/lib/libv8/v8/src/rewriter.h +50 -0
  358. data/lib/libv8/v8/src/runtime-profiler.cc +489 -0
  359. data/lib/libv8/v8/src/runtime-profiler.h +201 -0
  360. data/lib/libv8/v8/src/runtime.cc +12227 -0
  361. data/lib/libv8/v8/src/runtime.h +652 -0
  362. data/lib/libv8/v8/src/runtime.js +649 -0
  363. data/lib/libv8/v8/src/safepoint-table.cc +256 -0
  364. data/lib/libv8/v8/src/safepoint-table.h +270 -0
  365. data/lib/libv8/v8/src/scanner-base.cc +952 -0
  366. data/lib/libv8/v8/src/scanner-base.h +670 -0
  367. data/lib/libv8/v8/src/scanner.cc +345 -0
  368. data/lib/libv8/v8/src/scanner.h +146 -0
  369. data/lib/libv8/v8/src/scopeinfo.cc +646 -0
  370. data/lib/libv8/v8/src/scopeinfo.h +254 -0
  371. data/lib/libv8/v8/src/scopes.cc +1150 -0
  372. data/lib/libv8/v8/src/scopes.h +507 -0
  373. data/lib/libv8/v8/src/serialize.cc +1574 -0
  374. data/lib/libv8/v8/src/serialize.h +589 -0
  375. data/lib/libv8/v8/src/shell.h +55 -0
  376. data/lib/libv8/v8/src/simulator.h +43 -0
  377. data/lib/libv8/v8/src/small-pointer-list.h +163 -0
  378. data/lib/libv8/v8/src/smart-pointer.h +109 -0
  379. data/lib/libv8/v8/src/snapshot-common.cc +83 -0
  380. data/lib/libv8/v8/src/snapshot-empty.cc +54 -0
  381. data/lib/libv8/v8/src/snapshot.h +91 -0
  382. data/lib/libv8/v8/src/spaces-inl.h +529 -0
  383. data/lib/libv8/v8/src/spaces.cc +3145 -0
  384. data/lib/libv8/v8/src/spaces.h +2369 -0
  385. data/lib/libv8/v8/src/splay-tree-inl.h +310 -0
  386. data/lib/libv8/v8/src/splay-tree.h +205 -0
  387. data/lib/libv8/v8/src/string-search.cc +41 -0
  388. data/lib/libv8/v8/src/string-search.h +568 -0
  389. data/lib/libv8/v8/src/string-stream.cc +592 -0
  390. data/lib/libv8/v8/src/string-stream.h +191 -0
  391. data/lib/libv8/v8/src/string.js +994 -0
  392. data/lib/libv8/v8/src/strtod.cc +440 -0
  393. data/lib/libv8/v8/src/strtod.h +40 -0
  394. data/lib/libv8/v8/src/stub-cache.cc +1965 -0
  395. data/lib/libv8/v8/src/stub-cache.h +924 -0
  396. data/lib/libv8/v8/src/third_party/valgrind/valgrind.h +3925 -0
  397. data/lib/libv8/v8/src/token.cc +63 -0
  398. data/lib/libv8/v8/src/token.h +288 -0
  399. data/lib/libv8/v8/src/type-info.cc +507 -0
  400. data/lib/libv8/v8/src/type-info.h +272 -0
  401. data/lib/libv8/v8/src/unbound-queue-inl.h +95 -0
  402. data/lib/libv8/v8/src/unbound-queue.h +69 -0
  403. data/lib/libv8/v8/src/unicode-inl.h +238 -0
  404. data/lib/libv8/v8/src/unicode.cc +1624 -0
  405. data/lib/libv8/v8/src/unicode.h +280 -0
  406. data/lib/libv8/v8/src/uri.js +408 -0
  407. data/lib/libv8/v8/src/utils-inl.h +48 -0
  408. data/lib/libv8/v8/src/utils.cc +371 -0
  409. data/lib/libv8/v8/src/utils.h +800 -0
  410. data/lib/libv8/v8/src/v8-counters.cc +62 -0
  411. data/lib/libv8/v8/src/v8-counters.h +314 -0
  412. data/lib/libv8/v8/src/v8.cc +213 -0
  413. data/lib/libv8/v8/src/v8.h +131 -0
  414. data/lib/libv8/v8/src/v8checks.h +64 -0
  415. data/lib/libv8/v8/src/v8dll-main.cc +44 -0
  416. data/lib/libv8/v8/src/v8globals.h +512 -0
  417. data/lib/libv8/v8/src/v8memory.h +82 -0
  418. data/lib/libv8/v8/src/v8natives.js +1310 -0
  419. data/lib/libv8/v8/src/v8preparserdll-main.cc +39 -0
  420. data/lib/libv8/v8/src/v8threads.cc +464 -0
  421. data/lib/libv8/v8/src/v8threads.h +165 -0
  422. data/lib/libv8/v8/src/v8utils.h +319 -0
  423. data/lib/libv8/v8/src/variables.cc +114 -0
  424. data/lib/libv8/v8/src/variables.h +167 -0
  425. data/lib/libv8/v8/src/version.cc +116 -0
  426. data/lib/libv8/v8/src/version.h +68 -0
  427. data/lib/libv8/v8/src/vm-state-inl.h +138 -0
  428. data/lib/libv8/v8/src/vm-state.h +71 -0
  429. data/lib/libv8/v8/src/win32-headers.h +96 -0
  430. data/lib/libv8/v8/src/x64/assembler-x64-inl.h +462 -0
  431. data/lib/libv8/v8/src/x64/assembler-x64.cc +3027 -0
  432. data/lib/libv8/v8/src/x64/assembler-x64.h +1633 -0
  433. data/lib/libv8/v8/src/x64/builtins-x64.cc +1520 -0
  434. data/lib/libv8/v8/src/x64/code-stubs-x64.cc +5132 -0
  435. data/lib/libv8/v8/src/x64/code-stubs-x64.h +514 -0
  436. data/lib/libv8/v8/src/x64/codegen-x64.cc +146 -0
  437. data/lib/libv8/v8/src/x64/codegen-x64.h +76 -0
  438. data/lib/libv8/v8/src/x64/cpu-x64.cc +88 -0
  439. data/lib/libv8/v8/src/x64/debug-x64.cc +319 -0
  440. data/lib/libv8/v8/src/x64/deoptimizer-x64.cc +815 -0
  441. data/lib/libv8/v8/src/x64/disasm-x64.cc +1832 -0
  442. data/lib/libv8/v8/src/x64/frames-x64.cc +45 -0
  443. data/lib/libv8/v8/src/x64/frames-x64.h +130 -0
  444. data/lib/libv8/v8/src/x64/full-codegen-x64.cc +4318 -0
  445. data/lib/libv8/v8/src/x64/ic-x64.cc +1608 -0
  446. data/lib/libv8/v8/src/x64/lithium-codegen-x64.cc +4267 -0
  447. data/lib/libv8/v8/src/x64/lithium-codegen-x64.h +367 -0
  448. data/lib/libv8/v8/src/x64/lithium-gap-resolver-x64.cc +320 -0
  449. data/lib/libv8/v8/src/x64/lithium-gap-resolver-x64.h +74 -0
  450. data/lib/libv8/v8/src/x64/lithium-x64.cc +2202 -0
  451. data/lib/libv8/v8/src/x64/lithium-x64.h +2333 -0
  452. data/lib/libv8/v8/src/x64/macro-assembler-x64.cc +3745 -0
  453. data/lib/libv8/v8/src/x64/macro-assembler-x64.h +1290 -0
  454. data/lib/libv8/v8/src/x64/regexp-macro-assembler-x64.cc +1398 -0
  455. data/lib/libv8/v8/src/x64/regexp-macro-assembler-x64.h +282 -0
  456. data/lib/libv8/v8/src/x64/simulator-x64.cc +27 -0
  457. data/lib/libv8/v8/src/x64/simulator-x64.h +72 -0
  458. data/lib/libv8/v8/src/x64/stub-cache-x64.cc +3610 -0
  459. data/lib/libv8/v8/src/zone-inl.h +140 -0
  460. data/lib/libv8/v8/src/zone.cc +196 -0
  461. data/lib/libv8/v8/src/zone.h +240 -0
  462. data/lib/libv8/v8/tools/codemap.js +265 -0
  463. data/lib/libv8/v8/tools/consarray.js +93 -0
  464. data/lib/libv8/v8/tools/csvparser.js +78 -0
  465. data/lib/libv8/v8/tools/disasm.py +92 -0
  466. data/lib/libv8/v8/tools/freebsd-tick-processor +10 -0
  467. data/lib/libv8/v8/tools/gc-nvp-trace-processor.py +342 -0
  468. data/lib/libv8/v8/tools/gcmole/README +62 -0
  469. data/lib/libv8/v8/tools/gcmole/gccause.lua +60 -0
  470. data/lib/libv8/v8/tools/gcmole/gcmole.cc +1261 -0
  471. data/lib/libv8/v8/tools/gcmole/gcmole.lua +378 -0
  472. data/lib/libv8/v8/tools/generate-ten-powers.scm +286 -0
  473. data/lib/libv8/v8/tools/grokdump.py +841 -0
  474. data/lib/libv8/v8/tools/gyp/v8.gyp +995 -0
  475. data/lib/libv8/v8/tools/js2c.py +364 -0
  476. data/lib/libv8/v8/tools/jsmin.py +280 -0
  477. data/lib/libv8/v8/tools/linux-tick-processor +35 -0
  478. data/lib/libv8/v8/tools/ll_prof.py +942 -0
  479. data/lib/libv8/v8/tools/logreader.js +185 -0
  480. data/lib/libv8/v8/tools/mac-nm +18 -0
  481. data/lib/libv8/v8/tools/mac-tick-processor +6 -0
  482. data/lib/libv8/v8/tools/oom_dump/README +31 -0
  483. data/lib/libv8/v8/tools/oom_dump/SConstruct +42 -0
  484. data/lib/libv8/v8/tools/oom_dump/oom_dump.cc +288 -0
  485. data/lib/libv8/v8/tools/presubmit.py +305 -0
  486. data/lib/libv8/v8/tools/process-heap-prof.py +120 -0
  487. data/lib/libv8/v8/tools/profile.js +751 -0
  488. data/lib/libv8/v8/tools/profile_view.js +219 -0
  489. data/lib/libv8/v8/tools/run-valgrind.py +77 -0
  490. data/lib/libv8/v8/tools/splaytree.js +316 -0
  491. data/lib/libv8/v8/tools/stats-viewer.py +468 -0
  492. data/lib/libv8/v8/tools/test.py +1510 -0
  493. data/lib/libv8/v8/tools/tickprocessor-driver.js +59 -0
  494. data/lib/libv8/v8/tools/tickprocessor.js +877 -0
  495. data/lib/libv8/v8/tools/utils.py +96 -0
  496. data/lib/libv8/v8/tools/visual_studio/README.txt +12 -0
  497. data/lib/libv8/v8/tools/windows-tick-processor.bat +30 -0
  498. data/lib/libv8/version.rb +5 -0
  499. data/libv8.gemspec +36 -0
  500. metadata +578 -0
@@ -0,0 +1,35 @@
1
+ #!/bin/sh
2
+
3
+ tools_path=`cd $(dirname "$0");pwd`
4
+ if [ ! "$D8_PATH" ]; then
5
+ d8_public=`which d8`
6
+ if [ -x $d8_public ]; then D8_PATH=$(dirname "$d8_public"); fi
7
+ fi
8
+ [ "$D8_PATH" ] || D8_PATH=$tools_path/..
9
+ d8_exec=$D8_PATH/d8
10
+
11
+ if [ "$1" = "--no-build" ]; then
12
+ shift
13
+ else
14
+ # compile d8 if it doesn't exist, assuming this script
15
+ # resides in the repository.
16
+ [ -x $d8_exec ] || scons -j4 -C $D8_PATH -Y $tools_path/.. d8
17
+ fi
18
+
19
+
20
+ # find the name of the log file to process, it must not start with a dash.
21
+ log_file="v8.log"
22
+ for arg in "$@"
23
+ do
24
+ if ! expr "X${arg}" : "^X-" > /dev/null; then
25
+ log_file=${arg}
26
+ fi
27
+ done
28
+
29
+
30
+ # nm spits out 'no symbols found' messages to stderr.
31
+ cat $log_file | $d8_exec $tools_path/splaytree.js $tools_path/codemap.js \
32
+ $tools_path/csvparser.js $tools_path/consarray.js \
33
+ $tools_path/profile.js $tools_path/profile_view.js \
34
+ $tools_path/logreader.js $tools_path/tickprocessor.js \
35
+ $tools_path/tickprocessor-driver.js -- $@ 2>/dev/null
@@ -0,0 +1,942 @@
1
+ #!/usr/bin/env python
2
+ #
3
+ # Copyright 2010 the V8 project authors. All rights reserved.
4
+ # Redistribution and use in source and binary forms, with or without
5
+ # modification, are permitted provided that the following conditions are
6
+ # met:
7
+ #
8
+ # * Redistributions of source code must retain the above copyright
9
+ # notice, this list of conditions and the following disclaimer.
10
+ # * Redistributions in binary form must reproduce the above
11
+ # copyright notice, this list of conditions and the following
12
+ # disclaimer in the documentation and/or other materials provided
13
+ # with the distribution.
14
+ # * Neither the name of Google Inc. nor the names of its
15
+ # contributors may be used to endorse or promote products derived
16
+ # from this software without specific prior written permission.
17
+ #
18
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19
+ # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20
+ # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21
+ # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22
+ # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23
+ # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24
+ # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
+ # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26
+ # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
+ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
+
30
+ import bisect
31
+ import collections
32
+ import ctypes
33
+ import disasm
34
+ import mmap
35
+ import optparse
36
+ import os
37
+ import re
38
+ import subprocess
39
+ import sys
40
+ import time
41
+
42
+
43
+ USAGE="""usage: %prog [OPTION]...
44
+
45
+ Analyses V8 and perf logs to produce profiles.
46
+
47
+ Perf logs can be collected using a command like:
48
+ $ perf record -R -e cycles -c 10000 -f -i ./shell bench.js --ll-prof
49
+ # -R: collect all data
50
+ # -e cycles: use cpu-cycles event (run "perf list" for details)
51
+ # -c 10000: write a sample after each 10000 events
52
+ # -f: force output file overwrite
53
+ # -i: limit profiling to our process and the kernel
54
+ # --ll-prof shell flag enables the right V8 logs
55
+ This will produce a binary trace file (perf.data) that %prog can analyse.
56
+
57
+ Examples:
58
+ # Print flat profile with annotated disassembly for the 10 top
59
+ # symbols. Use default log names and include the snapshot log.
60
+ $ %prog --snapshot --disasm-top=10
61
+
62
+ # Print flat profile with annotated disassembly for all used symbols.
63
+ # Use default log names and include kernel symbols into analysis.
64
+ $ %prog --disasm-all --kernel
65
+
66
+ # Print flat profile. Use custom log names.
67
+ $ %prog --log=foo.log --snapshot-log=snap-foo.log --trace=foo.data --snapshot
68
+ """
69
+
70
+
71
+ # Must match kGcFakeMmap.
72
+ V8_GC_FAKE_MMAP = "/tmp/__v8_gc__"
73
+
74
+ JS_ORIGIN = "js"
75
+ JS_SNAPSHOT_ORIGIN = "js-snapshot"
76
+
77
+ OBJDUMP_BIN = disasm.OBJDUMP_BIN
78
+
79
+
80
+ class Code(object):
81
+ """Code object."""
82
+
83
+ _id = 0
84
+
85
+ def __init__(self, name, start_address, end_address, origin, origin_offset):
86
+ self.id = Code._id
87
+ Code._id += 1
88
+ self.name = name
89
+ self.other_names = None
90
+ self.start_address = start_address
91
+ self.end_address = end_address
92
+ self.origin = origin
93
+ self.origin_offset = origin_offset
94
+ self.self_ticks = 0
95
+ self.self_ticks_map = None
96
+ self.callee_ticks = None
97
+
98
+ def AddName(self, name):
99
+ assert self.name != name
100
+ if self.other_names is None:
101
+ self.other_names = [name]
102
+ return
103
+ if not name in self.other_names:
104
+ self.other_names.append(name)
105
+
106
+ def FullName(self):
107
+ if self.other_names is None:
108
+ return self.name
109
+ self.other_names.sort()
110
+ return "%s (aka %s)" % (self.name, ", ".join(self.other_names))
111
+
112
+ def IsUsed(self):
113
+ return self.self_ticks > 0 or self.callee_ticks is not None
114
+
115
+ def Tick(self, pc):
116
+ self.self_ticks += 1
117
+ if self.self_ticks_map is None:
118
+ self.self_ticks_map = collections.defaultdict(lambda: 0)
119
+ offset = pc - self.start_address
120
+ self.self_ticks_map[offset] += 1
121
+
122
+ def CalleeTick(self, callee):
123
+ if self.callee_ticks is None:
124
+ self.callee_ticks = collections.defaultdict(lambda: 0)
125
+ self.callee_ticks[callee] += 1
126
+
127
+ def PrintAnnotated(self, arch, options):
128
+ if self.self_ticks_map is None:
129
+ ticks_map = []
130
+ else:
131
+ ticks_map = self.self_ticks_map.items()
132
+ # Convert the ticks map to offsets and counts arrays so that later
133
+ # we can do binary search in the offsets array.
134
+ ticks_map.sort(key=lambda t: t[0])
135
+ ticks_offsets = [t[0] for t in ticks_map]
136
+ ticks_counts = [t[1] for t in ticks_map]
137
+ # Get a list of disassembled lines and their addresses.
138
+ lines = self._GetDisasmLines(arch, options)
139
+ if len(lines) == 0:
140
+ return
141
+ # Print annotated lines.
142
+ address = lines[0][0]
143
+ total_count = 0
144
+ for i in xrange(len(lines)):
145
+ start_offset = lines[i][0] - address
146
+ if i == len(lines) - 1:
147
+ end_offset = self.end_address - self.start_address
148
+ else:
149
+ end_offset = lines[i + 1][0] - address
150
+ # Ticks (reported pc values) are not always precise, i.e. not
151
+ # necessarily point at instruction starts. So we have to search
152
+ # for ticks that touch the current instruction line.
153
+ j = bisect.bisect_left(ticks_offsets, end_offset)
154
+ count = 0
155
+ for offset, cnt in reversed(zip(ticks_offsets[:j], ticks_counts[:j])):
156
+ if offset < start_offset:
157
+ break
158
+ count += cnt
159
+ total_count += count
160
+ count = 100.0 * count / self.self_ticks
161
+ if count >= 0.01:
162
+ print "%15.2f %x: %s" % (count, lines[i][0], lines[i][1])
163
+ else:
164
+ print "%s %x: %s" % (" " * 15, lines[i][0], lines[i][1])
165
+ print
166
+ assert total_count == self.self_ticks, \
167
+ "Lost ticks (%d != %d) in %s" % (total_count, self.self_ticks, self)
168
+
169
+ def __str__(self):
170
+ return "%s [0x%x, 0x%x) size: %d origin: %s" % (
171
+ self.name,
172
+ self.start_address,
173
+ self.end_address,
174
+ self.end_address - self.start_address,
175
+ self.origin)
176
+
177
+ def _GetDisasmLines(self, arch, options):
178
+ if self.origin == JS_ORIGIN or self.origin == JS_SNAPSHOT_ORIGIN:
179
+ inplace = False
180
+ filename = options.log + ".ll"
181
+ else:
182
+ inplace = True
183
+ filename = self.origin
184
+ return disasm.GetDisasmLines(filename,
185
+ self.origin_offset,
186
+ self.end_address - self.start_address,
187
+ arch,
188
+ inplace)
189
+
190
+
191
+ class CodePage(object):
192
+ """Group of adjacent code objects."""
193
+
194
+ SHIFT = 12 # 4K pages
195
+ SIZE = (1 << SHIFT)
196
+ MASK = ~(SIZE - 1)
197
+
198
+ @staticmethod
199
+ def PageAddress(address):
200
+ return address & CodePage.MASK
201
+
202
+ @staticmethod
203
+ def PageId(address):
204
+ return address >> CodePage.SHIFT
205
+
206
+ @staticmethod
207
+ def PageAddressFromId(id):
208
+ return id << CodePage.SHIFT
209
+
210
+ def __init__(self, address):
211
+ self.address = address
212
+ self.code_objects = []
213
+
214
+ def Add(self, code):
215
+ self.code_objects.append(code)
216
+
217
+ def Remove(self, code):
218
+ self.code_objects.remove(code)
219
+
220
+ def Find(self, pc):
221
+ code_objects = self.code_objects
222
+ for i, code in enumerate(code_objects):
223
+ if code.start_address <= pc < code.end_address:
224
+ code_objects[0], code_objects[i] = code, code_objects[0]
225
+ return code
226
+ return None
227
+
228
+ def __iter__(self):
229
+ return self.code_objects.__iter__()
230
+
231
+
232
+ class CodeMap(object):
233
+ """Code object map."""
234
+
235
+ def __init__(self):
236
+ self.pages = {}
237
+ self.min_address = 1 << 64
238
+ self.max_address = -1
239
+
240
+ def Add(self, code, max_pages=-1):
241
+ page_id = CodePage.PageId(code.start_address)
242
+ limit_id = CodePage.PageId(code.end_address + CodePage.SIZE - 1)
243
+ pages = 0
244
+ while page_id < limit_id:
245
+ if max_pages >= 0 and pages > max_pages:
246
+ print >>sys.stderr, \
247
+ "Warning: page limit (%d) reached for %s [%s]" % (
248
+ max_pages, code.name, code.origin)
249
+ break
250
+ if page_id in self.pages:
251
+ page = self.pages[page_id]
252
+ else:
253
+ page = CodePage(CodePage.PageAddressFromId(page_id))
254
+ self.pages[page_id] = page
255
+ page.Add(code)
256
+ page_id += 1
257
+ pages += 1
258
+ self.min_address = min(self.min_address, code.start_address)
259
+ self.max_address = max(self.max_address, code.end_address)
260
+
261
+ def Remove(self, code):
262
+ page_id = CodePage.PageId(code.start_address)
263
+ limit_id = CodePage.PageId(code.end_address + CodePage.SIZE - 1)
264
+ removed = False
265
+ while page_id < limit_id:
266
+ if page_id not in self.pages:
267
+ page_id += 1
268
+ continue
269
+ page = self.pages[page_id]
270
+ page.Remove(code)
271
+ removed = True
272
+ page_id += 1
273
+ return removed
274
+
275
+ def AllCode(self):
276
+ for page in self.pages.itervalues():
277
+ for code in page:
278
+ if CodePage.PageAddress(code.start_address) == page.address:
279
+ yield code
280
+
281
+ def UsedCode(self):
282
+ for code in self.AllCode():
283
+ if code.IsUsed():
284
+ yield code
285
+
286
+ def Print(self):
287
+ for code in self.AllCode():
288
+ print code
289
+
290
+ def Find(self, pc):
291
+ if pc < self.min_address or pc >= self.max_address:
292
+ return None
293
+ page_id = CodePage.PageId(pc)
294
+ if page_id not in self.pages:
295
+ return None
296
+ return self.pages[page_id].Find(pc)
297
+
298
+
299
+ class CodeInfo(object):
300
+ """Generic info about generated code objects."""
301
+
302
+ def __init__(self, arch, header_size):
303
+ self.arch = arch
304
+ self.header_size = header_size
305
+
306
+
307
+ class SnapshotLogReader(object):
308
+ """V8 snapshot log reader."""
309
+
310
+ _SNAPSHOT_CODE_NAME_RE = re.compile(
311
+ r"snapshot-code-name,(\d+),\"(.*)\"")
312
+
313
+ def __init__(self, log_name):
314
+ self.log_name = log_name
315
+
316
+ def ReadNameMap(self):
317
+ log = open(self.log_name, "r")
318
+ try:
319
+ snapshot_pos_to_name = {}
320
+ for line in log:
321
+ match = SnapshotLogReader._SNAPSHOT_CODE_NAME_RE.match(line)
322
+ if match:
323
+ pos = int(match.group(1))
324
+ name = match.group(2)
325
+ snapshot_pos_to_name[pos] = name
326
+ finally:
327
+ log.close()
328
+ return snapshot_pos_to_name
329
+
330
+
331
+ class LogReader(object):
332
+ """V8 low-level (binary) log reader."""
333
+
334
+ _ARCH_TO_POINTER_TYPE_MAP = {
335
+ "ia32": ctypes.c_uint32,
336
+ "arm": ctypes.c_uint32,
337
+ "x64": ctypes.c_uint64
338
+ }
339
+
340
+ _CODE_CREATE_TAG = "C"
341
+ _CODE_MOVE_TAG = "M"
342
+ _CODE_DELETE_TAG = "D"
343
+ _SNAPSHOT_POSITION_TAG = "P"
344
+ _CODE_MOVING_GC_TAG = "G"
345
+
346
+ def __init__(self, log_name, code_map, snapshot_pos_to_name):
347
+ self.log_file = open(log_name, "r")
348
+ self.log = mmap.mmap(self.log_file.fileno(), 0, mmap.MAP_PRIVATE)
349
+ self.log_pos = 0
350
+ self.code_map = code_map
351
+ self.snapshot_pos_to_name = snapshot_pos_to_name
352
+ self.address_to_snapshot_name = {}
353
+
354
+ self.arch = self.log[:self.log.find("\0")]
355
+ self.log_pos += len(self.arch) + 1
356
+ assert self.arch in LogReader._ARCH_TO_POINTER_TYPE_MAP, \
357
+ "Unsupported architecture %s" % self.arch
358
+ pointer_type = LogReader._ARCH_TO_POINTER_TYPE_MAP[self.arch]
359
+
360
+ self.code_create_struct = LogReader._DefineStruct([
361
+ ("name_size", ctypes.c_int32),
362
+ ("code_address", pointer_type),
363
+ ("code_size", ctypes.c_int32)])
364
+
365
+ self.code_move_struct = LogReader._DefineStruct([
366
+ ("from_address", pointer_type),
367
+ ("to_address", pointer_type)])
368
+
369
+ self.code_delete_struct = LogReader._DefineStruct([
370
+ ("address", pointer_type)])
371
+
372
+ self.snapshot_position_struct = LogReader._DefineStruct([
373
+ ("address", pointer_type),
374
+ ("position", ctypes.c_int32)])
375
+
376
+ def ReadUpToGC(self):
377
+ while self.log_pos < self.log.size():
378
+ tag = self.log[self.log_pos]
379
+ self.log_pos += 1
380
+
381
+ if tag == LogReader._CODE_MOVING_GC_TAG:
382
+ self.address_to_snapshot_name.clear()
383
+ return
384
+
385
+ if tag == LogReader._CODE_CREATE_TAG:
386
+ event = self.code_create_struct.from_buffer(self.log, self.log_pos)
387
+ self.log_pos += ctypes.sizeof(event)
388
+ start_address = event.code_address
389
+ end_address = start_address + event.code_size
390
+ if start_address in self.address_to_snapshot_name:
391
+ name = self.address_to_snapshot_name[start_address]
392
+ origin = JS_SNAPSHOT_ORIGIN
393
+ else:
394
+ name = self.log[self.log_pos:self.log_pos + event.name_size]
395
+ origin = JS_ORIGIN
396
+ self.log_pos += event.name_size
397
+ origin_offset = self.log_pos
398
+ self.log_pos += event.code_size
399
+ code = Code(name, start_address, end_address, origin, origin_offset)
400
+ conficting_code = self.code_map.Find(start_address)
401
+ if conficting_code:
402
+ LogReader._HandleCodeConflict(conficting_code, code)
403
+ # TODO(vitalyr): this warning is too noisy because of our
404
+ # attempts to reconstruct code log from the snapshot.
405
+ # print >>sys.stderr, \
406
+ # "Warning: Skipping duplicate code log entry %s" % code
407
+ continue
408
+ self.code_map.Add(code)
409
+ continue
410
+
411
+ if tag == LogReader._CODE_MOVE_TAG:
412
+ event = self.code_move_struct.from_buffer(self.log, self.log_pos)
413
+ self.log_pos += ctypes.sizeof(event)
414
+ old_start_address = event.from_address
415
+ new_start_address = event.to_address
416
+ if old_start_address == new_start_address:
417
+ # Skip useless code move entries.
418
+ continue
419
+ code = self.code_map.Find(old_start_address)
420
+ if not code:
421
+ print >>sys.stderr, "Warning: Not found %x" % old_start_address
422
+ continue
423
+ assert code.start_address == old_start_address, \
424
+ "Inexact move address %x for %s" % (old_start_address, code)
425
+ self.code_map.Remove(code)
426
+ size = code.end_address - code.start_address
427
+ code.start_address = new_start_address
428
+ code.end_address = new_start_address + size
429
+ self.code_map.Add(code)
430
+ continue
431
+
432
+ if tag == LogReader._CODE_DELETE_TAG:
433
+ event = self.code_delete_struct.from_buffer(self.log, self.log_pos)
434
+ self.log_pos += ctypes.sizeof(event)
435
+ old_start_address = event.address
436
+ code = self.code_map.Find(old_start_address)
437
+ if not code:
438
+ print >>sys.stderr, "Warning: Not found %x" % old_start_address
439
+ continue
440
+ assert code.start_address == old_start_address, \
441
+ "Inexact delete address %x for %s" % (old_start_address, code)
442
+ self.code_map.Remove(code)
443
+ continue
444
+
445
+ if tag == LogReader._SNAPSHOT_POSITION_TAG:
446
+ event = self.snapshot_position_struct.from_buffer(self.log,
447
+ self.log_pos)
448
+ self.log_pos += ctypes.sizeof(event)
449
+ start_address = event.address
450
+ snapshot_pos = event.position
451
+ if snapshot_pos in self.snapshot_pos_to_name:
452
+ self.address_to_snapshot_name[start_address] = \
453
+ self.snapshot_pos_to_name[snapshot_pos]
454
+ continue
455
+
456
+ assert False, "Unknown tag %s" % tag
457
+
458
+ def Dispose(self):
459
+ self.log.close()
460
+ self.log_file.close()
461
+
462
+ @staticmethod
463
+ def _DefineStruct(fields):
464
+ class Struct(ctypes.Structure):
465
+ _fields_ = fields
466
+ return Struct
467
+
468
+ @staticmethod
469
+ def _HandleCodeConflict(old_code, new_code):
470
+ assert (old_code.start_address == new_code.start_address and
471
+ old_code.end_address == new_code.end_address), \
472
+ "Conficting code log entries %s and %s" % (old_code, new_code)
473
+ if old_code.name == new_code.name:
474
+ return
475
+ # Code object may be shared by a few functions. Collect the full
476
+ # set of names.
477
+ old_code.AddName(new_code.name)
478
+
479
+
480
+ class Descriptor(object):
481
+ """Descriptor of a structure in the binary trace log."""
482
+
483
+ CTYPE_MAP = {
484
+ "u16": ctypes.c_uint16,
485
+ "u32": ctypes.c_uint32,
486
+ "u64": ctypes.c_uint64
487
+ }
488
+
489
+ def __init__(self, fields):
490
+ class TraceItem(ctypes.Structure):
491
+ _fields_ = Descriptor.CtypesFields(fields)
492
+
493
+ def __str__(self):
494
+ return ", ".join("%s: %s" % (field, self.__getattribute__(field))
495
+ for field, _ in TraceItem._fields_)
496
+
497
+ self.ctype = TraceItem
498
+
499
+ def Read(self, trace, offset):
500
+ return self.ctype.from_buffer(trace, offset)
501
+
502
+ @staticmethod
503
+ def CtypesFields(fields):
504
+ return [(field, Descriptor.CTYPE_MAP[format]) for (field, format) in fields]
505
+
506
+
507
+ # Please see http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=tree;f=tools/perf
508
+ # for the gory details.
509
+
510
+
511
+ TRACE_HEADER_DESC = Descriptor([
512
+ ("magic", "u64"),
513
+ ("size", "u64"),
514
+ ("attr_size", "u64"),
515
+ ("attrs_offset", "u64"),
516
+ ("attrs_size", "u64"),
517
+ ("data_offset", "u64"),
518
+ ("data_size", "u64"),
519
+ ("event_types_offset", "u64"),
520
+ ("event_types_size", "u64")
521
+ ])
522
+
523
+
524
+ PERF_EVENT_ATTR_DESC = Descriptor([
525
+ ("type", "u32"),
526
+ ("size", "u32"),
527
+ ("config", "u64"),
528
+ ("sample_period_or_freq", "u64"),
529
+ ("sample_type", "u64"),
530
+ ("read_format", "u64"),
531
+ ("flags", "u64"),
532
+ ("wakeup_events_or_watermark", "u32"),
533
+ ("bt_type", "u32"),
534
+ ("bp_addr", "u64"),
535
+ ("bp_len", "u64"),
536
+ ])
537
+
538
+
539
+ PERF_EVENT_HEADER_DESC = Descriptor([
540
+ ("type", "u32"),
541
+ ("misc", "u16"),
542
+ ("size", "u16")
543
+ ])
544
+
545
+
546
+ PERF_MMAP_EVENT_BODY_DESC = Descriptor([
547
+ ("pid", "u32"),
548
+ ("tid", "u32"),
549
+ ("addr", "u64"),
550
+ ("len", "u64"),
551
+ ("pgoff", "u64")
552
+ ])
553
+
554
+
555
+ # perf_event_attr.sample_type bits control the set of
556
+ # perf_sample_event fields.
557
+ PERF_SAMPLE_IP = 1 << 0
558
+ PERF_SAMPLE_TID = 1 << 1
559
+ PERF_SAMPLE_TIME = 1 << 2
560
+ PERF_SAMPLE_ADDR = 1 << 3
561
+ PERF_SAMPLE_READ = 1 << 4
562
+ PERF_SAMPLE_CALLCHAIN = 1 << 5
563
+ PERF_SAMPLE_ID = 1 << 6
564
+ PERF_SAMPLE_CPU = 1 << 7
565
+ PERF_SAMPLE_PERIOD = 1 << 8
566
+ PERF_SAMPLE_STREAM_ID = 1 << 9
567
+ PERF_SAMPLE_RAW = 1 << 10
568
+
569
+
570
+ PERF_SAMPLE_EVENT_BODY_FIELDS = [
571
+ ("ip", "u64", PERF_SAMPLE_IP),
572
+ ("pid", "u32", PERF_SAMPLE_TID),
573
+ ("tid", "u32", PERF_SAMPLE_TID),
574
+ ("time", "u64", PERF_SAMPLE_TIME),
575
+ ("addr", "u64", PERF_SAMPLE_ADDR),
576
+ ("id", "u64", PERF_SAMPLE_ID),
577
+ ("stream_id", "u64", PERF_SAMPLE_STREAM_ID),
578
+ ("cpu", "u32", PERF_SAMPLE_CPU),
579
+ ("res", "u32", PERF_SAMPLE_CPU),
580
+ ("period", "u64", PERF_SAMPLE_PERIOD),
581
+ # Don't want to handle read format that comes after the period and
582
+ # before the callchain and has variable size.
583
+ ("nr", "u64", PERF_SAMPLE_CALLCHAIN)
584
+ # Raw data follows the callchain and is ignored.
585
+ ]
586
+
587
+
588
+ PERF_SAMPLE_EVENT_IP_FORMAT = "u64"
589
+
590
+
591
+ PERF_RECORD_MMAP = 1
592
+ PERF_RECORD_SAMPLE = 9
593
+
594
+
595
+ class TraceReader(object):
596
+ """Perf (linux-2.6/tools/perf) trace file reader."""
597
+
598
+ _TRACE_HEADER_MAGIC = 4993446653023372624
599
+
600
+ def __init__(self, trace_name):
601
+ self.trace_file = open(trace_name, "r")
602
+ self.trace = mmap.mmap(self.trace_file.fileno(), 0, mmap.MAP_PRIVATE)
603
+ self.trace_header = TRACE_HEADER_DESC.Read(self.trace, 0)
604
+ if self.trace_header.magic != TraceReader._TRACE_HEADER_MAGIC:
605
+ print >>sys.stderr, "Warning: unsupported trace header magic"
606
+ self.offset = self.trace_header.data_offset
607
+ self.limit = self.trace_header.data_offset + self.trace_header.data_size
608
+ assert self.limit <= self.trace.size(), \
609
+ "Trace data limit exceeds trace file size"
610
+ self.header_size = ctypes.sizeof(PERF_EVENT_HEADER_DESC.ctype)
611
+ assert self.trace_header.attrs_size != 0, \
612
+ "No perf event attributes found in the trace"
613
+ perf_event_attr = PERF_EVENT_ATTR_DESC.Read(self.trace,
614
+ self.trace_header.attrs_offset)
615
+ self.sample_event_body_desc = self._SampleEventBodyDesc(
616
+ perf_event_attr.sample_type)
617
+ self.callchain_supported = \
618
+ (perf_event_attr.sample_type & PERF_SAMPLE_CALLCHAIN) != 0
619
+ if self.callchain_supported:
620
+ self.ip_struct = Descriptor.CTYPE_MAP[PERF_SAMPLE_EVENT_IP_FORMAT]
621
+ self.ip_size = ctypes.sizeof(self.ip_struct)
622
+
623
+ def ReadEventHeader(self):
624
+ if self.offset >= self.limit:
625
+ return None, 0
626
+ offset = self.offset
627
+ header = PERF_EVENT_HEADER_DESC.Read(self.trace, self.offset)
628
+ self.offset += header.size
629
+ return header, offset
630
+
631
+ def ReadMmap(self, header, offset):
632
+ mmap_info = PERF_MMAP_EVENT_BODY_DESC.Read(self.trace,
633
+ offset + self.header_size)
634
+ # Read null-padded filename.
635
+ filename = self.trace[offset + self.header_size + ctypes.sizeof(mmap_info):
636
+ offset + header.size].rstrip(chr(0))
637
+ mmap_info.filename = filename
638
+ return mmap_info
639
+
640
+ def ReadSample(self, header, offset):
641
+ sample = self.sample_event_body_desc.Read(self.trace,
642
+ offset + self.header_size)
643
+ if not self.callchain_supported:
644
+ return sample
645
+ sample.ips = []
646
+ offset += self.header_size + ctypes.sizeof(sample)
647
+ for _ in xrange(sample.nr):
648
+ sample.ips.append(
649
+ self.ip_struct.from_buffer(self.trace, offset).value)
650
+ offset += self.ip_size
651
+ return sample
652
+
653
+ def Dispose(self):
654
+ self.trace.close()
655
+ self.trace_file.close()
656
+
657
+ def _SampleEventBodyDesc(self, sample_type):
658
+ assert (sample_type & PERF_SAMPLE_READ) == 0, \
659
+ "Can't hande read format in samples"
660
+ fields = [(field, format)
661
+ for (field, format, bit) in PERF_SAMPLE_EVENT_BODY_FIELDS
662
+ if (bit & sample_type) != 0]
663
+ return Descriptor(fields)
664
+
665
+
666
+ OBJDUMP_SECTION_HEADER_RE = re.compile(
667
+ r"^\s*\d+\s(\.\S+)\s+[a-f0-9]")
668
+ OBJDUMP_SYMBOL_LINE_RE = re.compile(
669
+ r"^([a-f0-9]+)\s(.{7})\s(\S+)\s+([a-f0-9]+)\s+(?:\.hidden\s+)?(.*)$")
670
+ OBJDUMP_DYNAMIC_SYMBOLS_START_RE = re.compile(
671
+ r"^DYNAMIC SYMBOL TABLE")
672
+ KERNEL_ALLSYMS_FILE = "/proc/kallsyms"
673
+ PERF_KERNEL_ALLSYMS_RE = re.compile(
674
+ r".*kallsyms.*")
675
+ KERNEL_ALLSYMS_LINE_RE = re.compile(
676
+ r"^([a-f0-9]+)\s(?:t|T)\s(\S+)$")
677
+
678
+
679
+ class LibraryRepo(object):
680
+ def __init__(self):
681
+ self.infos = []
682
+ self.names = set()
683
+ self.ticks = {}
684
+
685
+ def Load(self, mmap_info, code_map, options):
686
+ # Skip kernel mmaps when requested using the fact that their tid
687
+ # is 0.
688
+ if mmap_info.tid == 0 and not options.kernel:
689
+ return True
690
+ if PERF_KERNEL_ALLSYMS_RE.match(mmap_info.filename):
691
+ return self._LoadKernelSymbols(code_map)
692
+ self.infos.append(mmap_info)
693
+ mmap_info.ticks = 0
694
+ mmap_info.unique_name = self._UniqueMmapName(mmap_info)
695
+ if not os.path.exists(mmap_info.filename):
696
+ return True
697
+ # Request section headers (-h), symbols (-t), and dynamic symbols
698
+ # (-T) from objdump.
699
+ # Unfortunately, section headers span two lines, so we have to
700
+ # keep the just seen section name (from the first line in each
701
+ # section header) in the after_section variable.
702
+ process = subprocess.Popen(
703
+ "%s -h -t -T -C %s" % (OBJDUMP_BIN, mmap_info.filename),
704
+ shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
705
+ pipe = process.stdout
706
+ after_section = None
707
+ code_sections = set()
708
+ reloc_sections = set()
709
+ dynamic = False
710
+ try:
711
+ for line in pipe:
712
+ if after_section:
713
+ if line.find("CODE") != -1:
714
+ code_sections.add(after_section)
715
+ if line.find("RELOC") != -1:
716
+ reloc_sections.add(after_section)
717
+ after_section = None
718
+ continue
719
+
720
+ match = OBJDUMP_SECTION_HEADER_RE.match(line)
721
+ if match:
722
+ after_section = match.group(1)
723
+ continue
724
+
725
+ if OBJDUMP_DYNAMIC_SYMBOLS_START_RE.match(line):
726
+ dynamic = True
727
+ continue
728
+
729
+ match = OBJDUMP_SYMBOL_LINE_RE.match(line)
730
+ if match:
731
+ start_address = int(match.group(1), 16)
732
+ origin_offset = start_address
733
+ flags = match.group(2)
734
+ section = match.group(3)
735
+ if section in code_sections:
736
+ if dynamic or section in reloc_sections:
737
+ start_address += mmap_info.addr
738
+ size = int(match.group(4), 16)
739
+ name = match.group(5)
740
+ origin = mmap_info.filename
741
+ code_map.Add(Code(name, start_address, start_address + size,
742
+ origin, origin_offset))
743
+ finally:
744
+ pipe.close()
745
+ assert process.wait() == 0, "Failed to objdump %s" % mmap_info.filename
746
+
747
+ def Tick(self, pc):
748
+ for i, mmap_info in enumerate(self.infos):
749
+ if mmap_info.addr <= pc < (mmap_info.addr + mmap_info.len):
750
+ mmap_info.ticks += 1
751
+ self.infos[0], self.infos[i] = mmap_info, self.infos[0]
752
+ return True
753
+ return False
754
+
755
+ def _UniqueMmapName(self, mmap_info):
756
+ name = mmap_info.filename
757
+ index = 1
758
+ while name in self.names:
759
+ name = "%s-%d" % (mmap_info.filename, index)
760
+ index += 1
761
+ self.names.add(name)
762
+ return name
763
+
764
+ def _LoadKernelSymbols(self, code_map):
765
+ if not os.path.exists(KERNEL_ALLSYMS_FILE):
766
+ print >>sys.stderr, "Warning: %s not found" % KERNEL_ALLSYMS_FILE
767
+ return False
768
+ kallsyms = open(KERNEL_ALLSYMS_FILE, "r")
769
+ code = None
770
+ for line in kallsyms:
771
+ match = KERNEL_ALLSYMS_LINE_RE.match(line)
772
+ if match:
773
+ start_address = int(match.group(1), 16)
774
+ end_address = start_address
775
+ name = match.group(2)
776
+ if code:
777
+ code.end_address = start_address
778
+ code_map.Add(code, 16)
779
+ code = Code(name, start_address, end_address, "kernel", 0)
780
+ return True
781
+
782
+
783
+ def PrintReport(code_map, library_repo, arch, ticks, options):
784
+ print "Ticks per symbol:"
785
+ used_code = [code for code in code_map.UsedCode()]
786
+ used_code.sort(key=lambda x: x.self_ticks, reverse=True)
787
+ for i, code in enumerate(used_code):
788
+ code_ticks = code.self_ticks
789
+ print "%10d %5.1f%% %s [%s]" % (code_ticks, 100. * code_ticks / ticks,
790
+ code.FullName(), code.origin)
791
+ if options.disasm_all or i < options.disasm_top:
792
+ code.PrintAnnotated(arch, options)
793
+ print
794
+ print "Ticks per library:"
795
+ mmap_infos = [m for m in library_repo.infos]
796
+ mmap_infos.sort(key=lambda m: m.ticks, reverse=True)
797
+ for mmap_info in mmap_infos:
798
+ mmap_ticks = mmap_info.ticks
799
+ print "%10d %5.1f%% %s" % (mmap_ticks, 100. * mmap_ticks / ticks,
800
+ mmap_info.unique_name)
801
+
802
+
803
+ def PrintDot(code_map, options):
804
+ print "digraph G {"
805
+ for code in code_map.UsedCode():
806
+ if code.self_ticks < 10:
807
+ continue
808
+ print "n%d [shape=box,label=\"%s\"];" % (code.id, code.name)
809
+ if code.callee_ticks:
810
+ for callee, ticks in code.callee_ticks.iteritems():
811
+ print "n%d -> n%d [label=\"%d\"];" % (code.id, callee.id, ticks)
812
+ print "}"
813
+
814
+
815
+ if __name__ == "__main__":
816
+ parser = optparse.OptionParser(USAGE)
817
+ parser.add_option("--snapshot-log",
818
+ default="obj/release/snapshot.log",
819
+ help="V8 snapshot log file name [default: %default]")
820
+ parser.add_option("--log",
821
+ default="v8.log",
822
+ help="V8 log file name [default: %default]")
823
+ parser.add_option("--snapshot",
824
+ default=False,
825
+ action="store_true",
826
+ help="process V8 snapshot log [default: %default]")
827
+ parser.add_option("--trace",
828
+ default="perf.data",
829
+ help="perf trace file name [default: %default]")
830
+ parser.add_option("--kernel",
831
+ default=False,
832
+ action="store_true",
833
+ help="process kernel entries [default: %default]")
834
+ parser.add_option("--disasm-top",
835
+ default=0,
836
+ type="int",
837
+ help=("number of top symbols to disassemble and annotate "
838
+ "[default: %default]"))
839
+ parser.add_option("--disasm-all",
840
+ default=False,
841
+ action="store_true",
842
+ help=("disassemble and annotate all used symbols "
843
+ "[default: %default]"))
844
+ parser.add_option("--dot",
845
+ default=False,
846
+ action="store_true",
847
+ help="produce dot output (WIP) [default: %default]")
848
+ parser.add_option("--quiet", "-q",
849
+ default=False,
850
+ action="store_true",
851
+ help="no auxiliary messages [default: %default]")
852
+ options, args = parser.parse_args()
853
+
854
+ if not options.quiet:
855
+ if options.snapshot:
856
+ print "V8 logs: %s, %s, %s.ll" % (options.snapshot_log,
857
+ options.log,
858
+ options.log)
859
+ else:
860
+ print "V8 log: %s, %s.ll (no snapshot)" % (options.log, options.log)
861
+ print "Perf trace file: %s" % options.trace
862
+
863
+ # Stats.
864
+ events = 0
865
+ ticks = 0
866
+ missed_ticks = 0
867
+ really_missed_ticks = 0
868
+ mmap_time = 0
869
+ sample_time = 0
870
+
871
+ # Process the snapshot log to fill the snapshot name map.
872
+ snapshot_name_map = {}
873
+ if options.snapshot:
874
+ snapshot_log_reader = SnapshotLogReader(log_name=options.snapshot_log)
875
+ snapshot_name_map = snapshot_log_reader.ReadNameMap()
876
+
877
+ # Initialize the log reader.
878
+ code_map = CodeMap()
879
+ log_reader = LogReader(log_name=options.log + ".ll",
880
+ code_map=code_map,
881
+ snapshot_pos_to_name=snapshot_name_map)
882
+ if not options.quiet:
883
+ print "Generated code architecture: %s" % log_reader.arch
884
+ print
885
+ sys.stdout.flush()
886
+
887
+ # Process the code and trace logs.
888
+ library_repo = LibraryRepo()
889
+ log_reader.ReadUpToGC()
890
+ trace_reader = TraceReader(options.trace)
891
+ while True:
892
+ header, offset = trace_reader.ReadEventHeader()
893
+ if not header:
894
+ break
895
+ events += 1
896
+ if header.type == PERF_RECORD_MMAP:
897
+ start = time.time()
898
+ mmap_info = trace_reader.ReadMmap(header, offset)
899
+ if mmap_info.filename == V8_GC_FAKE_MMAP:
900
+ log_reader.ReadUpToGC()
901
+ else:
902
+ library_repo.Load(mmap_info, code_map, options)
903
+ mmap_time += time.time() - start
904
+ elif header.type == PERF_RECORD_SAMPLE:
905
+ ticks += 1
906
+ start = time.time()
907
+ sample = trace_reader.ReadSample(header, offset)
908
+ code = code_map.Find(sample.ip)
909
+ if code:
910
+ code.Tick(sample.ip)
911
+ else:
912
+ missed_ticks += 1
913
+ if not library_repo.Tick(sample.ip) and not code:
914
+ really_missed_ticks += 1
915
+ if trace_reader.callchain_supported:
916
+ for ip in sample.ips:
917
+ caller_code = code_map.Find(ip)
918
+ if caller_code:
919
+ if code:
920
+ caller_code.CalleeTick(code)
921
+ code = caller_code
922
+ sample_time += time.time() - start
923
+
924
+ if options.dot:
925
+ PrintDot(code_map, options)
926
+ else:
927
+ PrintReport(code_map, library_repo, log_reader.arch, ticks, options)
928
+
929
+ if not options.quiet:
930
+ print
931
+ print "Stats:"
932
+ print "%10d total trace events" % events
933
+ print "%10d total ticks" % ticks
934
+ print "%10d ticks not in symbols" % missed_ticks
935
+ print "%10d unaccounted ticks" % really_missed_ticks
936
+ print "%10d total symbols" % len([c for c in code_map.AllCode()])
937
+ print "%10d used symbols" % len([c for c in code_map.UsedCode()])
938
+ print "%9.2fs library processing time" % mmap_time
939
+ print "%9.2fs tick processing time" % sample_time
940
+
941
+ log_reader.Dispose()
942
+ trace_reader.Dispose()