libv8 3.11.8.17 → 3.16.14.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (754) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -2
  3. data/Gemfile +1 -1
  4. data/Rakefile +6 -7
  5. data/lib/libv8/version.rb +1 -1
  6. data/vendor/v8/.gitignore +24 -3
  7. data/vendor/v8/AUTHORS +7 -0
  8. data/vendor/v8/ChangeLog +839 -0
  9. data/vendor/v8/DEPS +1 -1
  10. data/vendor/v8/Makefile.android +92 -0
  11. data/vendor/v8/OWNERS +11 -0
  12. data/vendor/v8/PRESUBMIT.py +71 -0
  13. data/vendor/v8/SConstruct +34 -39
  14. data/vendor/v8/build/android.gypi +56 -37
  15. data/vendor/v8/build/common.gypi +112 -30
  16. data/vendor/v8/build/gyp_v8 +1 -1
  17. data/vendor/v8/build/standalone.gypi +15 -11
  18. data/vendor/v8/include/v8-debug.h +9 -1
  19. data/vendor/v8/include/v8-preparser.h +4 -3
  20. data/vendor/v8/include/v8-profiler.h +25 -25
  21. data/vendor/v8/include/v8-testing.h +4 -3
  22. data/vendor/v8/include/v8.h +994 -540
  23. data/vendor/v8/preparser/preparser-process.cc +3 -3
  24. data/vendor/v8/samples/lineprocessor.cc +20 -27
  25. data/vendor/v8/samples/process.cc +18 -14
  26. data/vendor/v8/samples/shell.cc +16 -15
  27. data/vendor/v8/src/SConscript +15 -14
  28. data/vendor/v8/src/accessors.cc +169 -77
  29. data/vendor/v8/src/accessors.h +4 -0
  30. data/vendor/v8/src/allocation-inl.h +2 -2
  31. data/vendor/v8/src/allocation.h +7 -7
  32. data/vendor/v8/src/api.cc +810 -497
  33. data/vendor/v8/src/api.h +85 -60
  34. data/vendor/v8/src/arm/assembler-arm-inl.h +179 -22
  35. data/vendor/v8/src/arm/assembler-arm.cc +633 -264
  36. data/vendor/v8/src/arm/assembler-arm.h +264 -197
  37. data/vendor/v8/src/arm/builtins-arm.cc +117 -27
  38. data/vendor/v8/src/arm/code-stubs-arm.cc +1241 -700
  39. data/vendor/v8/src/arm/code-stubs-arm.h +35 -138
  40. data/vendor/v8/src/arm/codegen-arm.cc +285 -16
  41. data/vendor/v8/src/arm/codegen-arm.h +22 -0
  42. data/vendor/v8/src/arm/constants-arm.cc +5 -3
  43. data/vendor/v8/src/arm/constants-arm.h +24 -11
  44. data/vendor/v8/src/arm/debug-arm.cc +3 -3
  45. data/vendor/v8/src/arm/deoptimizer-arm.cc +382 -92
  46. data/vendor/v8/src/arm/disasm-arm.cc +61 -12
  47. data/vendor/v8/src/arm/frames-arm.h +0 -14
  48. data/vendor/v8/src/arm/full-codegen-arm.cc +332 -304
  49. data/vendor/v8/src/arm/ic-arm.cc +180 -259
  50. data/vendor/v8/src/arm/lithium-arm.cc +364 -316
  51. data/vendor/v8/src/arm/lithium-arm.h +512 -275
  52. data/vendor/v8/src/arm/lithium-codegen-arm.cc +1768 -809
  53. data/vendor/v8/src/arm/lithium-codegen-arm.h +97 -35
  54. data/vendor/v8/src/arm/lithium-gap-resolver-arm.cc +12 -5
  55. data/vendor/v8/src/arm/macro-assembler-arm.cc +439 -228
  56. data/vendor/v8/src/arm/macro-assembler-arm.h +116 -70
  57. data/vendor/v8/src/arm/regexp-macro-assembler-arm.cc +54 -44
  58. data/vendor/v8/src/arm/regexp-macro-assembler-arm.h +3 -10
  59. data/vendor/v8/src/arm/simulator-arm.cc +272 -238
  60. data/vendor/v8/src/arm/simulator-arm.h +38 -8
  61. data/vendor/v8/src/arm/stub-cache-arm.cc +522 -895
  62. data/vendor/v8/src/array.js +101 -70
  63. data/vendor/v8/src/assembler.cc +270 -19
  64. data/vendor/v8/src/assembler.h +110 -15
  65. data/vendor/v8/src/ast.cc +79 -69
  66. data/vendor/v8/src/ast.h +255 -301
  67. data/vendor/v8/src/atomicops.h +7 -1
  68. data/vendor/v8/src/atomicops_internals_tsan.h +335 -0
  69. data/vendor/v8/src/bootstrapper.cc +481 -418
  70. data/vendor/v8/src/bootstrapper.h +4 -4
  71. data/vendor/v8/src/builtins.cc +498 -311
  72. data/vendor/v8/src/builtins.h +75 -47
  73. data/vendor/v8/src/checks.cc +2 -1
  74. data/vendor/v8/src/checks.h +8 -0
  75. data/vendor/v8/src/code-stubs-hydrogen.cc +253 -0
  76. data/vendor/v8/src/code-stubs.cc +249 -84
  77. data/vendor/v8/src/code-stubs.h +501 -169
  78. data/vendor/v8/src/codegen.cc +36 -18
  79. data/vendor/v8/src/codegen.h +25 -3
  80. data/vendor/v8/src/collection.js +54 -17
  81. data/vendor/v8/src/compilation-cache.cc +24 -16
  82. data/vendor/v8/src/compilation-cache.h +15 -6
  83. data/vendor/v8/src/compiler.cc +497 -195
  84. data/vendor/v8/src/compiler.h +246 -38
  85. data/vendor/v8/src/contexts.cc +64 -24
  86. data/vendor/v8/src/contexts.h +60 -29
  87. data/vendor/v8/src/conversions-inl.h +24 -14
  88. data/vendor/v8/src/conversions.h +7 -4
  89. data/vendor/v8/src/counters.cc +21 -12
  90. data/vendor/v8/src/counters.h +44 -16
  91. data/vendor/v8/src/cpu-profiler.h +1 -1
  92. data/vendor/v8/src/d8-debug.cc +2 -2
  93. data/vendor/v8/src/d8-readline.cc +13 -2
  94. data/vendor/v8/src/d8.cc +681 -273
  95. data/vendor/v8/src/d8.gyp +4 -4
  96. data/vendor/v8/src/d8.h +38 -18
  97. data/vendor/v8/src/d8.js +0 -617
  98. data/vendor/v8/src/data-flow.h +55 -0
  99. data/vendor/v8/src/date.js +1 -42
  100. data/vendor/v8/src/dateparser-inl.h +5 -1
  101. data/vendor/v8/src/debug-agent.cc +10 -15
  102. data/vendor/v8/src/debug-debugger.js +147 -149
  103. data/vendor/v8/src/debug.cc +323 -164
  104. data/vendor/v8/src/debug.h +26 -14
  105. data/vendor/v8/src/deoptimizer.cc +765 -290
  106. data/vendor/v8/src/deoptimizer.h +130 -28
  107. data/vendor/v8/src/disassembler.cc +10 -4
  108. data/vendor/v8/src/elements-kind.cc +7 -2
  109. data/vendor/v8/src/elements-kind.h +19 -0
  110. data/vendor/v8/src/elements.cc +607 -285
  111. data/vendor/v8/src/elements.h +36 -13
  112. data/vendor/v8/src/execution.cc +52 -31
  113. data/vendor/v8/src/execution.h +4 -4
  114. data/vendor/v8/src/extensions/externalize-string-extension.cc +5 -4
  115. data/vendor/v8/src/extensions/gc-extension.cc +5 -1
  116. data/vendor/v8/src/extensions/statistics-extension.cc +153 -0
  117. data/vendor/v8/src/{inspector.h → extensions/statistics-extension.h} +12 -23
  118. data/vendor/v8/src/factory.cc +101 -134
  119. data/vendor/v8/src/factory.h +36 -31
  120. data/vendor/v8/src/flag-definitions.h +102 -25
  121. data/vendor/v8/src/flags.cc +9 -5
  122. data/vendor/v8/src/frames-inl.h +10 -0
  123. data/vendor/v8/src/frames.cc +116 -26
  124. data/vendor/v8/src/frames.h +96 -12
  125. data/vendor/v8/src/full-codegen.cc +219 -74
  126. data/vendor/v8/src/full-codegen.h +63 -21
  127. data/vendor/v8/src/func-name-inferrer.cc +8 -7
  128. data/vendor/v8/src/func-name-inferrer.h +5 -3
  129. data/vendor/v8/src/gdb-jit.cc +71 -57
  130. data/vendor/v8/src/global-handles.cc +230 -101
  131. data/vendor/v8/src/global-handles.h +26 -27
  132. data/vendor/v8/src/globals.h +17 -19
  133. data/vendor/v8/src/handles-inl.h +59 -12
  134. data/vendor/v8/src/handles.cc +180 -200
  135. data/vendor/v8/src/handles.h +80 -11
  136. data/vendor/v8/src/hashmap.h +60 -40
  137. data/vendor/v8/src/heap-inl.h +107 -45
  138. data/vendor/v8/src/heap-profiler.cc +38 -19
  139. data/vendor/v8/src/heap-profiler.h +24 -14
  140. data/vendor/v8/src/heap.cc +1123 -738
  141. data/vendor/v8/src/heap.h +385 -146
  142. data/vendor/v8/src/hydrogen-instructions.cc +700 -217
  143. data/vendor/v8/src/hydrogen-instructions.h +1158 -472
  144. data/vendor/v8/src/hydrogen.cc +3319 -1662
  145. data/vendor/v8/src/hydrogen.h +411 -170
  146. data/vendor/v8/src/ia32/assembler-ia32-inl.h +46 -16
  147. data/vendor/v8/src/ia32/assembler-ia32.cc +131 -61
  148. data/vendor/v8/src/ia32/assembler-ia32.h +115 -57
  149. data/vendor/v8/src/ia32/builtins-ia32.cc +99 -5
  150. data/vendor/v8/src/ia32/code-stubs-ia32.cc +787 -495
  151. data/vendor/v8/src/ia32/code-stubs-ia32.h +10 -100
  152. data/vendor/v8/src/ia32/codegen-ia32.cc +227 -23
  153. data/vendor/v8/src/ia32/codegen-ia32.h +14 -0
  154. data/vendor/v8/src/ia32/deoptimizer-ia32.cc +428 -87
  155. data/vendor/v8/src/ia32/disasm-ia32.cc +28 -1
  156. data/vendor/v8/src/ia32/frames-ia32.h +6 -16
  157. data/vendor/v8/src/ia32/full-codegen-ia32.cc +280 -272
  158. data/vendor/v8/src/ia32/ic-ia32.cc +150 -250
  159. data/vendor/v8/src/ia32/lithium-codegen-ia32.cc +1600 -517
  160. data/vendor/v8/src/ia32/lithium-codegen-ia32.h +90 -24
  161. data/vendor/v8/src/ia32/lithium-gap-resolver-ia32.cc +10 -6
  162. data/vendor/v8/src/ia32/lithium-gap-resolver-ia32.h +2 -2
  163. data/vendor/v8/src/ia32/lithium-ia32.cc +405 -302
  164. data/vendor/v8/src/ia32/lithium-ia32.h +526 -271
  165. data/vendor/v8/src/ia32/macro-assembler-ia32.cc +378 -119
  166. data/vendor/v8/src/ia32/macro-assembler-ia32.h +62 -28
  167. data/vendor/v8/src/ia32/regexp-macro-assembler-ia32.cc +43 -30
  168. data/vendor/v8/src/ia32/regexp-macro-assembler-ia32.h +2 -10
  169. data/vendor/v8/src/ia32/stub-cache-ia32.cc +492 -678
  170. data/vendor/v8/src/ic-inl.h +9 -4
  171. data/vendor/v8/src/ic.cc +836 -923
  172. data/vendor/v8/src/ic.h +228 -247
  173. data/vendor/v8/src/incremental-marking-inl.h +26 -30
  174. data/vendor/v8/src/incremental-marking.cc +276 -248
  175. data/vendor/v8/src/incremental-marking.h +29 -37
  176. data/vendor/v8/src/interface.cc +34 -25
  177. data/vendor/v8/src/interface.h +69 -25
  178. data/vendor/v8/src/interpreter-irregexp.cc +2 -2
  179. data/vendor/v8/src/isolate.cc +382 -76
  180. data/vendor/v8/src/isolate.h +109 -56
  181. data/vendor/v8/src/json-parser.h +217 -104
  182. data/vendor/v8/src/json-stringifier.h +745 -0
  183. data/vendor/v8/src/json.js +10 -132
  184. data/vendor/v8/src/jsregexp-inl.h +106 -0
  185. data/vendor/v8/src/jsregexp.cc +517 -285
  186. data/vendor/v8/src/jsregexp.h +145 -117
  187. data/vendor/v8/src/list-inl.h +35 -22
  188. data/vendor/v8/src/list.h +46 -19
  189. data/vendor/v8/src/lithium-allocator-inl.h +22 -2
  190. data/vendor/v8/src/lithium-allocator.cc +85 -70
  191. data/vendor/v8/src/lithium-allocator.h +21 -39
  192. data/vendor/v8/src/lithium.cc +259 -5
  193. data/vendor/v8/src/lithium.h +131 -32
  194. data/vendor/v8/src/liveedit-debugger.js +52 -3
  195. data/vendor/v8/src/liveedit.cc +393 -113
  196. data/vendor/v8/src/liveedit.h +7 -3
  197. data/vendor/v8/src/log-utils.cc +4 -2
  198. data/vendor/v8/src/log.cc +170 -140
  199. data/vendor/v8/src/log.h +62 -11
  200. data/vendor/v8/src/macro-assembler.h +17 -0
  201. data/vendor/v8/src/macros.py +2 -0
  202. data/vendor/v8/src/mark-compact-inl.h +3 -23
  203. data/vendor/v8/src/mark-compact.cc +801 -830
  204. data/vendor/v8/src/mark-compact.h +154 -47
  205. data/vendor/v8/src/marking-thread.cc +85 -0
  206. data/vendor/v8/src/{inspector.cc → marking-thread.h} +32 -24
  207. data/vendor/v8/src/math.js +12 -18
  208. data/vendor/v8/src/messages.cc +18 -8
  209. data/vendor/v8/src/messages.js +314 -261
  210. data/vendor/v8/src/mips/assembler-mips-inl.h +58 -6
  211. data/vendor/v8/src/mips/assembler-mips.cc +92 -75
  212. data/vendor/v8/src/mips/assembler-mips.h +54 -60
  213. data/vendor/v8/src/mips/builtins-mips.cc +116 -17
  214. data/vendor/v8/src/mips/code-stubs-mips.cc +919 -556
  215. data/vendor/v8/src/mips/code-stubs-mips.h +22 -131
  216. data/vendor/v8/src/mips/codegen-mips.cc +281 -6
  217. data/vendor/v8/src/mips/codegen-mips.h +22 -0
  218. data/vendor/v8/src/mips/constants-mips.cc +2 -0
  219. data/vendor/v8/src/mips/constants-mips.h +12 -2
  220. data/vendor/v8/src/mips/deoptimizer-mips.cc +286 -50
  221. data/vendor/v8/src/mips/disasm-mips.cc +13 -0
  222. data/vendor/v8/src/mips/full-codegen-mips.cc +297 -284
  223. data/vendor/v8/src/mips/ic-mips.cc +182 -263
  224. data/vendor/v8/src/mips/lithium-codegen-mips.cc +1208 -556
  225. data/vendor/v8/src/mips/lithium-codegen-mips.h +72 -19
  226. data/vendor/v8/src/mips/lithium-gap-resolver-mips.cc +9 -2
  227. data/vendor/v8/src/mips/lithium-mips.cc +290 -302
  228. data/vendor/v8/src/mips/lithium-mips.h +463 -266
  229. data/vendor/v8/src/mips/macro-assembler-mips.cc +208 -115
  230. data/vendor/v8/src/mips/macro-assembler-mips.h +67 -24
  231. data/vendor/v8/src/mips/regexp-macro-assembler-mips.cc +40 -25
  232. data/vendor/v8/src/mips/regexp-macro-assembler-mips.h +3 -9
  233. data/vendor/v8/src/mips/simulator-mips.cc +112 -40
  234. data/vendor/v8/src/mips/simulator-mips.h +5 -0
  235. data/vendor/v8/src/mips/stub-cache-mips.cc +502 -884
  236. data/vendor/v8/src/mirror-debugger.js +157 -30
  237. data/vendor/v8/src/mksnapshot.cc +88 -14
  238. data/vendor/v8/src/object-observe.js +235 -0
  239. data/vendor/v8/src/objects-debug.cc +178 -176
  240. data/vendor/v8/src/objects-inl.h +1333 -486
  241. data/vendor/v8/src/objects-printer.cc +125 -43
  242. data/vendor/v8/src/objects-visiting-inl.h +578 -6
  243. data/vendor/v8/src/objects-visiting.cc +2 -2
  244. data/vendor/v8/src/objects-visiting.h +172 -79
  245. data/vendor/v8/src/objects.cc +3533 -2885
  246. data/vendor/v8/src/objects.h +1352 -1131
  247. data/vendor/v8/src/optimizing-compiler-thread.cc +152 -0
  248. data/vendor/v8/src/optimizing-compiler-thread.h +111 -0
  249. data/vendor/v8/src/parser.cc +390 -500
  250. data/vendor/v8/src/parser.h +45 -33
  251. data/vendor/v8/src/platform-cygwin.cc +10 -21
  252. data/vendor/v8/src/platform-freebsd.cc +36 -41
  253. data/vendor/v8/src/platform-linux.cc +160 -124
  254. data/vendor/v8/src/platform-macos.cc +30 -27
  255. data/vendor/v8/src/platform-nullos.cc +17 -1
  256. data/vendor/v8/src/platform-openbsd.cc +19 -50
  257. data/vendor/v8/src/platform-posix.cc +14 -0
  258. data/vendor/v8/src/platform-solaris.cc +20 -53
  259. data/vendor/v8/src/platform-win32.cc +49 -26
  260. data/vendor/v8/src/platform.h +40 -1
  261. data/vendor/v8/src/preparser.cc +8 -5
  262. data/vendor/v8/src/preparser.h +2 -2
  263. data/vendor/v8/src/prettyprinter.cc +16 -0
  264. data/vendor/v8/src/prettyprinter.h +2 -0
  265. data/vendor/v8/src/profile-generator-inl.h +1 -0
  266. data/vendor/v8/src/profile-generator.cc +209 -147
  267. data/vendor/v8/src/profile-generator.h +15 -12
  268. data/vendor/v8/src/property-details.h +46 -31
  269. data/vendor/v8/src/property.cc +27 -46
  270. data/vendor/v8/src/property.h +163 -83
  271. data/vendor/v8/src/proxy.js +7 -2
  272. data/vendor/v8/src/regexp-macro-assembler-irregexp.cc +4 -13
  273. data/vendor/v8/src/regexp-macro-assembler-irregexp.h +1 -2
  274. data/vendor/v8/src/regexp-macro-assembler-tracer.cc +1 -11
  275. data/vendor/v8/src/regexp-macro-assembler-tracer.h +0 -1
  276. data/vendor/v8/src/regexp-macro-assembler.cc +31 -14
  277. data/vendor/v8/src/regexp-macro-assembler.h +14 -11
  278. data/vendor/v8/src/regexp-stack.cc +1 -0
  279. data/vendor/v8/src/regexp.js +9 -8
  280. data/vendor/v8/src/rewriter.cc +18 -7
  281. data/vendor/v8/src/runtime-profiler.cc +52 -43
  282. data/vendor/v8/src/runtime-profiler.h +0 -25
  283. data/vendor/v8/src/runtime.cc +2006 -2023
  284. data/vendor/v8/src/runtime.h +56 -49
  285. data/vendor/v8/src/safepoint-table.cc +12 -18
  286. data/vendor/v8/src/safepoint-table.h +11 -8
  287. data/vendor/v8/src/scanner.cc +1 -0
  288. data/vendor/v8/src/scanner.h +4 -10
  289. data/vendor/v8/src/scopeinfo.cc +35 -9
  290. data/vendor/v8/src/scopeinfo.h +64 -3
  291. data/vendor/v8/src/scopes.cc +251 -156
  292. data/vendor/v8/src/scopes.h +61 -27
  293. data/vendor/v8/src/serialize.cc +348 -396
  294. data/vendor/v8/src/serialize.h +125 -114
  295. data/vendor/v8/src/small-pointer-list.h +11 -11
  296. data/vendor/v8/src/{smart-array-pointer.h → smart-pointers.h} +64 -15
  297. data/vendor/v8/src/snapshot-common.cc +64 -15
  298. data/vendor/v8/src/snapshot-empty.cc +7 -1
  299. data/vendor/v8/src/snapshot.h +9 -2
  300. data/vendor/v8/src/spaces-inl.h +17 -0
  301. data/vendor/v8/src/spaces.cc +477 -183
  302. data/vendor/v8/src/spaces.h +238 -58
  303. data/vendor/v8/src/splay-tree-inl.h +8 -7
  304. data/vendor/v8/src/splay-tree.h +24 -10
  305. data/vendor/v8/src/store-buffer.cc +12 -5
  306. data/vendor/v8/src/store-buffer.h +2 -4
  307. data/vendor/v8/src/string-search.h +22 -6
  308. data/vendor/v8/src/string-stream.cc +11 -8
  309. data/vendor/v8/src/string.js +47 -15
  310. data/vendor/v8/src/stub-cache.cc +461 -224
  311. data/vendor/v8/src/stub-cache.h +164 -102
  312. data/vendor/v8/src/sweeper-thread.cc +105 -0
  313. data/vendor/v8/src/sweeper-thread.h +81 -0
  314. data/vendor/v8/src/token.h +1 -0
  315. data/vendor/v8/src/transitions-inl.h +220 -0
  316. data/vendor/v8/src/transitions.cc +160 -0
  317. data/vendor/v8/src/transitions.h +207 -0
  318. data/vendor/v8/src/type-info.cc +182 -181
  319. data/vendor/v8/src/type-info.h +31 -19
  320. data/vendor/v8/src/unicode-inl.h +62 -106
  321. data/vendor/v8/src/unicode.cc +57 -67
  322. data/vendor/v8/src/unicode.h +45 -91
  323. data/vendor/v8/src/uri.js +57 -29
  324. data/vendor/v8/src/utils.h +105 -5
  325. data/vendor/v8/src/v8-counters.cc +54 -11
  326. data/vendor/v8/src/v8-counters.h +134 -19
  327. data/vendor/v8/src/v8.cc +29 -29
  328. data/vendor/v8/src/v8.h +1 -0
  329. data/vendor/v8/src/v8conversions.cc +26 -22
  330. data/vendor/v8/src/v8globals.h +56 -43
  331. data/vendor/v8/src/v8natives.js +83 -30
  332. data/vendor/v8/src/v8threads.cc +42 -21
  333. data/vendor/v8/src/v8threads.h +4 -1
  334. data/vendor/v8/src/v8utils.cc +9 -93
  335. data/vendor/v8/src/v8utils.h +37 -33
  336. data/vendor/v8/src/variables.cc +6 -3
  337. data/vendor/v8/src/variables.h +6 -13
  338. data/vendor/v8/src/version.cc +2 -2
  339. data/vendor/v8/src/vm-state-inl.h +11 -0
  340. data/vendor/v8/src/x64/assembler-x64-inl.h +39 -8
  341. data/vendor/v8/src/x64/assembler-x64.cc +78 -64
  342. data/vendor/v8/src/x64/assembler-x64.h +38 -33
  343. data/vendor/v8/src/x64/builtins-x64.cc +105 -7
  344. data/vendor/v8/src/x64/code-stubs-x64.cc +790 -413
  345. data/vendor/v8/src/x64/code-stubs-x64.h +10 -106
  346. data/vendor/v8/src/x64/codegen-x64.cc +210 -8
  347. data/vendor/v8/src/x64/codegen-x64.h +20 -1
  348. data/vendor/v8/src/x64/deoptimizer-x64.cc +336 -75
  349. data/vendor/v8/src/x64/disasm-x64.cc +15 -0
  350. data/vendor/v8/src/x64/frames-x64.h +0 -14
  351. data/vendor/v8/src/x64/full-codegen-x64.cc +293 -270
  352. data/vendor/v8/src/x64/ic-x64.cc +153 -251
  353. data/vendor/v8/src/x64/lithium-codegen-x64.cc +1379 -531
  354. data/vendor/v8/src/x64/lithium-codegen-x64.h +67 -23
  355. data/vendor/v8/src/x64/lithium-gap-resolver-x64.cc +2 -2
  356. data/vendor/v8/src/x64/lithium-x64.cc +349 -289
  357. data/vendor/v8/src/x64/lithium-x64.h +460 -250
  358. data/vendor/v8/src/x64/macro-assembler-x64.cc +350 -177
  359. data/vendor/v8/src/x64/macro-assembler-x64.h +67 -49
  360. data/vendor/v8/src/x64/regexp-macro-assembler-x64.cc +46 -33
  361. data/vendor/v8/src/x64/regexp-macro-assembler-x64.h +2 -3
  362. data/vendor/v8/src/x64/stub-cache-x64.cc +484 -653
  363. data/vendor/v8/src/zone-inl.h +9 -27
  364. data/vendor/v8/src/zone.cc +5 -5
  365. data/vendor/v8/src/zone.h +53 -27
  366. data/vendor/v8/test/benchmarks/testcfg.py +5 -0
  367. data/vendor/v8/test/cctest/cctest.cc +4 -0
  368. data/vendor/v8/test/cctest/cctest.gyp +3 -1
  369. data/vendor/v8/test/cctest/cctest.h +57 -9
  370. data/vendor/v8/test/cctest/cctest.status +15 -15
  371. data/vendor/v8/test/cctest/test-accessors.cc +26 -0
  372. data/vendor/v8/test/cctest/test-alloc.cc +22 -30
  373. data/vendor/v8/test/cctest/test-api.cc +1943 -314
  374. data/vendor/v8/test/cctest/test-assembler-arm.cc +133 -13
  375. data/vendor/v8/test/cctest/test-assembler-ia32.cc +1 -1
  376. data/vendor/v8/test/cctest/test-assembler-mips.cc +12 -0
  377. data/vendor/v8/test/cctest/test-ast.cc +4 -2
  378. data/vendor/v8/test/cctest/test-compiler.cc +61 -29
  379. data/vendor/v8/test/cctest/test-dataflow.cc +2 -2
  380. data/vendor/v8/test/cctest/test-debug.cc +212 -33
  381. data/vendor/v8/test/cctest/test-decls.cc +257 -11
  382. data/vendor/v8/test/cctest/test-dictionary.cc +24 -10
  383. data/vendor/v8/test/cctest/test-disasm-arm.cc +118 -1
  384. data/vendor/v8/test/cctest/test-disasm-ia32.cc +3 -2
  385. data/vendor/v8/test/cctest/test-flags.cc +14 -1
  386. data/vendor/v8/test/cctest/test-func-name-inference.cc +7 -4
  387. data/vendor/v8/test/cctest/test-global-object.cc +51 -0
  388. data/vendor/v8/test/cctest/test-hashing.cc +32 -23
  389. data/vendor/v8/test/cctest/test-heap-profiler.cc +131 -77
  390. data/vendor/v8/test/cctest/test-heap.cc +1084 -143
  391. data/vendor/v8/test/cctest/test-list.cc +1 -1
  392. data/vendor/v8/test/cctest/test-liveedit.cc +3 -2
  393. data/vendor/v8/test/cctest/test-lockers.cc +12 -13
  394. data/vendor/v8/test/cctest/test-log.cc +10 -8
  395. data/vendor/v8/test/cctest/test-macro-assembler-x64.cc +2 -2
  396. data/vendor/v8/test/cctest/test-mark-compact.cc +44 -22
  397. data/vendor/v8/test/cctest/test-object-observe.cc +434 -0
  398. data/vendor/v8/test/cctest/test-parsing.cc +86 -39
  399. data/vendor/v8/test/cctest/test-platform-linux.cc +6 -0
  400. data/vendor/v8/test/cctest/test-platform-win32.cc +7 -0
  401. data/vendor/v8/test/cctest/test-random.cc +5 -4
  402. data/vendor/v8/test/cctest/test-regexp.cc +137 -101
  403. data/vendor/v8/test/cctest/test-serialize.cc +150 -230
  404. data/vendor/v8/test/cctest/test-sockets.cc +1 -1
  405. data/vendor/v8/test/cctest/test-spaces.cc +139 -0
  406. data/vendor/v8/test/cctest/test-strings.cc +736 -74
  407. data/vendor/v8/test/cctest/test-thread-termination.cc +10 -11
  408. data/vendor/v8/test/cctest/test-threads.cc +4 -4
  409. data/vendor/v8/test/cctest/test-utils.cc +16 -0
  410. data/vendor/v8/test/cctest/test-weakmaps.cc +7 -3
  411. data/vendor/v8/test/cctest/testcfg.py +64 -5
  412. data/vendor/v8/test/es5conform/testcfg.py +5 -0
  413. data/vendor/v8/test/message/message.status +1 -1
  414. data/vendor/v8/test/message/overwritten-builtins.out +3 -0
  415. data/vendor/v8/test/message/testcfg.py +89 -8
  416. data/vendor/v8/test/message/try-catch-finally-no-message.out +26 -26
  417. data/vendor/v8/test/mjsunit/accessor-map-sharing.js +18 -2
  418. data/vendor/v8/test/mjsunit/allocation-site-info.js +126 -0
  419. data/vendor/v8/test/mjsunit/array-bounds-check-removal.js +62 -1
  420. data/vendor/v8/test/mjsunit/array-iteration.js +1 -1
  421. data/vendor/v8/test/mjsunit/array-literal-transitions.js +2 -0
  422. data/vendor/v8/test/mjsunit/array-natives-elements.js +317 -0
  423. data/vendor/v8/test/mjsunit/array-reduce.js +8 -8
  424. data/vendor/v8/test/mjsunit/array-slice.js +12 -0
  425. data/vendor/v8/test/mjsunit/array-store-and-grow.js +4 -1
  426. data/vendor/v8/test/mjsunit/assert-opt-and-deopt.js +1 -1
  427. data/vendor/v8/test/mjsunit/bugs/bug-2337.js +53 -0
  428. data/vendor/v8/test/mjsunit/compare-known-objects-slow.js +69 -0
  429. data/vendor/v8/test/mjsunit/compiler/alloc-object-huge.js +3 -1
  430. data/vendor/v8/test/mjsunit/compiler/inline-accessors.js +368 -0
  431. data/vendor/v8/test/mjsunit/compiler/inline-arguments.js +87 -1
  432. data/vendor/v8/test/mjsunit/compiler/inline-closures.js +49 -0
  433. data/vendor/v8/test/mjsunit/compiler/inline-construct.js +55 -43
  434. data/vendor/v8/test/mjsunit/compiler/inline-literals.js +39 -0
  435. data/vendor/v8/test/mjsunit/compiler/multiply-add.js +69 -0
  436. data/vendor/v8/test/mjsunit/compiler/optimized-closures.js +57 -0
  437. data/vendor/v8/test/mjsunit/compiler/parallel-proto-change.js +44 -0
  438. data/vendor/v8/test/mjsunit/compiler/property-static.js +69 -0
  439. data/vendor/v8/test/mjsunit/compiler/proto-chain-constant.js +55 -0
  440. data/vendor/v8/test/mjsunit/compiler/proto-chain-load.js +44 -0
  441. data/vendor/v8/test/mjsunit/compiler/regress-gvn.js +3 -2
  442. data/vendor/v8/test/mjsunit/compiler/regress-or.js +6 -2
  443. data/vendor/v8/test/mjsunit/compiler/rotate.js +224 -0
  444. data/vendor/v8/test/mjsunit/compiler/uint32.js +173 -0
  445. data/vendor/v8/test/mjsunit/count-based-osr.js +2 -1
  446. data/vendor/v8/test/mjsunit/d8-os.js +3 -3
  447. data/vendor/v8/test/mjsunit/date-parse.js +3 -0
  448. data/vendor/v8/test/mjsunit/date.js +22 -0
  449. data/vendor/v8/test/mjsunit/debug-break-inline.js +1 -0
  450. data/vendor/v8/test/mjsunit/debug-evaluate-locals-optimized-double.js +22 -12
  451. data/vendor/v8/test/mjsunit/debug-evaluate-locals-optimized.js +21 -10
  452. data/vendor/v8/test/mjsunit/debug-liveedit-compile-error.js +60 -0
  453. data/vendor/v8/test/mjsunit/debug-liveedit-double-call.js +142 -0
  454. data/vendor/v8/test/mjsunit/debug-liveedit-literals.js +94 -0
  455. data/vendor/v8/test/mjsunit/debug-liveedit-restart-frame.js +153 -0
  456. data/vendor/v8/test/mjsunit/debug-multiple-breakpoints.js +1 -1
  457. data/vendor/v8/test/mjsunit/debug-script-breakpoints-closure.js +67 -0
  458. data/vendor/v8/test/mjsunit/debug-script-breakpoints-nested.js +82 -0
  459. data/vendor/v8/test/mjsunit/debug-script.js +4 -2
  460. data/vendor/v8/test/mjsunit/debug-set-variable-value.js +308 -0
  461. data/vendor/v8/test/mjsunit/debug-stepout-scope-part1.js +190 -0
  462. data/vendor/v8/test/mjsunit/debug-stepout-scope-part2.js +83 -0
  463. data/vendor/v8/test/mjsunit/debug-stepout-scope-part3.js +80 -0
  464. data/vendor/v8/test/mjsunit/debug-stepout-scope-part4.js +80 -0
  465. data/vendor/v8/test/mjsunit/debug-stepout-scope-part5.js +77 -0
  466. data/vendor/v8/test/mjsunit/debug-stepout-scope-part6.js +79 -0
  467. data/vendor/v8/test/mjsunit/debug-stepout-scope-part7.js +79 -0
  468. data/vendor/v8/test/mjsunit/{debug-stepout-scope.js → debug-stepout-scope-part8.js} +0 -189
  469. data/vendor/v8/test/mjsunit/delete-non-configurable.js +74 -0
  470. data/vendor/v8/test/mjsunit/deopt-minus-zero.js +56 -0
  471. data/vendor/v8/test/mjsunit/elements-kind.js +6 -4
  472. data/vendor/v8/test/mjsunit/elements-length-no-holey.js +33 -0
  473. data/vendor/v8/test/mjsunit/elements-transition-hoisting.js +46 -19
  474. data/vendor/v8/test/mjsunit/error-accessors.js +54 -0
  475. data/vendor/v8/test/mjsunit/error-constructors.js +1 -14
  476. data/vendor/v8/test/mjsunit/error-tostring.js +8 -0
  477. data/vendor/v8/test/mjsunit/eval-stack-trace.js +204 -0
  478. data/vendor/v8/test/mjsunit/external-array.js +364 -1
  479. data/vendor/v8/test/mjsunit/fast-array-length.js +37 -0
  480. data/vendor/v8/test/mjsunit/fast-non-keyed.js +113 -0
  481. data/vendor/v8/test/mjsunit/fast-prototype.js +117 -0
  482. data/vendor/v8/test/mjsunit/function-call.js +14 -18
  483. data/vendor/v8/test/mjsunit/fuzz-natives-part1.js +230 -0
  484. data/vendor/v8/test/mjsunit/fuzz-natives-part2.js +229 -0
  485. data/vendor/v8/test/mjsunit/fuzz-natives-part3.js +229 -0
  486. data/vendor/v8/test/mjsunit/{fuzz-natives.js → fuzz-natives-part4.js} +12 -2
  487. data/vendor/v8/test/mjsunit/generated-transition-stub.js +218 -0
  488. data/vendor/v8/test/mjsunit/greedy.js +1 -1
  489. data/vendor/v8/test/mjsunit/harmony/block-conflicts.js +2 -1
  490. data/vendor/v8/test/mjsunit/harmony/block-let-crankshaft.js +1 -1
  491. data/vendor/v8/test/mjsunit/harmony/collections.js +69 -11
  492. data/vendor/v8/test/mjsunit/harmony/debug-blockscopes.js +2 -2
  493. data/vendor/v8/test/mjsunit/harmony/module-linking.js +180 -3
  494. data/vendor/v8/test/mjsunit/harmony/module-parsing.js +31 -0
  495. data/vendor/v8/test/mjsunit/harmony/module-recompile.js +87 -0
  496. data/vendor/v8/test/mjsunit/harmony/module-resolution.js +15 -2
  497. data/vendor/v8/test/mjsunit/harmony/object-observe.js +1056 -0
  498. data/vendor/v8/test/mjsunit/harmony/proxies-json.js +178 -0
  499. data/vendor/v8/test/mjsunit/harmony/proxies.js +25 -10
  500. data/vendor/v8/test/mjsunit/json-parser-recursive.js +33 -0
  501. data/vendor/v8/test/mjsunit/json-stringify-recursive.js +52 -0
  502. data/vendor/v8/test/mjsunit/json.js +38 -2
  503. data/vendor/v8/test/mjsunit/json2.js +153 -0
  504. data/vendor/v8/test/mjsunit/limit-locals.js +5 -4
  505. data/vendor/v8/test/mjsunit/manual-parallel-recompile.js +79 -0
  506. data/vendor/v8/test/mjsunit/math-exp-precision.js +64 -0
  507. data/vendor/v8/test/mjsunit/math-floor-negative.js +59 -0
  508. data/vendor/v8/test/mjsunit/math-floor-of-div-minus-zero.js +41 -0
  509. data/vendor/v8/test/mjsunit/math-floor-of-div-nosudiv.js +288 -0
  510. data/vendor/v8/test/mjsunit/math-floor-of-div.js +81 -9
  511. data/vendor/v8/test/mjsunit/{math-floor.js → math-floor-part1.js} +1 -72
  512. data/vendor/v8/test/mjsunit/math-floor-part2.js +76 -0
  513. data/vendor/v8/test/mjsunit/math-floor-part3.js +78 -0
  514. data/vendor/v8/test/mjsunit/math-floor-part4.js +76 -0
  515. data/vendor/v8/test/mjsunit/mirror-object.js +43 -9
  516. data/vendor/v8/test/mjsunit/mjsunit.js +1 -1
  517. data/vendor/v8/test/mjsunit/mjsunit.status +52 -27
  518. data/vendor/v8/test/mjsunit/mul-exhaustive-part1.js +491 -0
  519. data/vendor/v8/test/mjsunit/mul-exhaustive-part10.js +470 -0
  520. data/vendor/v8/test/mjsunit/mul-exhaustive-part2.js +525 -0
  521. data/vendor/v8/test/mjsunit/mul-exhaustive-part3.js +532 -0
  522. data/vendor/v8/test/mjsunit/mul-exhaustive-part4.js +509 -0
  523. data/vendor/v8/test/mjsunit/mul-exhaustive-part5.js +505 -0
  524. data/vendor/v8/test/mjsunit/mul-exhaustive-part6.js +554 -0
  525. data/vendor/v8/test/mjsunit/mul-exhaustive-part7.js +497 -0
  526. data/vendor/v8/test/mjsunit/mul-exhaustive-part8.js +526 -0
  527. data/vendor/v8/test/mjsunit/mul-exhaustive-part9.js +533 -0
  528. data/vendor/v8/test/mjsunit/new-function.js +34 -0
  529. data/vendor/v8/test/mjsunit/numops-fuzz-part1.js +1172 -0
  530. data/vendor/v8/test/mjsunit/numops-fuzz-part2.js +1178 -0
  531. data/vendor/v8/test/mjsunit/numops-fuzz-part3.js +1178 -0
  532. data/vendor/v8/test/mjsunit/numops-fuzz-part4.js +1177 -0
  533. data/vendor/v8/test/mjsunit/object-define-property.js +107 -2
  534. data/vendor/v8/test/mjsunit/override-read-only-property.js +6 -4
  535. data/vendor/v8/test/mjsunit/packed-elements.js +2 -2
  536. data/vendor/v8/test/mjsunit/parse-int-float.js +4 -4
  537. data/vendor/v8/test/mjsunit/pixel-array-rounding.js +1 -1
  538. data/vendor/v8/test/mjsunit/readonly.js +228 -0
  539. data/vendor/v8/test/mjsunit/regexp-capture-3.js +16 -18
  540. data/vendor/v8/test/mjsunit/regexp-capture.js +2 -0
  541. data/vendor/v8/test/mjsunit/regexp-global.js +122 -0
  542. data/vendor/v8/test/mjsunit/regexp-results-cache.js +78 -0
  543. data/vendor/v8/test/mjsunit/regress/regress-1117.js +12 -3
  544. data/vendor/v8/test/mjsunit/regress/regress-1118.js +1 -1
  545. data/vendor/v8/test/mjsunit/regress/regress-115100.js +36 -0
  546. data/vendor/v8/test/mjsunit/regress/regress-1199637.js +1 -3
  547. data/vendor/v8/test/mjsunit/regress/regress-121407.js +1 -1
  548. data/vendor/v8/test/mjsunit/regress/regress-131923.js +30 -0
  549. data/vendor/v8/test/mjsunit/regress/regress-131994.js +70 -0
  550. data/vendor/v8/test/mjsunit/regress/regress-133211.js +35 -0
  551. data/vendor/v8/test/mjsunit/regress/regress-133211b.js +39 -0
  552. data/vendor/v8/test/mjsunit/regress/regress-136048.js +34 -0
  553. data/vendor/v8/test/mjsunit/regress/regress-137768.js +73 -0
  554. data/vendor/v8/test/mjsunit/regress/regress-143967.js +34 -0
  555. data/vendor/v8/test/mjsunit/regress/regress-145201.js +107 -0
  556. data/vendor/v8/test/mjsunit/regress/regress-147497.js +45 -0
  557. data/vendor/v8/test/mjsunit/regress/regress-148378.js +38 -0
  558. data/vendor/v8/test/mjsunit/regress/regress-1563.js +1 -1
  559. data/vendor/v8/test/mjsunit/regress/regress-1591.js +48 -0
  560. data/vendor/v8/test/mjsunit/regress/regress-164442.js +45 -0
  561. data/vendor/v8/test/mjsunit/regress/regress-165637.js +61 -0
  562. data/vendor/v8/test/mjsunit/regress/regress-166379.js +39 -0
  563. data/vendor/v8/test/mjsunit/regress/regress-166553.js +33 -0
  564. data/vendor/v8/test/mjsunit/regress/regress-1692.js +1 -1
  565. data/vendor/v8/test/mjsunit/regress/regress-171641.js +40 -0
  566. data/vendor/v8/test/mjsunit/regress/regress-1980.js +1 -1
  567. data/vendor/v8/test/mjsunit/regress/regress-2073.js +99 -0
  568. data/vendor/v8/test/mjsunit/regress/regress-2119.js +36 -0
  569. data/vendor/v8/test/mjsunit/regress/regress-2156.js +39 -0
  570. data/vendor/v8/test/mjsunit/regress/regress-2163.js +70 -0
  571. data/vendor/v8/test/mjsunit/regress/regress-2170.js +58 -0
  572. data/vendor/v8/test/mjsunit/regress/regress-2172.js +35 -0
  573. data/vendor/v8/test/mjsunit/regress/regress-2185-2.js +145 -0
  574. data/vendor/v8/test/mjsunit/regress/regress-2185.js +38 -0
  575. data/vendor/v8/test/mjsunit/regress/regress-2186.js +49 -0
  576. data/vendor/v8/test/mjsunit/regress/regress-2193.js +58 -0
  577. data/vendor/v8/test/mjsunit/regress/regress-2219.js +32 -0
  578. data/vendor/v8/test/mjsunit/regress/regress-2225.js +65 -0
  579. data/vendor/v8/test/mjsunit/regress/regress-2226.js +36 -0
  580. data/vendor/v8/test/mjsunit/regress/regress-2234.js +41 -0
  581. data/vendor/v8/test/mjsunit/regress/regress-2243.js +31 -0
  582. data/vendor/v8/test/mjsunit/regress/regress-2249.js +33 -0
  583. data/vendor/v8/test/mjsunit/regress/regress-2250.js +68 -0
  584. data/vendor/v8/test/mjsunit/regress/regress-2261.js +113 -0
  585. data/vendor/v8/test/mjsunit/regress/regress-2263.js +30 -0
  586. data/vendor/v8/test/mjsunit/regress/regress-2284.js +32 -0
  587. data/vendor/v8/test/mjsunit/regress/regress-2285.js +32 -0
  588. data/vendor/v8/test/mjsunit/regress/regress-2286.js +32 -0
  589. data/vendor/v8/test/mjsunit/regress/regress-2289.js +34 -0
  590. data/vendor/v8/test/mjsunit/regress/regress-2291.js +36 -0
  591. data/vendor/v8/test/mjsunit/regress/regress-2294.js +70 -0
  592. data/vendor/v8/test/mjsunit/regress/regress-2296.js +40 -0
  593. data/vendor/v8/test/mjsunit/regress/regress-2315.js +40 -0
  594. data/vendor/v8/test/mjsunit/regress/regress-2318.js +66 -0
  595. data/vendor/v8/test/mjsunit/regress/regress-2322.js +36 -0
  596. data/vendor/v8/test/mjsunit/regress/regress-2326.js +54 -0
  597. data/vendor/v8/test/mjsunit/regress/regress-2336.js +53 -0
  598. data/vendor/v8/test/mjsunit/regress/regress-2339.js +59 -0
  599. data/vendor/v8/test/mjsunit/regress/regress-2346.js +123 -0
  600. data/vendor/v8/test/mjsunit/regress/regress-2373.js +29 -0
  601. data/vendor/v8/test/mjsunit/regress/regress-2374.js +33 -0
  602. data/vendor/v8/test/mjsunit/regress/regress-2398.js +41 -0
  603. data/vendor/v8/test/mjsunit/regress/regress-2410.js +36 -0
  604. data/vendor/v8/test/mjsunit/regress/regress-2416.js +75 -0
  605. data/vendor/v8/test/mjsunit/regress/regress-2419.js +37 -0
  606. data/vendor/v8/test/mjsunit/regress/regress-2433.js +36 -0
  607. data/vendor/v8/test/mjsunit/regress/regress-2437.js +156 -0
  608. data/vendor/v8/test/mjsunit/regress/regress-2438.js +52 -0
  609. data/vendor/v8/test/mjsunit/regress/regress-2443.js +129 -0
  610. data/vendor/v8/test/mjsunit/regress/regress-2444.js +120 -0
  611. data/vendor/v8/test/mjsunit/regress/regress-2489.js +50 -0
  612. data/vendor/v8/test/mjsunit/regress/regress-2499.js +40 -0
  613. data/vendor/v8/test/mjsunit/regress/regress-334.js +1 -1
  614. data/vendor/v8/test/mjsunit/regress/regress-492.js +39 -1
  615. data/vendor/v8/test/mjsunit/regress/regress-builtin-array-op.js +38 -0
  616. data/vendor/v8/test/mjsunit/regress/regress-cnlt-elements.js +43 -0
  617. data/vendor/v8/test/mjsunit/regress/regress-cnlt-enum-indices.js +45 -0
  618. data/vendor/v8/test/mjsunit/regress/regress-cntl-descriptors-enum.js +46 -0
  619. data/vendor/v8/test/mjsunit/regress/regress-convert-enum.js +60 -0
  620. data/vendor/v8/test/mjsunit/regress/regress-convert-enum2.js +46 -0
  621. data/vendor/v8/test/mjsunit/regress/regress-convert-transition.js +40 -0
  622. data/vendor/v8/test/mjsunit/regress/regress-crbug-119926.js +3 -1
  623. data/vendor/v8/test/mjsunit/regress/regress-crbug-125148.js +90 -0
  624. data/vendor/v8/test/mjsunit/regress/regress-crbug-134055.js +63 -0
  625. data/vendor/v8/test/mjsunit/regress/regress-crbug-134609.js +59 -0
  626. data/vendor/v8/test/mjsunit/regress/regress-crbug-135008.js +45 -0
  627. data/vendor/v8/test/mjsunit/regress/regress-crbug-135066.js +55 -0
  628. data/vendor/v8/test/mjsunit/regress/regress-crbug-137689.js +47 -0
  629. data/vendor/v8/test/mjsunit/regress/regress-crbug-138887.js +48 -0
  630. data/vendor/v8/test/mjsunit/regress/regress-crbug-140083.js +44 -0
  631. data/vendor/v8/test/mjsunit/regress/regress-crbug-142087.js +38 -0
  632. data/vendor/v8/test/mjsunit/regress/regress-crbug-142218.js +44 -0
  633. data/vendor/v8/test/mjsunit/regress/regress-crbug-145961.js +39 -0
  634. data/vendor/v8/test/mjsunit/regress/regress-crbug-146910.js +33 -0
  635. data/vendor/v8/test/mjsunit/regress/regress-crbug-147475.js +48 -0
  636. data/vendor/v8/test/mjsunit/regress/regress-crbug-148376.js +35 -0
  637. data/vendor/v8/test/mjsunit/regress/regress-crbug-150545.js +53 -0
  638. data/vendor/v8/test/mjsunit/regress/regress-crbug-150729.js +39 -0
  639. data/vendor/v8/test/mjsunit/regress/regress-crbug-157019.js +54 -0
  640. data/vendor/v8/test/mjsunit/regress/regress-crbug-157520.js +38 -0
  641. data/vendor/v8/test/mjsunit/regress/regress-crbug-158185.js +39 -0
  642. data/vendor/v8/test/mjsunit/regress/regress-crbug-160010.js +35 -0
  643. data/vendor/v8/test/mjsunit/regress/regress-crbug-162085.js +71 -0
  644. data/vendor/v8/test/mjsunit/regress/regress-crbug-168545.js +34 -0
  645. data/vendor/v8/test/mjsunit/regress/regress-crbug-170856.js +33 -0
  646. data/vendor/v8/test/mjsunit/regress/regress-crbug-172345.js +34 -0
  647. data/vendor/v8/test/mjsunit/regress/regress-crbug-173974.js +36 -0
  648. data/vendor/v8/test/mjsunit/regress/regress-crbug-18639.js +9 -5
  649. data/vendor/v8/test/mjsunit/regress/regress-debug-code-recompilation.js +2 -1
  650. data/vendor/v8/test/mjsunit/regress/regress-deep-proto.js +45 -0
  651. data/vendor/v8/test/mjsunit/regress/regress-delete-empty-double.js +40 -0
  652. data/vendor/v8/test/mjsunit/regress/regress-iteration-order.js +42 -0
  653. data/vendor/v8/test/mjsunit/regress/regress-json-stringify-gc.js +41 -0
  654. data/vendor/v8/test/mjsunit/regress/regress-latin-1.js +78 -0
  655. data/vendor/v8/test/mjsunit/regress/regress-load-elements.js +49 -0
  656. data/vendor/v8/test/mjsunit/regress/regress-observe-empty-double-array.js +38 -0
  657. data/vendor/v8/test/mjsunit/regress/regress-undefined-store-keyed-fast-element.js +37 -0
  658. data/vendor/v8/test/mjsunit/shift-for-integer-div.js +59 -0
  659. data/vendor/v8/test/mjsunit/stack-traces-gc.js +119 -0
  660. data/vendor/v8/test/mjsunit/stack-traces-overflow.js +122 -0
  661. data/vendor/v8/test/mjsunit/stack-traces.js +39 -1
  662. data/vendor/v8/test/mjsunit/str-to-num.js +7 -2
  663. data/vendor/v8/test/mjsunit/strict-mode.js +36 -11
  664. data/vendor/v8/test/mjsunit/string-charcodeat.js +3 -0
  665. data/vendor/v8/test/mjsunit/string-natives.js +72 -0
  666. data/vendor/v8/test/mjsunit/string-split.js +17 -0
  667. data/vendor/v8/test/mjsunit/testcfg.py +76 -6
  668. data/vendor/v8/test/mjsunit/tools/tickprocessor.js +4 -1
  669. data/vendor/v8/test/mjsunit/try-finally-continue.js +72 -0
  670. data/vendor/v8/test/mjsunit/typed-array-slice.js +61 -0
  671. data/vendor/v8/test/mjsunit/unbox-double-arrays.js +2 -0
  672. data/vendor/v8/test/mjsunit/uri.js +12 -0
  673. data/vendor/v8/test/mjsunit/with-readonly.js +4 -2
  674. data/vendor/v8/test/mozilla/mozilla.status +19 -113
  675. data/vendor/v8/test/mozilla/testcfg.py +122 -3
  676. data/vendor/v8/test/preparser/preparser.status +5 -0
  677. data/vendor/v8/test/preparser/strict-identifiers.pyt +1 -1
  678. data/vendor/v8/test/preparser/testcfg.py +101 -5
  679. data/vendor/v8/test/sputnik/sputnik.status +1 -1
  680. data/vendor/v8/test/sputnik/testcfg.py +5 -0
  681. data/vendor/v8/test/test262/README +2 -2
  682. data/vendor/v8/test/test262/test262.status +13 -36
  683. data/vendor/v8/test/test262/testcfg.py +102 -8
  684. data/vendor/v8/tools/android-build.sh +0 -0
  685. data/vendor/v8/tools/android-ll-prof.sh +69 -0
  686. data/vendor/v8/tools/android-run.py +109 -0
  687. data/vendor/v8/tools/android-sync.sh +105 -0
  688. data/vendor/v8/tools/bash-completion.sh +0 -0
  689. data/vendor/v8/tools/check-static-initializers.sh +0 -0
  690. data/vendor/v8/tools/common-includes.sh +15 -22
  691. data/vendor/v8/tools/disasm.py +4 -4
  692. data/vendor/v8/tools/fuzz-harness.sh +0 -0
  693. data/vendor/v8/tools/gen-postmortem-metadata.py +6 -8
  694. data/vendor/v8/tools/grokdump.py +404 -129
  695. data/vendor/v8/tools/gyp/v8.gyp +105 -43
  696. data/vendor/v8/tools/linux-tick-processor +5 -5
  697. data/vendor/v8/tools/ll_prof.py +75 -15
  698. data/vendor/v8/tools/merge-to-branch.sh +2 -2
  699. data/vendor/v8/tools/plot-timer-events +70 -0
  700. data/vendor/v8/tools/plot-timer-events.js +510 -0
  701. data/vendor/v8/tools/presubmit.py +1 -0
  702. data/vendor/v8/tools/push-to-trunk.sh +14 -4
  703. data/vendor/v8/tools/run-llprof.sh +69 -0
  704. data/vendor/v8/tools/run-tests.py +372 -0
  705. data/vendor/v8/tools/run-valgrind.py +1 -1
  706. data/vendor/v8/tools/status-file-converter.py +39 -0
  707. data/vendor/v8/tools/test-server.py +224 -0
  708. data/vendor/v8/tools/test-wrapper-gypbuild.py +13 -16
  709. data/vendor/v8/tools/test.py +10 -19
  710. data/vendor/v8/tools/testrunner/README +174 -0
  711. data/vendor/v8/tools/testrunner/__init__.py +26 -0
  712. data/vendor/v8/tools/testrunner/local/__init__.py +26 -0
  713. data/vendor/v8/tools/testrunner/local/commands.py +153 -0
  714. data/vendor/v8/tools/testrunner/local/execution.py +182 -0
  715. data/vendor/v8/tools/testrunner/local/old_statusfile.py +460 -0
  716. data/vendor/v8/tools/testrunner/local/progress.py +238 -0
  717. data/vendor/v8/tools/testrunner/local/statusfile.py +145 -0
  718. data/vendor/v8/tools/testrunner/local/testsuite.py +187 -0
  719. data/vendor/v8/tools/testrunner/local/utils.py +108 -0
  720. data/vendor/v8/tools/testrunner/local/verbose.py +99 -0
  721. data/vendor/v8/tools/testrunner/network/__init__.py +26 -0
  722. data/vendor/v8/tools/testrunner/network/distro.py +90 -0
  723. data/vendor/v8/tools/testrunner/network/endpoint.py +124 -0
  724. data/vendor/v8/tools/testrunner/network/network_execution.py +253 -0
  725. data/vendor/v8/tools/testrunner/network/perfdata.py +120 -0
  726. data/vendor/v8/tools/testrunner/objects/__init__.py +26 -0
  727. data/vendor/v8/tools/testrunner/objects/context.py +50 -0
  728. data/vendor/v8/tools/testrunner/objects/output.py +60 -0
  729. data/vendor/v8/tools/testrunner/objects/peer.py +80 -0
  730. data/vendor/v8/tools/testrunner/objects/testcase.py +83 -0
  731. data/vendor/v8/tools/testrunner/objects/workpacket.py +90 -0
  732. data/vendor/v8/tools/testrunner/server/__init__.py +26 -0
  733. data/vendor/v8/tools/testrunner/server/compression.py +111 -0
  734. data/vendor/v8/tools/testrunner/server/constants.py +51 -0
  735. data/vendor/v8/tools/testrunner/server/daemon.py +147 -0
  736. data/vendor/v8/tools/testrunner/server/local_handler.py +119 -0
  737. data/vendor/v8/tools/testrunner/server/main.py +245 -0
  738. data/vendor/v8/tools/testrunner/server/presence_handler.py +120 -0
  739. data/vendor/v8/tools/testrunner/server/signatures.py +63 -0
  740. data/vendor/v8/tools/testrunner/server/status_handler.py +112 -0
  741. data/vendor/v8/tools/testrunner/server/work_handler.py +150 -0
  742. data/vendor/v8/tools/tick-processor.html +168 -0
  743. data/vendor/v8/tools/tickprocessor-driver.js +5 -3
  744. data/vendor/v8/tools/tickprocessor.js +58 -15
  745. metadata +534 -30
  746. data/patches/add-freebsd9-and-freebsd10-to-gyp-GetFlavor.patch +0 -11
  747. data/patches/do-not-imply-vfp3-and-armv7.patch +0 -44
  748. data/patches/fPIC-on-x64.patch +0 -14
  749. data/vendor/v8/src/liveobjectlist-inl.h +0 -126
  750. data/vendor/v8/src/liveobjectlist.cc +0 -2631
  751. data/vendor/v8/src/liveobjectlist.h +0 -319
  752. data/vendor/v8/test/mjsunit/mul-exhaustive.js +0 -4629
  753. data/vendor/v8/test/mjsunit/numops-fuzz.js +0 -4609
  754. data/vendor/v8/test/mjsunit/regress/regress-1969.js +0 -5045
@@ -1,11 +0,0 @@
1
- --- build/gyp/pylib/gyp/common.py.orig 2012-05-12 15:36:46.235280559 +0100
2
- +++ build/gyp/pylib/gyp/common.py 2012-05-12 15:37:10.315754125 +0100
3
- @@ -355,6 +355,8 @@
4
- 'sunos5': 'solaris',
5
- 'freebsd7': 'freebsd',
6
- 'freebsd8': 'freebsd',
7
- + 'freebsd9': 'freebsd',
8
- + 'freebsd10': 'freebsd',
9
- }
10
- flavor = flavors.get(sys.platform, 'linux')
11
- return params.get('flavor', flavor)
@@ -1,44 +0,0 @@
1
- diff --git a/Makefile b/Makefile
2
- index 0d825c0..c508f33 100644
3
- --- a/Makefile
4
- +++ b/Makefile
5
- @@ -95,6 +95,11 @@ endif
6
- ifeq ($(strictaliasing), off)
7
- GYPFLAGS += -Dv8_no_strict_aliasing=1
8
- endif
9
- +# hardfp=on
10
- +ifeq ($(hardfp), on)
11
- + GYPFLAGS += -Dv8_use_arm_eabi_hardfloat=true
12
- +endif
13
- +
14
-
15
- # ----------------- available targets: --------------------
16
- # - "dependencies": pulls in external dependencies (currently: GYP)
17
- diff --git a/build/common.gypi b/build/common.gypi
18
- index 7f084b8..d89f1f4 100644
19
- --- a/build/common.gypi
20
- +++ b/build/common.gypi
21
- @@ -133,7 +133,6 @@
22
- [ 'v8_use_arm_eabi_hardfloat=="true"', {
23
- 'defines': [
24
- 'USE_EABI_HARDFLOAT=1',
25
- - 'CAN_USE_VFP_INSTRUCTIONS',
26
- ],
27
- 'target_conditions': [
28
- ['_toolset=="target"', {
29
- diff --git a/build/standalone.gypi b/build/standalone.gypi
30
- index ebdf557..2961bac 100644
31
- --- a/build/standalone.gypi
32
- +++ b/build/standalone.gypi
33
- @@ -74,9 +74,9 @@
34
- }],
35
- ],
36
- # Default ARM variable settings.
37
- - 'armv7%': 1,
38
- + 'armv7%': 0,
39
- 'arm_neon%': 0,
40
- - 'arm_fpu%': 'vfpv3',
41
- + 'arm_fpu%': 'vfp',
42
- },
43
- 'target_defaults': {
44
- 'default_configuration': 'Debug',
@@ -1,14 +0,0 @@
1
- diff --git a/build/standalone.gypi b/build/standalone.gypi
2
- index ebdf557..c7a59bc 100644
3
- --- a/build/standalone.gypi
4
- +++ b/build/standalone.gypi
5
- @@ -98,6 +98,9 @@
6
- [ 'OS=="linux"', {
7
- 'cflags': [ '-ansi' ],
8
- }],
9
- + [ '(OS=="linux" or OS=="freebsd" or OS=="solaris") and v8_target_arch=="x64" and component=="static_library"', {
10
- + 'cflags': [ '-fPIC' ],
11
- + }],
12
- [ 'visibility=="hidden"', {
13
- 'cflags': [ '-fvisibility=hidden' ],
14
- }],
@@ -1,126 +0,0 @@
1
- // Copyright 2011 the V8 project authors. All rights reserved.
2
- // Redistribution and use in source and binary forms, with or without
3
- // modification, are permitted provided that the following conditions are
4
- // met:
5
- //
6
- // * Redistributions of source code must retain the above copyright
7
- // notice, this list of conditions and the following disclaimer.
8
- // * Redistributions in binary form must reproduce the above
9
- // copyright notice, this list of conditions and the following
10
- // disclaimer in the documentation and/or other materials provided
11
- // with the distribution.
12
- // * Neither the name of Google Inc. nor the names of its
13
- // contributors may be used to endorse or promote products derived
14
- // from this software without specific prior written permission.
15
- //
16
- // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
- // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
- // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
- // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20
- // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
- // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
- // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
- // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
- // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
- // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
- // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
-
28
- #ifndef V8_LIVEOBJECTLIST_INL_H_
29
- #define V8_LIVEOBJECTLIST_INL_H_
30
-
31
- #include "v8.h"
32
-
33
- #include "liveobjectlist.h"
34
-
35
- namespace v8 {
36
- namespace internal {
37
-
38
- #ifdef LIVE_OBJECT_LIST
39
-
40
- void LiveObjectList::GCEpilogue() {
41
- if (!NeedLOLProcessing()) return;
42
- GCEpiloguePrivate();
43
- }
44
-
45
-
46
- void LiveObjectList::GCPrologue() {
47
- if (!NeedLOLProcessing()) return;
48
- #ifdef VERIFY_LOL
49
- if (FLAG_verify_lol) {
50
- Verify();
51
- }
52
- #endif
53
- }
54
-
55
-
56
- void LiveObjectList::IterateElements(ObjectVisitor* v) {
57
- if (!NeedLOLProcessing()) return;
58
- IterateElementsPrivate(v);
59
- }
60
-
61
-
62
- void LiveObjectList::ProcessNonLive(HeapObject* obj) {
63
- // Only do work if we have at least one list to process.
64
- if (last()) DoProcessNonLive(obj);
65
- }
66
-
67
-
68
- void LiveObjectList::UpdateReferencesForScavengeGC() {
69
- if (LiveObjectList::NeedLOLProcessing()) {
70
- UpdateLiveObjectListVisitor update_visitor;
71
- LiveObjectList::IterateElements(&update_visitor);
72
- }
73
- }
74
-
75
-
76
- LiveObjectList* LiveObjectList::FindLolForId(int id,
77
- LiveObjectList* start_lol) {
78
- if (id != 0) {
79
- LiveObjectList* lol = start_lol;
80
- while (lol != NULL) {
81
- if (lol->id() == id) {
82
- return lol;
83
- }
84
- lol = lol->prev_;
85
- }
86
- }
87
- return NULL;
88
- }
89
-
90
-
91
- // Iterates the elements in every lol and returns the one that matches the
92
- // specified key. If no matching element is found, then it returns NULL.
93
- template <typename T>
94
- inline LiveObjectList::Element*
95
- LiveObjectList::FindElementFor(T (*GetValue)(LiveObjectList::Element*), T key) {
96
- LiveObjectList* lol = last();
97
- while (lol != NULL) {
98
- Element* elements = lol->elements_;
99
- for (int i = 0; i < lol->obj_count_; i++) {
100
- Element* element = &elements[i];
101
- if (GetValue(element) == key) {
102
- return element;
103
- }
104
- }
105
- lol = lol->prev_;
106
- }
107
- return NULL;
108
- }
109
-
110
-
111
- inline int LiveObjectList::GetElementId(LiveObjectList::Element* element) {
112
- return element->id_;
113
- }
114
-
115
-
116
- inline HeapObject*
117
- LiveObjectList::GetElementObj(LiveObjectList::Element* element) {
118
- return element->obj_;
119
- }
120
-
121
- #endif // LIVE_OBJECT_LIST
122
-
123
- } } // namespace v8::internal
124
-
125
- #endif // V8_LIVEOBJECTLIST_INL_H_
126
-
@@ -1,2631 +0,0 @@
1
- // Copyright 2011 the V8 project authors. All rights reserved.
2
- // Redistribution and use in source and binary forms, with or without
3
- // modification, are permitted provided that the following conditions are
4
- // met:
5
- //
6
- // * Redistributions of source code must retain the above copyright
7
- // notice, this list of conditions and the following disclaimer.
8
- // * Redistributions in binary form must reproduce the above
9
- // copyright notice, this list of conditions and the following
10
- // disclaimer in the documentation and/or other materials provided
11
- // with the distribution.
12
- // * Neither the name of Google Inc. nor the names of its
13
- // contributors may be used to endorse or promote products derived
14
- // from this software without specific prior written permission.
15
- //
16
- // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
- // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
- // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
- // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20
- // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
- // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
- // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
- // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
- // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
- // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
- // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
-
28
- #ifdef LIVE_OBJECT_LIST
29
-
30
- #include <ctype.h>
31
- #include <stdlib.h>
32
-
33
- #include "v8.h"
34
-
35
- #include "checks.h"
36
- #include "global-handles.h"
37
- #include "heap.h"
38
- #include "inspector.h"
39
- #include "isolate.h"
40
- #include "list-inl.h"
41
- #include "liveobjectlist-inl.h"
42
- #include "string-stream.h"
43
- #include "v8utils.h"
44
- #include "v8conversions.h"
45
-
46
- namespace v8 {
47
- namespace internal {
48
-
49
-
50
- typedef int (*RawComparer)(const void*, const void*);
51
-
52
-
53
- #ifdef CHECK_ALL_OBJECT_TYPES
54
-
55
- #define DEBUG_LIVE_OBJECT_TYPES(v) \
56
- v(Smi, "unexpected: Smi") \
57
- \
58
- v(CodeCache, "unexpected: CodeCache") \
59
- v(BreakPointInfo, "unexpected: BreakPointInfo") \
60
- v(DebugInfo, "unexpected: DebugInfo") \
61
- v(TypeSwitchInfo, "unexpected: TypeSwitchInfo") \
62
- v(SignatureInfo, "unexpected: SignatureInfo") \
63
- v(Script, "unexpected: Script") \
64
- v(ObjectTemplateInfo, "unexpected: ObjectTemplateInfo") \
65
- v(FunctionTemplateInfo, "unexpected: FunctionTemplateInfo") \
66
- v(CallHandlerInfo, "unexpected: CallHandlerInfo") \
67
- v(InterceptorInfo, "unexpected: InterceptorInfo") \
68
- v(AccessCheckInfo, "unexpected: AccessCheckInfo") \
69
- v(AccessorInfo, "unexpected: AccessorInfo") \
70
- v(ExternalTwoByteString, "unexpected: ExternalTwoByteString") \
71
- v(ExternalAsciiString, "unexpected: ExternalAsciiString") \
72
- v(ExternalString, "unexpected: ExternalString") \
73
- v(SeqTwoByteString, "unexpected: SeqTwoByteString") \
74
- v(SeqAsciiString, "unexpected: SeqAsciiString") \
75
- v(SeqString, "unexpected: SeqString") \
76
- v(JSFunctionResultCache, "unexpected: JSFunctionResultCache") \
77
- v(GlobalContext, "unexpected: GlobalContext") \
78
- v(MapCache, "unexpected: MapCache") \
79
- v(CodeCacheHashTable, "unexpected: CodeCacheHashTable") \
80
- v(CompilationCacheTable, "unexpected: CompilationCacheTable") \
81
- v(SymbolTable, "unexpected: SymbolTable") \
82
- v(Dictionary, "unexpected: Dictionary") \
83
- v(HashTable, "unexpected: HashTable") \
84
- v(DescriptorArray, "unexpected: DescriptorArray") \
85
- v(ExternalFloatArray, "unexpected: ExternalFloatArray") \
86
- v(ExternalUnsignedIntArray, "unexpected: ExternalUnsignedIntArray") \
87
- v(ExternalIntArray, "unexpected: ExternalIntArray") \
88
- v(ExternalUnsignedShortArray, "unexpected: ExternalUnsignedShortArray") \
89
- v(ExternalShortArray, "unexpected: ExternalShortArray") \
90
- v(ExternalUnsignedByteArray, "unexpected: ExternalUnsignedByteArray") \
91
- v(ExternalByteArray, "unexpected: ExternalByteArray") \
92
- v(JSValue, "unexpected: JSValue")
93
-
94
- #else
95
- #define DEBUG_LIVE_OBJECT_TYPES(v)
96
- #endif
97
-
98
-
99
- #define FOR_EACH_LIVE_OBJECT_TYPE(v) \
100
- DEBUG_LIVE_OBJECT_TYPES(v) \
101
- \
102
- v(JSArray, "JSArray") \
103
- v(JSRegExp, "JSRegExp") \
104
- v(JSFunction, "JSFunction") \
105
- v(JSGlobalObject, "JSGlobal") \
106
- v(JSBuiltinsObject, "JSBuiltins") \
107
- v(GlobalObject, "Global") \
108
- v(JSGlobalProxy, "JSGlobalProxy") \
109
- v(JSObject, "JSObject") \
110
- \
111
- v(Context, "meta: Context") \
112
- v(ByteArray, "meta: ByteArray") \
113
- v(ExternalPixelArray, "meta: PixelArray") \
114
- v(ExternalArray, "meta: ExternalArray") \
115
- v(FixedArray, "meta: FixedArray") \
116
- v(String, "String") \
117
- v(HeapNumber, "HeapNumber") \
118
- \
119
- v(Code, "meta: Code") \
120
- v(Map, "meta: Map") \
121
- v(Oddball, "Oddball") \
122
- v(Foreign, "meta: Foreign") \
123
- v(SharedFunctionInfo, "meta: SharedFunctionInfo") \
124
- v(Struct, "meta: Struct") \
125
- \
126
- v(HeapObject, "HeapObject")
127
-
128
-
129
- enum /* LiveObjectType */ {
130
- #define DECLARE_OBJECT_TYPE_ENUM(type, name) kType##type,
131
- FOR_EACH_LIVE_OBJECT_TYPE(DECLARE_OBJECT_TYPE_ENUM)
132
- kInvalidLiveObjType,
133
- kNumberOfTypes
134
- #undef DECLARE_OBJECT_TYPE_ENUM
135
- };
136
-
137
-
138
- LiveObjectType GetObjectType(HeapObject* heap_obj) {
139
- // TODO(mlam): investigate usint Map::instance_type() instead.
140
- #define CHECK_FOR_OBJECT_TYPE(type, name) \
141
- if (heap_obj->Is##type()) return kType##type;
142
- FOR_EACH_LIVE_OBJECT_TYPE(CHECK_FOR_OBJECT_TYPE)
143
- #undef CHECK_FOR_OBJECT_TYPE
144
-
145
- UNREACHABLE();
146
- return kInvalidLiveObjType;
147
- }
148
-
149
-
150
- inline const char* GetObjectTypeDesc(LiveObjectType type) {
151
- static const char* const name[kNumberOfTypes] = {
152
- #define DEFINE_OBJECT_TYPE_NAME(type, name) name,
153
- FOR_EACH_LIVE_OBJECT_TYPE(DEFINE_OBJECT_TYPE_NAME)
154
- "invalid"
155
- #undef DEFINE_OBJECT_TYPE_NAME
156
- };
157
- ASSERT(type < kNumberOfTypes);
158
- return name[type];
159
- }
160
-
161
-
162
- const char* GetObjectTypeDesc(HeapObject* heap_obj) {
163
- LiveObjectType type = GetObjectType(heap_obj);
164
- return GetObjectTypeDesc(type);
165
- }
166
-
167
-
168
- bool IsOfType(LiveObjectType type, HeapObject* obj) {
169
- // Note: there are types that are more general (e.g. JSObject) that would
170
- // have passed the Is##type_() test for more specialized types (e.g.
171
- // JSFunction). If we find a more specialized match but we're looking for
172
- // the general type, then we should reject the ones that matches the
173
- // specialized type.
174
- #define CHECK_OBJECT_TYPE(type_, name) \
175
- if (obj->Is##type_()) return (type == kType##type_);
176
-
177
- FOR_EACH_LIVE_OBJECT_TYPE(CHECK_OBJECT_TYPE)
178
- #undef CHECK_OBJECT_TYPE
179
-
180
- return false;
181
- }
182
-
183
-
184
- const AllocationSpace kInvalidSpace = static_cast<AllocationSpace>(-1);
185
-
186
- static AllocationSpace FindSpaceFor(String* space_str) {
187
- SmartArrayPointer<char> s =
188
- space_str->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
189
-
190
- const char* key_str = *s;
191
- switch (key_str[0]) {
192
- case 'c':
193
- if (strcmp(key_str, "cell") == 0) return CELL_SPACE;
194
- if (strcmp(key_str, "code") == 0) return CODE_SPACE;
195
- break;
196
- case 'l':
197
- if (strcmp(key_str, "lo") == 0) return LO_SPACE;
198
- break;
199
- case 'm':
200
- if (strcmp(key_str, "map") == 0) return MAP_SPACE;
201
- break;
202
- case 'n':
203
- if (strcmp(key_str, "new") == 0) return NEW_SPACE;
204
- break;
205
- case 'o':
206
- if (strcmp(key_str, "old-pointer") == 0) return OLD_POINTER_SPACE;
207
- if (strcmp(key_str, "old-data") == 0) return OLD_DATA_SPACE;
208
- break;
209
- }
210
- return kInvalidSpace;
211
- }
212
-
213
-
214
- static bool InSpace(AllocationSpace space, HeapObject* heap_obj) {
215
- Heap* heap = ISOLATE->heap();
216
- if (space != LO_SPACE) {
217
- return heap->InSpace(heap_obj, space);
218
- }
219
-
220
- // This is an optimization to speed up the check for an object in the LO
221
- // space by exclusion because we know that all object pointers passed in
222
- // here are guaranteed to be in the heap. Hence, it is safe to infer
223
- // using an exclusion test.
224
- // Note: calling Heap::InSpace(heap_obj, LO_SPACE) is too slow for our
225
- // filters.
226
- int first_space = static_cast<int>(FIRST_SPACE);
227
- int last_space = static_cast<int>(LO_SPACE);
228
- for (int sp = first_space; sp < last_space; sp++) {
229
- if (heap->InSpace(heap_obj, static_cast<AllocationSpace>(sp))) {
230
- return false;
231
- }
232
- }
233
- SLOW_ASSERT(heap->InSpace(heap_obj, LO_SPACE));
234
- return true;
235
- }
236
-
237
-
238
- static LiveObjectType FindTypeFor(String* type_str) {
239
- SmartArrayPointer<char> s =
240
- type_str->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
241
-
242
- #define CHECK_OBJECT_TYPE(type_, name) { \
243
- const char* type_desc = GetObjectTypeDesc(kType##type_); \
244
- const char* key_str = *s; \
245
- if (strstr(type_desc, key_str) != NULL) return kType##type_; \
246
- }
247
- FOR_EACH_LIVE_OBJECT_TYPE(CHECK_OBJECT_TYPE)
248
- #undef CHECK_OBJECT_TYPE
249
-
250
- return kInvalidLiveObjType;
251
- }
252
-
253
-
254
- class LolFilter {
255
- public:
256
- explicit LolFilter(Handle<JSObject> filter_obj);
257
-
258
- inline bool is_active() const { return is_active_; }
259
- inline bool Matches(HeapObject* obj) {
260
- return !is_active() || MatchesSlow(obj);
261
- }
262
-
263
- private:
264
- void InitTypeFilter(Handle<JSObject> filter_obj);
265
- void InitSpaceFilter(Handle<JSObject> filter_obj);
266
- void InitPropertyFilter(Handle<JSObject> filter_obj);
267
- bool MatchesSlow(HeapObject* obj);
268
-
269
- bool is_active_;
270
- LiveObjectType type_;
271
- AllocationSpace space_;
272
- Handle<String> prop_;
273
- };
274
-
275
-
276
- LolFilter::LolFilter(Handle<JSObject> filter_obj)
277
- : is_active_(false),
278
- type_(kInvalidLiveObjType),
279
- space_(kInvalidSpace),
280
- prop_() {
281
- if (filter_obj.is_null()) return;
282
-
283
- InitTypeFilter(filter_obj);
284
- InitSpaceFilter(filter_obj);
285
- InitPropertyFilter(filter_obj);
286
- }
287
-
288
-
289
- void LolFilter::InitTypeFilter(Handle<JSObject> filter_obj) {
290
- Handle<String> type_sym = FACTORY->LookupAsciiSymbol("type");
291
- MaybeObject* maybe_result = filter_obj->GetProperty(*type_sym);
292
- Object* type_obj;
293
- if (maybe_result->ToObject(&type_obj)) {
294
- if (type_obj->IsString()) {
295
- String* type_str = String::cast(type_obj);
296
- type_ = FindTypeFor(type_str);
297
- if (type_ != kInvalidLiveObjType) {
298
- is_active_ = true;
299
- }
300
- }
301
- }
302
- }
303
-
304
-
305
- void LolFilter::InitSpaceFilter(Handle<JSObject> filter_obj) {
306
- Handle<String> space_sym = FACTORY->LookupAsciiSymbol("space");
307
- MaybeObject* maybe_result = filter_obj->GetProperty(*space_sym);
308
- Object* space_obj;
309
- if (maybe_result->ToObject(&space_obj)) {
310
- if (space_obj->IsString()) {
311
- String* space_str = String::cast(space_obj);
312
- space_ = FindSpaceFor(space_str);
313
- if (space_ != kInvalidSpace) {
314
- is_active_ = true;
315
- }
316
- }
317
- }
318
- }
319
-
320
-
321
- void LolFilter::InitPropertyFilter(Handle<JSObject> filter_obj) {
322
- Handle<String> prop_sym = FACTORY->LookupAsciiSymbol("prop");
323
- MaybeObject* maybe_result = filter_obj->GetProperty(*prop_sym);
324
- Object* prop_obj;
325
- if (maybe_result->ToObject(&prop_obj)) {
326
- if (prop_obj->IsString()) {
327
- prop_ = Handle<String>(String::cast(prop_obj));
328
- is_active_ = true;
329
- }
330
- }
331
- }
332
-
333
-
334
- bool LolFilter::MatchesSlow(HeapObject* obj) {
335
- if ((type_ != kInvalidLiveObjType) && !IsOfType(type_, obj)) {
336
- return false; // Fail because obj is not of the type of interest.
337
- }
338
- if ((space_ != kInvalidSpace) && !InSpace(space_, obj)) {
339
- return false; // Fail because obj is not in the space of interest.
340
- }
341
- if (!prop_.is_null() && obj->IsJSObject()) {
342
- LookupResult result;
343
- obj->Lookup(*prop_, &result);
344
- if (!result.IsProperty()) {
345
- return false; // Fail because obj does not have the property of interest.
346
- }
347
- }
348
- return true;
349
- }
350
-
351
-
352
- class LolIterator {
353
- public:
354
- LolIterator(LiveObjectList* older, LiveObjectList* newer)
355
- : older_(older),
356
- newer_(newer),
357
- curr_(0),
358
- elements_(0),
359
- count_(0),
360
- index_(0) { }
361
-
362
- inline void Init() {
363
- SetCurrent(newer_);
364
- // If the elements_ list is empty, then move on to the next list as long
365
- // as we're not at the last list (indicated by done()).
366
- while ((elements_ == NULL) && !Done()) {
367
- SetCurrent(curr_->prev_);
368
- }
369
- }
370
-
371
- inline bool Done() const {
372
- return (curr_ == older_);
373
- }
374
-
375
- // Object level iteration.
376
- inline void Next() {
377
- index_++;
378
- if (index_ >= count_) {
379
- // Iterate backwards until we get to the oldest list.
380
- while (!Done()) {
381
- SetCurrent(curr_->prev_);
382
- // If we have elements to process, we're good to go.
383
- if (elements_ != NULL) break;
384
-
385
- // Else, we should advance to the next older list.
386
- }
387
- }
388
- }
389
-
390
- inline int Id() const {
391
- return elements_[index_].id_;
392
- }
393
- inline HeapObject* Obj() const {
394
- return elements_[index_].obj_;
395
- }
396
-
397
- inline int LolObjCount() const {
398
- if (curr_ != NULL) return curr_->obj_count_;
399
- return 0;
400
- }
401
-
402
- protected:
403
- inline void SetCurrent(LiveObjectList* new_curr) {
404
- curr_ = new_curr;
405
- if (curr_ != NULL) {
406
- elements_ = curr_->elements_;
407
- count_ = curr_->obj_count_;
408
- index_ = 0;
409
- }
410
- }
411
-
412
- LiveObjectList* older_;
413
- LiveObjectList* newer_;
414
- LiveObjectList* curr_;
415
- LiveObjectList::Element* elements_;
416
- int count_;
417
- int index_;
418
- };
419
-
420
-
421
- class LolForwardIterator : public LolIterator {
422
- public:
423
- LolForwardIterator(LiveObjectList* first, LiveObjectList* last)
424
- : LolIterator(first, last) {
425
- }
426
-
427
- inline void Init() {
428
- SetCurrent(older_);
429
- // If the elements_ list is empty, then move on to the next list as long
430
- // as we're not at the last list (indicated by Done()).
431
- while ((elements_ == NULL) && !Done()) {
432
- SetCurrent(curr_->next_);
433
- }
434
- }
435
-
436
- inline bool Done() const {
437
- return (curr_ == newer_);
438
- }
439
-
440
- // Object level iteration.
441
- inline void Next() {
442
- index_++;
443
- if (index_ >= count_) {
444
- // Done with current list. Move on to the next.
445
- while (!Done()) { // If not at the last list already, ...
446
- SetCurrent(curr_->next_);
447
- // If we have elements to process, we're good to go.
448
- if (elements_ != NULL) break;
449
-
450
- // Else, we should advance to the next list.
451
- }
452
- }
453
- }
454
- };
455
-
456
-
457
- // Minimizes the white space in a string. Tabs and newlines are replaced
458
- // with a space where appropriate.
459
- static int CompactString(char* str) {
460
- char* src = str;
461
- char* dst = str;
462
- char prev_ch = 0;
463
- while (*dst != '\0') {
464
- char ch = *src++;
465
- // We will treat non-ASCII chars as '?'.
466
- if ((ch & 0x80) != 0) {
467
- ch = '?';
468
- }
469
- // Compact contiguous whitespace chars into a single ' '.
470
- if (isspace(ch)) {
471
- if (prev_ch != ' ') *dst++ = ' ';
472
- prev_ch = ' ';
473
- continue;
474
- }
475
- *dst++ = ch;
476
- prev_ch = ch;
477
- }
478
- return (dst - str);
479
- }
480
-
481
-
482
- // Generates a custom description based on the specific type of
483
- // object we're looking at. We only generate specialized
484
- // descriptions where we can. In all other cases, we emit the
485
- // generic info.
486
- static void GenerateObjectDesc(HeapObject* obj,
487
- char* buffer,
488
- int buffer_size) {
489
- Vector<char> buffer_v(buffer, buffer_size);
490
- ASSERT(obj != NULL);
491
- if (obj->IsJSArray()) {
492
- JSArray* jsarray = JSArray::cast(obj);
493
- double length = jsarray->length()->Number();
494
- OS::SNPrintF(buffer_v,
495
- "%p <%s> len %g",
496
- reinterpret_cast<void*>(obj),
497
- GetObjectTypeDesc(obj),
498
- length);
499
-
500
- } else if (obj->IsString()) {
501
- String* str = String::cast(obj);
502
- // Only grab up to 160 chars in case they are double byte.
503
- // We'll only dump 80 of them after we compact them.
504
- const int kMaxCharToDump = 80;
505
- const int kMaxBufferSize = kMaxCharToDump * 2;
506
- SmartArrayPointer<char> str_sp = str->ToCString(DISALLOW_NULLS,
507
- ROBUST_STRING_TRAVERSAL,
508
- 0,
509
- kMaxBufferSize);
510
- char* str_cstr = *str_sp;
511
- int length = CompactString(str_cstr);
512
- OS::SNPrintF(buffer_v,
513
- "%p <%s> '%.80s%s'",
514
- reinterpret_cast<void*>(obj),
515
- GetObjectTypeDesc(obj),
516
- str_cstr,
517
- (length > kMaxCharToDump) ? "..." : "");
518
-
519
- } else if (obj->IsJSFunction() || obj->IsSharedFunctionInfo()) {
520
- SharedFunctionInfo* sinfo;
521
- if (obj->IsJSFunction()) {
522
- JSFunction* func = JSFunction::cast(obj);
523
- sinfo = func->shared();
524
- } else {
525
- sinfo = SharedFunctionInfo::cast(obj);
526
- }
527
-
528
- String* name = sinfo->DebugName();
529
- SmartArrayPointer<char> name_sp =
530
- name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
531
- char* name_cstr = *name_sp;
532
-
533
- HeapStringAllocator string_allocator;
534
- StringStream stream(&string_allocator);
535
- sinfo->SourceCodePrint(&stream, 50);
536
- SmartArrayPointer<const char> source_sp = stream.ToCString();
537
- const char* source_cstr = *source_sp;
538
-
539
- OS::SNPrintF(buffer_v,
540
- "%p <%s> '%s' %s",
541
- reinterpret_cast<void*>(obj),
542
- GetObjectTypeDesc(obj),
543
- name_cstr,
544
- source_cstr);
545
-
546
- } else if (obj->IsFixedArray()) {
547
- FixedArray* fixed = FixedArray::cast(obj);
548
-
549
- OS::SNPrintF(buffer_v,
550
- "%p <%s> len %d",
551
- reinterpret_cast<void*>(obj),
552
- GetObjectTypeDesc(obj),
553
- fixed->length());
554
-
555
- } else {
556
- OS::SNPrintF(buffer_v,
557
- "%p <%s>",
558
- reinterpret_cast<void*>(obj),
559
- GetObjectTypeDesc(obj));
560
- }
561
- }
562
-
563
-
564
- // Utility function for filling in a line of detail in a verbose dump.
565
- static bool AddObjDetail(Handle<FixedArray> arr,
566
- int index,
567
- int obj_id,
568
- Handle<HeapObject> target,
569
- const char* desc_str,
570
- Handle<String> id_sym,
571
- Handle<String> desc_sym,
572
- Handle<String> size_sym,
573
- Handle<JSObject> detail,
574
- Handle<String> desc,
575
- Handle<Object> error) {
576
- Isolate* isolate = Isolate::Current();
577
- Factory* factory = isolate->factory();
578
- detail = factory->NewJSObject(isolate->object_function());
579
- if (detail->IsFailure()) {
580
- error = detail;
581
- return false;
582
- }
583
-
584
- int size = 0;
585
- char buffer[512];
586
- if (desc_str == NULL) {
587
- ASSERT(!target.is_null());
588
- HeapObject* obj = *target;
589
- GenerateObjectDesc(obj, buffer, sizeof(buffer));
590
- desc_str = buffer;
591
- size = obj->Size();
592
- }
593
- desc = factory->NewStringFromAscii(CStrVector(desc_str));
594
- if (desc->IsFailure()) {
595
- error = desc;
596
- return false;
597
- }
598
-
599
- { MaybeObject* maybe_result = detail->SetProperty(*id_sym,
600
- Smi::FromInt(obj_id),
601
- NONE,
602
- kNonStrictMode);
603
- if (maybe_result->IsFailure()) return false;
604
- }
605
- { MaybeObject* maybe_result = detail->SetProperty(*desc_sym,
606
- *desc,
607
- NONE,
608
- kNonStrictMode);
609
- if (maybe_result->IsFailure()) return false;
610
- }
611
- { MaybeObject* maybe_result = detail->SetProperty(*size_sym,
612
- Smi::FromInt(size),
613
- NONE,
614
- kNonStrictMode);
615
- if (maybe_result->IsFailure()) return false;
616
- }
617
-
618
- arr->set(index, *detail);
619
- return true;
620
- }
621
-
622
-
623
- class DumpWriter {
624
- public:
625
- virtual ~DumpWriter() {}
626
-
627
- virtual void ComputeTotalCountAndSize(LolFilter* filter,
628
- int* count,
629
- int* size) = 0;
630
- virtual bool Write(Handle<FixedArray> elements_arr,
631
- int start,
632
- int dump_limit,
633
- LolFilter* filter,
634
- Handle<Object> error) = 0;
635
- };
636
-
637
-
638
- class LolDumpWriter: public DumpWriter {
639
- public:
640
- LolDumpWriter(LiveObjectList* older, LiveObjectList* newer)
641
- : older_(older), newer_(newer) {
642
- }
643
-
644
- void ComputeTotalCountAndSize(LolFilter* filter, int* count, int* size) {
645
- *count = 0;
646
- *size = 0;
647
-
648
- LolIterator it(older_, newer_);
649
- for (it.Init(); !it.Done(); it.Next()) {
650
- HeapObject* heap_obj = it.Obj();
651
- if (!filter->Matches(heap_obj)) {
652
- continue;
653
- }
654
-
655
- *size += heap_obj->Size();
656
- (*count)++;
657
- }
658
- }
659
-
660
- bool Write(Handle<FixedArray> elements_arr,
661
- int start,
662
- int dump_limit,
663
- LolFilter* filter,
664
- Handle<Object> error) {
665
- // The lols are listed in latest to earliest. We want to dump from
666
- // earliest to latest. So, compute the last element to start with.
667
- int index = 0;
668
- int count = 0;
669
-
670
- Isolate* isolate = Isolate::Current();
671
- Factory* factory = isolate->factory();
672
-
673
- // Prefetch some needed symbols.
674
- Handle<String> id_sym = factory->LookupAsciiSymbol("id");
675
- Handle<String> desc_sym = factory->LookupAsciiSymbol("desc");
676
- Handle<String> size_sym = factory->LookupAsciiSymbol("size");
677
-
678
- // Fill the array with the lol object details.
679
- Handle<JSObject> detail;
680
- Handle<String> desc;
681
- Handle<HeapObject> target;
682
-
683
- LiveObjectList* first_lol = (older_ != NULL) ?
684
- older_->next_ : LiveObjectList::first_;
685
- LiveObjectList* last_lol = (newer_ != NULL) ? newer_->next_ : NULL;
686
-
687
- LolForwardIterator it(first_lol, last_lol);
688
- for (it.Init(); !it.Done() && (index < dump_limit); it.Next()) {
689
- HeapObject* heap_obj = it.Obj();
690
-
691
- // Skip objects that have been filtered out.
692
- if (!filter->Matches(heap_obj)) {
693
- continue;
694
- }
695
-
696
- // Only report objects that are in the section of interest.
697
- if (count >= start) {
698
- target = Handle<HeapObject>(heap_obj);
699
- bool success = AddObjDetail(elements_arr,
700
- index++,
701
- it.Id(),
702
- target,
703
- NULL,
704
- id_sym,
705
- desc_sym,
706
- size_sym,
707
- detail,
708
- desc,
709
- error);
710
- if (!success) return false;
711
- }
712
- count++;
713
- }
714
- return true;
715
- }
716
-
717
- private:
718
- LiveObjectList* older_;
719
- LiveObjectList* newer_;
720
- };
721
-
722
-
723
- class RetainersDumpWriter: public DumpWriter {
724
- public:
725
- RetainersDumpWriter(Handle<HeapObject> target,
726
- Handle<JSObject> instance_filter,
727
- Handle<JSFunction> args_function)
728
- : target_(target),
729
- instance_filter_(instance_filter),
730
- args_function_(args_function) {
731
- }
732
-
733
- void ComputeTotalCountAndSize(LolFilter* filter, int* count, int* size) {
734
- Handle<FixedArray> retainers_arr;
735
- Handle<Object> error;
736
-
737
- *size = -1;
738
- LiveObjectList::GetRetainers(target_,
739
- instance_filter_,
740
- retainers_arr,
741
- 0,
742
- Smi::kMaxValue,
743
- count,
744
- filter,
745
- NULL,
746
- *args_function_,
747
- error);
748
- }
749
-
750
- bool Write(Handle<FixedArray> elements_arr,
751
- int start,
752
- int dump_limit,
753
- LolFilter* filter,
754
- Handle<Object> error) {
755
- int dummy;
756
- int count;
757
-
758
- // Fill the retainer objects.
759
- count = LiveObjectList::GetRetainers(target_,
760
- instance_filter_,
761
- elements_arr,
762
- start,
763
- dump_limit,
764
- &dummy,
765
- filter,
766
- NULL,
767
- *args_function_,
768
- error);
769
- if (count < 0) {
770
- return false;
771
- }
772
- return true;
773
- }
774
-
775
- private:
776
- Handle<HeapObject> target_;
777
- Handle<JSObject> instance_filter_;
778
- Handle<JSFunction> args_function_;
779
- };
780
-
781
-
782
- class LiveObjectSummary {
783
- public:
784
- explicit LiveObjectSummary(LolFilter* filter)
785
- : total_count_(0),
786
- total_size_(0),
787
- found_root_(false),
788
- found_weak_root_(false),
789
- filter_(filter) {
790
- memset(counts_, 0, sizeof(counts_[0]) * kNumberOfEntries);
791
- memset(sizes_, 0, sizeof(sizes_[0]) * kNumberOfEntries);
792
- }
793
-
794
- void Add(HeapObject* heap_obj) {
795
- int size = heap_obj->Size();
796
- LiveObjectType type = GetObjectType(heap_obj);
797
- ASSERT(type != kInvalidLiveObjType);
798
- counts_[type]++;
799
- sizes_[type] += size;
800
- total_count_++;
801
- total_size_ += size;
802
- }
803
-
804
- void set_found_root() { found_root_ = true; }
805
- void set_found_weak_root() { found_weak_root_ = true; }
806
-
807
- inline int Count(LiveObjectType type) {
808
- return counts_[type];
809
- }
810
- inline int Size(LiveObjectType type) {
811
- return sizes_[type];
812
- }
813
- inline int total_count() {
814
- return total_count_;
815
- }
816
- inline int total_size() {
817
- return total_size_;
818
- }
819
- inline bool found_root() {
820
- return found_root_;
821
- }
822
- inline bool found_weak_root() {
823
- return found_weak_root_;
824
- }
825
- int GetNumberOfEntries() {
826
- int entries = 0;
827
- for (int i = 0; i < kNumberOfEntries; i++) {
828
- if (counts_[i]) entries++;
829
- }
830
- return entries;
831
- }
832
-
833
- inline LolFilter* filter() { return filter_; }
834
-
835
- static const int kNumberOfEntries = kNumberOfTypes;
836
-
837
- private:
838
- int counts_[kNumberOfEntries];
839
- int sizes_[kNumberOfEntries];
840
- int total_count_;
841
- int total_size_;
842
- bool found_root_;
843
- bool found_weak_root_;
844
-
845
- LolFilter* filter_;
846
- };
847
-
848
-
849
- // Abstraction for a summary writer.
850
- class SummaryWriter {
851
- public:
852
- virtual ~SummaryWriter() {}
853
- virtual void Write(LiveObjectSummary* summary) = 0;
854
- };
855
-
856
-
857
- // A summary writer for filling in a summary of lol lists and diffs.
858
- class LolSummaryWriter: public SummaryWriter {
859
- public:
860
- LolSummaryWriter(LiveObjectList* older_lol,
861
- LiveObjectList* newer_lol)
862
- : older_(older_lol), newer_(newer_lol) {
863
- }
864
-
865
- void Write(LiveObjectSummary* summary) {
866
- LolFilter* filter = summary->filter();
867
-
868
- // Fill the summary with the lol object details.
869
- LolIterator it(older_, newer_);
870
- for (it.Init(); !it.Done(); it.Next()) {
871
- HeapObject* heap_obj = it.Obj();
872
- if (!filter->Matches(heap_obj)) {
873
- continue;
874
- }
875
- summary->Add(heap_obj);
876
- }
877
- }
878
-
879
- private:
880
- LiveObjectList* older_;
881
- LiveObjectList* newer_;
882
- };
883
-
884
-
885
- // A summary writer for filling in a retainers list.
886
- class RetainersSummaryWriter: public SummaryWriter {
887
- public:
888
- RetainersSummaryWriter(Handle<HeapObject> target,
889
- Handle<JSObject> instance_filter,
890
- Handle<JSFunction> args_function)
891
- : target_(target),
892
- instance_filter_(instance_filter),
893
- args_function_(args_function) {
894
- }
895
-
896
- void Write(LiveObjectSummary* summary) {
897
- Handle<FixedArray> retainers_arr;
898
- Handle<Object> error;
899
- int dummy_total_count;
900
- LiveObjectList::GetRetainers(target_,
901
- instance_filter_,
902
- retainers_arr,
903
- 0,
904
- Smi::kMaxValue,
905
- &dummy_total_count,
906
- summary->filter(),
907
- summary,
908
- *args_function_,
909
- error);
910
- }
911
-
912
- private:
913
- Handle<HeapObject> target_;
914
- Handle<JSObject> instance_filter_;
915
- Handle<JSFunction> args_function_;
916
- };
917
-
918
-
919
- uint32_t LiveObjectList::next_element_id_ = 1;
920
- int LiveObjectList::list_count_ = 0;
921
- int LiveObjectList::last_id_ = 0;
922
- LiveObjectList* LiveObjectList::first_ = NULL;
923
- LiveObjectList* LiveObjectList::last_ = NULL;
924
-
925
-
926
- LiveObjectList::LiveObjectList(LiveObjectList* prev, int capacity)
927
- : prev_(prev),
928
- next_(NULL),
929
- capacity_(capacity),
930
- obj_count_(0) {
931
- elements_ = NewArray<Element>(capacity);
932
- id_ = ++last_id_;
933
-
934
- list_count_++;
935
- }
936
-
937
-
938
- LiveObjectList::~LiveObjectList() {
939
- DeleteArray<Element>(elements_);
940
- delete prev_;
941
- }
942
-
943
-
944
- int LiveObjectList::GetTotalObjCountAndSize(int* size_p) {
945
- int size = 0;
946
- int count = 0;
947
- LiveObjectList* lol = this;
948
- do {
949
- // Only compute total size if requested i.e. when size_p is not null.
950
- if (size_p != NULL) {
951
- Element* elements = lol->elements_;
952
- for (int i = 0; i < lol->obj_count_; i++) {
953
- HeapObject* heap_obj = elements[i].obj_;
954
- size += heap_obj->Size();
955
- }
956
- }
957
- count += lol->obj_count_;
958
- lol = lol->prev_;
959
- } while (lol != NULL);
960
-
961
- if (size_p != NULL) {
962
- *size_p = size;
963
- }
964
- return count;
965
- }
966
-
967
-
968
- // Adds an object to the lol.
969
- // Returns true if successful, else returns false.
970
- bool LiveObjectList::Add(HeapObject* obj) {
971
- // If the object is already accounted for in the prev list which we inherit
972
- // from, then no need to add it to this list.
973
- if ((prev() != NULL) && (prev()->Find(obj) != NULL)) {
974
- return true;
975
- }
976
- ASSERT(obj_count_ <= capacity_);
977
- if (obj_count_ == capacity_) {
978
- // The heap must have grown and we have more objects than capacity to store
979
- // them.
980
- return false; // Fail this addition.
981
- }
982
- Element& element = elements_[obj_count_++];
983
- element.id_ = next_element_id_++;
984
- element.obj_ = obj;
985
- return true;
986
- }
987
-
988
-
989
- // Comparator used for sorting and searching the lol.
990
- int LiveObjectList::CompareElement(const Element* a, const Element* b) {
991
- const HeapObject* obj1 = a->obj_;
992
- const HeapObject* obj2 = b->obj_;
993
- // For lol elements, it doesn't matter which comes first if 2 elements point
994
- // to the same object (which gets culled later). Hence, we only care about
995
- // the the greater than / less than relationships.
996
- return (obj1 > obj2) ? 1 : (obj1 == obj2) ? 0 : -1;
997
- }
998
-
999
-
1000
- // Looks for the specified object in the lol, and returns its element if found.
1001
- LiveObjectList::Element* LiveObjectList::Find(HeapObject* obj) {
1002
- LiveObjectList* lol = this;
1003
- Element key;
1004
- Element* result = NULL;
1005
-
1006
- key.obj_ = obj;
1007
- // Iterate through the chain of lol's to look for the object.
1008
- while ((result == NULL) && (lol != NULL)) {
1009
- result = reinterpret_cast<Element*>(
1010
- bsearch(&key, lol->elements_, lol->obj_count_,
1011
- sizeof(Element),
1012
- reinterpret_cast<RawComparer>(CompareElement)));
1013
- lol = lol->prev_;
1014
- }
1015
- return result;
1016
- }
1017
-
1018
-
1019
- // "Nullifies" (convert the HeapObject* into an SMI) so that it will get cleaned
1020
- // up in the GCEpilogue, while preserving the sort order of the lol.
1021
- // NOTE: the lols need to be already sorted before NullifyMostRecent() is
1022
- // called.
1023
- void LiveObjectList::NullifyMostRecent(HeapObject* obj) {
1024
- LiveObjectList* lol = last();
1025
- Element key;
1026
- Element* result = NULL;
1027
-
1028
- key.obj_ = obj;
1029
- // Iterate through the chain of lol's to look for the object.
1030
- while (lol != NULL) {
1031
- result = reinterpret_cast<Element*>(
1032
- bsearch(&key, lol->elements_, lol->obj_count_,
1033
- sizeof(Element),
1034
- reinterpret_cast<RawComparer>(CompareElement)));
1035
- if (result != NULL) {
1036
- // Since there may be more than one (we are nullifying dup's after all),
1037
- // find the first in the current lol, and nullify that. The lol should
1038
- // be sorted already to make this easy (see the use of SortAll()).
1039
- int i = result - lol->elements_;
1040
-
1041
- // NOTE: we sort the lol in increasing order. So, if an object has been
1042
- // "nullified" (its lowest bit will be cleared to make it look like an
1043
- // SMI), it would/should show up before the equivalent dups that have not
1044
- // yet been "nullified". Hence, we should be searching backwards for the
1045
- // first occurence of a matching object and nullify that instance. This
1046
- // will ensure that we preserve the expected sorting order.
1047
- for (i--; i > 0; i--) {
1048
- Element* element = &lol->elements_[i];
1049
- HeapObject* curr_obj = element->obj_;
1050
- if (curr_obj != obj) {
1051
- break; // No more matches. Let's move on.
1052
- }
1053
- result = element; // Let this earlier match be the result.
1054
- }
1055
-
1056
- // Nullify the object.
1057
- NullifyNonLivePointer(&result->obj_);
1058
- return;
1059
- }
1060
- lol = lol->prev_;
1061
- }
1062
- }
1063
-
1064
-
1065
- // Sorts the lol.
1066
- void LiveObjectList::Sort() {
1067
- if (obj_count_ > 0) {
1068
- Vector<Element> elements_v(elements_, obj_count_);
1069
- elements_v.Sort(CompareElement);
1070
- }
1071
- }
1072
-
1073
-
1074
- // Sorts all captured lols starting from the latest.
1075
- void LiveObjectList::SortAll() {
1076
- LiveObjectList* lol = last();
1077
- while (lol != NULL) {
1078
- lol->Sort();
1079
- lol = lol->prev_;
1080
- }
1081
- }
1082
-
1083
-
1084
- // Counts the number of objects in the heap.
1085
- static int CountHeapObjects() {
1086
- int count = 0;
1087
- // Iterate over all the heap spaces and count the number of objects.
1088
- HeapIterator iterator;
1089
- HeapObject* heap_obj = NULL;
1090
- while ((heap_obj = iterator.next()) != NULL) {
1091
- count++;
1092
- }
1093
- return count;
1094
- }
1095
-
1096
-
1097
- // Captures a current snapshot of all objects in the heap.
1098
- MaybeObject* LiveObjectList::Capture() {
1099
- Isolate* isolate = Isolate::Current();
1100
- Factory* factory = isolate->factory();
1101
- HandleScope scope(isolate);
1102
-
1103
- // Count the number of objects in the heap.
1104
- int total_count = CountHeapObjects();
1105
- int count = total_count;
1106
- int size = 0;
1107
-
1108
- LiveObjectList* last_lol = last();
1109
- if (last_lol != NULL) {
1110
- count -= last_lol->TotalObjCount();
1111
- }
1112
-
1113
- LiveObjectList* lol;
1114
-
1115
- // Create a lol large enough to track all the objects.
1116
- lol = new LiveObjectList(last_lol, count);
1117
- if (lol == NULL) {
1118
- return NULL; // No memory to proceed.
1119
- }
1120
-
1121
- // The HeapIterator needs to be in its own scope because it disables
1122
- // allocation, and we need allocate below.
1123
- {
1124
- // Iterate over all the heap spaces and add the objects.
1125
- HeapIterator iterator;
1126
- HeapObject* heap_obj = NULL;
1127
- bool failed = false;
1128
- while (!failed && (heap_obj = iterator.next()) != NULL) {
1129
- failed = !lol->Add(heap_obj);
1130
- size += heap_obj->Size();
1131
- }
1132
- ASSERT(!failed);
1133
-
1134
- lol->Sort();
1135
-
1136
- // Add the current lol to the list of lols.
1137
- if (last_ != NULL) {
1138
- last_->next_ = lol;
1139
- } else {
1140
- first_ = lol;
1141
- }
1142
- last_ = lol;
1143
-
1144
- #ifdef VERIFY_LOL
1145
- if (FLAG_verify_lol) {
1146
- Verify(true);
1147
- }
1148
- #endif
1149
- }
1150
-
1151
- Handle<String> id_sym = factory->LookupAsciiSymbol("id");
1152
- Handle<String> count_sym = factory->LookupAsciiSymbol("count");
1153
- Handle<String> size_sym = factory->LookupAsciiSymbol("size");
1154
-
1155
- Handle<JSObject> result = factory->NewJSObject(isolate->object_function());
1156
- if (result->IsFailure()) return Object::cast(*result);
1157
-
1158
- { MaybeObject* maybe_result = result->SetProperty(*id_sym,
1159
- Smi::FromInt(lol->id()),
1160
- NONE,
1161
- kNonStrictMode);
1162
- if (maybe_result->IsFailure()) return maybe_result;
1163
- }
1164
- { MaybeObject* maybe_result = result->SetProperty(*count_sym,
1165
- Smi::FromInt(total_count),
1166
- NONE,
1167
- kNonStrictMode);
1168
- if (maybe_result->IsFailure()) return maybe_result;
1169
- }
1170
- { MaybeObject* maybe_result = result->SetProperty(*size_sym,
1171
- Smi::FromInt(size),
1172
- NONE,
1173
- kNonStrictMode);
1174
- if (maybe_result->IsFailure()) return maybe_result;
1175
- }
1176
-
1177
- return *result;
1178
- }
1179
-
1180
-
1181
- // Delete doesn't actually deletes an lol. It just marks it as invisible since
1182
- // its contents are considered to be part of subsequent lists as well. The
1183
- // only time we'll actually delete the lol is when we Reset() or if the lol is
1184
- // invisible, and its element count reaches 0.
1185
- bool LiveObjectList::Delete(int id) {
1186
- LiveObjectList* lol = last();
1187
- while (lol != NULL) {
1188
- if (lol->id() == id) {
1189
- break;
1190
- }
1191
- lol = lol->prev_;
1192
- }
1193
-
1194
- // If no lol is found for this id, then we fail to delete.
1195
- if (lol == NULL) return false;
1196
-
1197
- // Else, mark the lol as invisible i.e. id == 0.
1198
- lol->id_ = 0;
1199
- list_count_--;
1200
- ASSERT(list_count_ >= 0);
1201
- if (lol->obj_count_ == 0) {
1202
- // Point the next lol's prev to this lol's prev.
1203
- LiveObjectList* next = lol->next_;
1204
- LiveObjectList* prev = lol->prev_;
1205
- // Point next's prev to prev.
1206
- if (next != NULL) {
1207
- next->prev_ = lol->prev_;
1208
- } else {
1209
- last_ = lol->prev_;
1210
- }
1211
- // Point prev's next to next.
1212
- if (prev != NULL) {
1213
- prev->next_ = lol->next_;
1214
- } else {
1215
- first_ = lol->next_;
1216
- }
1217
-
1218
- lol->prev_ = NULL;
1219
- lol->next_ = NULL;
1220
-
1221
- // Delete this now empty and invisible lol.
1222
- delete lol;
1223
- }
1224
-
1225
- // Just in case we've marked everything invisible, then clean up completely.
1226
- if (list_count_ == 0) {
1227
- Reset();
1228
- }
1229
-
1230
- return true;
1231
- }
1232
-
1233
-
1234
- MaybeObject* LiveObjectList::Dump(int older_id,
1235
- int newer_id,
1236
- int start_idx,
1237
- int dump_limit,
1238
- Handle<JSObject> filter_obj) {
1239
- if ((older_id < 0) || (newer_id < 0) || (last() == NULL)) {
1240
- return Failure::Exception(); // Fail: 0 is not a valid lol id.
1241
- }
1242
- if (newer_id < older_id) {
1243
- // They are not in the expected order. Swap them.
1244
- int temp = older_id;
1245
- older_id = newer_id;
1246
- newer_id = temp;
1247
- }
1248
-
1249
- LiveObjectList* newer_lol = FindLolForId(newer_id, last());
1250
- LiveObjectList* older_lol = FindLolForId(older_id, newer_lol);
1251
-
1252
- // If the id is defined, and we can't find a LOL for it, then we have an
1253
- // invalid id.
1254
- if ((newer_id != 0) && (newer_lol == NULL)) {
1255
- return Failure::Exception(); // Fail: the newer lol id is invalid.
1256
- }
1257
- if ((older_id != 0) && (older_lol == NULL)) {
1258
- return Failure::Exception(); // Fail: the older lol id is invalid.
1259
- }
1260
-
1261
- LolFilter filter(filter_obj);
1262
- LolDumpWriter writer(older_lol, newer_lol);
1263
- return DumpPrivate(&writer, start_idx, dump_limit, &filter);
1264
- }
1265
-
1266
-
1267
- MaybeObject* LiveObjectList::DumpPrivate(DumpWriter* writer,
1268
- int start,
1269
- int dump_limit,
1270
- LolFilter* filter) {
1271
- Isolate* isolate = Isolate::Current();
1272
- Factory* factory = isolate->factory();
1273
-
1274
- HandleScope scope(isolate);
1275
-
1276
- // Calculate the number of entries of the dump.
1277
- int count = -1;
1278
- int size = -1;
1279
- writer->ComputeTotalCountAndSize(filter, &count, &size);
1280
-
1281
- // Adjust for where to start the dump.
1282
- if ((start < 0) || (start >= count)) {
1283
- return Failure::Exception(); // invalid start.
1284
- }
1285
-
1286
- int remaining_count = count - start;
1287
- if (dump_limit > remaining_count) {
1288
- dump_limit = remaining_count;
1289
- }
1290
-
1291
- // Allocate an array to hold the result.
1292
- Handle<FixedArray> elements_arr = factory->NewFixedArray(dump_limit);
1293
- if (elements_arr->IsFailure()) return Object::cast(*elements_arr);
1294
-
1295
- // Fill in the dump.
1296
- Handle<Object> error;
1297
- bool success = writer->Write(elements_arr,
1298
- start,
1299
- dump_limit,
1300
- filter,
1301
- error);
1302
- if (!success) return Object::cast(*error);
1303
-
1304
- MaybeObject* maybe_result;
1305
-
1306
- // Allocate the result body.
1307
- Handle<JSObject> body = factory->NewJSObject(isolate->object_function());
1308
- if (body->IsFailure()) return Object::cast(*body);
1309
-
1310
- // Set the updated body.count.
1311
- Handle<String> count_sym = factory->LookupAsciiSymbol("count");
1312
- maybe_result = body->SetProperty(*count_sym,
1313
- Smi::FromInt(count),
1314
- NONE,
1315
- kNonStrictMode);
1316
- if (maybe_result->IsFailure()) return maybe_result;
1317
-
1318
- // Set the updated body.size if appropriate.
1319
- if (size >= 0) {
1320
- Handle<String> size_sym = factory->LookupAsciiSymbol("size");
1321
- maybe_result = body->SetProperty(*size_sym,
1322
- Smi::FromInt(size),
1323
- NONE,
1324
- kNonStrictMode);
1325
- if (maybe_result->IsFailure()) return maybe_result;
1326
- }
1327
-
1328
- // Set body.first_index.
1329
- Handle<String> first_sym = factory->LookupAsciiSymbol("first_index");
1330
- maybe_result = body->SetProperty(*first_sym,
1331
- Smi::FromInt(start),
1332
- NONE,
1333
- kNonStrictMode);
1334
- if (maybe_result->IsFailure()) return maybe_result;
1335
-
1336
- // Allocate the JSArray of the elements.
1337
- Handle<JSObject> elements = factory->NewJSObject(isolate->array_function());
1338
- if (elements->IsFailure()) return Object::cast(*elements);
1339
-
1340
- maybe_result = Handle<JSArray>::cast(elements)->SetContent(*elements_arr);
1341
- if (maybe_result->IsFailure()) return maybe_result;
1342
-
1343
- // Set body.elements.
1344
- Handle<String> elements_sym = factory->LookupAsciiSymbol("elements");
1345
- maybe_result = body->SetProperty(*elements_sym,
1346
- *elements,
1347
- NONE,
1348
- kNonStrictMode);
1349
- if (maybe_result->IsFailure()) return maybe_result;
1350
-
1351
- return *body;
1352
- }
1353
-
1354
-
1355
- MaybeObject* LiveObjectList::Summarize(int older_id,
1356
- int newer_id,
1357
- Handle<JSObject> filter_obj) {
1358
- if ((older_id < 0) || (newer_id < 0) || (last() == NULL)) {
1359
- return Failure::Exception(); // Fail: 0 is not a valid lol id.
1360
- }
1361
- if (newer_id < older_id) {
1362
- // They are not in the expected order. Swap them.
1363
- int temp = older_id;
1364
- older_id = newer_id;
1365
- newer_id = temp;
1366
- }
1367
-
1368
- LiveObjectList* newer_lol = FindLolForId(newer_id, last());
1369
- LiveObjectList* older_lol = FindLolForId(older_id, newer_lol);
1370
-
1371
- // If the id is defined, and we can't find a LOL for it, then we have an
1372
- // invalid id.
1373
- if ((newer_id != 0) && (newer_lol == NULL)) {
1374
- return Failure::Exception(); // Fail: the newer lol id is invalid.
1375
- }
1376
- if ((older_id != 0) && (older_lol == NULL)) {
1377
- return Failure::Exception(); // Fail: the older lol id is invalid.
1378
- }
1379
-
1380
- LolFilter filter(filter_obj);
1381
- LolSummaryWriter writer(older_lol, newer_lol);
1382
- return SummarizePrivate(&writer, &filter, false);
1383
- }
1384
-
1385
-
1386
- // Creates a summary report for the debugger.
1387
- // Note: the SummaryWriter takes care of iterating over objects and filling in
1388
- // the summary.
1389
- MaybeObject* LiveObjectList::SummarizePrivate(SummaryWriter* writer,
1390
- LolFilter* filter,
1391
- bool is_tracking_roots) {
1392
- HandleScope scope;
1393
- MaybeObject* maybe_result;
1394
-
1395
- LiveObjectSummary summary(filter);
1396
- writer->Write(&summary);
1397
-
1398
- Isolate* isolate = Isolate::Current();
1399
- Factory* factory = isolate->factory();
1400
-
1401
- // The result body will look like this:
1402
- // body: {
1403
- // count: <total_count>,
1404
- // size: <total_size>,
1405
- // found_root: <boolean>, // optional.
1406
- // found_weak_root: <boolean>, // optional.
1407
- // summary: [
1408
- // {
1409
- // desc: "<object type name>",
1410
- // count: <count>,
1411
- // size: size
1412
- // },
1413
- // ...
1414
- // ]
1415
- // }
1416
-
1417
- // Prefetch some needed symbols.
1418
- Handle<String> desc_sym = factory->LookupAsciiSymbol("desc");
1419
- Handle<String> count_sym = factory->LookupAsciiSymbol("count");
1420
- Handle<String> size_sym = factory->LookupAsciiSymbol("size");
1421
- Handle<String> summary_sym = factory->LookupAsciiSymbol("summary");
1422
-
1423
- // Allocate the summary array.
1424
- int entries_count = summary.GetNumberOfEntries();
1425
- Handle<FixedArray> summary_arr =
1426
- factory->NewFixedArray(entries_count);
1427
- if (summary_arr->IsFailure()) return Object::cast(*summary_arr);
1428
-
1429
- int idx = 0;
1430
- for (int i = 0; i < LiveObjectSummary::kNumberOfEntries; i++) {
1431
- // Allocate the summary record.
1432
- Handle<JSObject> detail = factory->NewJSObject(isolate->object_function());
1433
- if (detail->IsFailure()) return Object::cast(*detail);
1434
-
1435
- // Fill in the summary record.
1436
- LiveObjectType type = static_cast<LiveObjectType>(i);
1437
- int count = summary.Count(type);
1438
- if (count) {
1439
- const char* desc_cstr = GetObjectTypeDesc(type);
1440
- Handle<String> desc = factory->LookupAsciiSymbol(desc_cstr);
1441
- int size = summary.Size(type);
1442
-
1443
- maybe_result = detail->SetProperty(*desc_sym,
1444
- *desc,
1445
- NONE,
1446
- kNonStrictMode);
1447
- if (maybe_result->IsFailure()) return maybe_result;
1448
- maybe_result = detail->SetProperty(*count_sym,
1449
- Smi::FromInt(count),
1450
- NONE,
1451
- kNonStrictMode);
1452
- if (maybe_result->IsFailure()) return maybe_result;
1453
- maybe_result = detail->SetProperty(*size_sym,
1454
- Smi::FromInt(size),
1455
- NONE,
1456
- kNonStrictMode);
1457
- if (maybe_result->IsFailure()) return maybe_result;
1458
-
1459
- summary_arr->set(idx++, *detail);
1460
- }
1461
- }
1462
-
1463
- // Wrap the summary fixed array in a JS array.
1464
- Handle<JSObject> summary_obj =
1465
- factory->NewJSObject(isolate->array_function());
1466
- if (summary_obj->IsFailure()) return Object::cast(*summary_obj);
1467
-
1468
- maybe_result = Handle<JSArray>::cast(summary_obj)->SetContent(*summary_arr);
1469
- if (maybe_result->IsFailure()) return maybe_result;
1470
-
1471
- // Create the body object.
1472
- Handle<JSObject> body = factory->NewJSObject(isolate->object_function());
1473
- if (body->IsFailure()) return Object::cast(*body);
1474
-
1475
- // Fill out the body object.
1476
- int total_count = summary.total_count();
1477
- int total_size = summary.total_size();
1478
- maybe_result = body->SetProperty(*count_sym,
1479
- Smi::FromInt(total_count),
1480
- NONE,
1481
- kNonStrictMode);
1482
- if (maybe_result->IsFailure()) return maybe_result;
1483
-
1484
- maybe_result = body->SetProperty(*size_sym,
1485
- Smi::FromInt(total_size),
1486
- NONE,
1487
- kNonStrictMode);
1488
- if (maybe_result->IsFailure()) return maybe_result;
1489
-
1490
- if (is_tracking_roots) {
1491
- int found_root = summary.found_root();
1492
- int found_weak_root = summary.found_weak_root();
1493
- Handle<String> root_sym = factory->LookupAsciiSymbol("found_root");
1494
- Handle<String> weak_root_sym =
1495
- factory->LookupAsciiSymbol("found_weak_root");
1496
- maybe_result = body->SetProperty(*root_sym,
1497
- Smi::FromInt(found_root),
1498
- NONE,
1499
- kNonStrictMode);
1500
- if (maybe_result->IsFailure()) return maybe_result;
1501
- maybe_result = body->SetProperty(*weak_root_sym,
1502
- Smi::FromInt(found_weak_root),
1503
- NONE,
1504
- kNonStrictMode);
1505
- if (maybe_result->IsFailure()) return maybe_result;
1506
- }
1507
-
1508
- maybe_result = body->SetProperty(*summary_sym,
1509
- *summary_obj,
1510
- NONE,
1511
- kNonStrictMode);
1512
- if (maybe_result->IsFailure()) return maybe_result;
1513
-
1514
- return *body;
1515
- }
1516
-
1517
-
1518
- // Returns an array listing the captured lols.
1519
- // Note: only dumps the section starting at start_idx and only up to
1520
- // dump_limit entries.
1521
- MaybeObject* LiveObjectList::Info(int start_idx, int dump_limit) {
1522
- Isolate* isolate = Isolate::Current();
1523
- Factory* factory = isolate->factory();
1524
-
1525
- HandleScope scope(isolate);
1526
- MaybeObject* maybe_result;
1527
-
1528
- int total_count = LiveObjectList::list_count();
1529
- int dump_count = total_count;
1530
-
1531
- // Adjust for where to start the dump.
1532
- if (total_count == 0) {
1533
- start_idx = 0; // Ensure this to get an empty list.
1534
- } else if ((start_idx < 0) || (start_idx >= total_count)) {
1535
- return Failure::Exception(); // invalid start.
1536
- }
1537
- dump_count -= start_idx;
1538
-
1539
- // Adjust for the dump limit.
1540
- if (dump_count > dump_limit) {
1541
- dump_count = dump_limit;
1542
- }
1543
-
1544
- // Allocate an array to hold the result.
1545
- Handle<FixedArray> list = factory->NewFixedArray(dump_count);
1546
- if (list->IsFailure()) return Object::cast(*list);
1547
-
1548
- // Prefetch some needed symbols.
1549
- Handle<String> id_sym = factory->LookupAsciiSymbol("id");
1550
- Handle<String> count_sym = factory->LookupAsciiSymbol("count");
1551
- Handle<String> size_sym = factory->LookupAsciiSymbol("size");
1552
-
1553
- // Fill the array with the lol details.
1554
- int idx = 0;
1555
- LiveObjectList* lol = first_;
1556
- while ((lol != NULL) && (idx < start_idx)) { // Skip tail entries.
1557
- if (lol->id() != 0) {
1558
- idx++;
1559
- }
1560
- lol = lol->next();
1561
- }
1562
- idx = 0;
1563
- while ((lol != NULL) && (dump_limit != 0)) {
1564
- if (lol->id() != 0) {
1565
- int count;
1566
- int size;
1567
- count = lol->GetTotalObjCountAndSize(&size);
1568
-
1569
- Handle<JSObject> detail =
1570
- factory->NewJSObject(isolate->object_function());
1571
- if (detail->IsFailure()) return Object::cast(*detail);
1572
-
1573
- maybe_result = detail->SetProperty(*id_sym,
1574
- Smi::FromInt(lol->id()),
1575
- NONE,
1576
- kNonStrictMode);
1577
- if (maybe_result->IsFailure()) return maybe_result;
1578
- maybe_result = detail->SetProperty(*count_sym,
1579
- Smi::FromInt(count),
1580
- NONE,
1581
- kNonStrictMode);
1582
- if (maybe_result->IsFailure()) return maybe_result;
1583
- maybe_result = detail->SetProperty(*size_sym,
1584
- Smi::FromInt(size),
1585
- NONE,
1586
- kNonStrictMode);
1587
- if (maybe_result->IsFailure()) return maybe_result;
1588
- list->set(idx++, *detail);
1589
- dump_limit--;
1590
- }
1591
- lol = lol->next();
1592
- }
1593
-
1594
- // Return the result as a JS array.
1595
- Handle<JSObject> lols = factory->NewJSObject(isolate->array_function());
1596
-
1597
- maybe_result = Handle<JSArray>::cast(lols)->SetContent(*list);
1598
- if (maybe_result->IsFailure()) return maybe_result;
1599
-
1600
- Handle<JSObject> result = factory->NewJSObject(isolate->object_function());
1601
- if (result->IsFailure()) return Object::cast(*result);
1602
-
1603
- maybe_result = result->SetProperty(*count_sym,
1604
- Smi::FromInt(total_count),
1605
- NONE,
1606
- kNonStrictMode);
1607
- if (maybe_result->IsFailure()) return maybe_result;
1608
-
1609
- Handle<String> first_sym = factory->LookupAsciiSymbol("first_index");
1610
- maybe_result = result->SetProperty(*first_sym,
1611
- Smi::FromInt(start_idx),
1612
- NONE,
1613
- kNonStrictMode);
1614
- if (maybe_result->IsFailure()) return maybe_result;
1615
-
1616
- Handle<String> lists_sym = factory->LookupAsciiSymbol("lists");
1617
- maybe_result = result->SetProperty(*lists_sym,
1618
- *lols,
1619
- NONE,
1620
- kNonStrictMode);
1621
- if (maybe_result->IsFailure()) return maybe_result;
1622
-
1623
- return *result;
1624
- }
1625
-
1626
-
1627
- // Deletes all captured lols.
1628
- void LiveObjectList::Reset() {
1629
- LiveObjectList* lol = last();
1630
- // Just delete the last. Each lol will delete it's prev automatically.
1631
- delete lol;
1632
-
1633
- next_element_id_ = 1;
1634
- list_count_ = 0;
1635
- last_id_ = 0;
1636
- first_ = NULL;
1637
- last_ = NULL;
1638
- }
1639
-
1640
-
1641
- // Gets the object for the specified obj id.
1642
- Object* LiveObjectList::GetObj(int obj_id) {
1643
- Element* element = FindElementFor<int>(GetElementId, obj_id);
1644
- if (element != NULL) {
1645
- return Object::cast(element->obj_);
1646
- }
1647
- return HEAP->undefined_value();
1648
- }
1649
-
1650
-
1651
- // Gets the obj id for the specified address if valid.
1652
- int LiveObjectList::GetObjId(Object* obj) {
1653
- // Make a heap object pointer from the address.
1654
- HeapObject* hobj = HeapObject::cast(obj);
1655
- Element* element = FindElementFor<HeapObject*>(GetElementObj, hobj);
1656
- if (element != NULL) {
1657
- return element->id_;
1658
- }
1659
- return 0; // Invalid address.
1660
- }
1661
-
1662
-
1663
- // Gets the obj id for the specified address if valid.
1664
- Object* LiveObjectList::GetObjId(Handle<String> address) {
1665
- SmartArrayPointer<char> addr_str =
1666
- address->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
1667
-
1668
- Isolate* isolate = Isolate::Current();
1669
-
1670
- // Extract the address value from the string.
1671
- int value =
1672
- static_cast<int>(StringToInt(isolate->unicode_cache(), *address, 16));
1673
- Object* obj = reinterpret_cast<Object*>(value);
1674
- return Smi::FromInt(GetObjId(obj));
1675
- }
1676
-
1677
-
1678
- // Helper class for copying HeapObjects.
1679
- class LolVisitor: public ObjectVisitor {
1680
- public:
1681
- LolVisitor(HeapObject* target, Handle<HeapObject> handle_to_skip)
1682
- : target_(target), handle_to_skip_(handle_to_skip), found_(false) {}
1683
-
1684
- void VisitPointer(Object** p) { CheckPointer(p); }
1685
-
1686
- void VisitPointers(Object** start, Object** end) {
1687
- // Check all HeapObject pointers in [start, end).
1688
- for (Object** p = start; !found() && p < end; p++) CheckPointer(p);
1689
- }
1690
-
1691
- inline bool found() const { return found_; }
1692
- inline bool reset() { return found_ = false; }
1693
-
1694
- private:
1695
- inline void CheckPointer(Object** p) {
1696
- Object* object = *p;
1697
- if (HeapObject::cast(object) == target_) {
1698
- // We may want to skip this handle because the handle may be a local
1699
- // handle in a handle scope in one of our callers. Once we return,
1700
- // that handle will be popped. Hence, we don't want to count it as
1701
- // a root that would have kept the target object alive.
1702
- if (!handle_to_skip_.is_null() &&
1703
- handle_to_skip_.location() == reinterpret_cast<HeapObject**>(p)) {
1704
- return; // Skip this handle.
1705
- }
1706
- found_ = true;
1707
- }
1708
- }
1709
-
1710
- HeapObject* target_;
1711
- Handle<HeapObject> handle_to_skip_;
1712
- bool found_;
1713
- };
1714
-
1715
-
1716
- inline bool AddRootRetainerIfFound(const LolVisitor& visitor,
1717
- LolFilter* filter,
1718
- LiveObjectSummary* summary,
1719
- void (*SetRootFound)(LiveObjectSummary* s),
1720
- int start,
1721
- int dump_limit,
1722
- int* total_count,
1723
- Handle<FixedArray> retainers_arr,
1724
- int* count,
1725
- int* index,
1726
- const char* root_name,
1727
- Handle<String> id_sym,
1728
- Handle<String> desc_sym,
1729
- Handle<String> size_sym,
1730
- Handle<Object> error) {
1731
- HandleScope scope;
1732
-
1733
- // Scratch handles.
1734
- Handle<JSObject> detail;
1735
- Handle<String> desc;
1736
- Handle<HeapObject> retainer;
1737
-
1738
- if (visitor.found()) {
1739
- if (!filter->is_active()) {
1740
- (*total_count)++;
1741
- if (summary) {
1742
- SetRootFound(summary);
1743
- } else if ((*total_count > start) && ((*index) < dump_limit)) {
1744
- (*count)++;
1745
- if (!retainers_arr.is_null()) {
1746
- return AddObjDetail(retainers_arr,
1747
- (*index)++,
1748
- 0,
1749
- retainer,
1750
- root_name,
1751
- id_sym,
1752
- desc_sym,
1753
- size_sym,
1754
- detail,
1755
- desc,
1756
- error);
1757
- }
1758
- }
1759
- }
1760
- }
1761
- return true;
1762
- }
1763
-
1764
-
1765
- inline void SetFoundRoot(LiveObjectSummary* summary) {
1766
- summary->set_found_root();
1767
- }
1768
-
1769
-
1770
- inline void SetFoundWeakRoot(LiveObjectSummary* summary) {
1771
- summary->set_found_weak_root();
1772
- }
1773
-
1774
-
1775
- int LiveObjectList::GetRetainers(Handle<HeapObject> target,
1776
- Handle<JSObject> instance_filter,
1777
- Handle<FixedArray> retainers_arr,
1778
- int start,
1779
- int dump_limit,
1780
- int* total_count,
1781
- LolFilter* filter,
1782
- LiveObjectSummary* summary,
1783
- JSFunction* arguments_function,
1784
- Handle<Object> error) {
1785
- HandleScope scope;
1786
-
1787
- // Scratch handles.
1788
- Handle<JSObject> detail;
1789
- Handle<String> desc;
1790
- Handle<HeapObject> retainer;
1791
-
1792
- Isolate* isolate = Isolate::Current();
1793
- Factory* factory = isolate->factory();
1794
-
1795
- // Prefetch some needed symbols.
1796
- Handle<String> id_sym = factory->LookupAsciiSymbol("id");
1797
- Handle<String> desc_sym = factory->LookupAsciiSymbol("desc");
1798
- Handle<String> size_sym = factory->LookupAsciiSymbol("size");
1799
-
1800
- NoHandleAllocation ha;
1801
- int count = 0;
1802
- int index = 0;
1803
- Handle<JSObject> last_obj;
1804
-
1805
- *total_count = 0;
1806
-
1807
- // Iterate roots.
1808
- LolVisitor lol_visitor(*target, target);
1809
- isolate->heap()->IterateStrongRoots(&lol_visitor, VISIT_ALL);
1810
- if (!AddRootRetainerIfFound(lol_visitor,
1811
- filter,
1812
- summary,
1813
- SetFoundRoot,
1814
- start,
1815
- dump_limit,
1816
- total_count,
1817
- retainers_arr,
1818
- &count,
1819
- &index,
1820
- "<root>",
1821
- id_sym,
1822
- desc_sym,
1823
- size_sym,
1824
- error)) {
1825
- return -1;
1826
- }
1827
-
1828
- lol_visitor.reset();
1829
- isolate->heap()->IterateWeakRoots(&lol_visitor, VISIT_ALL);
1830
- if (!AddRootRetainerIfFound(lol_visitor,
1831
- filter,
1832
- summary,
1833
- SetFoundWeakRoot,
1834
- start,
1835
- dump_limit,
1836
- total_count,
1837
- retainers_arr,
1838
- &count,
1839
- &index,
1840
- "<weak root>",
1841
- id_sym,
1842
- desc_sym,
1843
- size_sym,
1844
- error)) {
1845
- return -1;
1846
- }
1847
-
1848
- // Iterate the live object lists.
1849
- LolIterator it(NULL, last());
1850
- for (it.Init(); !it.Done() && (index < dump_limit); it.Next()) {
1851
- HeapObject* heap_obj = it.Obj();
1852
-
1853
- // Only look at all JSObjects.
1854
- if (heap_obj->IsJSObject()) {
1855
- // Skip context extension objects and argument arrays as these are
1856
- // checked in the context of functions using them.
1857
- JSObject* obj = JSObject::cast(heap_obj);
1858
- if (obj->IsJSContextExtensionObject() ||
1859
- obj->map()->constructor() == arguments_function) {
1860
- continue;
1861
- }
1862
-
1863
- // Check if the JS object has a reference to the object looked for.
1864
- if (obj->ReferencesObject(*target)) {
1865
- // Check instance filter if supplied. This is normally used to avoid
1866
- // references from mirror objects (see Runtime_IsInPrototypeChain).
1867
- if (!instance_filter->IsUndefined()) {
1868
- Object* V = obj;
1869
- while (true) {
1870
- Object* prototype = V->GetPrototype();
1871
- if (prototype->IsNull()) {
1872
- break;
1873
- }
1874
- if (*instance_filter == prototype) {
1875
- obj = NULL; // Don't add this object.
1876
- break;
1877
- }
1878
- V = prototype;
1879
- }
1880
- }
1881
-
1882
- if (obj != NULL) {
1883
- // Skip objects that have been filtered out.
1884
- if (filter->Matches(heap_obj)) {
1885
- continue;
1886
- }
1887
-
1888
- // Valid reference found add to instance array if supplied an update
1889
- // count.
1890
- last_obj = Handle<JSObject>(obj);
1891
- (*total_count)++;
1892
-
1893
- if (summary != NULL) {
1894
- summary->Add(heap_obj);
1895
- } else if ((*total_count > start) && (index < dump_limit)) {
1896
- count++;
1897
- if (!retainers_arr.is_null()) {
1898
- retainer = Handle<HeapObject>(heap_obj);
1899
- bool success = AddObjDetail(retainers_arr,
1900
- index++,
1901
- it.Id(),
1902
- retainer,
1903
- NULL,
1904
- id_sym,
1905
- desc_sym,
1906
- size_sym,
1907
- detail,
1908
- desc,
1909
- error);
1910
- if (!success) return -1;
1911
- }
1912
- }
1913
- }
1914
- }
1915
- }
1916
- }
1917
-
1918
- // Check for circular reference only. This can happen when the object is only
1919
- // referenced from mirrors and has a circular reference in which case the
1920
- // object is not really alive and would have been garbage collected if not
1921
- // referenced from the mirror.
1922
-
1923
- if (*total_count == 1 && !last_obj.is_null() && *last_obj == *target) {
1924
- count = 0;
1925
- *total_count = 0;
1926
- }
1927
-
1928
- return count;
1929
- }
1930
-
1931
-
1932
- MaybeObject* LiveObjectList::GetObjRetainers(int obj_id,
1933
- Handle<JSObject> instance_filter,
1934
- bool verbose,
1935
- int start,
1936
- int dump_limit,
1937
- Handle<JSObject> filter_obj) {
1938
- Isolate* isolate = Isolate::Current();
1939
- Factory* factory = isolate->factory();
1940
- Heap* heap = isolate->heap();
1941
-
1942
- HandleScope scope(isolate);
1943
-
1944
- // Get the target object.
1945
- HeapObject* heap_obj = HeapObject::cast(GetObj(obj_id));
1946
- if (heap_obj == heap->undefined_value()) {
1947
- return heap_obj;
1948
- }
1949
-
1950
- Handle<HeapObject> target = Handle<HeapObject>(heap_obj);
1951
-
1952
- // Get the constructor function for context extension and arguments array.
1953
- JSObject* arguments_boilerplate =
1954
- isolate->context()->global_context()->arguments_boilerplate();
1955
- JSFunction* arguments_function =
1956
- JSFunction::cast(arguments_boilerplate->map()->constructor());
1957
-
1958
- Handle<JSFunction> args_function = Handle<JSFunction>(arguments_function);
1959
- LolFilter filter(filter_obj);
1960
-
1961
- if (!verbose) {
1962
- RetainersSummaryWriter writer(target, instance_filter, args_function);
1963
- return SummarizePrivate(&writer, &filter, true);
1964
-
1965
- } else {
1966
- RetainersDumpWriter writer(target, instance_filter, args_function);
1967
- Object* body_obj;
1968
- MaybeObject* maybe_result =
1969
- DumpPrivate(&writer, start, dump_limit, &filter);
1970
- if (!maybe_result->ToObject(&body_obj)) {
1971
- return maybe_result;
1972
- }
1973
-
1974
- // Set body.id.
1975
- Handle<JSObject> body = Handle<JSObject>(JSObject::cast(body_obj));
1976
- Handle<String> id_sym = factory->LookupAsciiSymbol("id");
1977
- maybe_result = body->SetProperty(*id_sym,
1978
- Smi::FromInt(obj_id),
1979
- NONE,
1980
- kNonStrictMode);
1981
- if (maybe_result->IsFailure()) return maybe_result;
1982
-
1983
- return *body;
1984
- }
1985
- }
1986
-
1987
-
1988
- Object* LiveObjectList::PrintObj(int obj_id) {
1989
- Object* obj = GetObj(obj_id);
1990
- if (!obj) {
1991
- return HEAP->undefined_value();
1992
- }
1993
-
1994
- EmbeddedVector<char, 128> temp_filename;
1995
- static int temp_count = 0;
1996
- const char* path_prefix = ".";
1997
-
1998
- Isolate* isolate = Isolate::Current();
1999
- Factory* factory = isolate->factory();
2000
- Heap* heap = isolate->heap();
2001
-
2002
- if (FLAG_lol_workdir) {
2003
- path_prefix = FLAG_lol_workdir;
2004
- }
2005
- OS::SNPrintF(temp_filename, "%s/lol-print-%d", path_prefix, ++temp_count);
2006
-
2007
- FILE* f = OS::FOpen(temp_filename.start(), "w+");
2008
-
2009
- PrintF(f, "@%d ", LiveObjectList::GetObjId(obj));
2010
- #ifdef OBJECT_PRINT
2011
- #ifdef INSPECTOR
2012
- Inspector::DumpObjectType(f, obj);
2013
- #endif // INSPECTOR
2014
- PrintF(f, "\n");
2015
- obj->Print(f);
2016
- #else // !OBJECT_PRINT
2017
- obj->ShortPrint(f);
2018
- #endif // !OBJECT_PRINT
2019
- PrintF(f, "\n");
2020
- Flush(f);
2021
- fclose(f);
2022
-
2023
- // Create a string from the temp_file.
2024
- // Note: the mmapped resource will take care of closing the file.
2025
- MemoryMappedExternalResource* resource =
2026
- new MemoryMappedExternalResource(temp_filename.start(), true);
2027
- if (resource->exists() && !resource->is_empty()) {
2028
- ASSERT(resource->IsAscii());
2029
- Handle<String> dump_string =
2030
- factory->NewExternalStringFromAscii(resource);
2031
- heap->external_string_table()->AddString(*dump_string);
2032
- return *dump_string;
2033
- } else {
2034
- delete resource;
2035
- }
2036
- return HEAP->undefined_value();
2037
- }
2038
-
2039
-
2040
- class LolPathTracer: public PathTracer {
2041
- public:
2042
- LolPathTracer(FILE* out,
2043
- Object* search_target,
2044
- WhatToFind what_to_find)
2045
- : PathTracer(search_target, what_to_find, VISIT_ONLY_STRONG), out_(out) {}
2046
-
2047
- private:
2048
- void ProcessResults();
2049
-
2050
- FILE* out_;
2051
- };
2052
-
2053
-
2054
- void LolPathTracer::ProcessResults() {
2055
- if (found_target_) {
2056
- PrintF(out_, "=====================================\n");
2057
- PrintF(out_, "==== Path to object ====\n");
2058
- PrintF(out_, "=====================================\n\n");
2059
-
2060
- ASSERT(!object_stack_.is_empty());
2061
- Object* prev = NULL;
2062
- for (int i = 0, index = 0; i < object_stack_.length(); i++) {
2063
- Object* obj = object_stack_[i];
2064
-
2065
- // Skip this object if it is basically the internals of the
2066
- // previous object (which would have dumped its details already).
2067
- if (prev && prev->IsJSObject() &&
2068
- (obj != search_target_)) {
2069
- JSObject* jsobj = JSObject::cast(prev);
2070
- if (obj->IsFixedArray() &&
2071
- jsobj->properties() == FixedArray::cast(obj)) {
2072
- // Skip this one because it would have been printed as the
2073
- // properties of the last object already.
2074
- continue;
2075
- } else if (obj->IsHeapObject() &&
2076
- jsobj->elements() == HeapObject::cast(obj)) {
2077
- // Skip this one because it would have been printed as the
2078
- // elements of the last object already.
2079
- continue;
2080
- }
2081
- }
2082
-
2083
- // Print a connecting arrow.
2084
- if (i > 0) PrintF(out_, "\n |\n |\n V\n\n");
2085
-
2086
- // Print the object index.
2087
- PrintF(out_, "[%d] ", ++index);
2088
-
2089
- // Print the LOL object ID:
2090
- int id = LiveObjectList::GetObjId(obj);
2091
- if (id > 0) PrintF(out_, "@%d ", id);
2092
-
2093
- #ifdef OBJECT_PRINT
2094
- #ifdef INSPECTOR
2095
- Inspector::DumpObjectType(out_, obj);
2096
- #endif // INSPECTOR
2097
- PrintF(out_, "\n");
2098
- obj->Print(out_);
2099
- #else // !OBJECT_PRINT
2100
- obj->ShortPrint(out_);
2101
- PrintF(out_, "\n");
2102
- #endif // !OBJECT_PRINT
2103
- Flush(out_);
2104
- }
2105
- PrintF(out_, "\n");
2106
- PrintF(out_, "=====================================\n\n");
2107
- Flush(out_);
2108
- }
2109
- }
2110
-
2111
-
2112
- Object* LiveObjectList::GetPathPrivate(HeapObject* obj1, HeapObject* obj2) {
2113
- EmbeddedVector<char, 128> temp_filename;
2114
- static int temp_count = 0;
2115
- const char* path_prefix = ".";
2116
-
2117
- if (FLAG_lol_workdir) {
2118
- path_prefix = FLAG_lol_workdir;
2119
- }
2120
- OS::SNPrintF(temp_filename, "%s/lol-getpath-%d", path_prefix, ++temp_count);
2121
-
2122
- FILE* f = OS::FOpen(temp_filename.start(), "w+");
2123
-
2124
- Isolate* isolate = Isolate::Current();
2125
- Factory* factory = isolate->factory();
2126
- Heap* heap = isolate->heap();
2127
-
2128
- // Save the previous verbosity.
2129
- bool prev_verbosity = FLAG_use_verbose_printer;
2130
- FLAG_use_verbose_printer = false;
2131
-
2132
- // Dump the paths.
2133
- {
2134
- // The tracer needs to be scoped because its usage asserts no allocation,
2135
- // and we need to allocate the result string below.
2136
- LolPathTracer tracer(f, obj2, LolPathTracer::FIND_FIRST);
2137
-
2138
- bool found = false;
2139
- if (obj1 == NULL) {
2140
- // Check for ObjectGroups that references this object.
2141
- // TODO(mlam): refactor this to be more modular.
2142
- {
2143
- List<ObjectGroup*>* groups = isolate->global_handles()->object_groups();
2144
- for (int i = 0; i < groups->length(); i++) {
2145
- ObjectGroup* group = groups->at(i);
2146
- if (group == NULL) continue;
2147
-
2148
- bool found_group = false;
2149
- for (size_t j = 0; j < group->length_; j++) {
2150
- Object* object = *(group->objects_[j]);
2151
- HeapObject* hobj = HeapObject::cast(object);
2152
- if (obj2 == hobj) {
2153
- found_group = true;
2154
- break;
2155
- }
2156
- }
2157
-
2158
- if (found_group) {
2159
- PrintF(f,
2160
- "obj %p is a member of object group %p {\n",
2161
- reinterpret_cast<void*>(obj2),
2162
- reinterpret_cast<void*>(group));
2163
- for (size_t j = 0; j < group->length_; j++) {
2164
- Object* object = *(group->objects_[j]);
2165
- if (!object->IsHeapObject()) continue;
2166
-
2167
- HeapObject* hobj = HeapObject::cast(object);
2168
- int id = GetObjId(hobj);
2169
- if (id != 0) {
2170
- PrintF(f, " @%d:", id);
2171
- } else {
2172
- PrintF(f, " <no id>:");
2173
- }
2174
-
2175
- char buffer[512];
2176
- GenerateObjectDesc(hobj, buffer, sizeof(buffer));
2177
- PrintF(f, " %s", buffer);
2178
- if (hobj == obj2) {
2179
- PrintF(f, " <===");
2180
- }
2181
- PrintF(f, "\n");
2182
- }
2183
- PrintF(f, "}\n");
2184
- }
2185
- }
2186
- }
2187
-
2188
- PrintF(f, "path from roots to obj %p\n", reinterpret_cast<void*>(obj2));
2189
- heap->IterateRoots(&tracer, VISIT_ONLY_STRONG);
2190
- found = tracer.found();
2191
-
2192
- if (!found) {
2193
- PrintF(f, " No paths found. Checking symbol tables ...\n");
2194
- SymbolTable* symbol_table = HEAP->raw_unchecked_symbol_table();
2195
- tracer.VisitPointers(reinterpret_cast<Object**>(&symbol_table),
2196
- reinterpret_cast<Object**>(&symbol_table)+1);
2197
- found = tracer.found();
2198
- if (!found) {
2199
- symbol_table->IteratePrefix(&tracer);
2200
- found = tracer.found();
2201
- }
2202
- }
2203
-
2204
- if (!found) {
2205
- PrintF(f, " No paths found. Checking weak roots ...\n");
2206
- // Check weak refs next.
2207
- isolate->global_handles()->IterateWeakRoots(&tracer);
2208
- found = tracer.found();
2209
- }
2210
-
2211
- } else {
2212
- PrintF(f, "path from obj %p to obj %p:\n",
2213
- reinterpret_cast<void*>(obj1), reinterpret_cast<void*>(obj2));
2214
- tracer.TracePathFrom(reinterpret_cast<Object**>(&obj1));
2215
- found = tracer.found();
2216
- }
2217
-
2218
- if (!found) {
2219
- PrintF(f, " No paths found\n\n");
2220
- }
2221
- }
2222
-
2223
- // Flush and clean up the dumped file.
2224
- Flush(f);
2225
- fclose(f);
2226
-
2227
- // Restore the previous verbosity.
2228
- FLAG_use_verbose_printer = prev_verbosity;
2229
-
2230
- // Create a string from the temp_file.
2231
- // Note: the mmapped resource will take care of closing the file.
2232
- MemoryMappedExternalResource* resource =
2233
- new MemoryMappedExternalResource(temp_filename.start(), true);
2234
- if (resource->exists() && !resource->is_empty()) {
2235
- ASSERT(resource->IsAscii());
2236
- Handle<String> path_string =
2237
- factory->NewExternalStringFromAscii(resource);
2238
- heap->external_string_table()->AddString(*path_string);
2239
- return *path_string;
2240
- } else {
2241
- delete resource;
2242
- }
2243
- return heap->undefined_value();
2244
- }
2245
-
2246
-
2247
- Object* LiveObjectList::GetPath(int obj_id1,
2248
- int obj_id2,
2249
- Handle<JSObject> instance_filter) {
2250
- HandleScope scope;
2251
-
2252
- // Get the target object.
2253
- HeapObject* obj1 = NULL;
2254
- if (obj_id1 != 0) {
2255
- obj1 = HeapObject::cast(GetObj(obj_id1));
2256
- if (obj1 == HEAP->undefined_value()) {
2257
- return obj1;
2258
- }
2259
- }
2260
-
2261
- HeapObject* obj2 = HeapObject::cast(GetObj(obj_id2));
2262
- if (obj2 == HEAP->undefined_value()) {
2263
- return obj2;
2264
- }
2265
-
2266
- return GetPathPrivate(obj1, obj2);
2267
- }
2268
-
2269
-
2270
- void LiveObjectList::DoProcessNonLive(HeapObject* obj) {
2271
- // We should only be called if we have at least one lol to search.
2272
- ASSERT(last() != NULL);
2273
- Element* element = last()->Find(obj);
2274
- if (element != NULL) {
2275
- NullifyNonLivePointer(&element->obj_);
2276
- }
2277
- }
2278
-
2279
-
2280
- void LiveObjectList::IterateElementsPrivate(ObjectVisitor* v) {
2281
- LiveObjectList* lol = last();
2282
- while (lol != NULL) {
2283
- Element* elements = lol->elements_;
2284
- int count = lol->obj_count_;
2285
- for (int i = 0; i < count; i++) {
2286
- HeapObject** p = &elements[i].obj_;
2287
- v->VisitPointer(reinterpret_cast<Object** >(p));
2288
- }
2289
- lol = lol->prev_;
2290
- }
2291
- }
2292
-
2293
-
2294
- // Purpose: Called by GCEpilogue to purge duplicates. Not to be called by
2295
- // anyone else.
2296
- void LiveObjectList::PurgeDuplicates() {
2297
- bool is_sorted = false;
2298
- LiveObjectList* lol = last();
2299
- if (!lol) {
2300
- return; // Nothing to purge.
2301
- }
2302
-
2303
- int total_count = lol->TotalObjCount();
2304
- if (!total_count) {
2305
- return; // Nothing to purge.
2306
- }
2307
-
2308
- Element* elements = NewArray<Element>(total_count);
2309
- int count = 0;
2310
-
2311
- // Copy all the object elements into a consecutive array.
2312
- while (lol) {
2313
- memcpy(&elements[count], lol->elements_, lol->obj_count_ * sizeof(Element));
2314
- count += lol->obj_count_;
2315
- lol = lol->prev_;
2316
- }
2317
- qsort(elements, total_count, sizeof(Element),
2318
- reinterpret_cast<RawComparer>(CompareElement));
2319
-
2320
- ASSERT(count == total_count);
2321
-
2322
- // Iterate over all objects in the consolidated list and check for dups.
2323
- total_count--;
2324
- for (int i = 0; i < total_count; ) {
2325
- Element* curr = &elements[i];
2326
- HeapObject* curr_obj = curr->obj_;
2327
- int j = i+1;
2328
- bool done = false;
2329
-
2330
- while (!done && (j < total_count)) {
2331
- // Process if the element's object is still live after the current GC.
2332
- // Non-live objects will be converted to SMIs i.e. not HeapObjects.
2333
- if (curr_obj->IsHeapObject()) {
2334
- Element* next = &elements[j];
2335
- HeapObject* next_obj = next->obj_;
2336
- if (next_obj->IsHeapObject()) {
2337
- if (curr_obj != next_obj) {
2338
- done = true;
2339
- continue; // Live object but no match. Move on.
2340
- }
2341
-
2342
- // NOTE: we've just GCed the LOLs. Hence, they are no longer sorted.
2343
- // Since we detected at least one need to search for entries, we'll
2344
- // sort it to enable the use of NullifyMostRecent() below. We only
2345
- // need to sort it once (except for one exception ... see below).
2346
- if (!is_sorted) {
2347
- SortAll();
2348
- is_sorted = true;
2349
- }
2350
-
2351
- // We have a match. Need to nullify the most recent ref to this
2352
- // object. We'll keep the oldest ref:
2353
- // Note: we will nullify the element record in the LOL
2354
- // database, not in the local sorted copy of the elements.
2355
- NullifyMostRecent(curr_obj);
2356
- }
2357
- }
2358
- // Either the object was already marked for purging, or we just marked
2359
- // it. Either way, if there's more than one dup, then we need to check
2360
- // the next element for another possible dup against the current as well
2361
- // before we move on. So, here we go.
2362
- j++;
2363
- }
2364
-
2365
- // We can move on to checking the match on the next element.
2366
- i = j;
2367
- }
2368
-
2369
- DeleteArray<Element>(elements);
2370
- }
2371
-
2372
-
2373
- // Purpose: Purges dead objects and resorts the LOLs.
2374
- void LiveObjectList::GCEpiloguePrivate() {
2375
- // Note: During the GC, ConsStrings may be collected and pointers may be
2376
- // forwarded to its constituent string. As a result, we may find dupes of
2377
- // objects references in the LOL list.
2378
- // Another common way we get dups is that free chunks that have been swept
2379
- // in the oldGen heap may be kept as ByteArray objects in a free list.
2380
- //
2381
- // When we promote live objects from the youngGen, the object may be moved
2382
- // to the start of these free chunks. Since there is no free or move event
2383
- // for the free chunks, their addresses will show up 2 times: once for their
2384
- // original free ByteArray selves, and once for the newly promoted youngGen
2385
- // object. Hence, we can get a duplicate address in the LOL again.
2386
- //
2387
- // We need to eliminate these dups because the LOL implementation expects to
2388
- // only have at most one unique LOL reference to any object at any time.
2389
- PurgeDuplicates();
2390
-
2391
- // After the GC, sweep away all free'd Elements and compact.
2392
- LiveObjectList* prev = NULL;
2393
- LiveObjectList* next = NULL;
2394
-
2395
- // Iterating from the youngest lol to the oldest lol.
2396
- for (LiveObjectList* lol = last(); lol; lol = prev) {
2397
- Element* elements = lol->elements_;
2398
- prev = lol->prev(); // Save the prev.
2399
-
2400
- // Remove any references to collected objects.
2401
- int i = 0;
2402
- while (i < lol->obj_count_) {
2403
- Element& element = elements[i];
2404
- if (!element.obj_->IsHeapObject()) {
2405
- // If the HeapObject address was converted into a SMI, then this
2406
- // is a dead object. Copy the last element over this one.
2407
- element = elements[lol->obj_count_ - 1];
2408
- lol->obj_count_--;
2409
- // We've just moved the last element into this index. We'll revisit
2410
- // this index again. Hence, no need to increment the iterator.
2411
- } else {
2412
- i++; // Look at the next element next.
2413
- }
2414
- }
2415
-
2416
- int new_count = lol->obj_count_;
2417
-
2418
- // Check if there are any more elements to keep after purging the dead ones.
2419
- if (new_count == 0) {
2420
- DeleteArray<Element>(elements);
2421
- lol->elements_ = NULL;
2422
- lol->capacity_ = 0;
2423
- ASSERT(lol->obj_count_ == 0);
2424
-
2425
- // If the list is also invisible, the clean up the list as well.
2426
- if (lol->id_ == 0) {
2427
- // Point the next lol's prev to this lol's prev.
2428
- if (next) {
2429
- next->prev_ = lol->prev_;
2430
- } else {
2431
- last_ = lol->prev_;
2432
- }
2433
-
2434
- // Delete this now empty and invisible lol.
2435
- delete lol;
2436
-
2437
- // Don't point the next to this lol since it is now deleted.
2438
- // Leave the next pointer pointing to the current lol.
2439
- continue;
2440
- }
2441
-
2442
- } else {
2443
- // If the obj_count_ is less than the capacity and the difference is
2444
- // greater than a specified threshold, then we should shrink the list.
2445
- int diff = lol->capacity_ - new_count;
2446
- const int kMaxUnusedSpace = 64;
2447
- if (diff > kMaxUnusedSpace) { // Threshold for shrinking.
2448
- // Shrink the list.
2449
- Element* new_elements = NewArray<Element>(new_count);
2450
- memcpy(new_elements, elements, new_count * sizeof(Element));
2451
-
2452
- DeleteArray<Element>(elements);
2453
- lol->elements_ = new_elements;
2454
- lol->capacity_ = new_count;
2455
- }
2456
- ASSERT(lol->obj_count_ == new_count);
2457
-
2458
- lol->Sort(); // We've moved objects. Re-sort in case.
2459
- }
2460
-
2461
- // Save the next (for the previous link) in case we need it later.
2462
- next = lol;
2463
- }
2464
-
2465
- #ifdef VERIFY_LOL
2466
- if (FLAG_verify_lol) {
2467
- Verify();
2468
- }
2469
- #endif
2470
- }
2471
-
2472
-
2473
- #ifdef VERIFY_LOL
2474
- void LiveObjectList::Verify(bool match_heap_exactly) {
2475
- OS::Print("Verifying the LiveObjectList database:\n");
2476
-
2477
- LiveObjectList* lol = last();
2478
- if (lol == NULL) {
2479
- OS::Print(" No lol database to verify\n");
2480
- return;
2481
- }
2482
-
2483
- OS::Print(" Preparing the lol database ...\n");
2484
- int total_count = lol->TotalObjCount();
2485
-
2486
- Element* elements = NewArray<Element>(total_count);
2487
- int count = 0;
2488
-
2489
- // Copy all the object elements into a consecutive array.
2490
- OS::Print(" Copying the lol database ...\n");
2491
- while (lol != NULL) {
2492
- memcpy(&elements[count], lol->elements_, lol->obj_count_ * sizeof(Element));
2493
- count += lol->obj_count_;
2494
- lol = lol->prev_;
2495
- }
2496
- qsort(elements, total_count, sizeof(Element),
2497
- reinterpret_cast<RawComparer>(CompareElement));
2498
-
2499
- ASSERT(count == total_count);
2500
-
2501
- // Iterate over all objects in the heap and check for:
2502
- // 1. object in LOL but not in heap i.e. error.
2503
- // 2. object in heap but not in LOL (possibly not an error). Usually
2504
- // just means that we don't have the a capture of the latest heap.
2505
- // That is unless we did this verify immediately after a capture,
2506
- // and specified match_heap_exactly = true.
2507
-
2508
- int number_of_heap_objects = 0;
2509
- int number_of_matches = 0;
2510
- int number_not_in_heap = total_count;
2511
- int number_not_in_lol = 0;
2512
-
2513
- OS::Print(" Start verify ...\n");
2514
- OS::Print(" Verifying ...");
2515
- Flush();
2516
- HeapIterator iterator;
2517
- HeapObject* heap_obj = NULL;
2518
- while ((heap_obj = iterator.next()) != NULL) {
2519
- number_of_heap_objects++;
2520
-
2521
- // Check if the heap_obj is in the lol.
2522
- Element key;
2523
- key.obj_ = heap_obj;
2524
-
2525
- Element* result = reinterpret_cast<Element*>(
2526
- bsearch(&key, elements, total_count, sizeof(Element),
2527
- reinterpret_cast<RawComparer>(CompareElement)));
2528
-
2529
- if (result != NULL) {
2530
- number_of_matches++;
2531
- number_not_in_heap--;
2532
- // Mark it as found by changing it into a SMI (mask off low bit).
2533
- // Note: we cannot use HeapObject::cast() here because it asserts that
2534
- // the HeapObject bit is set on the address, but we're unsetting it on
2535
- // purpose here for our marking.
2536
- result->obj_ = reinterpret_cast<HeapObject*>(heap_obj->address());
2537
-
2538
- } else {
2539
- number_not_in_lol++;
2540
- if (match_heap_exactly) {
2541
- OS::Print("heap object %p NOT in lol database\n", heap_obj);
2542
- }
2543
- }
2544
- // Show some sign of life.
2545
- if (number_of_heap_objects % 1000 == 0) {
2546
- OS::Print(".");
2547
- fflush(stdout);
2548
- }
2549
- }
2550
- OS::Print("\n");
2551
-
2552
- // Reporting lol objects not found in the heap.
2553
- if (number_not_in_heap) {
2554
- int found = 0;
2555
- for (int i = 0; (i < total_count) && (found < number_not_in_heap); i++) {
2556
- Element& element = elements[i];
2557
- if (element.obj_->IsHeapObject()) {
2558
- OS::Print("lol database object [%d of %d] %p NOT in heap\n",
2559
- i, total_count, element.obj_);
2560
- found++;
2561
- }
2562
- }
2563
- }
2564
-
2565
- DeleteArray<Element>(elements);
2566
-
2567
- OS::Print("number of objects in lol database %d\n", total_count);
2568
- OS::Print("number of heap objects .......... %d\n", number_of_heap_objects);
2569
- OS::Print("number of matches ............... %d\n", number_of_matches);
2570
- OS::Print("number NOT in heap .............. %d\n", number_not_in_heap);
2571
- OS::Print("number NOT in lol database ...... %d\n", number_not_in_lol);
2572
-
2573
- if (number_of_matches != total_count) {
2574
- OS::Print(" *** ERROR: "
2575
- "NOT all lol database objects match heap objects.\n");
2576
- }
2577
- if (number_not_in_heap != 0) {
2578
- OS::Print(" *** ERROR: %d lol database objects not found in heap.\n",
2579
- number_not_in_heap);
2580
- }
2581
- if (match_heap_exactly) {
2582
- if (!(number_not_in_lol == 0)) {
2583
- OS::Print(" *** ERROR: %d heap objects NOT found in lol database.\n",
2584
- number_not_in_lol);
2585
- }
2586
- }
2587
-
2588
- ASSERT(number_of_matches == total_count);
2589
- ASSERT(number_not_in_heap == 0);
2590
- ASSERT(number_not_in_lol == (number_of_heap_objects - total_count));
2591
- if (match_heap_exactly) {
2592
- ASSERT(total_count == number_of_heap_objects);
2593
- ASSERT(number_not_in_lol == 0);
2594
- }
2595
-
2596
- OS::Print(" Verify the lol database is sorted ...\n");
2597
- lol = last();
2598
- while (lol != NULL) {
2599
- Element* elements = lol->elements_;
2600
- for (int i = 0; i < lol->obj_count_ - 1; i++) {
2601
- if (elements[i].obj_ >= elements[i+1].obj_) {
2602
- OS::Print(" *** ERROR: lol %p obj[%d] %p > obj[%d] %p\n",
2603
- lol, i, elements[i].obj_, i+1, elements[i+1].obj_);
2604
- }
2605
- }
2606
- lol = lol->prev_;
2607
- }
2608
-
2609
- OS::Print(" DONE verifying.\n\n\n");
2610
- }
2611
-
2612
-
2613
- void LiveObjectList::VerifyNotInFromSpace() {
2614
- OS::Print("VerifyNotInFromSpace() ...\n");
2615
- LolIterator it(NULL, last());
2616
- Heap* heap = ISOLATE->heap();
2617
- int i = 0;
2618
- for (it.Init(); !it.Done(); it.Next()) {
2619
- HeapObject* heap_obj = it.Obj();
2620
- if (heap->InFromSpace(heap_obj)) {
2621
- OS::Print(" ERROR: VerifyNotInFromSpace: [%d] obj %p in From space %p\n",
2622
- i++, heap_obj, Heap::new_space()->FromSpaceStart());
2623
- }
2624
- }
2625
- }
2626
- #endif // VERIFY_LOL
2627
-
2628
-
2629
- } } // namespace v8::internal
2630
-
2631
- #endif // LIVE_OBJECT_LIST