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,2206 @@
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 "lithium-allocator-inl.h"
31
+ #include "arm/lithium-arm.h"
32
+ #include "arm/lithium-codegen-arm.h"
33
+
34
+ namespace v8 {
35
+ namespace internal {
36
+
37
+ #define DEFINE_COMPILE(type) \
38
+ void L##type::CompileToNative(LCodeGen* generator) { \
39
+ generator->Do##type(this); \
40
+ }
41
+ LITHIUM_CONCRETE_INSTRUCTION_LIST(DEFINE_COMPILE)
42
+ #undef DEFINE_COMPILE
43
+
44
+ LOsrEntry::LOsrEntry() {
45
+ for (int i = 0; i < Register::kNumAllocatableRegisters; ++i) {
46
+ register_spills_[i] = NULL;
47
+ }
48
+ for (int i = 0; i < DoubleRegister::kNumAllocatableRegisters; ++i) {
49
+ double_register_spills_[i] = NULL;
50
+ }
51
+ }
52
+
53
+
54
+ void LOsrEntry::MarkSpilledRegister(int allocation_index,
55
+ LOperand* spill_operand) {
56
+ ASSERT(spill_operand->IsStackSlot());
57
+ ASSERT(register_spills_[allocation_index] == NULL);
58
+ register_spills_[allocation_index] = spill_operand;
59
+ }
60
+
61
+
62
+ #ifdef DEBUG
63
+ void LInstruction::VerifyCall() {
64
+ // Call instructions can use only fixed registers as temporaries and
65
+ // outputs because all registers are blocked by the calling convention.
66
+ // Inputs operands must use a fixed register or use-at-start policy or
67
+ // a non-register policy.
68
+ ASSERT(Output() == NULL ||
69
+ LUnallocated::cast(Output())->HasFixedPolicy() ||
70
+ !LUnallocated::cast(Output())->HasRegisterPolicy());
71
+ for (UseIterator it(this); it.HasNext(); it.Advance()) {
72
+ LUnallocated* operand = LUnallocated::cast(it.Next());
73
+ ASSERT(operand->HasFixedPolicy() ||
74
+ operand->IsUsedAtStart());
75
+ }
76
+ for (TempIterator it(this); it.HasNext(); it.Advance()) {
77
+ LUnallocated* operand = LUnallocated::cast(it.Next());
78
+ ASSERT(operand->HasFixedPolicy() ||!operand->HasRegisterPolicy());
79
+ }
80
+ }
81
+ #endif
82
+
83
+
84
+ void LOsrEntry::MarkSpilledDoubleRegister(int allocation_index,
85
+ LOperand* spill_operand) {
86
+ ASSERT(spill_operand->IsDoubleStackSlot());
87
+ ASSERT(double_register_spills_[allocation_index] == NULL);
88
+ double_register_spills_[allocation_index] = spill_operand;
89
+ }
90
+
91
+
92
+ void LInstruction::PrintTo(StringStream* stream) {
93
+ stream->Add("%s ", this->Mnemonic());
94
+
95
+ PrintOutputOperandTo(stream);
96
+
97
+ PrintDataTo(stream);
98
+
99
+ if (HasEnvironment()) {
100
+ stream->Add(" ");
101
+ environment()->PrintTo(stream);
102
+ }
103
+
104
+ if (HasPointerMap()) {
105
+ stream->Add(" ");
106
+ pointer_map()->PrintTo(stream);
107
+ }
108
+ }
109
+
110
+
111
+ template<int R, int I, int T>
112
+ void LTemplateInstruction<R, I, T>::PrintDataTo(StringStream* stream) {
113
+ stream->Add("= ");
114
+ inputs_.PrintOperandsTo(stream);
115
+ }
116
+
117
+
118
+ template<int R, int I, int T>
119
+ void LTemplateInstruction<R, I, T>::PrintOutputOperandTo(StringStream* stream) {
120
+ results_.PrintOperandsTo(stream);
121
+ }
122
+
123
+
124
+ template<typename T, int N>
125
+ void OperandContainer<T, N>::PrintOperandsTo(StringStream* stream) {
126
+ for (int i = 0; i < N; i++) {
127
+ if (i > 0) stream->Add(" ");
128
+ elems_[i]->PrintTo(stream);
129
+ }
130
+ }
131
+
132
+
133
+ void LLabel::PrintDataTo(StringStream* stream) {
134
+ LGap::PrintDataTo(stream);
135
+ LLabel* rep = replacement();
136
+ if (rep != NULL) {
137
+ stream->Add(" Dead block replaced with B%d", rep->block_id());
138
+ }
139
+ }
140
+
141
+
142
+ bool LGap::IsRedundant() const {
143
+ for (int i = 0; i < 4; i++) {
144
+ if (parallel_moves_[i] != NULL && !parallel_moves_[i]->IsRedundant()) {
145
+ return false;
146
+ }
147
+ }
148
+
149
+ return true;
150
+ }
151
+
152
+
153
+ void LGap::PrintDataTo(StringStream* stream) {
154
+ for (int i = 0; i < 4; i++) {
155
+ stream->Add("(");
156
+ if (parallel_moves_[i] != NULL) {
157
+ parallel_moves_[i]->PrintDataTo(stream);
158
+ }
159
+ stream->Add(") ");
160
+ }
161
+ }
162
+
163
+
164
+ const char* LArithmeticD::Mnemonic() const {
165
+ switch (op()) {
166
+ case Token::ADD: return "add-d";
167
+ case Token::SUB: return "sub-d";
168
+ case Token::MUL: return "mul-d";
169
+ case Token::DIV: return "div-d";
170
+ case Token::MOD: return "mod-d";
171
+ default:
172
+ UNREACHABLE();
173
+ return NULL;
174
+ }
175
+ }
176
+
177
+
178
+ const char* LArithmeticT::Mnemonic() const {
179
+ switch (op()) {
180
+ case Token::ADD: return "add-t";
181
+ case Token::SUB: return "sub-t";
182
+ case Token::MUL: return "mul-t";
183
+ case Token::MOD: return "mod-t";
184
+ case Token::DIV: return "div-t";
185
+ case Token::BIT_AND: return "bit-and-t";
186
+ case Token::BIT_OR: return "bit-or-t";
187
+ case Token::BIT_XOR: return "bit-xor-t";
188
+ case Token::SHL: return "shl-t";
189
+ case Token::SAR: return "sar-t";
190
+ case Token::SHR: return "shr-t";
191
+ default:
192
+ UNREACHABLE();
193
+ return NULL;
194
+ }
195
+ }
196
+
197
+
198
+ void LGoto::PrintDataTo(StringStream* stream) {
199
+ stream->Add("B%d", block_id());
200
+ }
201
+
202
+
203
+ void LBranch::PrintDataTo(StringStream* stream) {
204
+ stream->Add("B%d | B%d on ", true_block_id(), false_block_id());
205
+ InputAt(0)->PrintTo(stream);
206
+ }
207
+
208
+
209
+ void LCmpIDAndBranch::PrintDataTo(StringStream* stream) {
210
+ stream->Add("if ");
211
+ InputAt(0)->PrintTo(stream);
212
+ stream->Add(" %s ", Token::String(op()));
213
+ InputAt(1)->PrintTo(stream);
214
+ stream->Add(" then B%d else B%d", true_block_id(), false_block_id());
215
+ }
216
+
217
+
218
+ void LIsNullAndBranch::PrintDataTo(StringStream* stream) {
219
+ stream->Add("if ");
220
+ InputAt(0)->PrintTo(stream);
221
+ stream->Add(is_strict() ? " === null" : " == null");
222
+ stream->Add(" then B%d else B%d", true_block_id(), false_block_id());
223
+ }
224
+
225
+
226
+ void LIsObjectAndBranch::PrintDataTo(StringStream* stream) {
227
+ stream->Add("if is_object(");
228
+ InputAt(0)->PrintTo(stream);
229
+ stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
230
+ }
231
+
232
+
233
+ void LIsSmiAndBranch::PrintDataTo(StringStream* stream) {
234
+ stream->Add("if is_smi(");
235
+ InputAt(0)->PrintTo(stream);
236
+ stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
237
+ }
238
+
239
+
240
+ void LIsUndetectableAndBranch::PrintDataTo(StringStream* stream) {
241
+ stream->Add("if is_undetectable(");
242
+ InputAt(0)->PrintTo(stream);
243
+ stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
244
+ }
245
+
246
+
247
+ void LHasInstanceTypeAndBranch::PrintDataTo(StringStream* stream) {
248
+ stream->Add("if has_instance_type(");
249
+ InputAt(0)->PrintTo(stream);
250
+ stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
251
+ }
252
+
253
+
254
+ void LHasCachedArrayIndexAndBranch::PrintDataTo(StringStream* stream) {
255
+ stream->Add("if has_cached_array_index(");
256
+ InputAt(0)->PrintTo(stream);
257
+ stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
258
+ }
259
+
260
+
261
+ void LClassOfTestAndBranch::PrintDataTo(StringStream* stream) {
262
+ stream->Add("if class_of_test(");
263
+ InputAt(0)->PrintTo(stream);
264
+ stream->Add(", \"%o\") then B%d else B%d",
265
+ *hydrogen()->class_name(),
266
+ true_block_id(),
267
+ false_block_id());
268
+ }
269
+
270
+
271
+ void LTypeofIs::PrintDataTo(StringStream* stream) {
272
+ InputAt(0)->PrintTo(stream);
273
+ stream->Add(" == \"%s\"", *hydrogen()->type_literal()->ToCString());
274
+ }
275
+
276
+
277
+ void LTypeofIsAndBranch::PrintDataTo(StringStream* stream) {
278
+ stream->Add("if typeof ");
279
+ InputAt(0)->PrintTo(stream);
280
+ stream->Add(" == \"%s\" then B%d else B%d",
281
+ *hydrogen()->type_literal()->ToCString(),
282
+ true_block_id(), false_block_id());
283
+ }
284
+
285
+
286
+ void LCallConstantFunction::PrintDataTo(StringStream* stream) {
287
+ stream->Add("#%d / ", arity());
288
+ }
289
+
290
+
291
+ void LUnaryMathOperation::PrintDataTo(StringStream* stream) {
292
+ stream->Add("/%s ", hydrogen()->OpName());
293
+ InputAt(0)->PrintTo(stream);
294
+ }
295
+
296
+
297
+ void LLoadContextSlot::PrintDataTo(StringStream* stream) {
298
+ InputAt(0)->PrintTo(stream);
299
+ stream->Add("[%d]", slot_index());
300
+ }
301
+
302
+
303
+ void LStoreContextSlot::PrintDataTo(StringStream* stream) {
304
+ InputAt(0)->PrintTo(stream);
305
+ stream->Add("[%d] <- ", slot_index());
306
+ InputAt(1)->PrintTo(stream);
307
+ }
308
+
309
+
310
+ void LInvokeFunction::PrintDataTo(StringStream* stream) {
311
+ stream->Add("= ");
312
+ InputAt(0)->PrintTo(stream);
313
+ stream->Add(" #%d / ", arity());
314
+ }
315
+
316
+
317
+ void LCallKeyed::PrintDataTo(StringStream* stream) {
318
+ stream->Add("[r2] #%d / ", arity());
319
+ }
320
+
321
+
322
+ void LCallNamed::PrintDataTo(StringStream* stream) {
323
+ SmartPointer<char> name_string = name()->ToCString();
324
+ stream->Add("%s #%d / ", *name_string, arity());
325
+ }
326
+
327
+
328
+ void LCallGlobal::PrintDataTo(StringStream* stream) {
329
+ SmartPointer<char> name_string = name()->ToCString();
330
+ stream->Add("%s #%d / ", *name_string, arity());
331
+ }
332
+
333
+
334
+ void LCallKnownGlobal::PrintDataTo(StringStream* stream) {
335
+ stream->Add("#%d / ", arity());
336
+ }
337
+
338
+
339
+ void LCallNew::PrintDataTo(StringStream* stream) {
340
+ stream->Add("= ");
341
+ InputAt(0)->PrintTo(stream);
342
+ stream->Add(" #%d / ", arity());
343
+ }
344
+
345
+
346
+ void LClassOfTest::PrintDataTo(StringStream* stream) {
347
+ stream->Add("= class_of_test(");
348
+ InputAt(0)->PrintTo(stream);
349
+ stream->Add(", \"%o\")", *hydrogen()->class_name());
350
+ }
351
+
352
+
353
+ void LAccessArgumentsAt::PrintDataTo(StringStream* stream) {
354
+ arguments()->PrintTo(stream);
355
+
356
+ stream->Add(" length ");
357
+ length()->PrintTo(stream);
358
+
359
+ stream->Add(" index ");
360
+ index()->PrintTo(stream);
361
+ }
362
+
363
+
364
+ void LStoreNamedField::PrintDataTo(StringStream* stream) {
365
+ object()->PrintTo(stream);
366
+ stream->Add(".");
367
+ stream->Add(*String::cast(*name())->ToCString());
368
+ stream->Add(" <- ");
369
+ value()->PrintTo(stream);
370
+ }
371
+
372
+
373
+ void LStoreNamedGeneric::PrintDataTo(StringStream* stream) {
374
+ object()->PrintTo(stream);
375
+ stream->Add(".");
376
+ stream->Add(*String::cast(*name())->ToCString());
377
+ stream->Add(" <- ");
378
+ value()->PrintTo(stream);
379
+ }
380
+
381
+
382
+ void LStoreKeyedFastElement::PrintDataTo(StringStream* stream) {
383
+ object()->PrintTo(stream);
384
+ stream->Add("[");
385
+ key()->PrintTo(stream);
386
+ stream->Add("] <- ");
387
+ value()->PrintTo(stream);
388
+ }
389
+
390
+
391
+ void LStoreKeyedGeneric::PrintDataTo(StringStream* stream) {
392
+ object()->PrintTo(stream);
393
+ stream->Add("[");
394
+ key()->PrintTo(stream);
395
+ stream->Add("] <- ");
396
+ value()->PrintTo(stream);
397
+ }
398
+
399
+
400
+ LChunk::LChunk(CompilationInfo* info, HGraph* graph)
401
+ : spill_slot_count_(0),
402
+ info_(info),
403
+ graph_(graph),
404
+ instructions_(32),
405
+ pointer_maps_(8),
406
+ inlined_closures_(1) {
407
+ }
408
+
409
+
410
+ int LChunk::GetNextSpillIndex(bool is_double) {
411
+ // Skip a slot if for a double-width slot.
412
+ if (is_double) spill_slot_count_++;
413
+ return spill_slot_count_++;
414
+ }
415
+
416
+
417
+ LOperand* LChunk::GetNextSpillSlot(bool is_double) {
418
+ int index = GetNextSpillIndex(is_double);
419
+ if (is_double) {
420
+ return LDoubleStackSlot::Create(index);
421
+ } else {
422
+ return LStackSlot::Create(index);
423
+ }
424
+ }
425
+
426
+
427
+ void LChunk::MarkEmptyBlocks() {
428
+ HPhase phase("Mark empty blocks", this);
429
+ for (int i = 0; i < graph()->blocks()->length(); ++i) {
430
+ HBasicBlock* block = graph()->blocks()->at(i);
431
+ int first = block->first_instruction_index();
432
+ int last = block->last_instruction_index();
433
+ LInstruction* first_instr = instructions()->at(first);
434
+ LInstruction* last_instr = instructions()->at(last);
435
+
436
+ LLabel* label = LLabel::cast(first_instr);
437
+ if (last_instr->IsGoto()) {
438
+ LGoto* goto_instr = LGoto::cast(last_instr);
439
+ if (!goto_instr->include_stack_check() &&
440
+ label->IsRedundant() &&
441
+ !label->is_loop_header()) {
442
+ bool can_eliminate = true;
443
+ for (int i = first + 1; i < last && can_eliminate; ++i) {
444
+ LInstruction* cur = instructions()->at(i);
445
+ if (cur->IsGap()) {
446
+ LGap* gap = LGap::cast(cur);
447
+ if (!gap->IsRedundant()) {
448
+ can_eliminate = false;
449
+ }
450
+ } else {
451
+ can_eliminate = false;
452
+ }
453
+ }
454
+
455
+ if (can_eliminate) {
456
+ label->set_replacement(GetLabel(goto_instr->block_id()));
457
+ }
458
+ }
459
+ }
460
+ }
461
+ }
462
+
463
+
464
+ void LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) {
465
+ LInstructionGap* gap = new LInstructionGap(block);
466
+ int index = -1;
467
+ if (instr->IsControl()) {
468
+ instructions_.Add(gap);
469
+ index = instructions_.length();
470
+ instructions_.Add(instr);
471
+ } else {
472
+ index = instructions_.length();
473
+ instructions_.Add(instr);
474
+ instructions_.Add(gap);
475
+ }
476
+ if (instr->HasPointerMap()) {
477
+ pointer_maps_.Add(instr->pointer_map());
478
+ instr->pointer_map()->set_lithium_position(index);
479
+ }
480
+ }
481
+
482
+
483
+ LConstantOperand* LChunk::DefineConstantOperand(HConstant* constant) {
484
+ return LConstantOperand::Create(constant->id());
485
+ }
486
+
487
+
488
+ int LChunk::GetParameterStackSlot(int index) const {
489
+ // The receiver is at index 0, the first parameter at index 1, so we
490
+ // shift all parameter indexes down by the number of parameters, and
491
+ // make sure they end up negative so they are distinguishable from
492
+ // spill slots.
493
+ int result = index - info()->scope()->num_parameters() - 1;
494
+ ASSERT(result < 0);
495
+ return result;
496
+ }
497
+
498
+ // A parameter relative to ebp in the arguments stub.
499
+ int LChunk::ParameterAt(int index) {
500
+ ASSERT(-1 <= index); // -1 is the receiver.
501
+ return (1 + info()->scope()->num_parameters() - index) *
502
+ kPointerSize;
503
+ }
504
+
505
+
506
+ LGap* LChunk::GetGapAt(int index) const {
507
+ return LGap::cast(instructions_[index]);
508
+ }
509
+
510
+
511
+ bool LChunk::IsGapAt(int index) const {
512
+ return instructions_[index]->IsGap();
513
+ }
514
+
515
+
516
+ int LChunk::NearestGapPos(int index) const {
517
+ while (!IsGapAt(index)) index--;
518
+ return index;
519
+ }
520
+
521
+
522
+ void LChunk::AddGapMove(int index, LOperand* from, LOperand* to) {
523
+ GetGapAt(index)->GetOrCreateParallelMove(LGap::START)->AddMove(from, to);
524
+ }
525
+
526
+
527
+ Handle<Object> LChunk::LookupLiteral(LConstantOperand* operand) const {
528
+ return HConstant::cast(graph_->LookupValue(operand->index()))->handle();
529
+ }
530
+
531
+
532
+ Representation LChunk::LookupLiteralRepresentation(
533
+ LConstantOperand* operand) const {
534
+ return graph_->LookupValue(operand->index())->representation();
535
+ }
536
+
537
+
538
+ LChunk* LChunkBuilder::Build() {
539
+ ASSERT(is_unused());
540
+ chunk_ = new LChunk(info(), graph());
541
+ HPhase phase("Building chunk", chunk_);
542
+ status_ = BUILDING;
543
+ const ZoneList<HBasicBlock*>* blocks = graph()->blocks();
544
+ for (int i = 0; i < blocks->length(); i++) {
545
+ HBasicBlock* next = NULL;
546
+ if (i < blocks->length() - 1) next = blocks->at(i + 1);
547
+ DoBasicBlock(blocks->at(i), next);
548
+ if (is_aborted()) return NULL;
549
+ }
550
+ status_ = DONE;
551
+ return chunk_;
552
+ }
553
+
554
+
555
+ void LChunkBuilder::Abort(const char* format, ...) {
556
+ if (FLAG_trace_bailout) {
557
+ SmartPointer<char> name(info()->shared_info()->DebugName()->ToCString());
558
+ PrintF("Aborting LChunk building in @\"%s\": ", *name);
559
+ va_list arguments;
560
+ va_start(arguments, format);
561
+ OS::VPrint(format, arguments);
562
+ va_end(arguments);
563
+ PrintF("\n");
564
+ }
565
+ status_ = ABORTED;
566
+ }
567
+
568
+
569
+ LRegister* LChunkBuilder::ToOperand(Register reg) {
570
+ return LRegister::Create(Register::ToAllocationIndex(reg));
571
+ }
572
+
573
+
574
+ LUnallocated* LChunkBuilder::ToUnallocated(Register reg) {
575
+ return new LUnallocated(LUnallocated::FIXED_REGISTER,
576
+ Register::ToAllocationIndex(reg));
577
+ }
578
+
579
+
580
+ LUnallocated* LChunkBuilder::ToUnallocated(DoubleRegister reg) {
581
+ return new LUnallocated(LUnallocated::FIXED_DOUBLE_REGISTER,
582
+ DoubleRegister::ToAllocationIndex(reg));
583
+ }
584
+
585
+
586
+ LOperand* LChunkBuilder::UseFixed(HValue* value, Register fixed_register) {
587
+ return Use(value, ToUnallocated(fixed_register));
588
+ }
589
+
590
+
591
+ LOperand* LChunkBuilder::UseFixedDouble(HValue* value, DoubleRegister reg) {
592
+ return Use(value, ToUnallocated(reg));
593
+ }
594
+
595
+
596
+ LOperand* LChunkBuilder::UseRegister(HValue* value) {
597
+ return Use(value, new LUnallocated(LUnallocated::MUST_HAVE_REGISTER));
598
+ }
599
+
600
+
601
+ LOperand* LChunkBuilder::UseRegisterAtStart(HValue* value) {
602
+ return Use(value,
603
+ new LUnallocated(LUnallocated::MUST_HAVE_REGISTER,
604
+ LUnallocated::USED_AT_START));
605
+ }
606
+
607
+
608
+ LOperand* LChunkBuilder::UseTempRegister(HValue* value) {
609
+ return Use(value, new LUnallocated(LUnallocated::WRITABLE_REGISTER));
610
+ }
611
+
612
+
613
+ LOperand* LChunkBuilder::Use(HValue* value) {
614
+ return Use(value, new LUnallocated(LUnallocated::NONE));
615
+ }
616
+
617
+
618
+ LOperand* LChunkBuilder::UseAtStart(HValue* value) {
619
+ return Use(value, new LUnallocated(LUnallocated::NONE,
620
+ LUnallocated::USED_AT_START));
621
+ }
622
+
623
+
624
+ LOperand* LChunkBuilder::UseOrConstant(HValue* value) {
625
+ return value->IsConstant()
626
+ ? chunk_->DefineConstantOperand(HConstant::cast(value))
627
+ : Use(value);
628
+ }
629
+
630
+
631
+ LOperand* LChunkBuilder::UseOrConstantAtStart(HValue* value) {
632
+ return value->IsConstant()
633
+ ? chunk_->DefineConstantOperand(HConstant::cast(value))
634
+ : UseAtStart(value);
635
+ }
636
+
637
+
638
+ LOperand* LChunkBuilder::UseRegisterOrConstant(HValue* value) {
639
+ return value->IsConstant()
640
+ ? chunk_->DefineConstantOperand(HConstant::cast(value))
641
+ : UseRegister(value);
642
+ }
643
+
644
+
645
+ LOperand* LChunkBuilder::UseRegisterOrConstantAtStart(HValue* value) {
646
+ return value->IsConstant()
647
+ ? chunk_->DefineConstantOperand(HConstant::cast(value))
648
+ : UseRegisterAtStart(value);
649
+ }
650
+
651
+
652
+ LOperand* LChunkBuilder::UseAny(HValue* value) {
653
+ return value->IsConstant()
654
+ ? chunk_->DefineConstantOperand(HConstant::cast(value))
655
+ : Use(value, new LUnallocated(LUnallocated::ANY));
656
+ }
657
+
658
+
659
+ LOperand* LChunkBuilder::Use(HValue* value, LUnallocated* operand) {
660
+ if (value->EmitAtUses()) {
661
+ HInstruction* instr = HInstruction::cast(value);
662
+ VisitInstruction(instr);
663
+ }
664
+ allocator_->RecordUse(value, operand);
665
+ return operand;
666
+ }
667
+
668
+
669
+ template<int I, int T>
670
+ LInstruction* LChunkBuilder::Define(LTemplateInstruction<1, I, T>* instr,
671
+ LUnallocated* result) {
672
+ allocator_->RecordDefinition(current_instruction_, result);
673
+ instr->set_result(result);
674
+ return instr;
675
+ }
676
+
677
+
678
+ template<int I, int T>
679
+ LInstruction* LChunkBuilder::Define(LTemplateInstruction<1, I, T>* instr) {
680
+ return Define(instr, new LUnallocated(LUnallocated::NONE));
681
+ }
682
+
683
+
684
+ template<int I, int T>
685
+ LInstruction* LChunkBuilder::DefineAsRegister(
686
+ LTemplateInstruction<1, I, T>* instr) {
687
+ return Define(instr, new LUnallocated(LUnallocated::MUST_HAVE_REGISTER));
688
+ }
689
+
690
+
691
+ template<int I, int T>
692
+ LInstruction* LChunkBuilder::DefineAsSpilled(
693
+ LTemplateInstruction<1, I, T>* instr, int index) {
694
+ return Define(instr, new LUnallocated(LUnallocated::FIXED_SLOT, index));
695
+ }
696
+
697
+
698
+ template<int I, int T>
699
+ LInstruction* LChunkBuilder::DefineSameAsFirst(
700
+ LTemplateInstruction<1, I, T>* instr) {
701
+ return Define(instr, new LUnallocated(LUnallocated::SAME_AS_FIRST_INPUT));
702
+ }
703
+
704
+
705
+ template<int I, int T>
706
+ LInstruction* LChunkBuilder::DefineFixed(
707
+ LTemplateInstruction<1, I, T>* instr, Register reg) {
708
+ return Define(instr, ToUnallocated(reg));
709
+ }
710
+
711
+
712
+ template<int I, int T>
713
+ LInstruction* LChunkBuilder::DefineFixedDouble(
714
+ LTemplateInstruction<1, I, T>* instr, DoubleRegister reg) {
715
+ return Define(instr, ToUnallocated(reg));
716
+ }
717
+
718
+
719
+ LInstruction* LChunkBuilder::AssignEnvironment(LInstruction* instr) {
720
+ HEnvironment* hydrogen_env = current_block_->last_environment();
721
+ instr->set_environment(CreateEnvironment(hydrogen_env));
722
+ return instr;
723
+ }
724
+
725
+
726
+ LInstruction* LChunkBuilder::SetInstructionPendingDeoptimizationEnvironment(
727
+ LInstruction* instr, int ast_id) {
728
+ ASSERT(instruction_pending_deoptimization_environment_ == NULL);
729
+ ASSERT(pending_deoptimization_ast_id_ == AstNode::kNoNumber);
730
+ instruction_pending_deoptimization_environment_ = instr;
731
+ pending_deoptimization_ast_id_ = ast_id;
732
+ return instr;
733
+ }
734
+
735
+
736
+ void LChunkBuilder::ClearInstructionPendingDeoptimizationEnvironment() {
737
+ instruction_pending_deoptimization_environment_ = NULL;
738
+ pending_deoptimization_ast_id_ = AstNode::kNoNumber;
739
+ }
740
+
741
+
742
+ LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr,
743
+ HInstruction* hinstr,
744
+ CanDeoptimize can_deoptimize) {
745
+ #ifdef DEBUG
746
+ instr->VerifyCall();
747
+ #endif
748
+ instr->MarkAsCall();
749
+ instr = AssignPointerMap(instr);
750
+
751
+ if (hinstr->HasSideEffects()) {
752
+ ASSERT(hinstr->next()->IsSimulate());
753
+ HSimulate* sim = HSimulate::cast(hinstr->next());
754
+ instr = SetInstructionPendingDeoptimizationEnvironment(
755
+ instr, sim->ast_id());
756
+ }
757
+
758
+ // If instruction does not have side-effects lazy deoptimization
759
+ // after the call will try to deoptimize to the point before the call.
760
+ // Thus we still need to attach environment to this call even if
761
+ // call sequence can not deoptimize eagerly.
762
+ bool needs_environment =
763
+ (can_deoptimize == CAN_DEOPTIMIZE_EAGERLY) || !hinstr->HasSideEffects();
764
+ if (needs_environment && !instr->HasEnvironment()) {
765
+ instr = AssignEnvironment(instr);
766
+ }
767
+
768
+ return instr;
769
+ }
770
+
771
+
772
+ LInstruction* LChunkBuilder::MarkAsSaveDoubles(LInstruction* instr) {
773
+ instr->MarkAsSaveDoubles();
774
+ return instr;
775
+ }
776
+
777
+
778
+ LInstruction* LChunkBuilder::AssignPointerMap(LInstruction* instr) {
779
+ ASSERT(!instr->HasPointerMap());
780
+ instr->set_pointer_map(new LPointerMap(position_));
781
+ return instr;
782
+ }
783
+
784
+
785
+ LUnallocated* LChunkBuilder::TempRegister() {
786
+ LUnallocated* operand = new LUnallocated(LUnallocated::MUST_HAVE_REGISTER);
787
+ allocator_->RecordTemporary(operand);
788
+ return operand;
789
+ }
790
+
791
+
792
+ LOperand* LChunkBuilder::FixedTemp(Register reg) {
793
+ LUnallocated* operand = ToUnallocated(reg);
794
+ allocator_->RecordTemporary(operand);
795
+ return operand;
796
+ }
797
+
798
+
799
+ LOperand* LChunkBuilder::FixedTemp(DoubleRegister reg) {
800
+ LUnallocated* operand = ToUnallocated(reg);
801
+ allocator_->RecordTemporary(operand);
802
+ return operand;
803
+ }
804
+
805
+
806
+ LInstruction* LChunkBuilder::DoBlockEntry(HBlockEntry* instr) {
807
+ return new LLabel(instr->block());
808
+ }
809
+
810
+
811
+ LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) {
812
+ return AssignEnvironment(new LDeoptimize);
813
+ }
814
+
815
+
816
+ LInstruction* LChunkBuilder::DoBit(Token::Value op,
817
+ HBitwiseBinaryOperation* instr) {
818
+ if (instr->representation().IsInteger32()) {
819
+ ASSERT(instr->left()->representation().IsInteger32());
820
+ ASSERT(instr->right()->representation().IsInteger32());
821
+
822
+ LOperand* left = UseRegisterAtStart(instr->LeastConstantOperand());
823
+ LOperand* right = UseOrConstantAtStart(instr->MostConstantOperand());
824
+ return DefineSameAsFirst(new LBitI(op, left, right));
825
+ } else {
826
+ ASSERT(instr->representation().IsTagged());
827
+ ASSERT(instr->left()->representation().IsTagged());
828
+ ASSERT(instr->right()->representation().IsTagged());
829
+
830
+ LOperand* left = UseFixed(instr->left(), r1);
831
+ LOperand* right = UseFixed(instr->right(), r0);
832
+ LArithmeticT* result = new LArithmeticT(op, left, right);
833
+ return MarkAsCall(DefineFixed(result, r0), instr);
834
+ }
835
+ }
836
+
837
+
838
+ LInstruction* LChunkBuilder::DoShift(Token::Value op,
839
+ HBitwiseBinaryOperation* instr) {
840
+ if (instr->representation().IsTagged()) {
841
+ ASSERT(instr->left()->representation().IsTagged());
842
+ ASSERT(instr->right()->representation().IsTagged());
843
+
844
+ LOperand* left = UseFixed(instr->left(), r1);
845
+ LOperand* right = UseFixed(instr->right(), r0);
846
+ LArithmeticT* result = new LArithmeticT(op, left, right);
847
+ return MarkAsCall(DefineFixed(result, r0), instr);
848
+ }
849
+
850
+ ASSERT(instr->representation().IsInteger32());
851
+ ASSERT(instr->OperandAt(0)->representation().IsInteger32());
852
+ ASSERT(instr->OperandAt(1)->representation().IsInteger32());
853
+ LOperand* left = UseRegisterAtStart(instr->OperandAt(0));
854
+
855
+ HValue* right_value = instr->OperandAt(1);
856
+ LOperand* right = NULL;
857
+ int constant_value = 0;
858
+ if (right_value->IsConstant()) {
859
+ HConstant* constant = HConstant::cast(right_value);
860
+ right = chunk_->DefineConstantOperand(constant);
861
+ constant_value = constant->Integer32Value() & 0x1f;
862
+ } else {
863
+ right = UseRegister(right_value);
864
+ }
865
+
866
+ // Shift operations can only deoptimize if we do a logical shift
867
+ // by 0 and the result cannot be truncated to int32.
868
+ bool may_deopt = (op == Token::SHR && constant_value == 0);
869
+ bool does_deopt = false;
870
+ if (may_deopt) {
871
+ for (HUseIterator it(instr->uses()); !it.Done(); it.Advance()) {
872
+ if (!it.value()->CheckFlag(HValue::kTruncatingToInt32)) {
873
+ does_deopt = true;
874
+ break;
875
+ }
876
+ }
877
+ }
878
+
879
+ LInstruction* result =
880
+ DefineSameAsFirst(new LShiftI(op, left, right, does_deopt));
881
+ return does_deopt ? AssignEnvironment(result) : result;
882
+ }
883
+
884
+
885
+ LInstruction* LChunkBuilder::DoArithmeticD(Token::Value op,
886
+ HArithmeticBinaryOperation* instr) {
887
+ ASSERT(instr->representation().IsDouble());
888
+ ASSERT(instr->left()->representation().IsDouble());
889
+ ASSERT(instr->right()->representation().IsDouble());
890
+ ASSERT(op != Token::MOD);
891
+ LOperand* left = UseRegisterAtStart(instr->left());
892
+ LOperand* right = UseRegisterAtStart(instr->right());
893
+ LArithmeticD* result = new LArithmeticD(op, left, right);
894
+ return DefineSameAsFirst(result);
895
+ }
896
+
897
+
898
+ LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op,
899
+ HArithmeticBinaryOperation* instr) {
900
+ ASSERT(op == Token::ADD ||
901
+ op == Token::DIV ||
902
+ op == Token::MOD ||
903
+ op == Token::MUL ||
904
+ op == Token::SUB);
905
+ HValue* left = instr->left();
906
+ HValue* right = instr->right();
907
+ ASSERT(left->representation().IsTagged());
908
+ ASSERT(right->representation().IsTagged());
909
+ LOperand* left_operand = UseFixed(left, r1);
910
+ LOperand* right_operand = UseFixed(right, r0);
911
+ LArithmeticT* result = new LArithmeticT(op, left_operand, right_operand);
912
+ return MarkAsCall(DefineFixed(result, r0), instr);
913
+ }
914
+
915
+
916
+ void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) {
917
+ ASSERT(is_building());
918
+ current_block_ = block;
919
+ next_block_ = next_block;
920
+ if (block->IsStartBlock()) {
921
+ block->UpdateEnvironment(graph_->start_environment());
922
+ argument_count_ = 0;
923
+ } else if (block->predecessors()->length() == 1) {
924
+ // We have a single predecessor => copy environment and outgoing
925
+ // argument count from the predecessor.
926
+ ASSERT(block->phis()->length() == 0);
927
+ HBasicBlock* pred = block->predecessors()->at(0);
928
+ HEnvironment* last_environment = pred->last_environment();
929
+ ASSERT(last_environment != NULL);
930
+ // Only copy the environment, if it is later used again.
931
+ if (pred->end()->SecondSuccessor() == NULL) {
932
+ ASSERT(pred->end()->FirstSuccessor() == block);
933
+ } else {
934
+ if (pred->end()->FirstSuccessor()->block_id() > block->block_id() ||
935
+ pred->end()->SecondSuccessor()->block_id() > block->block_id()) {
936
+ last_environment = last_environment->Copy();
937
+ }
938
+ }
939
+ block->UpdateEnvironment(last_environment);
940
+ ASSERT(pred->argument_count() >= 0);
941
+ argument_count_ = pred->argument_count();
942
+ } else {
943
+ // We are at a state join => process phis.
944
+ HBasicBlock* pred = block->predecessors()->at(0);
945
+ // No need to copy the environment, it cannot be used later.
946
+ HEnvironment* last_environment = pred->last_environment();
947
+ for (int i = 0; i < block->phis()->length(); ++i) {
948
+ HPhi* phi = block->phis()->at(i);
949
+ last_environment->SetValueAt(phi->merged_index(), phi);
950
+ }
951
+ for (int i = 0; i < block->deleted_phis()->length(); ++i) {
952
+ last_environment->SetValueAt(block->deleted_phis()->at(i),
953
+ graph_->GetConstantUndefined());
954
+ }
955
+ block->UpdateEnvironment(last_environment);
956
+ // Pick up the outgoing argument count of one of the predecessors.
957
+ argument_count_ = pred->argument_count();
958
+ }
959
+ HInstruction* current = block->first();
960
+ int start = chunk_->instructions()->length();
961
+ while (current != NULL && !is_aborted()) {
962
+ // Code for constants in registers is generated lazily.
963
+ if (!current->EmitAtUses()) {
964
+ VisitInstruction(current);
965
+ }
966
+ current = current->next();
967
+ }
968
+ int end = chunk_->instructions()->length() - 1;
969
+ if (end >= start) {
970
+ block->set_first_instruction_index(start);
971
+ block->set_last_instruction_index(end);
972
+ }
973
+ block->set_argument_count(argument_count_);
974
+ next_block_ = NULL;
975
+ current_block_ = NULL;
976
+ }
977
+
978
+
979
+ void LChunkBuilder::VisitInstruction(HInstruction* current) {
980
+ HInstruction* old_current = current_instruction_;
981
+ current_instruction_ = current;
982
+ if (current->has_position()) position_ = current->position();
983
+ LInstruction* instr = current->CompileToLithium(this);
984
+
985
+ if (instr != NULL) {
986
+ if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) {
987
+ instr = AssignPointerMap(instr);
988
+ }
989
+ if (FLAG_stress_environments && !instr->HasEnvironment()) {
990
+ instr = AssignEnvironment(instr);
991
+ }
992
+ if (current->IsTest() && !instr->IsGoto()) {
993
+ ASSERT(instr->IsControl());
994
+ HTest* test = HTest::cast(current);
995
+ instr->set_hydrogen_value(test->value());
996
+ HBasicBlock* first = test->FirstSuccessor();
997
+ HBasicBlock* second = test->SecondSuccessor();
998
+ ASSERT(first != NULL && second != NULL);
999
+ instr->SetBranchTargets(first->block_id(), second->block_id());
1000
+ } else {
1001
+ instr->set_hydrogen_value(current);
1002
+ }
1003
+
1004
+ chunk_->AddInstruction(instr, current_block_);
1005
+ }
1006
+ current_instruction_ = old_current;
1007
+ }
1008
+
1009
+
1010
+ LEnvironment* LChunkBuilder::CreateEnvironment(HEnvironment* hydrogen_env) {
1011
+ if (hydrogen_env == NULL) return NULL;
1012
+
1013
+ LEnvironment* outer = CreateEnvironment(hydrogen_env->outer());
1014
+ int ast_id = hydrogen_env->ast_id();
1015
+ ASSERT(ast_id != AstNode::kNoNumber);
1016
+ int value_count = hydrogen_env->length();
1017
+ LEnvironment* result = new LEnvironment(hydrogen_env->closure(),
1018
+ ast_id,
1019
+ hydrogen_env->parameter_count(),
1020
+ argument_count_,
1021
+ value_count,
1022
+ outer);
1023
+ int argument_index = 0;
1024
+ for (int i = 0; i < value_count; ++i) {
1025
+ if (hydrogen_env->is_special_index(i)) continue;
1026
+
1027
+ HValue* value = hydrogen_env->values()->at(i);
1028
+ LOperand* op = NULL;
1029
+ if (value->IsArgumentsObject()) {
1030
+ op = NULL;
1031
+ } else if (value->IsPushArgument()) {
1032
+ op = new LArgument(argument_index++);
1033
+ } else {
1034
+ op = UseAny(value);
1035
+ }
1036
+ result->AddValue(op, value->representation());
1037
+ }
1038
+
1039
+ return result;
1040
+ }
1041
+
1042
+
1043
+ LInstruction* LChunkBuilder::DoGoto(HGoto* instr) {
1044
+ LInstruction* result = new LGoto(instr->FirstSuccessor()->block_id(),
1045
+ instr->include_stack_check());
1046
+ if (instr->include_stack_check()) result = AssignPointerMap(result);
1047
+ return result;
1048
+ }
1049
+
1050
+
1051
+ LInstruction* LChunkBuilder::DoTest(HTest* instr) {
1052
+ HValue* v = instr->value();
1053
+ if (!v->EmitAtUses()) {
1054
+ return new LBranch(UseRegisterAtStart(v));
1055
+ } else if (v->IsClassOfTest()) {
1056
+ HClassOfTest* compare = HClassOfTest::cast(v);
1057
+ ASSERT(compare->value()->representation().IsTagged());
1058
+ return new LClassOfTestAndBranch(UseTempRegister(compare->value()),
1059
+ TempRegister());
1060
+ } else if (v->IsCompare()) {
1061
+ HCompare* compare = HCompare::cast(v);
1062
+ Token::Value op = compare->token();
1063
+ HValue* left = compare->left();
1064
+ HValue* right = compare->right();
1065
+ Representation r = compare->GetInputRepresentation();
1066
+ if (r.IsInteger32()) {
1067
+ ASSERT(left->representation().IsInteger32());
1068
+ ASSERT(right->representation().IsInteger32());
1069
+ return new LCmpIDAndBranch(UseRegisterAtStart(left),
1070
+ UseRegisterAtStart(right));
1071
+ } else if (r.IsDouble()) {
1072
+ ASSERT(left->representation().IsDouble());
1073
+ ASSERT(right->representation().IsDouble());
1074
+ return new LCmpIDAndBranch(UseRegisterAtStart(left),
1075
+ UseRegisterAtStart(right));
1076
+ } else {
1077
+ ASSERT(left->representation().IsTagged());
1078
+ ASSERT(right->representation().IsTagged());
1079
+ bool reversed = op == Token::GT || op == Token::LTE;
1080
+ LOperand* left_operand = UseFixed(left, reversed ? r0 : r1);
1081
+ LOperand* right_operand = UseFixed(right, reversed ? r1 : r0);
1082
+ LInstruction* result = new LCmpTAndBranch(left_operand, right_operand);
1083
+ return MarkAsCall(result, instr);
1084
+ }
1085
+ } else if (v->IsIsSmi()) {
1086
+ HIsSmi* compare = HIsSmi::cast(v);
1087
+ ASSERT(compare->value()->representation().IsTagged());
1088
+ return new LIsSmiAndBranch(Use(compare->value()));
1089
+ } else if (v->IsIsUndetectable()) {
1090
+ HIsUndetectable* compare = HIsUndetectable::cast(v);
1091
+ ASSERT(compare->value()->representation().IsTagged());
1092
+ return new LIsUndetectableAndBranch(UseRegisterAtStart(compare->value()),
1093
+ TempRegister());
1094
+ } else if (v->IsHasInstanceType()) {
1095
+ HHasInstanceType* compare = HHasInstanceType::cast(v);
1096
+ ASSERT(compare->value()->representation().IsTagged());
1097
+ return new LHasInstanceTypeAndBranch(UseRegisterAtStart(compare->value()));
1098
+ } else if (v->IsHasCachedArrayIndex()) {
1099
+ HHasCachedArrayIndex* compare = HHasCachedArrayIndex::cast(v);
1100
+ ASSERT(compare->value()->representation().IsTagged());
1101
+ return new LHasCachedArrayIndexAndBranch(
1102
+ UseRegisterAtStart(compare->value()));
1103
+ } else if (v->IsIsNull()) {
1104
+ HIsNull* compare = HIsNull::cast(v);
1105
+ ASSERT(compare->value()->representation().IsTagged());
1106
+ return new LIsNullAndBranch(UseRegisterAtStart(compare->value()));
1107
+ } else if (v->IsIsObject()) {
1108
+ HIsObject* compare = HIsObject::cast(v);
1109
+ ASSERT(compare->value()->representation().IsTagged());
1110
+ LOperand* temp = TempRegister();
1111
+ return new LIsObjectAndBranch(UseRegisterAtStart(compare->value()), temp);
1112
+ } else if (v->IsCompareJSObjectEq()) {
1113
+ HCompareJSObjectEq* compare = HCompareJSObjectEq::cast(v);
1114
+ return new LCmpJSObjectEqAndBranch(UseRegisterAtStart(compare->left()),
1115
+ UseRegisterAtStart(compare->right()));
1116
+ } else if (v->IsCompareSymbolEq()) {
1117
+ HCompareSymbolEq* compare = HCompareSymbolEq::cast(v);
1118
+ return new LCmpSymbolEqAndBranch(UseRegisterAtStart(compare->left()),
1119
+ UseRegisterAtStart(compare->right()));
1120
+ } else if (v->IsInstanceOf()) {
1121
+ HInstanceOf* instance_of = HInstanceOf::cast(v);
1122
+ LInstruction* result =
1123
+ new LInstanceOfAndBranch(UseFixed(instance_of->left(), r0),
1124
+ UseFixed(instance_of->right(), r1));
1125
+ return MarkAsCall(result, instr);
1126
+ } else if (v->IsTypeofIs()) {
1127
+ HTypeofIs* typeof_is = HTypeofIs::cast(v);
1128
+ return new LTypeofIsAndBranch(UseTempRegister(typeof_is->value()));
1129
+ } else if (v->IsIsConstructCall()) {
1130
+ return new LIsConstructCallAndBranch(TempRegister());
1131
+ } else if (v->IsConstant()) {
1132
+ HBasicBlock* successor = HConstant::cast(v)->ToBoolean()
1133
+ ? instr->FirstSuccessor()
1134
+ : instr->SecondSuccessor();
1135
+ return new LGoto(successor->block_id());
1136
+ } else {
1137
+ Abort("Undefined compare before branch");
1138
+ return NULL;
1139
+ }
1140
+ }
1141
+
1142
+
1143
+
1144
+ LInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) {
1145
+ ASSERT(instr->value()->representation().IsTagged());
1146
+ LOperand* value = UseRegisterAtStart(instr->value());
1147
+ LOperand* temp = TempRegister();
1148
+ return new LCmpMapAndBranch(value, temp);
1149
+ }
1150
+
1151
+
1152
+ LInstruction* LChunkBuilder::DoArgumentsLength(HArgumentsLength* length) {
1153
+ return DefineAsRegister(new LArgumentsLength(UseRegister(length->value())));
1154
+ }
1155
+
1156
+
1157
+ LInstruction* LChunkBuilder::DoArgumentsElements(HArgumentsElements* elems) {
1158
+ return DefineAsRegister(new LArgumentsElements);
1159
+ }
1160
+
1161
+
1162
+ LInstruction* LChunkBuilder::DoInstanceOf(HInstanceOf* instr) {
1163
+ LInstanceOf* result =
1164
+ new LInstanceOf(UseFixed(instr->left(), r0),
1165
+ UseFixed(instr->right(), r1));
1166
+ return MarkAsCall(DefineFixed(result, r0), instr);
1167
+ }
1168
+
1169
+
1170
+ LInstruction* LChunkBuilder::DoInstanceOfKnownGlobal(
1171
+ HInstanceOfKnownGlobal* instr) {
1172
+ LInstanceOfKnownGlobal* result =
1173
+ new LInstanceOfKnownGlobal(UseFixed(instr->value(), r0), FixedTemp(r4));
1174
+ return MarkAsCall(DefineFixed(result, r0), instr);
1175
+ }
1176
+
1177
+
1178
+ LInstruction* LChunkBuilder::DoApplyArguments(HApplyArguments* instr) {
1179
+ LOperand* function = UseFixed(instr->function(), r1);
1180
+ LOperand* receiver = UseFixed(instr->receiver(), r0);
1181
+ LOperand* length = UseFixed(instr->length(), r2);
1182
+ LOperand* elements = UseFixed(instr->elements(), r3);
1183
+ LApplyArguments* result = new LApplyArguments(function,
1184
+ receiver,
1185
+ length,
1186
+ elements);
1187
+ return MarkAsCall(DefineFixed(result, r0), instr, CAN_DEOPTIMIZE_EAGERLY);
1188
+ }
1189
+
1190
+
1191
+ LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) {
1192
+ ++argument_count_;
1193
+ LOperand* argument = Use(instr->argument());
1194
+ return new LPushArgument(argument);
1195
+ }
1196
+
1197
+
1198
+ LInstruction* LChunkBuilder::DoContext(HContext* instr) {
1199
+ return instr->HasNoUses() ? NULL : DefineAsRegister(new LContext);
1200
+ }
1201
+
1202
+
1203
+ LInstruction* LChunkBuilder::DoOuterContext(HOuterContext* instr) {
1204
+ LOperand* context = UseRegisterAtStart(instr->value());
1205
+ return DefineAsRegister(new LOuterContext(context));
1206
+ }
1207
+
1208
+
1209
+ LInstruction* LChunkBuilder::DoGlobalObject(HGlobalObject* instr) {
1210
+ LOperand* context = UseRegisterAtStart(instr->value());
1211
+ return DefineAsRegister(new LGlobalObject(context));
1212
+ }
1213
+
1214
+
1215
+ LInstruction* LChunkBuilder::DoGlobalReceiver(HGlobalReceiver* instr) {
1216
+ LOperand* global_object = UseRegisterAtStart(instr->value());
1217
+ return DefineAsRegister(new LGlobalReceiver(global_object));
1218
+ }
1219
+
1220
+
1221
+ LInstruction* LChunkBuilder::DoCallConstantFunction(
1222
+ HCallConstantFunction* instr) {
1223
+ argument_count_ -= instr->argument_count();
1224
+ return MarkAsCall(DefineFixed(new LCallConstantFunction, r0), instr);
1225
+ }
1226
+
1227
+
1228
+ LInstruction* LChunkBuilder::DoInvokeFunction(HInvokeFunction* instr) {
1229
+ LOperand* function = UseFixed(instr->function(), r1);
1230
+ argument_count_ -= instr->argument_count();
1231
+ LInvokeFunction* result = new LInvokeFunction(function);
1232
+ return MarkAsCall(DefineFixed(result, r0), instr, CANNOT_DEOPTIMIZE_EAGERLY);
1233
+ }
1234
+
1235
+
1236
+ LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) {
1237
+ BuiltinFunctionId op = instr->op();
1238
+ if (op == kMathLog || op == kMathSin || op == kMathCos) {
1239
+ LOperand* input = UseFixedDouble(instr->value(), d2);
1240
+ LUnaryMathOperation* result = new LUnaryMathOperation(input, NULL);
1241
+ return MarkAsCall(DefineFixedDouble(result, d2), instr);
1242
+ } else {
1243
+ LOperand* input = UseRegisterAtStart(instr->value());
1244
+ LOperand* temp = (op == kMathFloor) ? TempRegister() : NULL;
1245
+ LUnaryMathOperation* result = new LUnaryMathOperation(input, temp);
1246
+ switch (op) {
1247
+ case kMathAbs:
1248
+ return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result)));
1249
+ case kMathFloor:
1250
+ return AssignEnvironment(AssignPointerMap(DefineAsRegister(result)));
1251
+ case kMathSqrt:
1252
+ return DefineSameAsFirst(result);
1253
+ case kMathRound:
1254
+ return AssignEnvironment(DefineAsRegister(result));
1255
+ case kMathPowHalf:
1256
+ return DefineSameAsFirst(result);
1257
+ default:
1258
+ UNREACHABLE();
1259
+ return NULL;
1260
+ }
1261
+ }
1262
+ }
1263
+
1264
+
1265
+ LInstruction* LChunkBuilder::DoCallKeyed(HCallKeyed* instr) {
1266
+ ASSERT(instr->key()->representation().IsTagged());
1267
+ argument_count_ -= instr->argument_count();
1268
+ LOperand* key = UseFixed(instr->key(), r2);
1269
+ return MarkAsCall(DefineFixed(new LCallKeyed(key), r0), instr);
1270
+ }
1271
+
1272
+
1273
+ LInstruction* LChunkBuilder::DoCallNamed(HCallNamed* instr) {
1274
+ argument_count_ -= instr->argument_count();
1275
+ return MarkAsCall(DefineFixed(new LCallNamed, r0), instr);
1276
+ }
1277
+
1278
+
1279
+ LInstruction* LChunkBuilder::DoCallGlobal(HCallGlobal* instr) {
1280
+ argument_count_ -= instr->argument_count();
1281
+ return MarkAsCall(DefineFixed(new LCallGlobal, r0), instr);
1282
+ }
1283
+
1284
+
1285
+ LInstruction* LChunkBuilder::DoCallKnownGlobal(HCallKnownGlobal* instr) {
1286
+ argument_count_ -= instr->argument_count();
1287
+ return MarkAsCall(DefineFixed(new LCallKnownGlobal, r0), instr);
1288
+ }
1289
+
1290
+
1291
+ LInstruction* LChunkBuilder::DoCallNew(HCallNew* instr) {
1292
+ LOperand* constructor = UseFixed(instr->constructor(), r1);
1293
+ argument_count_ -= instr->argument_count();
1294
+ LCallNew* result = new LCallNew(constructor);
1295
+ return MarkAsCall(DefineFixed(result, r0), instr);
1296
+ }
1297
+
1298
+
1299
+ LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) {
1300
+ argument_count_ -= instr->argument_count();
1301
+ return MarkAsCall(DefineFixed(new LCallFunction, r0), instr);
1302
+ }
1303
+
1304
+
1305
+ LInstruction* LChunkBuilder::DoCallRuntime(HCallRuntime* instr) {
1306
+ argument_count_ -= instr->argument_count();
1307
+ return MarkAsCall(DefineFixed(new LCallRuntime, r0), instr);
1308
+ }
1309
+
1310
+
1311
+ LInstruction* LChunkBuilder::DoShr(HShr* instr) {
1312
+ return DoShift(Token::SHR, instr);
1313
+ }
1314
+
1315
+
1316
+ LInstruction* LChunkBuilder::DoSar(HSar* instr) {
1317
+ return DoShift(Token::SAR, instr);
1318
+ }
1319
+
1320
+
1321
+ LInstruction* LChunkBuilder::DoShl(HShl* instr) {
1322
+ return DoShift(Token::SHL, instr);
1323
+ }
1324
+
1325
+
1326
+ LInstruction* LChunkBuilder::DoBitAnd(HBitAnd* instr) {
1327
+ return DoBit(Token::BIT_AND, instr);
1328
+ }
1329
+
1330
+
1331
+ LInstruction* LChunkBuilder::DoBitNot(HBitNot* instr) {
1332
+ ASSERT(instr->value()->representation().IsInteger32());
1333
+ ASSERT(instr->representation().IsInteger32());
1334
+ return DefineSameAsFirst(new LBitNotI(UseRegisterAtStart(instr->value())));
1335
+ }
1336
+
1337
+
1338
+ LInstruction* LChunkBuilder::DoBitOr(HBitOr* instr) {
1339
+ return DoBit(Token::BIT_OR, instr);
1340
+ }
1341
+
1342
+
1343
+ LInstruction* LChunkBuilder::DoBitXor(HBitXor* instr) {
1344
+ return DoBit(Token::BIT_XOR, instr);
1345
+ }
1346
+
1347
+
1348
+ LInstruction* LChunkBuilder::DoDiv(HDiv* instr) {
1349
+ if (instr->representation().IsDouble()) {
1350
+ return DoArithmeticD(Token::DIV, instr);
1351
+ } else if (instr->representation().IsInteger32()) {
1352
+ // TODO(1042) The fixed register allocation
1353
+ // is needed because we call TypeRecordingBinaryOpStub from
1354
+ // the generated code, which requires registers r0
1355
+ // and r1 to be used. We should remove that
1356
+ // when we provide a native implementation.
1357
+ LOperand* dividend = UseFixed(instr->left(), r0);
1358
+ LOperand* divisor = UseFixed(instr->right(), r1);
1359
+ return AssignEnvironment(AssignPointerMap(
1360
+ DefineFixed(new LDivI(dividend, divisor), r0)));
1361
+ } else {
1362
+ return DoArithmeticT(Token::DIV, instr);
1363
+ }
1364
+ }
1365
+
1366
+
1367
+ LInstruction* LChunkBuilder::DoMod(HMod* instr) {
1368
+ if (instr->representation().IsInteger32()) {
1369
+ ASSERT(instr->left()->representation().IsInteger32());
1370
+ ASSERT(instr->right()->representation().IsInteger32());
1371
+
1372
+ LModI* mod;
1373
+ if (instr->HasPowerOf2Divisor()) {
1374
+ ASSERT(!instr->CheckFlag(HValue::kCanBeDivByZero));
1375
+ LOperand* value = UseRegisterAtStart(instr->left());
1376
+ mod = new LModI(value, UseOrConstant(instr->right()));
1377
+ } else {
1378
+ LOperand* dividend = UseRegister(instr->left());
1379
+ LOperand* divisor = UseRegisterAtStart(instr->right());
1380
+ mod = new LModI(dividend,
1381
+ divisor,
1382
+ TempRegister(),
1383
+ FixedTemp(d1),
1384
+ FixedTemp(d2));
1385
+ }
1386
+
1387
+ return AssignEnvironment(DefineSameAsFirst(mod));
1388
+ } else if (instr->representation().IsTagged()) {
1389
+ return DoArithmeticT(Token::MOD, instr);
1390
+ } else {
1391
+ ASSERT(instr->representation().IsDouble());
1392
+ // We call a C function for double modulo. It can't trigger a GC.
1393
+ // We need to use fixed result register for the call.
1394
+ // TODO(fschneider): Allow any register as input registers.
1395
+ LOperand* left = UseFixedDouble(instr->left(), d1);
1396
+ LOperand* right = UseFixedDouble(instr->right(), d2);
1397
+ LArithmeticD* result = new LArithmeticD(Token::MOD, left, right);
1398
+ return MarkAsCall(DefineFixedDouble(result, d1), instr);
1399
+ }
1400
+ }
1401
+
1402
+
1403
+ LInstruction* LChunkBuilder::DoMul(HMul* instr) {
1404
+ if (instr->representation().IsInteger32()) {
1405
+ ASSERT(instr->left()->representation().IsInteger32());
1406
+ ASSERT(instr->right()->representation().IsInteger32());
1407
+ LOperand* left = UseRegisterAtStart(instr->LeastConstantOperand());
1408
+ LOperand* right = UseOrConstant(instr->MostConstantOperand());
1409
+ LOperand* temp = NULL;
1410
+ if (instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
1411
+ temp = TempRegister();
1412
+ }
1413
+ LMulI* mul = new LMulI(left, right, temp);
1414
+ return AssignEnvironment(DefineSameAsFirst(mul));
1415
+ } else if (instr->representation().IsDouble()) {
1416
+ return DoArithmeticD(Token::MUL, instr);
1417
+ } else {
1418
+ return DoArithmeticT(Token::MUL, instr);
1419
+ }
1420
+ }
1421
+
1422
+
1423
+ LInstruction* LChunkBuilder::DoSub(HSub* instr) {
1424
+ if (instr->representation().IsInteger32()) {
1425
+ ASSERT(instr->left()->representation().IsInteger32());
1426
+ ASSERT(instr->right()->representation().IsInteger32());
1427
+ LOperand* left = UseRegisterAtStart(instr->left());
1428
+ LOperand* right = UseOrConstantAtStart(instr->right());
1429
+ LSubI* sub = new LSubI(left, right);
1430
+ LInstruction* result = DefineSameAsFirst(sub);
1431
+ if (instr->CheckFlag(HValue::kCanOverflow)) {
1432
+ result = AssignEnvironment(result);
1433
+ }
1434
+ return result;
1435
+ } else if (instr->representation().IsDouble()) {
1436
+ return DoArithmeticD(Token::SUB, instr);
1437
+ } else {
1438
+ return DoArithmeticT(Token::SUB, instr);
1439
+ }
1440
+ }
1441
+
1442
+
1443
+ LInstruction* LChunkBuilder::DoAdd(HAdd* instr) {
1444
+ if (instr->representation().IsInteger32()) {
1445
+ ASSERT(instr->left()->representation().IsInteger32());
1446
+ ASSERT(instr->right()->representation().IsInteger32());
1447
+ LOperand* left = UseRegisterAtStart(instr->LeastConstantOperand());
1448
+ LOperand* right = UseOrConstantAtStart(instr->MostConstantOperand());
1449
+ LAddI* add = new LAddI(left, right);
1450
+ LInstruction* result = DefineSameAsFirst(add);
1451
+ if (instr->CheckFlag(HValue::kCanOverflow)) {
1452
+ result = AssignEnvironment(result);
1453
+ }
1454
+ return result;
1455
+ } else if (instr->representation().IsDouble()) {
1456
+ return DoArithmeticD(Token::ADD, instr);
1457
+ } else {
1458
+ ASSERT(instr->representation().IsTagged());
1459
+ return DoArithmeticT(Token::ADD, instr);
1460
+ }
1461
+ }
1462
+
1463
+
1464
+ LInstruction* LChunkBuilder::DoPower(HPower* instr) {
1465
+ ASSERT(instr->representation().IsDouble());
1466
+ // We call a C function for double power. It can't trigger a GC.
1467
+ // We need to use fixed result register for the call.
1468
+ Representation exponent_type = instr->right()->representation();
1469
+ ASSERT(instr->left()->representation().IsDouble());
1470
+ LOperand* left = UseFixedDouble(instr->left(), d1);
1471
+ LOperand* right = exponent_type.IsDouble() ?
1472
+ UseFixedDouble(instr->right(), d2) :
1473
+ UseFixed(instr->right(), r0);
1474
+ LPower* result = new LPower(left, right);
1475
+ return MarkAsCall(DefineFixedDouble(result, d3),
1476
+ instr,
1477
+ CAN_DEOPTIMIZE_EAGERLY);
1478
+ }
1479
+
1480
+
1481
+ LInstruction* LChunkBuilder::DoCompare(HCompare* instr) {
1482
+ Token::Value op = instr->token();
1483
+ Representation r = instr->GetInputRepresentation();
1484
+ if (r.IsInteger32()) {
1485
+ ASSERT(instr->left()->representation().IsInteger32());
1486
+ ASSERT(instr->right()->representation().IsInteger32());
1487
+ LOperand* left = UseRegisterAtStart(instr->left());
1488
+ LOperand* right = UseRegisterAtStart(instr->right());
1489
+ return DefineAsRegister(new LCmpID(left, right));
1490
+ } else if (r.IsDouble()) {
1491
+ ASSERT(instr->left()->representation().IsDouble());
1492
+ ASSERT(instr->right()->representation().IsDouble());
1493
+ LOperand* left = UseRegisterAtStart(instr->left());
1494
+ LOperand* right = UseRegisterAtStart(instr->right());
1495
+ return DefineAsRegister(new LCmpID(left, right));
1496
+ } else {
1497
+ ASSERT(instr->left()->representation().IsTagged());
1498
+ ASSERT(instr->right()->representation().IsTagged());
1499
+ bool reversed = (op == Token::GT || op == Token::LTE);
1500
+ LOperand* left = UseFixed(instr->left(), reversed ? r0 : r1);
1501
+ LOperand* right = UseFixed(instr->right(), reversed ? r1 : r0);
1502
+ LCmpT* result = new LCmpT(left, right);
1503
+ return MarkAsCall(DefineFixed(result, r0), instr);
1504
+ }
1505
+ }
1506
+
1507
+
1508
+ LInstruction* LChunkBuilder::DoCompareJSObjectEq(
1509
+ HCompareJSObjectEq* instr) {
1510
+ LOperand* left = UseRegisterAtStart(instr->left());
1511
+ LOperand* right = UseRegisterAtStart(instr->right());
1512
+ LCmpJSObjectEq* result = new LCmpJSObjectEq(left, right);
1513
+ return DefineAsRegister(result);
1514
+ }
1515
+
1516
+
1517
+ LInstruction* LChunkBuilder::DoCompareSymbolEq(
1518
+ HCompareSymbolEq* instr) {
1519
+ LOperand* left = UseRegisterAtStart(instr->left());
1520
+ LOperand* right = UseRegisterAtStart(instr->right());
1521
+ LCmpSymbolEq* result = new LCmpSymbolEq(left, right);
1522
+ return DefineAsRegister(result);
1523
+ }
1524
+
1525
+
1526
+ LInstruction* LChunkBuilder::DoIsNull(HIsNull* instr) {
1527
+ ASSERT(instr->value()->representation().IsTagged());
1528
+ LOperand* value = UseRegisterAtStart(instr->value());
1529
+
1530
+ return DefineAsRegister(new LIsNull(value));
1531
+ }
1532
+
1533
+
1534
+ LInstruction* LChunkBuilder::DoIsObject(HIsObject* instr) {
1535
+ ASSERT(instr->value()->representation().IsTagged());
1536
+ LOperand* value = UseRegisterAtStart(instr->value());
1537
+
1538
+ return DefineAsRegister(new LIsObject(value));
1539
+ }
1540
+
1541
+
1542
+ LInstruction* LChunkBuilder::DoIsSmi(HIsSmi* instr) {
1543
+ ASSERT(instr->value()->representation().IsTagged());
1544
+ LOperand* value = UseAtStart(instr->value());
1545
+
1546
+ return DefineAsRegister(new LIsSmi(value));
1547
+ }
1548
+
1549
+
1550
+ LInstruction* LChunkBuilder::DoIsUndetectable(HIsUndetectable* instr) {
1551
+ ASSERT(instr->value()->representation().IsTagged());
1552
+ LOperand* value = UseRegisterAtStart(instr->value());
1553
+
1554
+ return DefineAsRegister(new LIsUndetectable(value));
1555
+ }
1556
+
1557
+
1558
+ LInstruction* LChunkBuilder::DoHasInstanceType(HHasInstanceType* instr) {
1559
+ ASSERT(instr->value()->representation().IsTagged());
1560
+ LOperand* value = UseRegisterAtStart(instr->value());
1561
+
1562
+ return DefineAsRegister(new LHasInstanceType(value));
1563
+ }
1564
+
1565
+
1566
+ LInstruction* LChunkBuilder::DoGetCachedArrayIndex(
1567
+ HGetCachedArrayIndex* instr) {
1568
+ ASSERT(instr->value()->representation().IsTagged());
1569
+ LOperand* value = UseRegisterAtStart(instr->value());
1570
+
1571
+ return DefineAsRegister(new LGetCachedArrayIndex(value));
1572
+ }
1573
+
1574
+
1575
+ LInstruction* LChunkBuilder::DoHasCachedArrayIndex(
1576
+ HHasCachedArrayIndex* instr) {
1577
+ ASSERT(instr->value()->representation().IsTagged());
1578
+ LOperand* value = UseRegister(instr->value());
1579
+
1580
+ return DefineAsRegister(new LHasCachedArrayIndex(value));
1581
+ }
1582
+
1583
+
1584
+ LInstruction* LChunkBuilder::DoClassOfTest(HClassOfTest* instr) {
1585
+ ASSERT(instr->value()->representation().IsTagged());
1586
+ LOperand* value = UseTempRegister(instr->value());
1587
+ return DefineSameAsFirst(new LClassOfTest(value));
1588
+ }
1589
+
1590
+
1591
+ LInstruction* LChunkBuilder::DoJSArrayLength(HJSArrayLength* instr) {
1592
+ LOperand* array = UseRegisterAtStart(instr->value());
1593
+ return DefineAsRegister(new LJSArrayLength(array));
1594
+ }
1595
+
1596
+
1597
+ LInstruction* LChunkBuilder::DoExternalArrayLength(
1598
+ HExternalArrayLength* instr) {
1599
+ LOperand* array = UseRegisterAtStart(instr->value());
1600
+ return DefineAsRegister(new LExternalArrayLength(array));
1601
+ }
1602
+
1603
+
1604
+ LInstruction* LChunkBuilder::DoFixedArrayLength(HFixedArrayLength* instr) {
1605
+ LOperand* array = UseRegisterAtStart(instr->value());
1606
+ return DefineAsRegister(new LFixedArrayLength(array));
1607
+ }
1608
+
1609
+
1610
+ LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) {
1611
+ LOperand* object = UseRegister(instr->value());
1612
+ LValueOf* result = new LValueOf(object, TempRegister());
1613
+ return AssignEnvironment(DefineSameAsFirst(result));
1614
+ }
1615
+
1616
+
1617
+ LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) {
1618
+ return AssignEnvironment(new LBoundsCheck(UseRegisterAtStart(instr->index()),
1619
+ UseRegister(instr->length())));
1620
+ }
1621
+
1622
+
1623
+ LInstruction* LChunkBuilder::DoAbnormalExit(HAbnormalExit* instr) {
1624
+ // The control instruction marking the end of a block that completed
1625
+ // abruptly (e.g., threw an exception). There is nothing specific to do.
1626
+ return NULL;
1627
+ }
1628
+
1629
+
1630
+ LInstruction* LChunkBuilder::DoThrow(HThrow* instr) {
1631
+ LOperand* value = UseFixed(instr->value(), r0);
1632
+ return MarkAsCall(new LThrow(value), instr);
1633
+ }
1634
+
1635
+
1636
+ LInstruction* LChunkBuilder::DoForceRepresentation(HForceRepresentation* bad) {
1637
+ // All HForceRepresentation instructions should be eliminated in the
1638
+ // representation change phase of Hydrogen.
1639
+ UNREACHABLE();
1640
+ return NULL;
1641
+ }
1642
+
1643
+
1644
+ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
1645
+ Representation from = instr->from();
1646
+ Representation to = instr->to();
1647
+ if (from.IsTagged()) {
1648
+ if (to.IsDouble()) {
1649
+ LOperand* value = UseRegister(instr->value());
1650
+ LNumberUntagD* res = new LNumberUntagD(value);
1651
+ return AssignEnvironment(DefineAsRegister(res));
1652
+ } else {
1653
+ ASSERT(to.IsInteger32());
1654
+ LOperand* value = UseRegister(instr->value());
1655
+ bool needs_check = !instr->value()->type().IsSmi();
1656
+ LInstruction* res = NULL;
1657
+ if (!needs_check) {
1658
+ res = DefineSameAsFirst(new LSmiUntag(value, needs_check));
1659
+ } else {
1660
+ LOperand* temp1 = TempRegister();
1661
+ LOperand* temp2 = instr->CanTruncateToInt32() ? TempRegister()
1662
+ : NULL;
1663
+ LOperand* temp3 = instr->CanTruncateToInt32() ? FixedTemp(d3)
1664
+ : NULL;
1665
+ res = DefineSameAsFirst(new LTaggedToI(value, temp1, temp2, temp3));
1666
+ res = AssignEnvironment(res);
1667
+ }
1668
+ return res;
1669
+ }
1670
+ } else if (from.IsDouble()) {
1671
+ if (to.IsTagged()) {
1672
+ LOperand* value = UseRegister(instr->value());
1673
+ LOperand* temp1 = TempRegister();
1674
+ LOperand* temp2 = TempRegister();
1675
+
1676
+ // Make sure that the temp and result_temp registers are
1677
+ // different.
1678
+ LUnallocated* result_temp = TempRegister();
1679
+ LNumberTagD* result = new LNumberTagD(value, temp1, temp2);
1680
+ Define(result, result_temp);
1681
+ return AssignPointerMap(result);
1682
+ } else {
1683
+ ASSERT(to.IsInteger32());
1684
+ LOperand* value = UseRegister(instr->value());
1685
+ LDoubleToI* res =
1686
+ new LDoubleToI(value,
1687
+ TempRegister(),
1688
+ instr->CanTruncateToInt32() ? TempRegister() : NULL);
1689
+ return AssignEnvironment(DefineAsRegister(res));
1690
+ }
1691
+ } else if (from.IsInteger32()) {
1692
+ if (to.IsTagged()) {
1693
+ HValue* val = instr->value();
1694
+ LOperand* value = UseRegister(val);
1695
+ if (val->HasRange() && val->range()->IsInSmiRange()) {
1696
+ return DefineSameAsFirst(new LSmiTag(value));
1697
+ } else {
1698
+ LNumberTagI* result = new LNumberTagI(value);
1699
+ return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result)));
1700
+ }
1701
+ } else {
1702
+ ASSERT(to.IsDouble());
1703
+ LOperand* value = Use(instr->value());
1704
+ return DefineAsRegister(new LInteger32ToDouble(value));
1705
+ }
1706
+ }
1707
+ UNREACHABLE();
1708
+ return NULL;
1709
+ }
1710
+
1711
+
1712
+ LInstruction* LChunkBuilder::DoCheckNonSmi(HCheckNonSmi* instr) {
1713
+ LOperand* value = UseRegisterAtStart(instr->value());
1714
+ return AssignEnvironment(new LCheckNonSmi(value));
1715
+ }
1716
+
1717
+
1718
+ LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) {
1719
+ LOperand* value = UseRegisterAtStart(instr->value());
1720
+ LInstruction* result = new LCheckInstanceType(value);
1721
+ return AssignEnvironment(result);
1722
+ }
1723
+
1724
+
1725
+ LInstruction* LChunkBuilder::DoCheckPrototypeMaps(HCheckPrototypeMaps* instr) {
1726
+ LOperand* temp1 = TempRegister();
1727
+ LOperand* temp2 = TempRegister();
1728
+ LInstruction* result = new LCheckPrototypeMaps(temp1, temp2);
1729
+ return AssignEnvironment(result);
1730
+ }
1731
+
1732
+
1733
+ LInstruction* LChunkBuilder::DoCheckSmi(HCheckSmi* instr) {
1734
+ LOperand* value = UseRegisterAtStart(instr->value());
1735
+ return AssignEnvironment(new LCheckSmi(value));
1736
+ }
1737
+
1738
+
1739
+ LInstruction* LChunkBuilder::DoCheckFunction(HCheckFunction* instr) {
1740
+ LOperand* value = UseRegisterAtStart(instr->value());
1741
+ return AssignEnvironment(new LCheckFunction(value));
1742
+ }
1743
+
1744
+
1745
+ LInstruction* LChunkBuilder::DoCheckMap(HCheckMap* instr) {
1746
+ LOperand* value = UseRegisterAtStart(instr->value());
1747
+ LInstruction* result = new LCheckMap(value);
1748
+ return AssignEnvironment(result);
1749
+ }
1750
+
1751
+
1752
+ LInstruction* LChunkBuilder::DoClampToUint8(HClampToUint8* instr) {
1753
+ HValue* value = instr->value();
1754
+ Representation input_rep = value->representation();
1755
+ LOperand* reg = UseRegister(value);
1756
+ if (input_rep.IsDouble()) {
1757
+ return DefineAsRegister(new LClampDToUint8(reg, FixedTemp(d1)));
1758
+ } else if (input_rep.IsInteger32()) {
1759
+ return DefineAsRegister(new LClampIToUint8(reg));
1760
+ } else {
1761
+ ASSERT(input_rep.IsTagged());
1762
+ // Register allocator doesn't (yet) support allocation of double
1763
+ // temps. Reserve d1 explicitly.
1764
+ LClampTToUint8* result = new LClampTToUint8(reg, FixedTemp(d1));
1765
+ return AssignEnvironment(DefineAsRegister(result));
1766
+ }
1767
+ }
1768
+
1769
+
1770
+ LInstruction* LChunkBuilder::DoReturn(HReturn* instr) {
1771
+ return new LReturn(UseFixed(instr->value(), r0));
1772
+ }
1773
+
1774
+
1775
+ LInstruction* LChunkBuilder::DoConstant(HConstant* instr) {
1776
+ Representation r = instr->representation();
1777
+ if (r.IsInteger32()) {
1778
+ return DefineAsRegister(new LConstantI);
1779
+ } else if (r.IsDouble()) {
1780
+ return DefineAsRegister(new LConstantD);
1781
+ } else if (r.IsTagged()) {
1782
+ return DefineAsRegister(new LConstantT);
1783
+ } else {
1784
+ UNREACHABLE();
1785
+ return NULL;
1786
+ }
1787
+ }
1788
+
1789
+
1790
+ LInstruction* LChunkBuilder::DoLoadGlobalCell(HLoadGlobalCell* instr) {
1791
+ LLoadGlobalCell* result = new LLoadGlobalCell;
1792
+ return instr->check_hole_value()
1793
+ ? AssignEnvironment(DefineAsRegister(result))
1794
+ : DefineAsRegister(result);
1795
+ }
1796
+
1797
+
1798
+ LInstruction* LChunkBuilder::DoLoadGlobalGeneric(HLoadGlobalGeneric* instr) {
1799
+ LOperand* global_object = UseFixed(instr->global_object(), r0);
1800
+ LLoadGlobalGeneric* result = new LLoadGlobalGeneric(global_object);
1801
+ return MarkAsCall(DefineFixed(result, r0), instr);
1802
+ }
1803
+
1804
+
1805
+ LInstruction* LChunkBuilder::DoStoreGlobalCell(HStoreGlobalCell* instr) {
1806
+ if (instr->check_hole_value()) {
1807
+ LOperand* temp = TempRegister();
1808
+ LOperand* value = UseRegister(instr->value());
1809
+ return AssignEnvironment(new LStoreGlobalCell(value, temp));
1810
+ } else {
1811
+ LOperand* value = UseRegisterAtStart(instr->value());
1812
+ return new LStoreGlobalCell(value, NULL);
1813
+ }
1814
+ }
1815
+
1816
+
1817
+ LInstruction* LChunkBuilder::DoStoreGlobalGeneric(HStoreGlobalGeneric* instr) {
1818
+ LOperand* global_object = UseFixed(instr->global_object(), r1);
1819
+ LOperand* value = UseFixed(instr->value(), r0);
1820
+ LStoreGlobalGeneric* result =
1821
+ new LStoreGlobalGeneric(global_object, value);
1822
+ return MarkAsCall(result, instr);
1823
+ }
1824
+
1825
+
1826
+ LInstruction* LChunkBuilder::DoLoadContextSlot(HLoadContextSlot* instr) {
1827
+ LOperand* context = UseRegisterAtStart(instr->value());
1828
+ return DefineAsRegister(new LLoadContextSlot(context));
1829
+ }
1830
+
1831
+
1832
+ LInstruction* LChunkBuilder::DoStoreContextSlot(HStoreContextSlot* instr) {
1833
+ LOperand* context;
1834
+ LOperand* value;
1835
+ if (instr->NeedsWriteBarrier()) {
1836
+ context = UseTempRegister(instr->context());
1837
+ value = UseTempRegister(instr->value());
1838
+ } else {
1839
+ context = UseRegister(instr->context());
1840
+ value = UseRegister(instr->value());
1841
+ }
1842
+ return new LStoreContextSlot(context, value);
1843
+ }
1844
+
1845
+
1846
+ LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) {
1847
+ return DefineAsRegister(
1848
+ new LLoadNamedField(UseRegisterAtStart(instr->object())));
1849
+ }
1850
+
1851
+
1852
+ LInstruction* LChunkBuilder::DoLoadNamedFieldPolymorphic(
1853
+ HLoadNamedFieldPolymorphic* instr) {
1854
+ ASSERT(instr->representation().IsTagged());
1855
+ if (instr->need_generic()) {
1856
+ LOperand* obj = UseFixed(instr->object(), r0);
1857
+ LLoadNamedFieldPolymorphic* result = new LLoadNamedFieldPolymorphic(obj);
1858
+ return MarkAsCall(DefineFixed(result, r0), instr);
1859
+ } else {
1860
+ LOperand* obj = UseRegisterAtStart(instr->object());
1861
+ LLoadNamedFieldPolymorphic* result = new LLoadNamedFieldPolymorphic(obj);
1862
+ return AssignEnvironment(DefineAsRegister(result));
1863
+ }
1864
+ }
1865
+
1866
+
1867
+ LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) {
1868
+ LOperand* object = UseFixed(instr->object(), r0);
1869
+ LInstruction* result = DefineFixed(new LLoadNamedGeneric(object), r0);
1870
+ return MarkAsCall(result, instr);
1871
+ }
1872
+
1873
+
1874
+ LInstruction* LChunkBuilder::DoLoadFunctionPrototype(
1875
+ HLoadFunctionPrototype* instr) {
1876
+ return AssignEnvironment(DefineAsRegister(
1877
+ new LLoadFunctionPrototype(UseRegister(instr->function()))));
1878
+ }
1879
+
1880
+
1881
+ LInstruction* LChunkBuilder::DoLoadElements(HLoadElements* instr) {
1882
+ LOperand* input = UseRegisterAtStart(instr->value());
1883
+ return DefineAsRegister(new LLoadElements(input));
1884
+ }
1885
+
1886
+
1887
+ LInstruction* LChunkBuilder::DoLoadExternalArrayPointer(
1888
+ HLoadExternalArrayPointer* instr) {
1889
+ LOperand* input = UseRegisterAtStart(instr->value());
1890
+ return DefineAsRegister(new LLoadExternalArrayPointer(input));
1891
+ }
1892
+
1893
+
1894
+ LInstruction* LChunkBuilder::DoLoadKeyedFastElement(
1895
+ HLoadKeyedFastElement* instr) {
1896
+ ASSERT(instr->representation().IsTagged());
1897
+ ASSERT(instr->key()->representation().IsInteger32());
1898
+ LOperand* obj = UseRegisterAtStart(instr->object());
1899
+ LOperand* key = UseRegisterAtStart(instr->key());
1900
+ LLoadKeyedFastElement* result = new LLoadKeyedFastElement(obj, key);
1901
+ return AssignEnvironment(DefineSameAsFirst(result));
1902
+ }
1903
+
1904
+
1905
+ LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement(
1906
+ HLoadKeyedSpecializedArrayElement* instr) {
1907
+ ExternalArrayType array_type = instr->array_type();
1908
+ Representation representation(instr->representation());
1909
+ ASSERT(
1910
+ (representation.IsInteger32() && (array_type != kExternalFloatArray &&
1911
+ array_type != kExternalDoubleArray)) ||
1912
+ (representation.IsDouble() && (array_type == kExternalFloatArray ||
1913
+ array_type == kExternalDoubleArray)));
1914
+ ASSERT(instr->key()->representation().IsInteger32());
1915
+ LOperand* external_pointer = UseRegister(instr->external_pointer());
1916
+ LOperand* key = UseRegisterOrConstant(instr->key());
1917
+ LLoadKeyedSpecializedArrayElement* result =
1918
+ new LLoadKeyedSpecializedArrayElement(external_pointer, key);
1919
+ LInstruction* load_instr = DefineAsRegister(result);
1920
+ // An unsigned int array load might overflow and cause a deopt, make sure it
1921
+ // has an environment.
1922
+ return (array_type == kExternalUnsignedIntArray) ?
1923
+ AssignEnvironment(load_instr) : load_instr;
1924
+ }
1925
+
1926
+
1927
+ LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) {
1928
+ LOperand* object = UseFixed(instr->object(), r1);
1929
+ LOperand* key = UseFixed(instr->key(), r0);
1930
+
1931
+ LInstruction* result =
1932
+ DefineFixed(new LLoadKeyedGeneric(object, key), r0);
1933
+ return MarkAsCall(result, instr);
1934
+ }
1935
+
1936
+
1937
+ LInstruction* LChunkBuilder::DoStoreKeyedFastElement(
1938
+ HStoreKeyedFastElement* instr) {
1939
+ bool needs_write_barrier = instr->NeedsWriteBarrier();
1940
+ ASSERT(instr->value()->representation().IsTagged());
1941
+ ASSERT(instr->object()->representation().IsTagged());
1942
+ ASSERT(instr->key()->representation().IsInteger32());
1943
+
1944
+ LOperand* obj = UseTempRegister(instr->object());
1945
+ LOperand* val = needs_write_barrier
1946
+ ? UseTempRegister(instr->value())
1947
+ : UseRegisterAtStart(instr->value());
1948
+ LOperand* key = needs_write_barrier
1949
+ ? UseTempRegister(instr->key())
1950
+ : UseRegisterOrConstantAtStart(instr->key());
1951
+
1952
+ return AssignEnvironment(new LStoreKeyedFastElement(obj, key, val));
1953
+ }
1954
+
1955
+
1956
+ LInstruction* LChunkBuilder::DoStoreKeyedSpecializedArrayElement(
1957
+ HStoreKeyedSpecializedArrayElement* instr) {
1958
+ Representation representation(instr->value()->representation());
1959
+ ExternalArrayType array_type = instr->array_type();
1960
+ ASSERT(
1961
+ (representation.IsInteger32() && (array_type != kExternalFloatArray &&
1962
+ array_type != kExternalDoubleArray)) ||
1963
+ (representation.IsDouble() && (array_type == kExternalFloatArray ||
1964
+ array_type == kExternalDoubleArray)));
1965
+ ASSERT(instr->external_pointer()->representation().IsExternal());
1966
+ ASSERT(instr->key()->representation().IsInteger32());
1967
+
1968
+ LOperand* external_pointer = UseRegister(instr->external_pointer());
1969
+ bool val_is_temp_register = array_type == kExternalPixelArray ||
1970
+ array_type == kExternalFloatArray;
1971
+ LOperand* val = val_is_temp_register
1972
+ ? UseTempRegister(instr->value())
1973
+ : UseRegister(instr->value());
1974
+ LOperand* key = UseRegisterOrConstant(instr->key());
1975
+
1976
+ return new LStoreKeyedSpecializedArrayElement(external_pointer,
1977
+ key,
1978
+ val);
1979
+ }
1980
+
1981
+
1982
+ LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) {
1983
+ LOperand* obj = UseFixed(instr->object(), r2);
1984
+ LOperand* key = UseFixed(instr->key(), r1);
1985
+ LOperand* val = UseFixed(instr->value(), r0);
1986
+
1987
+ ASSERT(instr->object()->representation().IsTagged());
1988
+ ASSERT(instr->key()->representation().IsTagged());
1989
+ ASSERT(instr->value()->representation().IsTagged());
1990
+
1991
+ return MarkAsCall(new LStoreKeyedGeneric(obj, key, val), instr);
1992
+ }
1993
+
1994
+
1995
+ LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) {
1996
+ bool needs_write_barrier = instr->NeedsWriteBarrier();
1997
+
1998
+ LOperand* obj = needs_write_barrier
1999
+ ? UseTempRegister(instr->object())
2000
+ : UseRegisterAtStart(instr->object());
2001
+
2002
+ LOperand* val = needs_write_barrier
2003
+ ? UseTempRegister(instr->value())
2004
+ : UseRegister(instr->value());
2005
+
2006
+ return new LStoreNamedField(obj, val);
2007
+ }
2008
+
2009
+
2010
+ LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) {
2011
+ LOperand* obj = UseFixed(instr->object(), r1);
2012
+ LOperand* val = UseFixed(instr->value(), r0);
2013
+
2014
+ LInstruction* result = new LStoreNamedGeneric(obj, val);
2015
+ return MarkAsCall(result, instr);
2016
+ }
2017
+
2018
+
2019
+ LInstruction* LChunkBuilder::DoStringAdd(HStringAdd* instr) {
2020
+ LOperand* left = UseRegisterAtStart(instr->left());
2021
+ LOperand* right = UseRegisterAtStart(instr->right());
2022
+ return MarkAsCall(DefineFixed(new LStringAdd(left, right), r0), instr);
2023
+ }
2024
+
2025
+
2026
+ LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) {
2027
+ LOperand* string = UseRegister(instr->string());
2028
+ LOperand* index = UseRegisterOrConstant(instr->index());
2029
+ LStringCharCodeAt* result = new LStringCharCodeAt(string, index);
2030
+ return AssignEnvironment(AssignPointerMap(DefineAsRegister(result)));
2031
+ }
2032
+
2033
+
2034
+ LInstruction* LChunkBuilder::DoStringCharFromCode(HStringCharFromCode* instr) {
2035
+ LOperand* char_code = UseRegister(instr->value());
2036
+ LStringCharFromCode* result = new LStringCharFromCode(char_code);
2037
+ return AssignPointerMap(DefineAsRegister(result));
2038
+ }
2039
+
2040
+
2041
+ LInstruction* LChunkBuilder::DoStringLength(HStringLength* instr) {
2042
+ LOperand* string = UseRegisterAtStart(instr->value());
2043
+ return DefineAsRegister(new LStringLength(string));
2044
+ }
2045
+
2046
+
2047
+ LInstruction* LChunkBuilder::DoArrayLiteral(HArrayLiteral* instr) {
2048
+ return MarkAsCall(DefineFixed(new LArrayLiteral, r0), instr);
2049
+ }
2050
+
2051
+
2052
+ LInstruction* LChunkBuilder::DoObjectLiteral(HObjectLiteral* instr) {
2053
+ return MarkAsCall(DefineFixed(new LObjectLiteral, r0), instr);
2054
+ }
2055
+
2056
+
2057
+ LInstruction* LChunkBuilder::DoRegExpLiteral(HRegExpLiteral* instr) {
2058
+ return MarkAsCall(DefineFixed(new LRegExpLiteral, r0), instr);
2059
+ }
2060
+
2061
+
2062
+ LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) {
2063
+ return MarkAsCall(DefineFixed(new LFunctionLiteral, r0), instr);
2064
+ }
2065
+
2066
+
2067
+ LInstruction* LChunkBuilder::DoDeleteProperty(HDeleteProperty* instr) {
2068
+ LOperand* object = UseFixed(instr->object(), r0);
2069
+ LOperand* key = UseFixed(instr->key(), r1);
2070
+ LDeleteProperty* result = new LDeleteProperty(object, key);
2071
+ return MarkAsCall(DefineFixed(result, r0), instr);
2072
+ }
2073
+
2074
+
2075
+ LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) {
2076
+ allocator_->MarkAsOsrEntry();
2077
+ current_block_->last_environment()->set_ast_id(instr->ast_id());
2078
+ return AssignEnvironment(new LOsrEntry);
2079
+ }
2080
+
2081
+
2082
+ LInstruction* LChunkBuilder::DoParameter(HParameter* instr) {
2083
+ int spill_index = chunk()->GetParameterStackSlot(instr->index());
2084
+ return DefineAsSpilled(new LParameter, spill_index);
2085
+ }
2086
+
2087
+
2088
+ LInstruction* LChunkBuilder::DoUnknownOSRValue(HUnknownOSRValue* instr) {
2089
+ int spill_index = chunk()->GetNextSpillIndex(false); // Not double-width.
2090
+ return DefineAsSpilled(new LUnknownOSRValue, spill_index);
2091
+ }
2092
+
2093
+
2094
+ LInstruction* LChunkBuilder::DoCallStub(HCallStub* instr) {
2095
+ argument_count_ -= instr->argument_count();
2096
+ return MarkAsCall(DefineFixed(new LCallStub, r0), instr);
2097
+ }
2098
+
2099
+
2100
+ LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) {
2101
+ // There are no real uses of the arguments object.
2102
+ // arguments.length and element access are supported directly on
2103
+ // stack arguments, and any real arguments object use causes a bailout.
2104
+ // So this value is never used.
2105
+ return NULL;
2106
+ }
2107
+
2108
+
2109
+ LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) {
2110
+ LOperand* arguments = UseRegister(instr->arguments());
2111
+ LOperand* length = UseTempRegister(instr->length());
2112
+ LOperand* index = UseRegister(instr->index());
2113
+ LAccessArgumentsAt* result = new LAccessArgumentsAt(arguments, length, index);
2114
+ return AssignEnvironment(DefineAsRegister(result));
2115
+ }
2116
+
2117
+
2118
+ LInstruction* LChunkBuilder::DoToFastProperties(HToFastProperties* instr) {
2119
+ LOperand* object = UseFixed(instr->value(), r0);
2120
+ LToFastProperties* result = new LToFastProperties(object);
2121
+ return MarkAsCall(DefineFixed(result, r0), instr);
2122
+ }
2123
+
2124
+
2125
+ LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) {
2126
+ LTypeof* result = new LTypeof(UseFixed(instr->value(), r0));
2127
+ return MarkAsCall(DefineFixed(result, r0), instr);
2128
+ }
2129
+
2130
+
2131
+ LInstruction* LChunkBuilder::DoTypeofIs(HTypeofIs* instr) {
2132
+ return DefineSameAsFirst(new LTypeofIs(UseRegister(instr->value())));
2133
+ }
2134
+
2135
+
2136
+ LInstruction* LChunkBuilder::DoIsConstructCall(HIsConstructCall* instr) {
2137
+ return DefineAsRegister(new LIsConstructCall());
2138
+ }
2139
+
2140
+
2141
+ LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) {
2142
+ HEnvironment* env = current_block_->last_environment();
2143
+ ASSERT(env != NULL);
2144
+
2145
+ env->set_ast_id(instr->ast_id());
2146
+
2147
+ env->Drop(instr->pop_count());
2148
+ for (int i = 0; i < instr->values()->length(); ++i) {
2149
+ HValue* value = instr->values()->at(i);
2150
+ if (instr->HasAssignedIndexAt(i)) {
2151
+ env->Bind(instr->GetAssignedIndexAt(i), value);
2152
+ } else {
2153
+ env->Push(value);
2154
+ }
2155
+ }
2156
+
2157
+ // If there is an instruction pending deoptimization environment create a
2158
+ // lazy bailout instruction to capture the environment.
2159
+ if (pending_deoptimization_ast_id_ == instr->ast_id()) {
2160
+ LInstruction* result = new LLazyBailout;
2161
+ result = AssignEnvironment(result);
2162
+ instruction_pending_deoptimization_environment_->
2163
+ set_deoptimization_environment(result->environment());
2164
+ ClearInstructionPendingDeoptimizationEnvironment();
2165
+ return result;
2166
+ }
2167
+
2168
+ return NULL;
2169
+ }
2170
+
2171
+
2172
+ LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) {
2173
+ return MarkAsCall(new LStackCheck, instr);
2174
+ }
2175
+
2176
+
2177
+ LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) {
2178
+ HEnvironment* outer = current_block_->last_environment();
2179
+ HConstant* undefined = graph()->GetConstantUndefined();
2180
+ HEnvironment* inner = outer->CopyForInlining(instr->closure(),
2181
+ instr->function(),
2182
+ HEnvironment::LITHIUM,
2183
+ undefined,
2184
+ instr->call_kind());
2185
+ current_block_->UpdateEnvironment(inner);
2186
+ chunk_->AddInlinedClosure(instr->closure());
2187
+ return NULL;
2188
+ }
2189
+
2190
+
2191
+ LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) {
2192
+ HEnvironment* outer = current_block_->last_environment()->outer();
2193
+ current_block_->UpdateEnvironment(outer);
2194
+ return NULL;
2195
+ }
2196
+
2197
+
2198
+ LInstruction* LChunkBuilder::DoIn(HIn* instr) {
2199
+ LOperand* key = UseRegisterAtStart(instr->key());
2200
+ LOperand* object = UseRegisterAtStart(instr->object());
2201
+ LIn* result = new LIn(key, object);
2202
+ return MarkAsCall(DefineFixed(result, r0), instr);
2203
+ }
2204
+
2205
+
2206
+ } } // namespace v8::internal