libv8-sgonyea 3.3.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (500) hide show
  1. data/.gitignore +8 -0
  2. data/.gitmodules +3 -0
  3. data/Gemfile +4 -0
  4. data/README.md +76 -0
  5. data/Rakefile +113 -0
  6. data/ext/libv8/extconf.rb +28 -0
  7. data/lib/libv8.rb +15 -0
  8. data/lib/libv8/Makefile +30 -0
  9. data/lib/libv8/detect_cpu.rb +27 -0
  10. data/lib/libv8/fpic-on-linux-amd64.patch +13 -0
  11. data/lib/libv8/v8/.gitignore +35 -0
  12. data/lib/libv8/v8/AUTHORS +44 -0
  13. data/lib/libv8/v8/ChangeLog +2839 -0
  14. data/lib/libv8/v8/LICENSE +52 -0
  15. data/lib/libv8/v8/LICENSE.strongtalk +29 -0
  16. data/lib/libv8/v8/LICENSE.v8 +26 -0
  17. data/lib/libv8/v8/LICENSE.valgrind +45 -0
  18. data/lib/libv8/v8/SConstruct +1478 -0
  19. data/lib/libv8/v8/build/README.txt +49 -0
  20. data/lib/libv8/v8/build/all.gyp +18 -0
  21. data/lib/libv8/v8/build/armu.gypi +32 -0
  22. data/lib/libv8/v8/build/common.gypi +144 -0
  23. data/lib/libv8/v8/build/gyp_v8 +145 -0
  24. data/lib/libv8/v8/include/v8-debug.h +395 -0
  25. data/lib/libv8/v8/include/v8-preparser.h +117 -0
  26. data/lib/libv8/v8/include/v8-profiler.h +505 -0
  27. data/lib/libv8/v8/include/v8-testing.h +104 -0
  28. data/lib/libv8/v8/include/v8.h +4124 -0
  29. data/lib/libv8/v8/include/v8stdint.h +53 -0
  30. data/lib/libv8/v8/preparser/SConscript +38 -0
  31. data/lib/libv8/v8/preparser/preparser-process.cc +379 -0
  32. data/lib/libv8/v8/src/SConscript +368 -0
  33. data/lib/libv8/v8/src/accessors.cc +767 -0
  34. data/lib/libv8/v8/src/accessors.h +123 -0
  35. data/lib/libv8/v8/src/allocation-inl.h +49 -0
  36. data/lib/libv8/v8/src/allocation.cc +122 -0
  37. data/lib/libv8/v8/src/allocation.h +143 -0
  38. data/lib/libv8/v8/src/api.cc +5845 -0
  39. data/lib/libv8/v8/src/api.h +574 -0
  40. data/lib/libv8/v8/src/apinatives.js +110 -0
  41. data/lib/libv8/v8/src/apiutils.h +73 -0
  42. data/lib/libv8/v8/src/arguments.h +118 -0
  43. data/lib/libv8/v8/src/arm/assembler-arm-inl.h +353 -0
  44. data/lib/libv8/v8/src/arm/assembler-arm.cc +2661 -0
  45. data/lib/libv8/v8/src/arm/assembler-arm.h +1375 -0
  46. data/lib/libv8/v8/src/arm/builtins-arm.cc +1658 -0
  47. data/lib/libv8/v8/src/arm/code-stubs-arm.cc +6398 -0
  48. data/lib/libv8/v8/src/arm/code-stubs-arm.h +673 -0
  49. data/lib/libv8/v8/src/arm/codegen-arm.cc +52 -0
  50. data/lib/libv8/v8/src/arm/codegen-arm.h +91 -0
  51. data/lib/libv8/v8/src/arm/constants-arm.cc +152 -0
  52. data/lib/libv8/v8/src/arm/constants-arm.h +775 -0
  53. data/lib/libv8/v8/src/arm/cpu-arm.cc +120 -0
  54. data/lib/libv8/v8/src/arm/debug-arm.cc +317 -0
  55. data/lib/libv8/v8/src/arm/deoptimizer-arm.cc +754 -0
  56. data/lib/libv8/v8/src/arm/disasm-arm.cc +1506 -0
  57. data/lib/libv8/v8/src/arm/frames-arm.cc +45 -0
  58. data/lib/libv8/v8/src/arm/frames-arm.h +168 -0
  59. data/lib/libv8/v8/src/arm/full-codegen-arm.cc +4375 -0
  60. data/lib/libv8/v8/src/arm/ic-arm.cc +1562 -0
  61. data/lib/libv8/v8/src/arm/lithium-arm.cc +2206 -0
  62. data/lib/libv8/v8/src/arm/lithium-arm.h +2348 -0
  63. data/lib/libv8/v8/src/arm/lithium-codegen-arm.cc +4526 -0
  64. data/lib/libv8/v8/src/arm/lithium-codegen-arm.h +403 -0
  65. data/lib/libv8/v8/src/arm/lithium-gap-resolver-arm.cc +305 -0
  66. data/lib/libv8/v8/src/arm/lithium-gap-resolver-arm.h +84 -0
  67. data/lib/libv8/v8/src/arm/macro-assembler-arm.cc +3163 -0
  68. data/lib/libv8/v8/src/arm/macro-assembler-arm.h +1126 -0
  69. data/lib/libv8/v8/src/arm/regexp-macro-assembler-arm.cc +1287 -0
  70. data/lib/libv8/v8/src/arm/regexp-macro-assembler-arm.h +253 -0
  71. data/lib/libv8/v8/src/arm/simulator-arm.cc +3424 -0
  72. data/lib/libv8/v8/src/arm/simulator-arm.h +431 -0
  73. data/lib/libv8/v8/src/arm/stub-cache-arm.cc +4243 -0
  74. data/lib/libv8/v8/src/array.js +1366 -0
  75. data/lib/libv8/v8/src/assembler.cc +1207 -0
  76. data/lib/libv8/v8/src/assembler.h +858 -0
  77. data/lib/libv8/v8/src/ast-inl.h +112 -0
  78. data/lib/libv8/v8/src/ast.cc +1146 -0
  79. data/lib/libv8/v8/src/ast.h +2188 -0
  80. data/lib/libv8/v8/src/atomicops.h +167 -0
  81. data/lib/libv8/v8/src/atomicops_internals_arm_gcc.h +145 -0
  82. data/lib/libv8/v8/src/atomicops_internals_mips_gcc.h +169 -0
  83. data/lib/libv8/v8/src/atomicops_internals_x86_gcc.cc +133 -0
  84. data/lib/libv8/v8/src/atomicops_internals_x86_gcc.h +287 -0
  85. data/lib/libv8/v8/src/atomicops_internals_x86_macosx.h +301 -0
  86. data/lib/libv8/v8/src/atomicops_internals_x86_msvc.h +203 -0
  87. data/lib/libv8/v8/src/bignum-dtoa.cc +655 -0
  88. data/lib/libv8/v8/src/bignum-dtoa.h +81 -0
  89. data/lib/libv8/v8/src/bignum.cc +768 -0
  90. data/lib/libv8/v8/src/bignum.h +140 -0
  91. data/lib/libv8/v8/src/bootstrapper.cc +2184 -0
  92. data/lib/libv8/v8/src/bootstrapper.h +188 -0
  93. data/lib/libv8/v8/src/builtins.cc +1707 -0
  94. data/lib/libv8/v8/src/builtins.h +371 -0
  95. data/lib/libv8/v8/src/bytecodes-irregexp.h +105 -0
  96. data/lib/libv8/v8/src/cached-powers.cc +177 -0
  97. data/lib/libv8/v8/src/cached-powers.h +65 -0
  98. data/lib/libv8/v8/src/char-predicates-inl.h +94 -0
  99. data/lib/libv8/v8/src/char-predicates.h +67 -0
  100. data/lib/libv8/v8/src/checks.cc +110 -0
  101. data/lib/libv8/v8/src/checks.h +296 -0
  102. data/lib/libv8/v8/src/circular-queue-inl.h +53 -0
  103. data/lib/libv8/v8/src/circular-queue.cc +122 -0
  104. data/lib/libv8/v8/src/circular-queue.h +103 -0
  105. data/lib/libv8/v8/src/code-stubs.cc +267 -0
  106. data/lib/libv8/v8/src/code-stubs.h +1011 -0
  107. data/lib/libv8/v8/src/code.h +70 -0
  108. data/lib/libv8/v8/src/codegen.cc +231 -0
  109. data/lib/libv8/v8/src/codegen.h +84 -0
  110. data/lib/libv8/v8/src/compilation-cache.cc +540 -0
  111. data/lib/libv8/v8/src/compilation-cache.h +287 -0
  112. data/lib/libv8/v8/src/compiler.cc +786 -0
  113. data/lib/libv8/v8/src/compiler.h +312 -0
  114. data/lib/libv8/v8/src/contexts.cc +347 -0
  115. data/lib/libv8/v8/src/contexts.h +391 -0
  116. data/lib/libv8/v8/src/conversions-inl.h +106 -0
  117. data/lib/libv8/v8/src/conversions.cc +1131 -0
  118. data/lib/libv8/v8/src/conversions.h +135 -0
  119. data/lib/libv8/v8/src/counters.cc +93 -0
  120. data/lib/libv8/v8/src/counters.h +254 -0
  121. data/lib/libv8/v8/src/cpu-profiler-inl.h +101 -0
  122. data/lib/libv8/v8/src/cpu-profiler.cc +609 -0
  123. data/lib/libv8/v8/src/cpu-profiler.h +302 -0
  124. data/lib/libv8/v8/src/cpu.h +69 -0
  125. data/lib/libv8/v8/src/d8-debug.cc +367 -0
  126. data/lib/libv8/v8/src/d8-debug.h +158 -0
  127. data/lib/libv8/v8/src/d8-posix.cc +695 -0
  128. data/lib/libv8/v8/src/d8-readline.cc +130 -0
  129. data/lib/libv8/v8/src/d8-windows.cc +42 -0
  130. data/lib/libv8/v8/src/d8.cc +803 -0
  131. data/lib/libv8/v8/src/d8.gyp +91 -0
  132. data/lib/libv8/v8/src/d8.h +235 -0
  133. data/lib/libv8/v8/src/d8.js +2798 -0
  134. data/lib/libv8/v8/src/data-flow.cc +66 -0
  135. data/lib/libv8/v8/src/data-flow.h +205 -0
  136. data/lib/libv8/v8/src/date.js +1103 -0
  137. data/lib/libv8/v8/src/dateparser-inl.h +127 -0
  138. data/lib/libv8/v8/src/dateparser.cc +178 -0
  139. data/lib/libv8/v8/src/dateparser.h +266 -0
  140. data/lib/libv8/v8/src/debug-agent.cc +447 -0
  141. data/lib/libv8/v8/src/debug-agent.h +129 -0
  142. data/lib/libv8/v8/src/debug-debugger.js +2569 -0
  143. data/lib/libv8/v8/src/debug.cc +3165 -0
  144. data/lib/libv8/v8/src/debug.h +1057 -0
  145. data/lib/libv8/v8/src/deoptimizer.cc +1256 -0
  146. data/lib/libv8/v8/src/deoptimizer.h +602 -0
  147. data/lib/libv8/v8/src/disasm.h +80 -0
  148. data/lib/libv8/v8/src/disassembler.cc +343 -0
  149. data/lib/libv8/v8/src/disassembler.h +58 -0
  150. data/lib/libv8/v8/src/diy-fp.cc +58 -0
  151. data/lib/libv8/v8/src/diy-fp.h +117 -0
  152. data/lib/libv8/v8/src/double.h +238 -0
  153. data/lib/libv8/v8/src/dtoa.cc +103 -0
  154. data/lib/libv8/v8/src/dtoa.h +85 -0
  155. data/lib/libv8/v8/src/execution.cc +849 -0
  156. data/lib/libv8/v8/src/execution.h +297 -0
  157. data/lib/libv8/v8/src/extensions/experimental/break-iterator.cc +250 -0
  158. data/lib/libv8/v8/src/extensions/experimental/break-iterator.h +89 -0
  159. data/lib/libv8/v8/src/extensions/experimental/collator.cc +218 -0
  160. data/lib/libv8/v8/src/extensions/experimental/collator.h +69 -0
  161. data/lib/libv8/v8/src/extensions/experimental/experimental.gyp +94 -0
  162. data/lib/libv8/v8/src/extensions/experimental/i18n-extension.cc +78 -0
  163. data/lib/libv8/v8/src/extensions/experimental/i18n-extension.h +54 -0
  164. data/lib/libv8/v8/src/extensions/experimental/i18n-locale.cc +112 -0
  165. data/lib/libv8/v8/src/extensions/experimental/i18n-locale.h +60 -0
  166. data/lib/libv8/v8/src/extensions/experimental/i18n-utils.cc +43 -0
  167. data/lib/libv8/v8/src/extensions/experimental/i18n-utils.h +49 -0
  168. data/lib/libv8/v8/src/extensions/experimental/i18n.js +180 -0
  169. data/lib/libv8/v8/src/extensions/experimental/language-matcher.cc +251 -0
  170. data/lib/libv8/v8/src/extensions/experimental/language-matcher.h +95 -0
  171. data/lib/libv8/v8/src/extensions/externalize-string-extension.cc +141 -0
  172. data/lib/libv8/v8/src/extensions/externalize-string-extension.h +50 -0
  173. data/lib/libv8/v8/src/extensions/gc-extension.cc +58 -0
  174. data/lib/libv8/v8/src/extensions/gc-extension.h +49 -0
  175. data/lib/libv8/v8/src/factory.cc +1222 -0
  176. data/lib/libv8/v8/src/factory.h +442 -0
  177. data/lib/libv8/v8/src/fast-dtoa.cc +736 -0
  178. data/lib/libv8/v8/src/fast-dtoa.h +83 -0
  179. data/lib/libv8/v8/src/fixed-dtoa.cc +405 -0
  180. data/lib/libv8/v8/src/fixed-dtoa.h +55 -0
  181. data/lib/libv8/v8/src/flag-definitions.h +560 -0
  182. data/lib/libv8/v8/src/flags.cc +551 -0
  183. data/lib/libv8/v8/src/flags.h +79 -0
  184. data/lib/libv8/v8/src/frames-inl.h +247 -0
  185. data/lib/libv8/v8/src/frames.cc +1243 -0
  186. data/lib/libv8/v8/src/frames.h +870 -0
  187. data/lib/libv8/v8/src/full-codegen.cc +1374 -0
  188. data/lib/libv8/v8/src/full-codegen.h +771 -0
  189. data/lib/libv8/v8/src/func-name-inferrer.cc +92 -0
  190. data/lib/libv8/v8/src/func-name-inferrer.h +111 -0
  191. data/lib/libv8/v8/src/gdb-jit.cc +1555 -0
  192. data/lib/libv8/v8/src/gdb-jit.h +143 -0
  193. data/lib/libv8/v8/src/global-handles.cc +665 -0
  194. data/lib/libv8/v8/src/global-handles.h +284 -0
  195. data/lib/libv8/v8/src/globals.h +325 -0
  196. data/lib/libv8/v8/src/handles-inl.h +177 -0
  197. data/lib/libv8/v8/src/handles.cc +987 -0
  198. data/lib/libv8/v8/src/handles.h +382 -0
  199. data/lib/libv8/v8/src/hashmap.cc +230 -0
  200. data/lib/libv8/v8/src/hashmap.h +123 -0
  201. data/lib/libv8/v8/src/heap-inl.h +704 -0
  202. data/lib/libv8/v8/src/heap-profiler.cc +1173 -0
  203. data/lib/libv8/v8/src/heap-profiler.h +397 -0
  204. data/lib/libv8/v8/src/heap.cc +5930 -0
  205. data/lib/libv8/v8/src/heap.h +2268 -0
  206. data/lib/libv8/v8/src/hydrogen-instructions.cc +1769 -0
  207. data/lib/libv8/v8/src/hydrogen-instructions.h +3971 -0
  208. data/lib/libv8/v8/src/hydrogen.cc +6239 -0
  209. data/lib/libv8/v8/src/hydrogen.h +1202 -0
  210. data/lib/libv8/v8/src/ia32/assembler-ia32-inl.h +446 -0
  211. data/lib/libv8/v8/src/ia32/assembler-ia32.cc +2487 -0
  212. data/lib/libv8/v8/src/ia32/assembler-ia32.h +1144 -0
  213. data/lib/libv8/v8/src/ia32/builtins-ia32.cc +1621 -0
  214. data/lib/libv8/v8/src/ia32/code-stubs-ia32.cc +6198 -0
  215. data/lib/libv8/v8/src/ia32/code-stubs-ia32.h +517 -0
  216. data/lib/libv8/v8/src/ia32/codegen-ia32.cc +265 -0
  217. data/lib/libv8/v8/src/ia32/codegen-ia32.h +79 -0
  218. data/lib/libv8/v8/src/ia32/cpu-ia32.cc +88 -0
  219. data/lib/libv8/v8/src/ia32/debug-ia32.cc +312 -0
  220. data/lib/libv8/v8/src/ia32/deoptimizer-ia32.cc +774 -0
  221. data/lib/libv8/v8/src/ia32/disasm-ia32.cc +1628 -0
  222. data/lib/libv8/v8/src/ia32/frames-ia32.cc +45 -0
  223. data/lib/libv8/v8/src/ia32/frames-ia32.h +142 -0
  224. data/lib/libv8/v8/src/ia32/full-codegen-ia32.cc +4338 -0
  225. data/lib/libv8/v8/src/ia32/ic-ia32.cc +1597 -0
  226. data/lib/libv8/v8/src/ia32/lithium-codegen-ia32.cc +4461 -0
  227. data/lib/libv8/v8/src/ia32/lithium-codegen-ia32.h +375 -0
  228. data/lib/libv8/v8/src/ia32/lithium-gap-resolver-ia32.cc +475 -0
  229. data/lib/libv8/v8/src/ia32/lithium-gap-resolver-ia32.h +110 -0
  230. data/lib/libv8/v8/src/ia32/lithium-ia32.cc +2261 -0
  231. data/lib/libv8/v8/src/ia32/lithium-ia32.h +2396 -0
  232. data/lib/libv8/v8/src/ia32/macro-assembler-ia32.cc +2136 -0
  233. data/lib/libv8/v8/src/ia32/macro-assembler-ia32.h +775 -0
  234. data/lib/libv8/v8/src/ia32/regexp-macro-assembler-ia32.cc +1263 -0
  235. data/lib/libv8/v8/src/ia32/regexp-macro-assembler-ia32.h +216 -0
  236. data/lib/libv8/v8/src/ia32/simulator-ia32.cc +30 -0
  237. data/lib/libv8/v8/src/ia32/simulator-ia32.h +74 -0
  238. data/lib/libv8/v8/src/ia32/stub-cache-ia32.cc +3847 -0
  239. data/lib/libv8/v8/src/ic-inl.h +130 -0
  240. data/lib/libv8/v8/src/ic.cc +2577 -0
  241. data/lib/libv8/v8/src/ic.h +736 -0
  242. data/lib/libv8/v8/src/inspector.cc +63 -0
  243. data/lib/libv8/v8/src/inspector.h +62 -0
  244. data/lib/libv8/v8/src/interpreter-irregexp.cc +659 -0
  245. data/lib/libv8/v8/src/interpreter-irregexp.h +49 -0
  246. data/lib/libv8/v8/src/isolate-inl.h +50 -0
  247. data/lib/libv8/v8/src/isolate.cc +1869 -0
  248. data/lib/libv8/v8/src/isolate.h +1382 -0
  249. data/lib/libv8/v8/src/json-parser.cc +504 -0
  250. data/lib/libv8/v8/src/json-parser.h +161 -0
  251. data/lib/libv8/v8/src/json.js +342 -0
  252. data/lib/libv8/v8/src/jsregexp.cc +5385 -0
  253. data/lib/libv8/v8/src/jsregexp.h +1492 -0
  254. data/lib/libv8/v8/src/list-inl.h +212 -0
  255. data/lib/libv8/v8/src/list.h +174 -0
  256. data/lib/libv8/v8/src/lithium-allocator-inl.h +142 -0
  257. data/lib/libv8/v8/src/lithium-allocator.cc +2123 -0
  258. data/lib/libv8/v8/src/lithium-allocator.h +630 -0
  259. data/lib/libv8/v8/src/lithium.cc +190 -0
  260. data/lib/libv8/v8/src/lithium.h +597 -0
  261. data/lib/libv8/v8/src/liveedit-debugger.js +1082 -0
  262. data/lib/libv8/v8/src/liveedit.cc +1691 -0
  263. data/lib/libv8/v8/src/liveedit.h +180 -0
  264. data/lib/libv8/v8/src/liveobjectlist-inl.h +126 -0
  265. data/lib/libv8/v8/src/liveobjectlist.cc +2589 -0
  266. data/lib/libv8/v8/src/liveobjectlist.h +322 -0
  267. data/lib/libv8/v8/src/log-inl.h +59 -0
  268. data/lib/libv8/v8/src/log-utils.cc +428 -0
  269. data/lib/libv8/v8/src/log-utils.h +231 -0
  270. data/lib/libv8/v8/src/log.cc +1993 -0
  271. data/lib/libv8/v8/src/log.h +476 -0
  272. data/lib/libv8/v8/src/macro-assembler.h +120 -0
  273. data/lib/libv8/v8/src/macros.py +178 -0
  274. data/lib/libv8/v8/src/mark-compact.cc +3143 -0
  275. data/lib/libv8/v8/src/mark-compact.h +506 -0
  276. data/lib/libv8/v8/src/math.js +264 -0
  277. data/lib/libv8/v8/src/messages.cc +179 -0
  278. data/lib/libv8/v8/src/messages.h +113 -0
  279. data/lib/libv8/v8/src/messages.js +1096 -0
  280. data/lib/libv8/v8/src/mips/assembler-mips-inl.h +312 -0
  281. data/lib/libv8/v8/src/mips/assembler-mips.cc +1960 -0
  282. data/lib/libv8/v8/src/mips/assembler-mips.h +1138 -0
  283. data/lib/libv8/v8/src/mips/builtins-mips.cc +1628 -0
  284. data/lib/libv8/v8/src/mips/code-stubs-mips.cc +6656 -0
  285. data/lib/libv8/v8/src/mips/code-stubs-mips.h +682 -0
  286. data/lib/libv8/v8/src/mips/codegen-mips.cc +52 -0
  287. data/lib/libv8/v8/src/mips/codegen-mips.h +98 -0
  288. data/lib/libv8/v8/src/mips/constants-mips.cc +352 -0
  289. data/lib/libv8/v8/src/mips/constants-mips.h +739 -0
  290. data/lib/libv8/v8/src/mips/cpu-mips.cc +96 -0
  291. data/lib/libv8/v8/src/mips/debug-mips.cc +308 -0
  292. data/lib/libv8/v8/src/mips/deoptimizer-mips.cc +91 -0
  293. data/lib/libv8/v8/src/mips/disasm-mips.cc +1050 -0
  294. data/lib/libv8/v8/src/mips/frames-mips.cc +47 -0
  295. data/lib/libv8/v8/src/mips/frames-mips.h +219 -0
  296. data/lib/libv8/v8/src/mips/full-codegen-mips.cc +4388 -0
  297. data/lib/libv8/v8/src/mips/ic-mips.cc +1580 -0
  298. data/lib/libv8/v8/src/mips/lithium-codegen-mips.h +65 -0
  299. data/lib/libv8/v8/src/mips/lithium-mips.h +307 -0
  300. data/lib/libv8/v8/src/mips/macro-assembler-mips.cc +4056 -0
  301. data/lib/libv8/v8/src/mips/macro-assembler-mips.h +1214 -0
  302. data/lib/libv8/v8/src/mips/regexp-macro-assembler-mips.cc +1251 -0
  303. data/lib/libv8/v8/src/mips/regexp-macro-assembler-mips.h +252 -0
  304. data/lib/libv8/v8/src/mips/simulator-mips.cc +2621 -0
  305. data/lib/libv8/v8/src/mips/simulator-mips.h +401 -0
  306. data/lib/libv8/v8/src/mips/stub-cache-mips.cc +4285 -0
  307. data/lib/libv8/v8/src/mirror-debugger.js +2382 -0
  308. data/lib/libv8/v8/src/mksnapshot.cc +328 -0
  309. data/lib/libv8/v8/src/natives.h +64 -0
  310. data/lib/libv8/v8/src/objects-debug.cc +738 -0
  311. data/lib/libv8/v8/src/objects-inl.h +4323 -0
  312. data/lib/libv8/v8/src/objects-printer.cc +829 -0
  313. data/lib/libv8/v8/src/objects-visiting.cc +148 -0
  314. data/lib/libv8/v8/src/objects-visiting.h +424 -0
  315. data/lib/libv8/v8/src/objects.cc +10585 -0
  316. data/lib/libv8/v8/src/objects.h +6838 -0
  317. data/lib/libv8/v8/src/parser.cc +4997 -0
  318. data/lib/libv8/v8/src/parser.h +765 -0
  319. data/lib/libv8/v8/src/platform-cygwin.cc +779 -0
  320. data/lib/libv8/v8/src/platform-freebsd.cc +826 -0
  321. data/lib/libv8/v8/src/platform-linux.cc +1149 -0
  322. data/lib/libv8/v8/src/platform-macos.cc +830 -0
  323. data/lib/libv8/v8/src/platform-nullos.cc +479 -0
  324. data/lib/libv8/v8/src/platform-openbsd.cc +640 -0
  325. data/lib/libv8/v8/src/platform-posix.cc +424 -0
  326. data/lib/libv8/v8/src/platform-solaris.cc +762 -0
  327. data/lib/libv8/v8/src/platform-tls-mac.h +62 -0
  328. data/lib/libv8/v8/src/platform-tls-win32.h +62 -0
  329. data/lib/libv8/v8/src/platform-tls.h +50 -0
  330. data/lib/libv8/v8/src/platform-win32.cc +2021 -0
  331. data/lib/libv8/v8/src/platform.h +667 -0
  332. data/lib/libv8/v8/src/preparse-data-format.h +62 -0
  333. data/lib/libv8/v8/src/preparse-data.cc +183 -0
  334. data/lib/libv8/v8/src/preparse-data.h +225 -0
  335. data/lib/libv8/v8/src/preparser-api.cc +220 -0
  336. data/lib/libv8/v8/src/preparser.cc +1450 -0
  337. data/lib/libv8/v8/src/preparser.h +493 -0
  338. data/lib/libv8/v8/src/prettyprinter.cc +1493 -0
  339. data/lib/libv8/v8/src/prettyprinter.h +223 -0
  340. data/lib/libv8/v8/src/profile-generator-inl.h +128 -0
  341. data/lib/libv8/v8/src/profile-generator.cc +3098 -0
  342. data/lib/libv8/v8/src/profile-generator.h +1126 -0
  343. data/lib/libv8/v8/src/property.cc +105 -0
  344. data/lib/libv8/v8/src/property.h +365 -0
  345. data/lib/libv8/v8/src/proxy.js +83 -0
  346. data/lib/libv8/v8/src/regexp-macro-assembler-irregexp-inl.h +78 -0
  347. data/lib/libv8/v8/src/regexp-macro-assembler-irregexp.cc +471 -0
  348. data/lib/libv8/v8/src/regexp-macro-assembler-irregexp.h +142 -0
  349. data/lib/libv8/v8/src/regexp-macro-assembler-tracer.cc +373 -0
  350. data/lib/libv8/v8/src/regexp-macro-assembler-tracer.h +104 -0
  351. data/lib/libv8/v8/src/regexp-macro-assembler.cc +267 -0
  352. data/lib/libv8/v8/src/regexp-macro-assembler.h +243 -0
  353. data/lib/libv8/v8/src/regexp-stack.cc +111 -0
  354. data/lib/libv8/v8/src/regexp-stack.h +147 -0
  355. data/lib/libv8/v8/src/regexp.js +483 -0
  356. data/lib/libv8/v8/src/rewriter.cc +360 -0
  357. data/lib/libv8/v8/src/rewriter.h +50 -0
  358. data/lib/libv8/v8/src/runtime-profiler.cc +489 -0
  359. data/lib/libv8/v8/src/runtime-profiler.h +201 -0
  360. data/lib/libv8/v8/src/runtime.cc +12227 -0
  361. data/lib/libv8/v8/src/runtime.h +652 -0
  362. data/lib/libv8/v8/src/runtime.js +649 -0
  363. data/lib/libv8/v8/src/safepoint-table.cc +256 -0
  364. data/lib/libv8/v8/src/safepoint-table.h +270 -0
  365. data/lib/libv8/v8/src/scanner-base.cc +952 -0
  366. data/lib/libv8/v8/src/scanner-base.h +670 -0
  367. data/lib/libv8/v8/src/scanner.cc +345 -0
  368. data/lib/libv8/v8/src/scanner.h +146 -0
  369. data/lib/libv8/v8/src/scopeinfo.cc +646 -0
  370. data/lib/libv8/v8/src/scopeinfo.h +254 -0
  371. data/lib/libv8/v8/src/scopes.cc +1150 -0
  372. data/lib/libv8/v8/src/scopes.h +507 -0
  373. data/lib/libv8/v8/src/serialize.cc +1574 -0
  374. data/lib/libv8/v8/src/serialize.h +589 -0
  375. data/lib/libv8/v8/src/shell.h +55 -0
  376. data/lib/libv8/v8/src/simulator.h +43 -0
  377. data/lib/libv8/v8/src/small-pointer-list.h +163 -0
  378. data/lib/libv8/v8/src/smart-pointer.h +109 -0
  379. data/lib/libv8/v8/src/snapshot-common.cc +83 -0
  380. data/lib/libv8/v8/src/snapshot-empty.cc +54 -0
  381. data/lib/libv8/v8/src/snapshot.h +91 -0
  382. data/lib/libv8/v8/src/spaces-inl.h +529 -0
  383. data/lib/libv8/v8/src/spaces.cc +3145 -0
  384. data/lib/libv8/v8/src/spaces.h +2369 -0
  385. data/lib/libv8/v8/src/splay-tree-inl.h +310 -0
  386. data/lib/libv8/v8/src/splay-tree.h +205 -0
  387. data/lib/libv8/v8/src/string-search.cc +41 -0
  388. data/lib/libv8/v8/src/string-search.h +568 -0
  389. data/lib/libv8/v8/src/string-stream.cc +592 -0
  390. data/lib/libv8/v8/src/string-stream.h +191 -0
  391. data/lib/libv8/v8/src/string.js +994 -0
  392. data/lib/libv8/v8/src/strtod.cc +440 -0
  393. data/lib/libv8/v8/src/strtod.h +40 -0
  394. data/lib/libv8/v8/src/stub-cache.cc +1965 -0
  395. data/lib/libv8/v8/src/stub-cache.h +924 -0
  396. data/lib/libv8/v8/src/third_party/valgrind/valgrind.h +3925 -0
  397. data/lib/libv8/v8/src/token.cc +63 -0
  398. data/lib/libv8/v8/src/token.h +288 -0
  399. data/lib/libv8/v8/src/type-info.cc +507 -0
  400. data/lib/libv8/v8/src/type-info.h +272 -0
  401. data/lib/libv8/v8/src/unbound-queue-inl.h +95 -0
  402. data/lib/libv8/v8/src/unbound-queue.h +69 -0
  403. data/lib/libv8/v8/src/unicode-inl.h +238 -0
  404. data/lib/libv8/v8/src/unicode.cc +1624 -0
  405. data/lib/libv8/v8/src/unicode.h +280 -0
  406. data/lib/libv8/v8/src/uri.js +408 -0
  407. data/lib/libv8/v8/src/utils-inl.h +48 -0
  408. data/lib/libv8/v8/src/utils.cc +371 -0
  409. data/lib/libv8/v8/src/utils.h +800 -0
  410. data/lib/libv8/v8/src/v8-counters.cc +62 -0
  411. data/lib/libv8/v8/src/v8-counters.h +314 -0
  412. data/lib/libv8/v8/src/v8.cc +213 -0
  413. data/lib/libv8/v8/src/v8.h +131 -0
  414. data/lib/libv8/v8/src/v8checks.h +64 -0
  415. data/lib/libv8/v8/src/v8dll-main.cc +44 -0
  416. data/lib/libv8/v8/src/v8globals.h +512 -0
  417. data/lib/libv8/v8/src/v8memory.h +82 -0
  418. data/lib/libv8/v8/src/v8natives.js +1310 -0
  419. data/lib/libv8/v8/src/v8preparserdll-main.cc +39 -0
  420. data/lib/libv8/v8/src/v8threads.cc +464 -0
  421. data/lib/libv8/v8/src/v8threads.h +165 -0
  422. data/lib/libv8/v8/src/v8utils.h +319 -0
  423. data/lib/libv8/v8/src/variables.cc +114 -0
  424. data/lib/libv8/v8/src/variables.h +167 -0
  425. data/lib/libv8/v8/src/version.cc +116 -0
  426. data/lib/libv8/v8/src/version.h +68 -0
  427. data/lib/libv8/v8/src/vm-state-inl.h +138 -0
  428. data/lib/libv8/v8/src/vm-state.h +71 -0
  429. data/lib/libv8/v8/src/win32-headers.h +96 -0
  430. data/lib/libv8/v8/src/x64/assembler-x64-inl.h +462 -0
  431. data/lib/libv8/v8/src/x64/assembler-x64.cc +3027 -0
  432. data/lib/libv8/v8/src/x64/assembler-x64.h +1633 -0
  433. data/lib/libv8/v8/src/x64/builtins-x64.cc +1520 -0
  434. data/lib/libv8/v8/src/x64/code-stubs-x64.cc +5132 -0
  435. data/lib/libv8/v8/src/x64/code-stubs-x64.h +514 -0
  436. data/lib/libv8/v8/src/x64/codegen-x64.cc +146 -0
  437. data/lib/libv8/v8/src/x64/codegen-x64.h +76 -0
  438. data/lib/libv8/v8/src/x64/cpu-x64.cc +88 -0
  439. data/lib/libv8/v8/src/x64/debug-x64.cc +319 -0
  440. data/lib/libv8/v8/src/x64/deoptimizer-x64.cc +815 -0
  441. data/lib/libv8/v8/src/x64/disasm-x64.cc +1832 -0
  442. data/lib/libv8/v8/src/x64/frames-x64.cc +45 -0
  443. data/lib/libv8/v8/src/x64/frames-x64.h +130 -0
  444. data/lib/libv8/v8/src/x64/full-codegen-x64.cc +4318 -0
  445. data/lib/libv8/v8/src/x64/ic-x64.cc +1608 -0
  446. data/lib/libv8/v8/src/x64/lithium-codegen-x64.cc +4267 -0
  447. data/lib/libv8/v8/src/x64/lithium-codegen-x64.h +367 -0
  448. data/lib/libv8/v8/src/x64/lithium-gap-resolver-x64.cc +320 -0
  449. data/lib/libv8/v8/src/x64/lithium-gap-resolver-x64.h +74 -0
  450. data/lib/libv8/v8/src/x64/lithium-x64.cc +2202 -0
  451. data/lib/libv8/v8/src/x64/lithium-x64.h +2333 -0
  452. data/lib/libv8/v8/src/x64/macro-assembler-x64.cc +3745 -0
  453. data/lib/libv8/v8/src/x64/macro-assembler-x64.h +1290 -0
  454. data/lib/libv8/v8/src/x64/regexp-macro-assembler-x64.cc +1398 -0
  455. data/lib/libv8/v8/src/x64/regexp-macro-assembler-x64.h +282 -0
  456. data/lib/libv8/v8/src/x64/simulator-x64.cc +27 -0
  457. data/lib/libv8/v8/src/x64/simulator-x64.h +72 -0
  458. data/lib/libv8/v8/src/x64/stub-cache-x64.cc +3610 -0
  459. data/lib/libv8/v8/src/zone-inl.h +140 -0
  460. data/lib/libv8/v8/src/zone.cc +196 -0
  461. data/lib/libv8/v8/src/zone.h +240 -0
  462. data/lib/libv8/v8/tools/codemap.js +265 -0
  463. data/lib/libv8/v8/tools/consarray.js +93 -0
  464. data/lib/libv8/v8/tools/csvparser.js +78 -0
  465. data/lib/libv8/v8/tools/disasm.py +92 -0
  466. data/lib/libv8/v8/tools/freebsd-tick-processor +10 -0
  467. data/lib/libv8/v8/tools/gc-nvp-trace-processor.py +342 -0
  468. data/lib/libv8/v8/tools/gcmole/README +62 -0
  469. data/lib/libv8/v8/tools/gcmole/gccause.lua +60 -0
  470. data/lib/libv8/v8/tools/gcmole/gcmole.cc +1261 -0
  471. data/lib/libv8/v8/tools/gcmole/gcmole.lua +378 -0
  472. data/lib/libv8/v8/tools/generate-ten-powers.scm +286 -0
  473. data/lib/libv8/v8/tools/grokdump.py +841 -0
  474. data/lib/libv8/v8/tools/gyp/v8.gyp +995 -0
  475. data/lib/libv8/v8/tools/js2c.py +364 -0
  476. data/lib/libv8/v8/tools/jsmin.py +280 -0
  477. data/lib/libv8/v8/tools/linux-tick-processor +35 -0
  478. data/lib/libv8/v8/tools/ll_prof.py +942 -0
  479. data/lib/libv8/v8/tools/logreader.js +185 -0
  480. data/lib/libv8/v8/tools/mac-nm +18 -0
  481. data/lib/libv8/v8/tools/mac-tick-processor +6 -0
  482. data/lib/libv8/v8/tools/oom_dump/README +31 -0
  483. data/lib/libv8/v8/tools/oom_dump/SConstruct +42 -0
  484. data/lib/libv8/v8/tools/oom_dump/oom_dump.cc +288 -0
  485. data/lib/libv8/v8/tools/presubmit.py +305 -0
  486. data/lib/libv8/v8/tools/process-heap-prof.py +120 -0
  487. data/lib/libv8/v8/tools/profile.js +751 -0
  488. data/lib/libv8/v8/tools/profile_view.js +219 -0
  489. data/lib/libv8/v8/tools/run-valgrind.py +77 -0
  490. data/lib/libv8/v8/tools/splaytree.js +316 -0
  491. data/lib/libv8/v8/tools/stats-viewer.py +468 -0
  492. data/lib/libv8/v8/tools/test.py +1510 -0
  493. data/lib/libv8/v8/tools/tickprocessor-driver.js +59 -0
  494. data/lib/libv8/v8/tools/tickprocessor.js +877 -0
  495. data/lib/libv8/v8/tools/utils.py +96 -0
  496. data/lib/libv8/v8/tools/visual_studio/README.txt +12 -0
  497. data/lib/libv8/v8/tools/windows-tick-processor.bat +30 -0
  498. data/lib/libv8/version.rb +5 -0
  499. data/libv8.gemspec +36 -0
  500. metadata +578 -0
@@ -0,0 +1,1574 @@
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
+ #include "v8.h"
29
+
30
+ #include "accessors.h"
31
+ #include "api.h"
32
+ #include "bootstrapper.h"
33
+ #include "execution.h"
34
+ #include "global-handles.h"
35
+ #include "ic-inl.h"
36
+ #include "natives.h"
37
+ #include "platform.h"
38
+ #include "runtime.h"
39
+ #include "serialize.h"
40
+ #include "stub-cache.h"
41
+ #include "v8threads.h"
42
+
43
+ namespace v8 {
44
+ namespace internal {
45
+
46
+
47
+ // -----------------------------------------------------------------------------
48
+ // Coding of external references.
49
+
50
+ // The encoding of an external reference. The type is in the high word.
51
+ // The id is in the low word.
52
+ static uint32_t EncodeExternal(TypeCode type, uint16_t id) {
53
+ return static_cast<uint32_t>(type) << 16 | id;
54
+ }
55
+
56
+
57
+ static int* GetInternalPointer(StatsCounter* counter) {
58
+ // All counters refer to dummy_counter, if deserializing happens without
59
+ // setting up counters.
60
+ static int dummy_counter = 0;
61
+ return counter->Enabled() ? counter->GetInternalPointer() : &dummy_counter;
62
+ }
63
+
64
+
65
+ // ExternalReferenceTable is a helper class that defines the relationship
66
+ // between external references and their encodings. It is used to build
67
+ // hashmaps in ExternalReferenceEncoder and ExternalReferenceDecoder.
68
+ class ExternalReferenceTable {
69
+ public:
70
+ static ExternalReferenceTable* instance(Isolate* isolate) {
71
+ ExternalReferenceTable* external_reference_table =
72
+ isolate->external_reference_table();
73
+ if (external_reference_table == NULL) {
74
+ external_reference_table = new ExternalReferenceTable(isolate);
75
+ isolate->set_external_reference_table(external_reference_table);
76
+ }
77
+ return external_reference_table;
78
+ }
79
+
80
+ int size() const { return refs_.length(); }
81
+
82
+ Address address(int i) { return refs_[i].address; }
83
+
84
+ uint32_t code(int i) { return refs_[i].code; }
85
+
86
+ const char* name(int i) { return refs_[i].name; }
87
+
88
+ int max_id(int code) { return max_id_[code]; }
89
+
90
+ private:
91
+ explicit ExternalReferenceTable(Isolate* isolate) : refs_(64) {
92
+ PopulateTable(isolate);
93
+ }
94
+ ~ExternalReferenceTable() { }
95
+
96
+ struct ExternalReferenceEntry {
97
+ Address address;
98
+ uint32_t code;
99
+ const char* name;
100
+ };
101
+
102
+ void PopulateTable(Isolate* isolate);
103
+
104
+ // For a few types of references, we can get their address from their id.
105
+ void AddFromId(TypeCode type,
106
+ uint16_t id,
107
+ const char* name,
108
+ Isolate* isolate);
109
+
110
+ // For other types of references, the caller will figure out the address.
111
+ void Add(Address address, TypeCode type, uint16_t id, const char* name);
112
+
113
+ List<ExternalReferenceEntry> refs_;
114
+ int max_id_[kTypeCodeCount];
115
+ };
116
+
117
+
118
+ void ExternalReferenceTable::AddFromId(TypeCode type,
119
+ uint16_t id,
120
+ const char* name,
121
+ Isolate* isolate) {
122
+ Address address;
123
+ switch (type) {
124
+ case C_BUILTIN: {
125
+ ExternalReference ref(static_cast<Builtins::CFunctionId>(id), isolate);
126
+ address = ref.address();
127
+ break;
128
+ }
129
+ case BUILTIN: {
130
+ ExternalReference ref(static_cast<Builtins::Name>(id), isolate);
131
+ address = ref.address();
132
+ break;
133
+ }
134
+ case RUNTIME_FUNCTION: {
135
+ ExternalReference ref(static_cast<Runtime::FunctionId>(id), isolate);
136
+ address = ref.address();
137
+ break;
138
+ }
139
+ case IC_UTILITY: {
140
+ ExternalReference ref(IC_Utility(static_cast<IC::UtilityId>(id)),
141
+ isolate);
142
+ address = ref.address();
143
+ break;
144
+ }
145
+ default:
146
+ UNREACHABLE();
147
+ return;
148
+ }
149
+ Add(address, type, id, name);
150
+ }
151
+
152
+
153
+ void ExternalReferenceTable::Add(Address address,
154
+ TypeCode type,
155
+ uint16_t id,
156
+ const char* name) {
157
+ ASSERT_NE(NULL, address);
158
+ ExternalReferenceEntry entry;
159
+ entry.address = address;
160
+ entry.code = EncodeExternal(type, id);
161
+ entry.name = name;
162
+ ASSERT_NE(0, entry.code);
163
+ refs_.Add(entry);
164
+ if (id > max_id_[type]) max_id_[type] = id;
165
+ }
166
+
167
+
168
+ void ExternalReferenceTable::PopulateTable(Isolate* isolate) {
169
+ for (int type_code = 0; type_code < kTypeCodeCount; type_code++) {
170
+ max_id_[type_code] = 0;
171
+ }
172
+
173
+ // The following populates all of the different type of external references
174
+ // into the ExternalReferenceTable.
175
+ //
176
+ // NOTE: This function was originally 100k of code. It has since been
177
+ // rewritten to be mostly table driven, as the callback macro style tends to
178
+ // very easily cause code bloat. Please be careful in the future when adding
179
+ // new references.
180
+
181
+ struct RefTableEntry {
182
+ TypeCode type;
183
+ uint16_t id;
184
+ const char* name;
185
+ };
186
+
187
+ static const RefTableEntry ref_table[] = {
188
+ // Builtins
189
+ #define DEF_ENTRY_C(name, ignored) \
190
+ { C_BUILTIN, \
191
+ Builtins::c_##name, \
192
+ "Builtins::" #name },
193
+
194
+ BUILTIN_LIST_C(DEF_ENTRY_C)
195
+ #undef DEF_ENTRY_C
196
+
197
+ #define DEF_ENTRY_C(name, ignored) \
198
+ { BUILTIN, \
199
+ Builtins::k##name, \
200
+ "Builtins::" #name },
201
+ #define DEF_ENTRY_A(name, kind, state, extra) DEF_ENTRY_C(name, ignored)
202
+
203
+ BUILTIN_LIST_C(DEF_ENTRY_C)
204
+ BUILTIN_LIST_A(DEF_ENTRY_A)
205
+ BUILTIN_LIST_DEBUG_A(DEF_ENTRY_A)
206
+ #undef DEF_ENTRY_C
207
+ #undef DEF_ENTRY_A
208
+
209
+ // Runtime functions
210
+ #define RUNTIME_ENTRY(name, nargs, ressize) \
211
+ { RUNTIME_FUNCTION, \
212
+ Runtime::k##name, \
213
+ "Runtime::" #name },
214
+
215
+ RUNTIME_FUNCTION_LIST(RUNTIME_ENTRY)
216
+ #undef RUNTIME_ENTRY
217
+
218
+ // IC utilities
219
+ #define IC_ENTRY(name) \
220
+ { IC_UTILITY, \
221
+ IC::k##name, \
222
+ "IC::" #name },
223
+
224
+ IC_UTIL_LIST(IC_ENTRY)
225
+ #undef IC_ENTRY
226
+ }; // end of ref_table[].
227
+
228
+ for (size_t i = 0; i < ARRAY_SIZE(ref_table); ++i) {
229
+ AddFromId(ref_table[i].type,
230
+ ref_table[i].id,
231
+ ref_table[i].name,
232
+ isolate);
233
+ }
234
+
235
+ #ifdef ENABLE_DEBUGGER_SUPPORT
236
+ // Debug addresses
237
+ Add(Debug_Address(Debug::k_after_break_target_address).address(isolate),
238
+ DEBUG_ADDRESS,
239
+ Debug::k_after_break_target_address << kDebugIdShift,
240
+ "Debug::after_break_target_address()");
241
+ Add(Debug_Address(Debug::k_debug_break_slot_address).address(isolate),
242
+ DEBUG_ADDRESS,
243
+ Debug::k_debug_break_slot_address << kDebugIdShift,
244
+ "Debug::debug_break_slot_address()");
245
+ Add(Debug_Address(Debug::k_debug_break_return_address).address(isolate),
246
+ DEBUG_ADDRESS,
247
+ Debug::k_debug_break_return_address << kDebugIdShift,
248
+ "Debug::debug_break_return_address()");
249
+ Add(Debug_Address(Debug::k_restarter_frame_function_pointer).address(isolate),
250
+ DEBUG_ADDRESS,
251
+ Debug::k_restarter_frame_function_pointer << kDebugIdShift,
252
+ "Debug::restarter_frame_function_pointer_address()");
253
+ #endif
254
+
255
+ // Stat counters
256
+ struct StatsRefTableEntry {
257
+ StatsCounter* (Counters::*counter)();
258
+ uint16_t id;
259
+ const char* name;
260
+ };
261
+
262
+ const StatsRefTableEntry stats_ref_table[] = {
263
+ #define COUNTER_ENTRY(name, caption) \
264
+ { &Counters::name, \
265
+ Counters::k_##name, \
266
+ "Counters::" #name },
267
+
268
+ STATS_COUNTER_LIST_1(COUNTER_ENTRY)
269
+ STATS_COUNTER_LIST_2(COUNTER_ENTRY)
270
+ #undef COUNTER_ENTRY
271
+ }; // end of stats_ref_table[].
272
+
273
+ Counters* counters = isolate->counters();
274
+ for (size_t i = 0; i < ARRAY_SIZE(stats_ref_table); ++i) {
275
+ Add(reinterpret_cast<Address>(GetInternalPointer(
276
+ (counters->*(stats_ref_table[i].counter))())),
277
+ STATS_COUNTER,
278
+ stats_ref_table[i].id,
279
+ stats_ref_table[i].name);
280
+ }
281
+
282
+ // Top addresses
283
+
284
+ const char* AddressNames[] = {
285
+ #define C(name) "Isolate::" #name,
286
+ ISOLATE_ADDRESS_LIST(C)
287
+ ISOLATE_ADDRESS_LIST_PROF(C)
288
+ NULL
289
+ #undef C
290
+ };
291
+
292
+ for (uint16_t i = 0; i < Isolate::k_isolate_address_count; ++i) {
293
+ Add(isolate->get_address_from_id((Isolate::AddressId)i),
294
+ TOP_ADDRESS, i, AddressNames[i]);
295
+ }
296
+
297
+ // Accessors
298
+ #define ACCESSOR_DESCRIPTOR_DECLARATION(name) \
299
+ Add((Address)&Accessors::name, \
300
+ ACCESSOR, \
301
+ Accessors::k##name, \
302
+ "Accessors::" #name);
303
+
304
+ ACCESSOR_DESCRIPTOR_LIST(ACCESSOR_DESCRIPTOR_DECLARATION)
305
+ #undef ACCESSOR_DESCRIPTOR_DECLARATION
306
+
307
+ StubCache* stub_cache = isolate->stub_cache();
308
+
309
+ // Stub cache tables
310
+ Add(stub_cache->key_reference(StubCache::kPrimary).address(),
311
+ STUB_CACHE_TABLE,
312
+ 1,
313
+ "StubCache::primary_->key");
314
+ Add(stub_cache->value_reference(StubCache::kPrimary).address(),
315
+ STUB_CACHE_TABLE,
316
+ 2,
317
+ "StubCache::primary_->value");
318
+ Add(stub_cache->key_reference(StubCache::kSecondary).address(),
319
+ STUB_CACHE_TABLE,
320
+ 3,
321
+ "StubCache::secondary_->key");
322
+ Add(stub_cache->value_reference(StubCache::kSecondary).address(),
323
+ STUB_CACHE_TABLE,
324
+ 4,
325
+ "StubCache::secondary_->value");
326
+
327
+ // Runtime entries
328
+ Add(ExternalReference::perform_gc_function(isolate).address(),
329
+ RUNTIME_ENTRY,
330
+ 1,
331
+ "Runtime::PerformGC");
332
+ Add(ExternalReference::fill_heap_number_with_random_function(
333
+ isolate).address(),
334
+ RUNTIME_ENTRY,
335
+ 2,
336
+ "V8::FillHeapNumberWithRandom");
337
+ Add(ExternalReference::random_uint32_function(isolate).address(),
338
+ RUNTIME_ENTRY,
339
+ 3,
340
+ "V8::Random");
341
+ Add(ExternalReference::delete_handle_scope_extensions(isolate).address(),
342
+ RUNTIME_ENTRY,
343
+ 4,
344
+ "HandleScope::DeleteExtensions");
345
+
346
+ // Miscellaneous
347
+ Add(ExternalReference::the_hole_value_location(isolate).address(),
348
+ UNCLASSIFIED,
349
+ 2,
350
+ "Factory::the_hole_value().location()");
351
+ Add(ExternalReference::roots_address(isolate).address(),
352
+ UNCLASSIFIED,
353
+ 3,
354
+ "Heap::roots_address()");
355
+ Add(ExternalReference::address_of_stack_limit(isolate).address(),
356
+ UNCLASSIFIED,
357
+ 4,
358
+ "StackGuard::address_of_jslimit()");
359
+ Add(ExternalReference::address_of_real_stack_limit(isolate).address(),
360
+ UNCLASSIFIED,
361
+ 5,
362
+ "StackGuard::address_of_real_jslimit()");
363
+ #ifndef V8_INTERPRETED_REGEXP
364
+ Add(ExternalReference::address_of_regexp_stack_limit(isolate).address(),
365
+ UNCLASSIFIED,
366
+ 6,
367
+ "RegExpStack::limit_address()");
368
+ Add(ExternalReference::address_of_regexp_stack_memory_address(
369
+ isolate).address(),
370
+ UNCLASSIFIED,
371
+ 7,
372
+ "RegExpStack::memory_address()");
373
+ Add(ExternalReference::address_of_regexp_stack_memory_size(isolate).address(),
374
+ UNCLASSIFIED,
375
+ 8,
376
+ "RegExpStack::memory_size()");
377
+ Add(ExternalReference::address_of_static_offsets_vector(isolate).address(),
378
+ UNCLASSIFIED,
379
+ 9,
380
+ "OffsetsVector::static_offsets_vector");
381
+ #endif // V8_INTERPRETED_REGEXP
382
+ Add(ExternalReference::new_space_start(isolate).address(),
383
+ UNCLASSIFIED,
384
+ 10,
385
+ "Heap::NewSpaceStart()");
386
+ Add(ExternalReference::new_space_mask(isolate).address(),
387
+ UNCLASSIFIED,
388
+ 11,
389
+ "Heap::NewSpaceMask()");
390
+ Add(ExternalReference::heap_always_allocate_scope_depth(isolate).address(),
391
+ UNCLASSIFIED,
392
+ 12,
393
+ "Heap::always_allocate_scope_depth()");
394
+ Add(ExternalReference::new_space_allocation_limit_address(isolate).address(),
395
+ UNCLASSIFIED,
396
+ 13,
397
+ "Heap::NewSpaceAllocationLimitAddress()");
398
+ Add(ExternalReference::new_space_allocation_top_address(isolate).address(),
399
+ UNCLASSIFIED,
400
+ 14,
401
+ "Heap::NewSpaceAllocationTopAddress()");
402
+ #ifdef ENABLE_DEBUGGER_SUPPORT
403
+ Add(ExternalReference::debug_break(isolate).address(),
404
+ UNCLASSIFIED,
405
+ 15,
406
+ "Debug::Break()");
407
+ Add(ExternalReference::debug_step_in_fp_address(isolate).address(),
408
+ UNCLASSIFIED,
409
+ 16,
410
+ "Debug::step_in_fp_addr()");
411
+ #endif
412
+ Add(ExternalReference::double_fp_operation(Token::ADD, isolate).address(),
413
+ UNCLASSIFIED,
414
+ 17,
415
+ "add_two_doubles");
416
+ Add(ExternalReference::double_fp_operation(Token::SUB, isolate).address(),
417
+ UNCLASSIFIED,
418
+ 18,
419
+ "sub_two_doubles");
420
+ Add(ExternalReference::double_fp_operation(Token::MUL, isolate).address(),
421
+ UNCLASSIFIED,
422
+ 19,
423
+ "mul_two_doubles");
424
+ Add(ExternalReference::double_fp_operation(Token::DIV, isolate).address(),
425
+ UNCLASSIFIED,
426
+ 20,
427
+ "div_two_doubles");
428
+ Add(ExternalReference::double_fp_operation(Token::MOD, isolate).address(),
429
+ UNCLASSIFIED,
430
+ 21,
431
+ "mod_two_doubles");
432
+ Add(ExternalReference::compare_doubles(isolate).address(),
433
+ UNCLASSIFIED,
434
+ 22,
435
+ "compare_doubles");
436
+ #ifndef V8_INTERPRETED_REGEXP
437
+ Add(ExternalReference::re_case_insensitive_compare_uc16(isolate).address(),
438
+ UNCLASSIFIED,
439
+ 23,
440
+ "NativeRegExpMacroAssembler::CaseInsensitiveCompareUC16()");
441
+ Add(ExternalReference::re_check_stack_guard_state(isolate).address(),
442
+ UNCLASSIFIED,
443
+ 24,
444
+ "RegExpMacroAssembler*::CheckStackGuardState()");
445
+ Add(ExternalReference::re_grow_stack(isolate).address(),
446
+ UNCLASSIFIED,
447
+ 25,
448
+ "NativeRegExpMacroAssembler::GrowStack()");
449
+ Add(ExternalReference::re_word_character_map().address(),
450
+ UNCLASSIFIED,
451
+ 26,
452
+ "NativeRegExpMacroAssembler::word_character_map");
453
+ #endif // V8_INTERPRETED_REGEXP
454
+ // Keyed lookup cache.
455
+ Add(ExternalReference::keyed_lookup_cache_keys(isolate).address(),
456
+ UNCLASSIFIED,
457
+ 27,
458
+ "KeyedLookupCache::keys()");
459
+ Add(ExternalReference::keyed_lookup_cache_field_offsets(isolate).address(),
460
+ UNCLASSIFIED,
461
+ 28,
462
+ "KeyedLookupCache::field_offsets()");
463
+ Add(ExternalReference::transcendental_cache_array_address(isolate).address(),
464
+ UNCLASSIFIED,
465
+ 29,
466
+ "TranscendentalCache::caches()");
467
+ Add(ExternalReference::handle_scope_next_address().address(),
468
+ UNCLASSIFIED,
469
+ 30,
470
+ "HandleScope::next");
471
+ Add(ExternalReference::handle_scope_limit_address().address(),
472
+ UNCLASSIFIED,
473
+ 31,
474
+ "HandleScope::limit");
475
+ Add(ExternalReference::handle_scope_level_address().address(),
476
+ UNCLASSIFIED,
477
+ 32,
478
+ "HandleScope::level");
479
+ Add(ExternalReference::new_deoptimizer_function(isolate).address(),
480
+ UNCLASSIFIED,
481
+ 33,
482
+ "Deoptimizer::New()");
483
+ Add(ExternalReference::compute_output_frames_function(isolate).address(),
484
+ UNCLASSIFIED,
485
+ 34,
486
+ "Deoptimizer::ComputeOutputFrames()");
487
+ Add(ExternalReference::address_of_min_int().address(),
488
+ UNCLASSIFIED,
489
+ 35,
490
+ "LDoubleConstant::min_int");
491
+ Add(ExternalReference::address_of_one_half().address(),
492
+ UNCLASSIFIED,
493
+ 36,
494
+ "LDoubleConstant::one_half");
495
+ Add(ExternalReference::isolate_address().address(),
496
+ UNCLASSIFIED,
497
+ 37,
498
+ "isolate");
499
+ Add(ExternalReference::address_of_minus_zero().address(),
500
+ UNCLASSIFIED,
501
+ 38,
502
+ "LDoubleConstant::minus_zero");
503
+ Add(ExternalReference::address_of_negative_infinity().address(),
504
+ UNCLASSIFIED,
505
+ 39,
506
+ "LDoubleConstant::negative_infinity");
507
+ Add(ExternalReference::power_double_double_function(isolate).address(),
508
+ UNCLASSIFIED,
509
+ 40,
510
+ "power_double_double_function");
511
+ Add(ExternalReference::power_double_int_function(isolate).address(),
512
+ UNCLASSIFIED,
513
+ 41,
514
+ "power_double_int_function");
515
+ Add(ExternalReference::arguments_marker_location(isolate).address(),
516
+ UNCLASSIFIED,
517
+ 42,
518
+ "Factory::arguments_marker().location()");
519
+ }
520
+
521
+
522
+ ExternalReferenceEncoder::ExternalReferenceEncoder()
523
+ : encodings_(Match),
524
+ isolate_(Isolate::Current()) {
525
+ ExternalReferenceTable* external_references =
526
+ ExternalReferenceTable::instance(isolate_);
527
+ for (int i = 0; i < external_references->size(); ++i) {
528
+ Put(external_references->address(i), i);
529
+ }
530
+ }
531
+
532
+
533
+ uint32_t ExternalReferenceEncoder::Encode(Address key) const {
534
+ int index = IndexOf(key);
535
+ ASSERT(key == NULL || index >= 0);
536
+ return index >=0 ?
537
+ ExternalReferenceTable::instance(isolate_)->code(index) : 0;
538
+ }
539
+
540
+
541
+ const char* ExternalReferenceEncoder::NameOfAddress(Address key) const {
542
+ int index = IndexOf(key);
543
+ return index >= 0 ?
544
+ ExternalReferenceTable::instance(isolate_)->name(index) : NULL;
545
+ }
546
+
547
+
548
+ int ExternalReferenceEncoder::IndexOf(Address key) const {
549
+ if (key == NULL) return -1;
550
+ HashMap::Entry* entry =
551
+ const_cast<HashMap&>(encodings_).Lookup(key, Hash(key), false);
552
+ return entry == NULL
553
+ ? -1
554
+ : static_cast<int>(reinterpret_cast<intptr_t>(entry->value));
555
+ }
556
+
557
+
558
+ void ExternalReferenceEncoder::Put(Address key, int index) {
559
+ HashMap::Entry* entry = encodings_.Lookup(key, Hash(key), true);
560
+ entry->value = reinterpret_cast<void*>(index);
561
+ }
562
+
563
+
564
+ ExternalReferenceDecoder::ExternalReferenceDecoder()
565
+ : encodings_(NewArray<Address*>(kTypeCodeCount)),
566
+ isolate_(Isolate::Current()) {
567
+ ExternalReferenceTable* external_references =
568
+ ExternalReferenceTable::instance(isolate_);
569
+ for (int type = kFirstTypeCode; type < kTypeCodeCount; ++type) {
570
+ int max = external_references->max_id(type) + 1;
571
+ encodings_[type] = NewArray<Address>(max + 1);
572
+ }
573
+ for (int i = 0; i < external_references->size(); ++i) {
574
+ Put(external_references->code(i), external_references->address(i));
575
+ }
576
+ }
577
+
578
+
579
+ ExternalReferenceDecoder::~ExternalReferenceDecoder() {
580
+ for (int type = kFirstTypeCode; type < kTypeCodeCount; ++type) {
581
+ DeleteArray(encodings_[type]);
582
+ }
583
+ DeleteArray(encodings_);
584
+ }
585
+
586
+
587
+ bool Serializer::serialization_enabled_ = false;
588
+ bool Serializer::too_late_to_enable_now_ = false;
589
+
590
+
591
+ Deserializer::Deserializer(SnapshotByteSource* source)
592
+ : isolate_(NULL),
593
+ source_(source),
594
+ external_reference_decoder_(NULL) {
595
+ }
596
+
597
+
598
+ // This routine both allocates a new object, and also keeps
599
+ // track of where objects have been allocated so that we can
600
+ // fix back references when deserializing.
601
+ Address Deserializer::Allocate(int space_index, Space* space, int size) {
602
+ Address address;
603
+ if (!SpaceIsLarge(space_index)) {
604
+ ASSERT(!SpaceIsPaged(space_index) ||
605
+ size <= Page::kPageSize - Page::kObjectStartOffset);
606
+ MaybeObject* maybe_new_allocation;
607
+ if (space_index == NEW_SPACE) {
608
+ maybe_new_allocation =
609
+ reinterpret_cast<NewSpace*>(space)->AllocateRaw(size);
610
+ } else {
611
+ maybe_new_allocation =
612
+ reinterpret_cast<PagedSpace*>(space)->AllocateRaw(size);
613
+ }
614
+ Object* new_allocation = maybe_new_allocation->ToObjectUnchecked();
615
+ HeapObject* new_object = HeapObject::cast(new_allocation);
616
+ address = new_object->address();
617
+ high_water_[space_index] = address + size;
618
+ } else {
619
+ ASSERT(SpaceIsLarge(space_index));
620
+ LargeObjectSpace* lo_space = reinterpret_cast<LargeObjectSpace*>(space);
621
+ Object* new_allocation;
622
+ if (space_index == kLargeData) {
623
+ new_allocation = lo_space->AllocateRaw(size)->ToObjectUnchecked();
624
+ } else if (space_index == kLargeFixedArray) {
625
+ new_allocation =
626
+ lo_space->AllocateRawFixedArray(size)->ToObjectUnchecked();
627
+ } else {
628
+ ASSERT_EQ(kLargeCode, space_index);
629
+ new_allocation = lo_space->AllocateRawCode(size)->ToObjectUnchecked();
630
+ }
631
+ HeapObject* new_object = HeapObject::cast(new_allocation);
632
+ // Record all large objects in the same space.
633
+ address = new_object->address();
634
+ pages_[LO_SPACE].Add(address);
635
+ }
636
+ last_object_address_ = address;
637
+ return address;
638
+ }
639
+
640
+
641
+ // This returns the address of an object that has been described in the
642
+ // snapshot as being offset bytes back in a particular space.
643
+ HeapObject* Deserializer::GetAddressFromEnd(int space) {
644
+ int offset = source_->GetInt();
645
+ ASSERT(!SpaceIsLarge(space));
646
+ offset <<= kObjectAlignmentBits;
647
+ return HeapObject::FromAddress(high_water_[space] - offset);
648
+ }
649
+
650
+
651
+ // This returns the address of an object that has been described in the
652
+ // snapshot as being offset bytes into a particular space.
653
+ HeapObject* Deserializer::GetAddressFromStart(int space) {
654
+ int offset = source_->GetInt();
655
+ if (SpaceIsLarge(space)) {
656
+ // Large spaces have one object per 'page'.
657
+ return HeapObject::FromAddress(pages_[LO_SPACE][offset]);
658
+ }
659
+ offset <<= kObjectAlignmentBits;
660
+ if (space == NEW_SPACE) {
661
+ // New space has only one space - numbered 0.
662
+ return HeapObject::FromAddress(pages_[space][0] + offset);
663
+ }
664
+ ASSERT(SpaceIsPaged(space));
665
+ int page_of_pointee = offset >> kPageSizeBits;
666
+ Address object_address = pages_[space][page_of_pointee] +
667
+ (offset & Page::kPageAlignmentMask);
668
+ return HeapObject::FromAddress(object_address);
669
+ }
670
+
671
+
672
+ void Deserializer::Deserialize() {
673
+ isolate_ = Isolate::Current();
674
+ // Don't GC while deserializing - just expand the heap.
675
+ AlwaysAllocateScope always_allocate;
676
+ // Don't use the free lists while deserializing.
677
+ LinearAllocationScope allocate_linearly;
678
+ // No active threads.
679
+ ASSERT_EQ(NULL, isolate_->thread_manager()->FirstThreadStateInUse());
680
+ // No active handles.
681
+ ASSERT(isolate_->handle_scope_implementer()->blocks()->is_empty());
682
+ // Make sure the entire partial snapshot cache is traversed, filling it with
683
+ // valid object pointers.
684
+ isolate_->set_serialize_partial_snapshot_cache_length(
685
+ Isolate::kPartialSnapshotCacheCapacity);
686
+ ASSERT_EQ(NULL, external_reference_decoder_);
687
+ external_reference_decoder_ = new ExternalReferenceDecoder();
688
+ isolate_->heap()->IterateStrongRoots(this, VISIT_ONLY_STRONG);
689
+ isolate_->heap()->IterateWeakRoots(this, VISIT_ALL);
690
+
691
+ isolate_->heap()->set_global_contexts_list(
692
+ isolate_->heap()->undefined_value());
693
+ }
694
+
695
+
696
+ void Deserializer::DeserializePartial(Object** root) {
697
+ isolate_ = Isolate::Current();
698
+ // Don't GC while deserializing - just expand the heap.
699
+ AlwaysAllocateScope always_allocate;
700
+ // Don't use the free lists while deserializing.
701
+ LinearAllocationScope allocate_linearly;
702
+ if (external_reference_decoder_ == NULL) {
703
+ external_reference_decoder_ = new ExternalReferenceDecoder();
704
+ }
705
+ VisitPointer(root);
706
+ }
707
+
708
+
709
+ Deserializer::~Deserializer() {
710
+ ASSERT(source_->AtEOF());
711
+ if (external_reference_decoder_) {
712
+ delete external_reference_decoder_;
713
+ external_reference_decoder_ = NULL;
714
+ }
715
+ }
716
+
717
+
718
+ // This is called on the roots. It is the driver of the deserialization
719
+ // process. It is also called on the body of each function.
720
+ void Deserializer::VisitPointers(Object** start, Object** end) {
721
+ // The space must be new space. Any other space would cause ReadChunk to try
722
+ // to update the remembered using NULL as the address.
723
+ ReadChunk(start, end, NEW_SPACE, NULL);
724
+ }
725
+
726
+
727
+ // This routine writes the new object into the pointer provided and then
728
+ // returns true if the new object was in young space and false otherwise.
729
+ // The reason for this strange interface is that otherwise the object is
730
+ // written very late, which means the ByteArray map is not set up by the
731
+ // time we need to use it to mark the space at the end of a page free (by
732
+ // making it into a byte array).
733
+ void Deserializer::ReadObject(int space_number,
734
+ Space* space,
735
+ Object** write_back) {
736
+ int size = source_->GetInt() << kObjectAlignmentBits;
737
+ Address address = Allocate(space_number, space, size);
738
+ *write_back = HeapObject::FromAddress(address);
739
+ Object** current = reinterpret_cast<Object**>(address);
740
+ Object** limit = current + (size >> kPointerSizeLog2);
741
+ if (FLAG_log_snapshot_positions) {
742
+ LOG(isolate_, SnapshotPositionEvent(address, source_->position()));
743
+ }
744
+ ReadChunk(current, limit, space_number, address);
745
+ #ifdef DEBUG
746
+ bool is_codespace = (space == HEAP->code_space()) ||
747
+ ((space == HEAP->lo_space()) && (space_number == kLargeCode));
748
+ ASSERT(HeapObject::FromAddress(address)->IsCode() == is_codespace);
749
+ #endif
750
+ }
751
+
752
+
753
+ // This macro is always used with a constant argument so it should all fold
754
+ // away to almost nothing in the generated code. It might be nicer to do this
755
+ // with the ternary operator but there are type issues with that.
756
+ #define ASSIGN_DEST_SPACE(space_number) \
757
+ Space* dest_space; \
758
+ if (space_number == NEW_SPACE) { \
759
+ dest_space = isolate->heap()->new_space(); \
760
+ } else if (space_number == OLD_POINTER_SPACE) { \
761
+ dest_space = isolate->heap()->old_pointer_space(); \
762
+ } else if (space_number == OLD_DATA_SPACE) { \
763
+ dest_space = isolate->heap()->old_data_space(); \
764
+ } else if (space_number == CODE_SPACE) { \
765
+ dest_space = isolate->heap()->code_space(); \
766
+ } else if (space_number == MAP_SPACE) { \
767
+ dest_space = isolate->heap()->map_space(); \
768
+ } else if (space_number == CELL_SPACE) { \
769
+ dest_space = isolate->heap()->cell_space(); \
770
+ } else { \
771
+ ASSERT(space_number >= LO_SPACE); \
772
+ dest_space = isolate->heap()->lo_space(); \
773
+ }
774
+
775
+
776
+ static const int kUnknownOffsetFromStart = -1;
777
+
778
+
779
+ void Deserializer::ReadChunk(Object** current,
780
+ Object** limit,
781
+ int source_space,
782
+ Address address) {
783
+ Isolate* const isolate = isolate_;
784
+ while (current < limit) {
785
+ int data = source_->Get();
786
+ switch (data) {
787
+ #define CASE_STATEMENT(where, how, within, space_number) \
788
+ case where + how + within + space_number: \
789
+ ASSERT((where & ~kPointedToMask) == 0); \
790
+ ASSERT((how & ~kHowToCodeMask) == 0); \
791
+ ASSERT((within & ~kWhereToPointMask) == 0); \
792
+ ASSERT((space_number & ~kSpaceMask) == 0);
793
+
794
+ #define CASE_BODY(where, how, within, space_number_if_any, offset_from_start) \
795
+ { \
796
+ bool emit_write_barrier = false; \
797
+ bool current_was_incremented = false; \
798
+ int space_number = space_number_if_any == kAnyOldSpace ? \
799
+ (data & kSpaceMask) : space_number_if_any; \
800
+ if (where == kNewObject && how == kPlain && within == kStartOfObject) {\
801
+ ASSIGN_DEST_SPACE(space_number) \
802
+ ReadObject(space_number, dest_space, current); \
803
+ emit_write_barrier = \
804
+ (space_number == NEW_SPACE && source_space != NEW_SPACE); \
805
+ } else { \
806
+ Object* new_object = NULL; /* May not be a real Object pointer. */ \
807
+ if (where == kNewObject) { \
808
+ ASSIGN_DEST_SPACE(space_number) \
809
+ ReadObject(space_number, dest_space, &new_object); \
810
+ } else if (where == kRootArray) { \
811
+ int root_id = source_->GetInt(); \
812
+ new_object = isolate->heap()->roots_address()[root_id]; \
813
+ } else if (where == kPartialSnapshotCache) { \
814
+ int cache_index = source_->GetInt(); \
815
+ new_object = isolate->serialize_partial_snapshot_cache() \
816
+ [cache_index]; \
817
+ } else if (where == kExternalReference) { \
818
+ int reference_id = source_->GetInt(); \
819
+ Address address = external_reference_decoder_-> \
820
+ Decode(reference_id); \
821
+ new_object = reinterpret_cast<Object*>(address); \
822
+ } else if (where == kBackref) { \
823
+ emit_write_barrier = \
824
+ (space_number == NEW_SPACE && source_space != NEW_SPACE); \
825
+ new_object = GetAddressFromEnd(data & kSpaceMask); \
826
+ } else { \
827
+ ASSERT(where == kFromStart); \
828
+ if (offset_from_start == kUnknownOffsetFromStart) { \
829
+ emit_write_barrier = \
830
+ (space_number == NEW_SPACE && source_space != NEW_SPACE); \
831
+ new_object = GetAddressFromStart(data & kSpaceMask); \
832
+ } else { \
833
+ Address object_address = pages_[space_number][0] + \
834
+ (offset_from_start << kObjectAlignmentBits); \
835
+ new_object = HeapObject::FromAddress(object_address); \
836
+ } \
837
+ } \
838
+ if (within == kFirstInstruction) { \
839
+ Code* new_code_object = reinterpret_cast<Code*>(new_object); \
840
+ new_object = reinterpret_cast<Object*>( \
841
+ new_code_object->instruction_start()); \
842
+ } \
843
+ if (how == kFromCode) { \
844
+ Address location_of_branch_data = \
845
+ reinterpret_cast<Address>(current); \
846
+ Assembler::set_target_at(location_of_branch_data, \
847
+ reinterpret_cast<Address>(new_object)); \
848
+ if (within == kFirstInstruction) { \
849
+ location_of_branch_data += Assembler::kCallTargetSize; \
850
+ current = reinterpret_cast<Object**>(location_of_branch_data); \
851
+ current_was_incremented = true; \
852
+ } \
853
+ } else { \
854
+ *current = new_object; \
855
+ } \
856
+ } \
857
+ if (emit_write_barrier) { \
858
+ isolate->heap()->RecordWrite(address, static_cast<int>( \
859
+ reinterpret_cast<Address>(current) - address)); \
860
+ } \
861
+ if (!current_was_incremented) { \
862
+ current++; /* Increment current if it wasn't done above. */ \
863
+ } \
864
+ break; \
865
+ } \
866
+
867
+ // This generates a case and a body for each space. The large object spaces are
868
+ // very rare in snapshots so they are grouped in one body.
869
+ #define ONE_PER_SPACE(where, how, within) \
870
+ CASE_STATEMENT(where, how, within, NEW_SPACE) \
871
+ CASE_BODY(where, how, within, NEW_SPACE, kUnknownOffsetFromStart) \
872
+ CASE_STATEMENT(where, how, within, OLD_DATA_SPACE) \
873
+ CASE_BODY(where, how, within, OLD_DATA_SPACE, kUnknownOffsetFromStart) \
874
+ CASE_STATEMENT(where, how, within, OLD_POINTER_SPACE) \
875
+ CASE_BODY(where, how, within, OLD_POINTER_SPACE, kUnknownOffsetFromStart) \
876
+ CASE_STATEMENT(where, how, within, CODE_SPACE) \
877
+ CASE_BODY(where, how, within, CODE_SPACE, kUnknownOffsetFromStart) \
878
+ CASE_STATEMENT(where, how, within, CELL_SPACE) \
879
+ CASE_BODY(where, how, within, CELL_SPACE, kUnknownOffsetFromStart) \
880
+ CASE_STATEMENT(where, how, within, MAP_SPACE) \
881
+ CASE_BODY(where, how, within, MAP_SPACE, kUnknownOffsetFromStart) \
882
+ CASE_STATEMENT(where, how, within, kLargeData) \
883
+ CASE_STATEMENT(where, how, within, kLargeCode) \
884
+ CASE_STATEMENT(where, how, within, kLargeFixedArray) \
885
+ CASE_BODY(where, how, within, kAnyOldSpace, kUnknownOffsetFromStart)
886
+
887
+ // This generates a case and a body for the new space (which has to do extra
888
+ // write barrier handling) and handles the other spaces with 8 fall-through
889
+ // cases and one body.
890
+ #define ALL_SPACES(where, how, within) \
891
+ CASE_STATEMENT(where, how, within, NEW_SPACE) \
892
+ CASE_BODY(where, how, within, NEW_SPACE, kUnknownOffsetFromStart) \
893
+ CASE_STATEMENT(where, how, within, OLD_DATA_SPACE) \
894
+ CASE_STATEMENT(where, how, within, OLD_POINTER_SPACE) \
895
+ CASE_STATEMENT(where, how, within, CODE_SPACE) \
896
+ CASE_STATEMENT(where, how, within, CELL_SPACE) \
897
+ CASE_STATEMENT(where, how, within, MAP_SPACE) \
898
+ CASE_STATEMENT(where, how, within, kLargeData) \
899
+ CASE_STATEMENT(where, how, within, kLargeCode) \
900
+ CASE_STATEMENT(where, how, within, kLargeFixedArray) \
901
+ CASE_BODY(where, how, within, kAnyOldSpace, kUnknownOffsetFromStart)
902
+
903
+ #define ONE_PER_CODE_SPACE(where, how, within) \
904
+ CASE_STATEMENT(where, how, within, CODE_SPACE) \
905
+ CASE_BODY(where, how, within, CODE_SPACE, kUnknownOffsetFromStart) \
906
+ CASE_STATEMENT(where, how, within, kLargeCode) \
907
+ CASE_BODY(where, how, within, kLargeCode, kUnknownOffsetFromStart)
908
+
909
+ #define EMIT_COMMON_REFERENCE_PATTERNS(pseudo_space_number, \
910
+ space_number, \
911
+ offset_from_start) \
912
+ CASE_STATEMENT(kFromStart, kPlain, kStartOfObject, pseudo_space_number) \
913
+ CASE_BODY(kFromStart, kPlain, kStartOfObject, space_number, offset_from_start)
914
+
915
+ // We generate 15 cases and bodies that process special tags that combine
916
+ // the raw data tag and the length into one byte.
917
+ #define RAW_CASE(index, size) \
918
+ case kRawData + index: { \
919
+ byte* raw_data_out = reinterpret_cast<byte*>(current); \
920
+ source_->CopyRaw(raw_data_out, size); \
921
+ current = reinterpret_cast<Object**>(raw_data_out + size); \
922
+ break; \
923
+ }
924
+ COMMON_RAW_LENGTHS(RAW_CASE)
925
+ #undef RAW_CASE
926
+
927
+ // Deserialize a chunk of raw data that doesn't have one of the popular
928
+ // lengths.
929
+ case kRawData: {
930
+ int size = source_->GetInt();
931
+ byte* raw_data_out = reinterpret_cast<byte*>(current);
932
+ source_->CopyRaw(raw_data_out, size);
933
+ current = reinterpret_cast<Object**>(raw_data_out + size);
934
+ break;
935
+ }
936
+
937
+ // Deserialize a new object and write a pointer to it to the current
938
+ // object.
939
+ ONE_PER_SPACE(kNewObject, kPlain, kStartOfObject)
940
+ // Support for direct instruction pointers in functions
941
+ ONE_PER_CODE_SPACE(kNewObject, kPlain, kFirstInstruction)
942
+ // Deserialize a new code object and write a pointer to its first
943
+ // instruction to the current code object.
944
+ ONE_PER_SPACE(kNewObject, kFromCode, kFirstInstruction)
945
+ // Find a recently deserialized object using its offset from the current
946
+ // allocation point and write a pointer to it to the current object.
947
+ ALL_SPACES(kBackref, kPlain, kStartOfObject)
948
+ // Find a recently deserialized code object using its offset from the
949
+ // current allocation point and write a pointer to its first instruction
950
+ // to the current code object or the instruction pointer in a function
951
+ // object.
952
+ ALL_SPACES(kBackref, kFromCode, kFirstInstruction)
953
+ ALL_SPACES(kBackref, kPlain, kFirstInstruction)
954
+ // Find an already deserialized object using its offset from the start
955
+ // and write a pointer to it to the current object.
956
+ ALL_SPACES(kFromStart, kPlain, kStartOfObject)
957
+ ALL_SPACES(kFromStart, kPlain, kFirstInstruction)
958
+ // Find an already deserialized code object using its offset from the
959
+ // start and write a pointer to its first instruction to the current code
960
+ // object.
961
+ ALL_SPACES(kFromStart, kFromCode, kFirstInstruction)
962
+ // Find an already deserialized object at one of the predetermined popular
963
+ // offsets from the start and write a pointer to it in the current object.
964
+ COMMON_REFERENCE_PATTERNS(EMIT_COMMON_REFERENCE_PATTERNS)
965
+ // Find an object in the roots array and write a pointer to it to the
966
+ // current object.
967
+ CASE_STATEMENT(kRootArray, kPlain, kStartOfObject, 0)
968
+ CASE_BODY(kRootArray, kPlain, kStartOfObject, 0, kUnknownOffsetFromStart)
969
+ // Find an object in the partial snapshots cache and write a pointer to it
970
+ // to the current object.
971
+ CASE_STATEMENT(kPartialSnapshotCache, kPlain, kStartOfObject, 0)
972
+ CASE_BODY(kPartialSnapshotCache,
973
+ kPlain,
974
+ kStartOfObject,
975
+ 0,
976
+ kUnknownOffsetFromStart)
977
+ // Find an code entry in the partial snapshots cache and
978
+ // write a pointer to it to the current object.
979
+ CASE_STATEMENT(kPartialSnapshotCache, kPlain, kFirstInstruction, 0)
980
+ CASE_BODY(kPartialSnapshotCache,
981
+ kPlain,
982
+ kFirstInstruction,
983
+ 0,
984
+ kUnknownOffsetFromStart)
985
+ // Find an external reference and write a pointer to it to the current
986
+ // object.
987
+ CASE_STATEMENT(kExternalReference, kPlain, kStartOfObject, 0)
988
+ CASE_BODY(kExternalReference,
989
+ kPlain,
990
+ kStartOfObject,
991
+ 0,
992
+ kUnknownOffsetFromStart)
993
+ // Find an external reference and write a pointer to it in the current
994
+ // code object.
995
+ CASE_STATEMENT(kExternalReference, kFromCode, kStartOfObject, 0)
996
+ CASE_BODY(kExternalReference,
997
+ kFromCode,
998
+ kStartOfObject,
999
+ 0,
1000
+ kUnknownOffsetFromStart)
1001
+
1002
+ #undef CASE_STATEMENT
1003
+ #undef CASE_BODY
1004
+ #undef ONE_PER_SPACE
1005
+ #undef ALL_SPACES
1006
+ #undef EMIT_COMMON_REFERENCE_PATTERNS
1007
+ #undef ASSIGN_DEST_SPACE
1008
+
1009
+ case kNewPage: {
1010
+ int space = source_->Get();
1011
+ pages_[space].Add(last_object_address_);
1012
+ if (space == CODE_SPACE) {
1013
+ CPU::FlushICache(last_object_address_, Page::kPageSize);
1014
+ }
1015
+ break;
1016
+ }
1017
+
1018
+ case kNativesStringResource: {
1019
+ int index = source_->Get();
1020
+ Vector<const char> source_vector = Natives::GetScriptSource(index);
1021
+ NativesExternalStringResource* resource =
1022
+ new NativesExternalStringResource(
1023
+ isolate->bootstrapper(), source_vector.start());
1024
+ *current++ = reinterpret_cast<Object*>(resource);
1025
+ break;
1026
+ }
1027
+
1028
+ case kSynchronize: {
1029
+ // If we get here then that indicates that you have a mismatch between
1030
+ // the number of GC roots when serializing and deserializing.
1031
+ UNREACHABLE();
1032
+ }
1033
+
1034
+ default:
1035
+ UNREACHABLE();
1036
+ }
1037
+ }
1038
+ ASSERT_EQ(current, limit);
1039
+ }
1040
+
1041
+
1042
+ void SnapshotByteSink::PutInt(uintptr_t integer, const char* description) {
1043
+ const int max_shift = ((kPointerSize * kBitsPerByte) / 7) * 7;
1044
+ for (int shift = max_shift; shift > 0; shift -= 7) {
1045
+ if (integer >= static_cast<uintptr_t>(1u) << shift) {
1046
+ Put((static_cast<int>((integer >> shift)) & 0x7f) | 0x80, "IntPart");
1047
+ }
1048
+ }
1049
+ PutSection(static_cast<int>(integer & 0x7f), "IntLastPart");
1050
+ }
1051
+
1052
+ #ifdef DEBUG
1053
+
1054
+ void Deserializer::Synchronize(const char* tag) {
1055
+ int data = source_->Get();
1056
+ // If this assert fails then that indicates that you have a mismatch between
1057
+ // the number of GC roots when serializing and deserializing.
1058
+ ASSERT_EQ(kSynchronize, data);
1059
+ do {
1060
+ int character = source_->Get();
1061
+ if (character == 0) break;
1062
+ if (FLAG_debug_serialization) {
1063
+ PrintF("%c", character);
1064
+ }
1065
+ } while (true);
1066
+ if (FLAG_debug_serialization) {
1067
+ PrintF("\n");
1068
+ }
1069
+ }
1070
+
1071
+
1072
+ void Serializer::Synchronize(const char* tag) {
1073
+ sink_->Put(kSynchronize, tag);
1074
+ int character;
1075
+ do {
1076
+ character = *tag++;
1077
+ sink_->PutSection(character, "TagCharacter");
1078
+ } while (character != 0);
1079
+ }
1080
+
1081
+ #endif
1082
+
1083
+ Serializer::Serializer(SnapshotByteSink* sink)
1084
+ : sink_(sink),
1085
+ current_root_index_(0),
1086
+ external_reference_encoder_(new ExternalReferenceEncoder),
1087
+ large_object_total_(0) {
1088
+ // The serializer is meant to be used only to generate initial heap images
1089
+ // from a context in which there is only one isolate.
1090
+ ASSERT(Isolate::Current()->IsDefaultIsolate());
1091
+ for (int i = 0; i <= LAST_SPACE; i++) {
1092
+ fullness_[i] = 0;
1093
+ }
1094
+ }
1095
+
1096
+
1097
+ Serializer::~Serializer() {
1098
+ delete external_reference_encoder_;
1099
+ }
1100
+
1101
+
1102
+ void StartupSerializer::SerializeStrongReferences() {
1103
+ Isolate* isolate = Isolate::Current();
1104
+ // No active threads.
1105
+ CHECK_EQ(NULL, Isolate::Current()->thread_manager()->FirstThreadStateInUse());
1106
+ // No active or weak handles.
1107
+ CHECK(isolate->handle_scope_implementer()->blocks()->is_empty());
1108
+ CHECK_EQ(0, isolate->global_handles()->NumberOfWeakHandles());
1109
+ // We don't support serializing installed extensions.
1110
+ for (RegisteredExtension* ext = v8::RegisteredExtension::first_extension();
1111
+ ext != NULL;
1112
+ ext = ext->next()) {
1113
+ CHECK_NE(v8::INSTALLED, ext->state());
1114
+ }
1115
+ HEAP->IterateStrongRoots(this, VISIT_ONLY_STRONG);
1116
+ }
1117
+
1118
+
1119
+ void PartialSerializer::Serialize(Object** object) {
1120
+ this->VisitPointer(object);
1121
+ Isolate* isolate = Isolate::Current();
1122
+
1123
+ // After we have done the partial serialization the partial snapshot cache
1124
+ // will contain some references needed to decode the partial snapshot. We
1125
+ // fill it up with undefineds so it has a predictable length so the
1126
+ // deserialization code doesn't need to know the length.
1127
+ for (int index = isolate->serialize_partial_snapshot_cache_length();
1128
+ index < Isolate::kPartialSnapshotCacheCapacity;
1129
+ index++) {
1130
+ isolate->serialize_partial_snapshot_cache()[index] =
1131
+ isolate->heap()->undefined_value();
1132
+ startup_serializer_->VisitPointer(
1133
+ &isolate->serialize_partial_snapshot_cache()[index]);
1134
+ }
1135
+ isolate->set_serialize_partial_snapshot_cache_length(
1136
+ Isolate::kPartialSnapshotCacheCapacity);
1137
+ }
1138
+
1139
+
1140
+ void Serializer::VisitPointers(Object** start, Object** end) {
1141
+ for (Object** current = start; current < end; current++) {
1142
+ if ((*current)->IsSmi()) {
1143
+ sink_->Put(kRawData, "RawData");
1144
+ sink_->PutInt(kPointerSize, "length");
1145
+ for (int i = 0; i < kPointerSize; i++) {
1146
+ sink_->Put(reinterpret_cast<byte*>(current)[i], "Byte");
1147
+ }
1148
+ } else {
1149
+ SerializeObject(*current, kPlain, kStartOfObject);
1150
+ }
1151
+ }
1152
+ }
1153
+
1154
+
1155
+ // This ensures that the partial snapshot cache keeps things alive during GC and
1156
+ // tracks their movement. When it is called during serialization of the startup
1157
+ // snapshot the partial snapshot is empty, so nothing happens. When the partial
1158
+ // (context) snapshot is created, this array is populated with the pointers that
1159
+ // the partial snapshot will need. As that happens we emit serialized objects to
1160
+ // the startup snapshot that correspond to the elements of this cache array. On
1161
+ // deserialization we therefore need to visit the cache array. This fills it up
1162
+ // with pointers to deserialized objects.
1163
+ void SerializerDeserializer::Iterate(ObjectVisitor* visitor) {
1164
+ Isolate* isolate = Isolate::Current();
1165
+ visitor->VisitPointers(
1166
+ isolate->serialize_partial_snapshot_cache(),
1167
+ &isolate->serialize_partial_snapshot_cache()[
1168
+ isolate->serialize_partial_snapshot_cache_length()]);
1169
+ }
1170
+
1171
+
1172
+ // When deserializing we need to set the size of the snapshot cache. This means
1173
+ // the root iteration code (above) will iterate over array elements, writing the
1174
+ // references to deserialized objects in them.
1175
+ void SerializerDeserializer::SetSnapshotCacheSize(int size) {
1176
+ Isolate::Current()->set_serialize_partial_snapshot_cache_length(size);
1177
+ }
1178
+
1179
+
1180
+ int PartialSerializer::PartialSnapshotCacheIndex(HeapObject* heap_object) {
1181
+ Isolate* isolate = Isolate::Current();
1182
+
1183
+ for (int i = 0;
1184
+ i < isolate->serialize_partial_snapshot_cache_length();
1185
+ i++) {
1186
+ Object* entry = isolate->serialize_partial_snapshot_cache()[i];
1187
+ if (entry == heap_object) return i;
1188
+ }
1189
+
1190
+ // We didn't find the object in the cache. So we add it to the cache and
1191
+ // then visit the pointer so that it becomes part of the startup snapshot
1192
+ // and we can refer to it from the partial snapshot.
1193
+ int length = isolate->serialize_partial_snapshot_cache_length();
1194
+ CHECK(length < Isolate::kPartialSnapshotCacheCapacity);
1195
+ isolate->serialize_partial_snapshot_cache()[length] = heap_object;
1196
+ startup_serializer_->VisitPointer(
1197
+ &isolate->serialize_partial_snapshot_cache()[length]);
1198
+ // We don't recurse from the startup snapshot generator into the partial
1199
+ // snapshot generator.
1200
+ ASSERT(length == isolate->serialize_partial_snapshot_cache_length());
1201
+ isolate->set_serialize_partial_snapshot_cache_length(length + 1);
1202
+ return length;
1203
+ }
1204
+
1205
+
1206
+ int PartialSerializer::RootIndex(HeapObject* heap_object) {
1207
+ for (int i = 0; i < Heap::kRootListLength; i++) {
1208
+ Object* root = HEAP->roots_address()[i];
1209
+ if (root == heap_object) return i;
1210
+ }
1211
+ return kInvalidRootIndex;
1212
+ }
1213
+
1214
+
1215
+ // Encode the location of an already deserialized object in order to write its
1216
+ // location into a later object. We can encode the location as an offset from
1217
+ // the start of the deserialized objects or as an offset backwards from the
1218
+ // current allocation pointer.
1219
+ void Serializer::SerializeReferenceToPreviousObject(
1220
+ int space,
1221
+ int address,
1222
+ HowToCode how_to_code,
1223
+ WhereToPoint where_to_point) {
1224
+ int offset = CurrentAllocationAddress(space) - address;
1225
+ bool from_start = true;
1226
+ if (SpaceIsPaged(space)) {
1227
+ // For paged space it is simple to encode back from current allocation if
1228
+ // the object is on the same page as the current allocation pointer.
1229
+ if ((CurrentAllocationAddress(space) >> kPageSizeBits) ==
1230
+ (address >> kPageSizeBits)) {
1231
+ from_start = false;
1232
+ address = offset;
1233
+ }
1234
+ } else if (space == NEW_SPACE) {
1235
+ // For new space it is always simple to encode back from current allocation.
1236
+ if (offset < address) {
1237
+ from_start = false;
1238
+ address = offset;
1239
+ }
1240
+ }
1241
+ // If we are actually dealing with real offsets (and not a numbering of
1242
+ // all objects) then we should shift out the bits that are always 0.
1243
+ if (!SpaceIsLarge(space)) address >>= kObjectAlignmentBits;
1244
+ if (from_start) {
1245
+ #define COMMON_REFS_CASE(pseudo_space, actual_space, offset) \
1246
+ if (space == actual_space && address == offset && \
1247
+ how_to_code == kPlain && where_to_point == kStartOfObject) { \
1248
+ sink_->Put(kFromStart + how_to_code + where_to_point + \
1249
+ pseudo_space, "RefSer"); \
1250
+ } else /* NOLINT */
1251
+ COMMON_REFERENCE_PATTERNS(COMMON_REFS_CASE)
1252
+ #undef COMMON_REFS_CASE
1253
+ { /* NOLINT */
1254
+ sink_->Put(kFromStart + how_to_code + where_to_point + space, "RefSer");
1255
+ sink_->PutInt(address, "address");
1256
+ }
1257
+ } else {
1258
+ sink_->Put(kBackref + how_to_code + where_to_point + space, "BackRefSer");
1259
+ sink_->PutInt(address, "address");
1260
+ }
1261
+ }
1262
+
1263
+
1264
+ void StartupSerializer::SerializeObject(
1265
+ Object* o,
1266
+ HowToCode how_to_code,
1267
+ WhereToPoint where_to_point) {
1268
+ CHECK(o->IsHeapObject());
1269
+ HeapObject* heap_object = HeapObject::cast(o);
1270
+
1271
+ if (address_mapper_.IsMapped(heap_object)) {
1272
+ int space = SpaceOfAlreadySerializedObject(heap_object);
1273
+ int address = address_mapper_.MappedTo(heap_object);
1274
+ SerializeReferenceToPreviousObject(space,
1275
+ address,
1276
+ how_to_code,
1277
+ where_to_point);
1278
+ } else {
1279
+ // Object has not yet been serialized. Serialize it here.
1280
+ ObjectSerializer object_serializer(this,
1281
+ heap_object,
1282
+ sink_,
1283
+ how_to_code,
1284
+ where_to_point);
1285
+ object_serializer.Serialize();
1286
+ }
1287
+ }
1288
+
1289
+
1290
+ void StartupSerializer::SerializeWeakReferences() {
1291
+ for (int i = Isolate::Current()->serialize_partial_snapshot_cache_length();
1292
+ i < Isolate::kPartialSnapshotCacheCapacity;
1293
+ i++) {
1294
+ sink_->Put(kRootArray + kPlain + kStartOfObject, "RootSerialization");
1295
+ sink_->PutInt(Heap::kUndefinedValueRootIndex, "root_index");
1296
+ }
1297
+ HEAP->IterateWeakRoots(this, VISIT_ALL);
1298
+ }
1299
+
1300
+
1301
+ void PartialSerializer::SerializeObject(
1302
+ Object* o,
1303
+ HowToCode how_to_code,
1304
+ WhereToPoint where_to_point) {
1305
+ CHECK(o->IsHeapObject());
1306
+ HeapObject* heap_object = HeapObject::cast(o);
1307
+
1308
+ int root_index;
1309
+ if ((root_index = RootIndex(heap_object)) != kInvalidRootIndex) {
1310
+ sink_->Put(kRootArray + how_to_code + where_to_point, "RootSerialization");
1311
+ sink_->PutInt(root_index, "root_index");
1312
+ return;
1313
+ }
1314
+
1315
+ if (ShouldBeInThePartialSnapshotCache(heap_object)) {
1316
+ int cache_index = PartialSnapshotCacheIndex(heap_object);
1317
+ sink_->Put(kPartialSnapshotCache + how_to_code + where_to_point,
1318
+ "PartialSnapshotCache");
1319
+ sink_->PutInt(cache_index, "partial_snapshot_cache_index");
1320
+ return;
1321
+ }
1322
+
1323
+ // Pointers from the partial snapshot to the objects in the startup snapshot
1324
+ // should go through the root array or through the partial snapshot cache.
1325
+ // If this is not the case you may have to add something to the root array.
1326
+ ASSERT(!startup_serializer_->address_mapper()->IsMapped(heap_object));
1327
+ // All the symbols that the partial snapshot needs should be either in the
1328
+ // root table or in the partial snapshot cache.
1329
+ ASSERT(!heap_object->IsSymbol());
1330
+
1331
+ if (address_mapper_.IsMapped(heap_object)) {
1332
+ int space = SpaceOfAlreadySerializedObject(heap_object);
1333
+ int address = address_mapper_.MappedTo(heap_object);
1334
+ SerializeReferenceToPreviousObject(space,
1335
+ address,
1336
+ how_to_code,
1337
+ where_to_point);
1338
+ } else {
1339
+ // Object has not yet been serialized. Serialize it here.
1340
+ ObjectSerializer serializer(this,
1341
+ heap_object,
1342
+ sink_,
1343
+ how_to_code,
1344
+ where_to_point);
1345
+ serializer.Serialize();
1346
+ }
1347
+ }
1348
+
1349
+
1350
+ void Serializer::ObjectSerializer::Serialize() {
1351
+ int space = Serializer::SpaceOfObject(object_);
1352
+ int size = object_->Size();
1353
+
1354
+ sink_->Put(kNewObject + reference_representation_ + space,
1355
+ "ObjectSerialization");
1356
+ sink_->PutInt(size >> kObjectAlignmentBits, "Size in words");
1357
+
1358
+ LOG(i::Isolate::Current(),
1359
+ SnapshotPositionEvent(object_->address(), sink_->Position()));
1360
+
1361
+ // Mark this object as already serialized.
1362
+ bool start_new_page;
1363
+ int offset = serializer_->Allocate(space, size, &start_new_page);
1364
+ serializer_->address_mapper()->AddMapping(object_, offset);
1365
+ if (start_new_page) {
1366
+ sink_->Put(kNewPage, "NewPage");
1367
+ sink_->PutSection(space, "NewPageSpace");
1368
+ }
1369
+
1370
+ // Serialize the map (first word of the object).
1371
+ serializer_->SerializeObject(object_->map(), kPlain, kStartOfObject);
1372
+
1373
+ // Serialize the rest of the object.
1374
+ CHECK_EQ(0, bytes_processed_so_far_);
1375
+ bytes_processed_so_far_ = kPointerSize;
1376
+ object_->IterateBody(object_->map()->instance_type(), size, this);
1377
+ OutputRawData(object_->address() + size);
1378
+ }
1379
+
1380
+
1381
+ void Serializer::ObjectSerializer::VisitPointers(Object** start,
1382
+ Object** end) {
1383
+ Object** current = start;
1384
+ while (current < end) {
1385
+ while (current < end && (*current)->IsSmi()) current++;
1386
+ if (current < end) OutputRawData(reinterpret_cast<Address>(current));
1387
+
1388
+ while (current < end && !(*current)->IsSmi()) {
1389
+ serializer_->SerializeObject(*current, kPlain, kStartOfObject);
1390
+ bytes_processed_so_far_ += kPointerSize;
1391
+ current++;
1392
+ }
1393
+ }
1394
+ }
1395
+
1396
+
1397
+ void Serializer::ObjectSerializer::VisitExternalReferences(Address* start,
1398
+ Address* end) {
1399
+ Address references_start = reinterpret_cast<Address>(start);
1400
+ OutputRawData(references_start);
1401
+
1402
+ for (Address* current = start; current < end; current++) {
1403
+ sink_->Put(kExternalReference + kPlain + kStartOfObject, "ExternalRef");
1404
+ int reference_id = serializer_->EncodeExternalReference(*current);
1405
+ sink_->PutInt(reference_id, "reference id");
1406
+ }
1407
+ bytes_processed_so_far_ += static_cast<int>((end - start) * kPointerSize);
1408
+ }
1409
+
1410
+
1411
+ void Serializer::ObjectSerializer::VisitRuntimeEntry(RelocInfo* rinfo) {
1412
+ Address target_start = rinfo->target_address_address();
1413
+ OutputRawData(target_start);
1414
+ Address target = rinfo->target_address();
1415
+ uint32_t encoding = serializer_->EncodeExternalReference(target);
1416
+ CHECK(target == NULL ? encoding == 0 : encoding != 0);
1417
+ int representation;
1418
+ // Can't use a ternary operator because of gcc.
1419
+ if (rinfo->IsCodedSpecially()) {
1420
+ representation = kStartOfObject + kFromCode;
1421
+ } else {
1422
+ representation = kStartOfObject + kPlain;
1423
+ }
1424
+ sink_->Put(kExternalReference + representation, "ExternalReference");
1425
+ sink_->PutInt(encoding, "reference id");
1426
+ bytes_processed_so_far_ += rinfo->target_address_size();
1427
+ }
1428
+
1429
+
1430
+ void Serializer::ObjectSerializer::VisitCodeTarget(RelocInfo* rinfo) {
1431
+ CHECK(RelocInfo::IsCodeTarget(rinfo->rmode()));
1432
+ Address target_start = rinfo->target_address_address();
1433
+ OutputRawData(target_start);
1434
+ Code* target = Code::GetCodeFromTargetAddress(rinfo->target_address());
1435
+ serializer_->SerializeObject(target, kFromCode, kFirstInstruction);
1436
+ bytes_processed_so_far_ += rinfo->target_address_size();
1437
+ }
1438
+
1439
+
1440
+ void Serializer::ObjectSerializer::VisitCodeEntry(Address entry_address) {
1441
+ Code* target = Code::cast(Code::GetObjectFromEntryAddress(entry_address));
1442
+ OutputRawData(entry_address);
1443
+ serializer_->SerializeObject(target, kPlain, kFirstInstruction);
1444
+ bytes_processed_so_far_ += kPointerSize;
1445
+ }
1446
+
1447
+
1448
+ void Serializer::ObjectSerializer::VisitGlobalPropertyCell(RelocInfo* rinfo) {
1449
+ // We shouldn't have any global property cell references in code
1450
+ // objects in the snapshot.
1451
+ UNREACHABLE();
1452
+ }
1453
+
1454
+
1455
+ void Serializer::ObjectSerializer::VisitExternalAsciiString(
1456
+ v8::String::ExternalAsciiStringResource** resource_pointer) {
1457
+ Address references_start = reinterpret_cast<Address>(resource_pointer);
1458
+ OutputRawData(references_start);
1459
+ for (int i = 0; i < Natives::GetBuiltinsCount(); i++) {
1460
+ Object* source = HEAP->natives_source_cache()->get(i);
1461
+ if (!source->IsUndefined()) {
1462
+ ExternalAsciiString* string = ExternalAsciiString::cast(source);
1463
+ typedef v8::String::ExternalAsciiStringResource Resource;
1464
+ Resource* resource = string->resource();
1465
+ if (resource == *resource_pointer) {
1466
+ sink_->Put(kNativesStringResource, "NativesStringResource");
1467
+ sink_->PutSection(i, "NativesStringResourceEnd");
1468
+ bytes_processed_so_far_ += sizeof(resource);
1469
+ return;
1470
+ }
1471
+ }
1472
+ }
1473
+ // One of the strings in the natives cache should match the resource. We
1474
+ // can't serialize any other kinds of external strings.
1475
+ UNREACHABLE();
1476
+ }
1477
+
1478
+
1479
+ void Serializer::ObjectSerializer::OutputRawData(Address up_to) {
1480
+ Address object_start = object_->address();
1481
+ int up_to_offset = static_cast<int>(up_to - object_start);
1482
+ int skipped = up_to_offset - bytes_processed_so_far_;
1483
+ // This assert will fail if the reloc info gives us the target_address_address
1484
+ // locations in a non-ascending order. Luckily that doesn't happen.
1485
+ ASSERT(skipped >= 0);
1486
+ if (skipped != 0) {
1487
+ Address base = object_start + bytes_processed_so_far_;
1488
+ #define RAW_CASE(index, length) \
1489
+ if (skipped == length) { \
1490
+ sink_->PutSection(kRawData + index, "RawDataFixed"); \
1491
+ } else /* NOLINT */
1492
+ COMMON_RAW_LENGTHS(RAW_CASE)
1493
+ #undef RAW_CASE
1494
+ { /* NOLINT */
1495
+ sink_->Put(kRawData, "RawData");
1496
+ sink_->PutInt(skipped, "length");
1497
+ }
1498
+ for (int i = 0; i < skipped; i++) {
1499
+ unsigned int data = base[i];
1500
+ sink_->PutSection(data, "Byte");
1501
+ }
1502
+ bytes_processed_so_far_ += skipped;
1503
+ }
1504
+ }
1505
+
1506
+
1507
+ int Serializer::SpaceOfObject(HeapObject* object) {
1508
+ for (int i = FIRST_SPACE; i <= LAST_SPACE; i++) {
1509
+ AllocationSpace s = static_cast<AllocationSpace>(i);
1510
+ if (HEAP->InSpace(object, s)) {
1511
+ if (i == LO_SPACE) {
1512
+ if (object->IsCode()) {
1513
+ return kLargeCode;
1514
+ } else if (object->IsFixedArray()) {
1515
+ return kLargeFixedArray;
1516
+ } else {
1517
+ return kLargeData;
1518
+ }
1519
+ }
1520
+ return i;
1521
+ }
1522
+ }
1523
+ UNREACHABLE();
1524
+ return 0;
1525
+ }
1526
+
1527
+
1528
+ int Serializer::SpaceOfAlreadySerializedObject(HeapObject* object) {
1529
+ for (int i = FIRST_SPACE; i <= LAST_SPACE; i++) {
1530
+ AllocationSpace s = static_cast<AllocationSpace>(i);
1531
+ if (HEAP->InSpace(object, s)) {
1532
+ return i;
1533
+ }
1534
+ }
1535
+ UNREACHABLE();
1536
+ return 0;
1537
+ }
1538
+
1539
+
1540
+ int Serializer::Allocate(int space, int size, bool* new_page) {
1541
+ CHECK(space >= 0 && space < kNumberOfSpaces);
1542
+ if (SpaceIsLarge(space)) {
1543
+ // In large object space we merely number the objects instead of trying to
1544
+ // determine some sort of address.
1545
+ *new_page = true;
1546
+ large_object_total_ += size;
1547
+ return fullness_[LO_SPACE]++;
1548
+ }
1549
+ *new_page = false;
1550
+ if (fullness_[space] == 0) {
1551
+ *new_page = true;
1552
+ }
1553
+ if (SpaceIsPaged(space)) {
1554
+ // Paged spaces are a little special. We encode their addresses as if the
1555
+ // pages were all contiguous and each page were filled up in the range
1556
+ // 0 - Page::kObjectAreaSize. In practice the pages may not be contiguous
1557
+ // and allocation does not start at offset 0 in the page, but this scheme
1558
+ // means the deserializer can get the page number quickly by shifting the
1559
+ // serialized address.
1560
+ CHECK(IsPowerOf2(Page::kPageSize));
1561
+ int used_in_this_page = (fullness_[space] & (Page::kPageSize - 1));
1562
+ CHECK(size <= Page::kObjectAreaSize);
1563
+ if (used_in_this_page + size > Page::kObjectAreaSize) {
1564
+ *new_page = true;
1565
+ fullness_[space] = RoundUp(fullness_[space], Page::kPageSize);
1566
+ }
1567
+ }
1568
+ int allocation_address = fullness_[space];
1569
+ fullness_[space] = allocation_address + size;
1570
+ return allocation_address;
1571
+ }
1572
+
1573
+
1574
+ } } // namespace v8::internal