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,3971 @@
1
+ // Copyright 2011 the V8 project authors. All rights reserved.
2
+ // Redistribution and use in source and binary forms, with or without
3
+ // modification, are permitted provided that the following conditions are
4
+ // met:
5
+ //
6
+ // * Redistributions of source code must retain the above copyright
7
+ // notice, this list of conditions and the following disclaimer.
8
+ // * Redistributions in binary form must reproduce the above
9
+ // copyright notice, this list of conditions and the following
10
+ // disclaimer in the documentation and/or other materials provided
11
+ // with the distribution.
12
+ // * Neither the name of Google Inc. nor the names of its
13
+ // contributors may be used to endorse or promote products derived
14
+ // from this software without specific prior written permission.
15
+ //
16
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
+ // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
+ // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
+ // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20
+ // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
+ // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
+ // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
+ // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
+ // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
+ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
+ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
+
28
+ #ifndef V8_HYDROGEN_INSTRUCTIONS_H_
29
+ #define V8_HYDROGEN_INSTRUCTIONS_H_
30
+
31
+ #include "v8.h"
32
+
33
+ #include "allocation.h"
34
+ #include "code-stubs.h"
35
+ #include "data-flow.h"
36
+ #include "small-pointer-list.h"
37
+ #include "string-stream.h"
38
+ #include "zone.h"
39
+
40
+ namespace v8 {
41
+ namespace internal {
42
+
43
+ // Forward declarations.
44
+ class HBasicBlock;
45
+ class HEnvironment;
46
+ class HInstruction;
47
+ class HLoopInformation;
48
+ class HValue;
49
+ class LInstruction;
50
+ class LChunkBuilder;
51
+
52
+
53
+ #define HYDROGEN_ABSTRACT_INSTRUCTION_LIST(V) \
54
+ V(BitwiseBinaryOperation) \
55
+ V(ControlInstruction) \
56
+ V(Instruction) \
57
+
58
+
59
+ #define HYDROGEN_CONCRETE_INSTRUCTION_LIST(V) \
60
+ V(AbnormalExit) \
61
+ V(AccessArgumentsAt) \
62
+ V(Add) \
63
+ V(ApplyArguments) \
64
+ V(ArgumentsElements) \
65
+ V(ArgumentsLength) \
66
+ V(ArgumentsObject) \
67
+ V(ArrayLiteral) \
68
+ V(BitAnd) \
69
+ V(BitNot) \
70
+ V(BitOr) \
71
+ V(BitXor) \
72
+ V(BlockEntry) \
73
+ V(BoundsCheck) \
74
+ V(CallConstantFunction) \
75
+ V(CallFunction) \
76
+ V(CallGlobal) \
77
+ V(CallKeyed) \
78
+ V(CallKnownGlobal) \
79
+ V(CallNamed) \
80
+ V(CallNew) \
81
+ V(CallRuntime) \
82
+ V(CallStub) \
83
+ V(Change) \
84
+ V(CheckFunction) \
85
+ V(CheckInstanceType) \
86
+ V(CheckMap) \
87
+ V(CheckNonSmi) \
88
+ V(CheckPrototypeMaps) \
89
+ V(CheckSmi) \
90
+ V(ClampToUint8) \
91
+ V(ClassOfTest) \
92
+ V(Compare) \
93
+ V(CompareJSObjectEq) \
94
+ V(CompareMap) \
95
+ V(CompareSymbolEq) \
96
+ V(Constant) \
97
+ V(Context) \
98
+ V(DeleteProperty) \
99
+ V(Deoptimize) \
100
+ V(Div) \
101
+ V(EnterInlined) \
102
+ V(ExternalArrayLength) \
103
+ V(FixedArrayLength) \
104
+ V(ForceRepresentation) \
105
+ V(FunctionLiteral) \
106
+ V(GetCachedArrayIndex) \
107
+ V(GlobalObject) \
108
+ V(GlobalReceiver) \
109
+ V(Goto) \
110
+ V(HasInstanceType) \
111
+ V(HasCachedArrayIndex) \
112
+ V(In) \
113
+ V(InstanceOf) \
114
+ V(InstanceOfKnownGlobal) \
115
+ V(InvokeFunction) \
116
+ V(IsConstructCall) \
117
+ V(IsNull) \
118
+ V(IsObject) \
119
+ V(IsSmi) \
120
+ V(IsUndetectable) \
121
+ V(JSArrayLength) \
122
+ V(LeaveInlined) \
123
+ V(LoadContextSlot) \
124
+ V(LoadElements) \
125
+ V(LoadExternalArrayPointer) \
126
+ V(LoadFunctionPrototype) \
127
+ V(LoadGlobalCell) \
128
+ V(LoadGlobalGeneric) \
129
+ V(LoadKeyedFastElement) \
130
+ V(LoadKeyedGeneric) \
131
+ V(LoadKeyedSpecializedArrayElement) \
132
+ V(LoadNamedField) \
133
+ V(LoadNamedFieldPolymorphic) \
134
+ V(LoadNamedGeneric) \
135
+ V(Mod) \
136
+ V(Mul) \
137
+ V(ObjectLiteral) \
138
+ V(OsrEntry) \
139
+ V(OuterContext) \
140
+ V(Parameter) \
141
+ V(Power) \
142
+ V(PushArgument) \
143
+ V(RegExpLiteral) \
144
+ V(Return) \
145
+ V(Sar) \
146
+ V(Shl) \
147
+ V(Shr) \
148
+ V(Simulate) \
149
+ V(StackCheck) \
150
+ V(StoreContextSlot) \
151
+ V(StoreGlobalCell) \
152
+ V(StoreGlobalGeneric) \
153
+ V(StoreKeyedFastElement) \
154
+ V(StoreKeyedSpecializedArrayElement) \
155
+ V(StoreKeyedGeneric) \
156
+ V(StoreNamedField) \
157
+ V(StoreNamedGeneric) \
158
+ V(StringAdd) \
159
+ V(StringCharCodeAt) \
160
+ V(StringCharFromCode) \
161
+ V(StringLength) \
162
+ V(Sub) \
163
+ V(Test) \
164
+ V(Throw) \
165
+ V(ToFastProperties) \
166
+ V(Typeof) \
167
+ V(TypeofIs) \
168
+ V(UnaryMathOperation) \
169
+ V(UnknownOSRValue) \
170
+ V(ValueOf)
171
+
172
+ #define GVN_FLAG_LIST(V) \
173
+ V(Calls) \
174
+ V(InobjectFields) \
175
+ V(BackingStoreFields) \
176
+ V(ArrayElements) \
177
+ V(SpecializedArrayElements) \
178
+ V(GlobalVars) \
179
+ V(Maps) \
180
+ V(ArrayLengths) \
181
+ V(ContextSlots) \
182
+ V(OsrEntries)
183
+
184
+ #define DECLARE_ABSTRACT_INSTRUCTION(type) \
185
+ virtual bool Is##type() const { return true; } \
186
+ static H##type* cast(HValue* value) { \
187
+ ASSERT(value->Is##type()); \
188
+ return reinterpret_cast<H##type*>(value); \
189
+ }
190
+
191
+
192
+ #define DECLARE_CONCRETE_INSTRUCTION(type) \
193
+ virtual LInstruction* CompileToLithium(LChunkBuilder* builder); \
194
+ static H##type* cast(HValue* value) { \
195
+ ASSERT(value->Is##type()); \
196
+ return reinterpret_cast<H##type*>(value); \
197
+ } \
198
+ virtual Opcode opcode() const { return HValue::k##type; }
199
+
200
+
201
+ class Range: public ZoneObject {
202
+ public:
203
+ Range()
204
+ : lower_(kMinInt),
205
+ upper_(kMaxInt),
206
+ next_(NULL),
207
+ can_be_minus_zero_(false) { }
208
+
209
+ Range(int32_t lower, int32_t upper)
210
+ : lower_(lower),
211
+ upper_(upper),
212
+ next_(NULL),
213
+ can_be_minus_zero_(false) { }
214
+
215
+ int32_t upper() const { return upper_; }
216
+ int32_t lower() const { return lower_; }
217
+ Range* next() const { return next_; }
218
+ Range* CopyClearLower() const { return new Range(kMinInt, upper_); }
219
+ Range* CopyClearUpper() const { return new Range(lower_, kMaxInt); }
220
+ Range* Copy() const { return new Range(lower_, upper_); }
221
+ int32_t Mask() const;
222
+ void set_can_be_minus_zero(bool b) { can_be_minus_zero_ = b; }
223
+ bool CanBeMinusZero() const { return CanBeZero() && can_be_minus_zero_; }
224
+ bool CanBeZero() const { return upper_ >= 0 && lower_ <= 0; }
225
+ bool CanBeNegative() const { return lower_ < 0; }
226
+ bool Includes(int value) const { return lower_ <= value && upper_ >= value; }
227
+ bool IsMostGeneric() const { return lower_ == kMinInt && upper_ == kMaxInt; }
228
+ bool IsInSmiRange() const {
229
+ return lower_ >= Smi::kMinValue && upper_ <= Smi::kMaxValue;
230
+ }
231
+ void KeepOrder();
232
+ void Verify() const;
233
+
234
+ void StackUpon(Range* other) {
235
+ Intersect(other);
236
+ next_ = other;
237
+ }
238
+
239
+ void Intersect(Range* other);
240
+ void Union(Range* other);
241
+
242
+ void AddConstant(int32_t value);
243
+ void Sar(int32_t value);
244
+ void Shl(int32_t value);
245
+ bool AddAndCheckOverflow(Range* other);
246
+ bool SubAndCheckOverflow(Range* other);
247
+ bool MulAndCheckOverflow(Range* other);
248
+
249
+ private:
250
+ int32_t lower_;
251
+ int32_t upper_;
252
+ Range* next_;
253
+ bool can_be_minus_zero_;
254
+ };
255
+
256
+
257
+ class Representation {
258
+ public:
259
+ enum Kind {
260
+ kNone,
261
+ kTagged,
262
+ kDouble,
263
+ kInteger32,
264
+ kExternal,
265
+ kNumRepresentations
266
+ };
267
+
268
+ Representation() : kind_(kNone) { }
269
+
270
+ static Representation None() { return Representation(kNone); }
271
+ static Representation Tagged() { return Representation(kTagged); }
272
+ static Representation Integer32() { return Representation(kInteger32); }
273
+ static Representation Double() { return Representation(kDouble); }
274
+ static Representation External() { return Representation(kExternal); }
275
+
276
+ bool Equals(const Representation& other) {
277
+ return kind_ == other.kind_;
278
+ }
279
+
280
+ Kind kind() const { return static_cast<Kind>(kind_); }
281
+ bool IsNone() const { return kind_ == kNone; }
282
+ bool IsTagged() const { return kind_ == kTagged; }
283
+ bool IsInteger32() const { return kind_ == kInteger32; }
284
+ bool IsDouble() const { return kind_ == kDouble; }
285
+ bool IsExternal() const { return kind_ == kExternal; }
286
+ bool IsSpecialization() const {
287
+ return kind_ == kInteger32 || kind_ == kDouble;
288
+ }
289
+ const char* Mnemonic() const;
290
+
291
+ private:
292
+ explicit Representation(Kind k) : kind_(k) { }
293
+
294
+ // Make sure kind fits in int8.
295
+ STATIC_ASSERT(kNumRepresentations <= (1 << kBitsPerByte));
296
+
297
+ int8_t kind_;
298
+ };
299
+
300
+
301
+ class HType {
302
+ public:
303
+ HType() : type_(kUninitialized) { }
304
+
305
+ static HType Tagged() { return HType(kTagged); }
306
+ static HType TaggedPrimitive() { return HType(kTaggedPrimitive); }
307
+ static HType TaggedNumber() { return HType(kTaggedNumber); }
308
+ static HType Smi() { return HType(kSmi); }
309
+ static HType HeapNumber() { return HType(kHeapNumber); }
310
+ static HType String() { return HType(kString); }
311
+ static HType Boolean() { return HType(kBoolean); }
312
+ static HType NonPrimitive() { return HType(kNonPrimitive); }
313
+ static HType JSArray() { return HType(kJSArray); }
314
+ static HType JSObject() { return HType(kJSObject); }
315
+ static HType Uninitialized() { return HType(kUninitialized); }
316
+
317
+ // Return the weakest (least precise) common type.
318
+ HType Combine(HType other) {
319
+ return HType(static_cast<Type>(type_ & other.type_));
320
+ }
321
+
322
+ bool Equals(const HType& other) {
323
+ return type_ == other.type_;
324
+ }
325
+
326
+ bool IsSubtypeOf(const HType& other) {
327
+ return Combine(other).Equals(other);
328
+ }
329
+
330
+ bool IsTagged() {
331
+ ASSERT(type_ != kUninitialized);
332
+ return ((type_ & kTagged) == kTagged);
333
+ }
334
+
335
+ bool IsTaggedPrimitive() {
336
+ ASSERT(type_ != kUninitialized);
337
+ return ((type_ & kTaggedPrimitive) == kTaggedPrimitive);
338
+ }
339
+
340
+ bool IsTaggedNumber() {
341
+ ASSERT(type_ != kUninitialized);
342
+ return ((type_ & kTaggedNumber) == kTaggedNumber);
343
+ }
344
+
345
+ bool IsSmi() {
346
+ ASSERT(type_ != kUninitialized);
347
+ return ((type_ & kSmi) == kSmi);
348
+ }
349
+
350
+ bool IsHeapNumber() {
351
+ ASSERT(type_ != kUninitialized);
352
+ return ((type_ & kHeapNumber) == kHeapNumber);
353
+ }
354
+
355
+ bool IsString() {
356
+ ASSERT(type_ != kUninitialized);
357
+ return ((type_ & kString) == kString);
358
+ }
359
+
360
+ bool IsBoolean() {
361
+ ASSERT(type_ != kUninitialized);
362
+ return ((type_ & kBoolean) == kBoolean);
363
+ }
364
+
365
+ bool IsNonPrimitive() {
366
+ ASSERT(type_ != kUninitialized);
367
+ return ((type_ & kNonPrimitive) == kNonPrimitive);
368
+ }
369
+
370
+ bool IsJSArray() {
371
+ ASSERT(type_ != kUninitialized);
372
+ return ((type_ & kJSArray) == kJSArray);
373
+ }
374
+
375
+ bool IsJSObject() {
376
+ ASSERT(type_ != kUninitialized);
377
+ return ((type_ & kJSObject) == kJSObject);
378
+ }
379
+
380
+ bool IsUninitialized() {
381
+ return type_ == kUninitialized;
382
+ }
383
+
384
+ static HType TypeFromValue(Handle<Object> value);
385
+
386
+ const char* ToString();
387
+ const char* ToShortString();
388
+
389
+ private:
390
+ enum Type {
391
+ kTagged = 0x1, // 0000 0000 0000 0001
392
+ kTaggedPrimitive = 0x5, // 0000 0000 0000 0101
393
+ kTaggedNumber = 0xd, // 0000 0000 0000 1101
394
+ kSmi = 0x1d, // 0000 0000 0001 1101
395
+ kHeapNumber = 0x2d, // 0000 0000 0010 1101
396
+ kString = 0x45, // 0000 0000 0100 0101
397
+ kBoolean = 0x85, // 0000 0000 1000 0101
398
+ kNonPrimitive = 0x101, // 0000 0001 0000 0001
399
+ kJSObject = 0x301, // 0000 0011 0000 0001
400
+ kJSArray = 0x701, // 0000 0111 1000 0001
401
+ kUninitialized = 0x1fff // 0001 1111 1111 1111
402
+ };
403
+
404
+ // Make sure type fits in int16.
405
+ STATIC_ASSERT(kUninitialized < (1 << (2 * kBitsPerByte)));
406
+
407
+ explicit HType(Type t) : type_(t) { }
408
+
409
+ int16_t type_;
410
+ };
411
+
412
+
413
+ class HUseListNode: public ZoneObject {
414
+ public:
415
+ HUseListNode(HValue* value, int index, HUseListNode* tail)
416
+ : tail_(tail), value_(value), index_(index) {
417
+ }
418
+
419
+ HUseListNode* tail() const { return tail_; }
420
+ HValue* value() const { return value_; }
421
+ int index() const { return index_; }
422
+
423
+ void set_tail(HUseListNode* list) { tail_ = list; }
424
+
425
+ #ifdef DEBUG
426
+ void Zap() {
427
+ tail_ = reinterpret_cast<HUseListNode*>(1);
428
+ value_ = NULL;
429
+ index_ = -1;
430
+ }
431
+ #endif
432
+
433
+ private:
434
+ HUseListNode* tail_;
435
+ HValue* value_;
436
+ int index_;
437
+ };
438
+
439
+
440
+ // We reuse use list nodes behind the scenes as uses are added and deleted.
441
+ // This class is the safe way to iterate uses while deleting them.
442
+ class HUseIterator BASE_EMBEDDED {
443
+ public:
444
+ bool Done() { return current_ == NULL; }
445
+ void Advance();
446
+
447
+ HValue* value() {
448
+ ASSERT(!Done());
449
+ return value_;
450
+ }
451
+
452
+ int index() {
453
+ ASSERT(!Done());
454
+ return index_;
455
+ }
456
+
457
+ private:
458
+ explicit HUseIterator(HUseListNode* head);
459
+
460
+ HUseListNode* current_;
461
+ HUseListNode* next_;
462
+ HValue* value_;
463
+ int index_;
464
+
465
+ friend class HValue;
466
+ };
467
+
468
+
469
+ class HValue: public ZoneObject {
470
+ public:
471
+ static const int kNoNumber = -1;
472
+
473
+ // There must be one corresponding kDepends flag for every kChanges flag and
474
+ // the order of the kChanges flags must be exactly the same as of the kDepends
475
+ // flags.
476
+ enum Flag {
477
+ // Declare global value numbering flags.
478
+ #define DECLARE_DO(type) kChanges##type, kDependsOn##type,
479
+ GVN_FLAG_LIST(DECLARE_DO)
480
+ #undef DECLARE_DO
481
+ kFlexibleRepresentation,
482
+ kUseGVN,
483
+ kCanOverflow,
484
+ kBailoutOnMinusZero,
485
+ kCanBeDivByZero,
486
+ kIsArguments,
487
+ kTruncatingToInt32,
488
+ kLastFlag = kTruncatingToInt32
489
+ };
490
+
491
+ STATIC_ASSERT(kLastFlag < kBitsPerInt);
492
+
493
+ static const int kChangesToDependsFlagsLeftShift = 1;
494
+
495
+ static int ChangesFlagsMask() {
496
+ int result = 0;
497
+ // Create changes mask.
498
+ #define DECLARE_DO(type) result |= (1 << kChanges##type);
499
+ GVN_FLAG_LIST(DECLARE_DO)
500
+ #undef DECLARE_DO
501
+ return result;
502
+ }
503
+
504
+ static int DependsFlagsMask() {
505
+ return ConvertChangesToDependsFlags(ChangesFlagsMask());
506
+ }
507
+
508
+ static int ConvertChangesToDependsFlags(int flags) {
509
+ return flags << kChangesToDependsFlagsLeftShift;
510
+ }
511
+
512
+ static HValue* cast(HValue* value) { return value; }
513
+
514
+ enum Opcode {
515
+ // Declare a unique enum value for each hydrogen instruction.
516
+ #define DECLARE_OPCODE(type) k##type,
517
+ HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_OPCODE)
518
+ kPhi
519
+ #undef DECLARE_OPCODE
520
+ };
521
+ virtual Opcode opcode() const = 0;
522
+
523
+ // Declare a non-virtual predicates for each concrete HInstruction or HValue.
524
+ #define DECLARE_PREDICATE(type) \
525
+ bool Is##type() const { return opcode() == k##type; }
526
+ HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_PREDICATE)
527
+ #undef DECLARE_PREDICATE
528
+ bool IsPhi() const { return opcode() == kPhi; }
529
+
530
+ // Declare virtual predicates for abstract HInstruction or HValue
531
+ #define DECLARE_PREDICATE(type) \
532
+ virtual bool Is##type() const { return false; }
533
+ HYDROGEN_ABSTRACT_INSTRUCTION_LIST(DECLARE_PREDICATE)
534
+ #undef DECLARE_PREDICATE
535
+
536
+ HValue() : block_(NULL),
537
+ id_(kNoNumber),
538
+ type_(HType::Tagged()),
539
+ use_list_(NULL),
540
+ range_(NULL),
541
+ flags_(0) {}
542
+ virtual ~HValue() {}
543
+
544
+ HBasicBlock* block() const { return block_; }
545
+ void SetBlock(HBasicBlock* block);
546
+
547
+ int id() const { return id_; }
548
+ void set_id(int id) { id_ = id; }
549
+
550
+ HUseIterator uses() const { return HUseIterator(use_list_); }
551
+
552
+ virtual bool EmitAtUses() { return false; }
553
+ Representation representation() const { return representation_; }
554
+ void ChangeRepresentation(Representation r) {
555
+ // Representation was already set and is allowed to be changed.
556
+ ASSERT(!r.IsNone());
557
+ ASSERT(CheckFlag(kFlexibleRepresentation));
558
+ RepresentationChanged(r);
559
+ representation_ = r;
560
+ }
561
+ void AssumeRepresentation(Representation r);
562
+
563
+ virtual bool IsConvertibleToInteger() const { return true; }
564
+
565
+ HType type() const { return type_; }
566
+ void set_type(HType type) {
567
+ ASSERT(HasNoUses());
568
+ type_ = type;
569
+ }
570
+
571
+ // An operation needs to override this function iff:
572
+ // 1) it can produce an int32 output.
573
+ // 2) the true value of its output can potentially be minus zero.
574
+ // The implementation must set a flag so that it bails out in the case where
575
+ // it would otherwise output what should be a minus zero as an int32 zero.
576
+ // If the operation also exists in a form that takes int32 and outputs int32
577
+ // then the operation should return its input value so that we can propagate
578
+ // back. There are two operations that need to propagate back to more than
579
+ // one input. They are phi and binary add. They always return NULL and
580
+ // expect the caller to take care of things.
581
+ virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited) {
582
+ visited->Add(id());
583
+ return NULL;
584
+ }
585
+
586
+ bool IsDefinedAfter(HBasicBlock* other) const;
587
+
588
+ // Operands.
589
+ virtual int OperandCount() = 0;
590
+ virtual HValue* OperandAt(int index) = 0;
591
+ void SetOperandAt(int index, HValue* value);
592
+
593
+ void DeleteAndReplaceWith(HValue* other);
594
+ bool HasNoUses() const { return use_list_ == NULL; }
595
+ bool HasMultipleUses() const {
596
+ return use_list_ != NULL && use_list_->tail() != NULL;
597
+ }
598
+ int UseCount() const;
599
+ void ClearOperands();
600
+
601
+ int flags() const { return flags_; }
602
+ void SetFlag(Flag f) { flags_ |= (1 << f); }
603
+ void ClearFlag(Flag f) { flags_ &= ~(1 << f); }
604
+ bool CheckFlag(Flag f) const { return (flags_ & (1 << f)) != 0; }
605
+
606
+ void SetAllSideEffects() { flags_ |= AllSideEffects(); }
607
+ void ClearAllSideEffects() { flags_ &= ~AllSideEffects(); }
608
+ bool HasSideEffects() const { return (flags_ & AllSideEffects()) != 0; }
609
+
610
+ Range* range() const { return range_; }
611
+ bool HasRange() const { return range_ != NULL; }
612
+ void AddNewRange(Range* r);
613
+ void RemoveLastAddedRange();
614
+ void ComputeInitialRange();
615
+
616
+ // Representation helpers.
617
+ virtual Representation RequiredInputRepresentation(int index) const = 0;
618
+
619
+ virtual Representation InferredRepresentation() {
620
+ return representation();
621
+ }
622
+
623
+ // This gives the instruction an opportunity to replace itself with an
624
+ // instruction that does the same in some better way. To replace an
625
+ // instruction with a new one, first add the new instruction to the graph,
626
+ // then return it. Return NULL to have the instruction deleted.
627
+ virtual HValue* Canonicalize() { return this; }
628
+
629
+ bool Equals(HValue* other);
630
+ virtual intptr_t Hashcode();
631
+
632
+ // Printing support.
633
+ virtual void PrintTo(StringStream* stream) = 0;
634
+ void PrintNameTo(StringStream* stream);
635
+ void PrintTypeTo(StringStream* stream);
636
+ void PrintRangeTo(StringStream* stream);
637
+ void PrintChangesTo(StringStream* stream);
638
+
639
+ const char* Mnemonic() const;
640
+
641
+ // Updated the inferred type of this instruction and returns true if
642
+ // it has changed.
643
+ bool UpdateInferredType();
644
+
645
+ virtual HType CalculateInferredType();
646
+
647
+ #ifdef DEBUG
648
+ virtual void Verify() = 0;
649
+ #endif
650
+
651
+ protected:
652
+ // This function must be overridden for instructions with flag kUseGVN, to
653
+ // compare the non-Operand parts of the instruction.
654
+ virtual bool DataEquals(HValue* other) {
655
+ UNREACHABLE();
656
+ return false;
657
+ }
658
+ virtual void RepresentationChanged(Representation to) { }
659
+ virtual Range* InferRange();
660
+ virtual void DeleteFromGraph() = 0;
661
+ virtual void InternalSetOperandAt(int index, HValue* value) = 0;
662
+ void clear_block() {
663
+ ASSERT(block_ != NULL);
664
+ block_ = NULL;
665
+ }
666
+
667
+ void set_representation(Representation r) {
668
+ // Representation is set-once.
669
+ ASSERT(representation_.IsNone() && !r.IsNone());
670
+ representation_ = r;
671
+ }
672
+
673
+ private:
674
+ // A flag mask to mark an instruction as having arbitrary side effects.
675
+ static int AllSideEffects() {
676
+ return ChangesFlagsMask() & ~(1 << kChangesOsrEntries);
677
+ }
678
+
679
+ // Remove the matching use from the use list if present. Returns the
680
+ // removed list node or NULL.
681
+ HUseListNode* RemoveUse(HValue* value, int index);
682
+
683
+ void ReplaceAllUsesWith(HValue* other);
684
+
685
+ void RegisterUse(int index, HValue* new_value);
686
+
687
+ HBasicBlock* block_;
688
+
689
+ // The id of this instruction in the hydrogen graph, assigned when first
690
+ // added to the graph. Reflects creation order.
691
+ int id_;
692
+
693
+ Representation representation_;
694
+ HType type_;
695
+ HUseListNode* use_list_;
696
+ Range* range_;
697
+ int flags_;
698
+
699
+ DISALLOW_COPY_AND_ASSIGN(HValue);
700
+ };
701
+
702
+
703
+ class HInstruction: public HValue {
704
+ public:
705
+ HInstruction* next() const { return next_; }
706
+ HInstruction* previous() const { return previous_; }
707
+
708
+ virtual void PrintTo(StringStream* stream);
709
+ virtual void PrintDataTo(StringStream* stream) { }
710
+
711
+ bool IsLinked() const { return block() != NULL; }
712
+ void Unlink();
713
+ void InsertBefore(HInstruction* next);
714
+ void InsertAfter(HInstruction* previous);
715
+
716
+ int position() const { return position_; }
717
+ bool has_position() const { return position_ != RelocInfo::kNoPosition; }
718
+ void set_position(int position) { position_ = position; }
719
+
720
+ virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0;
721
+
722
+ #ifdef DEBUG
723
+ virtual void Verify();
724
+ #endif
725
+
726
+ // Returns whether this is some kind of deoptimizing check
727
+ // instruction.
728
+ virtual bool IsCheckInstruction() const { return false; }
729
+
730
+ virtual bool IsCall() { return false; }
731
+
732
+ DECLARE_ABSTRACT_INSTRUCTION(Instruction)
733
+
734
+ protected:
735
+ HInstruction()
736
+ : next_(NULL),
737
+ previous_(NULL),
738
+ position_(RelocInfo::kNoPosition) {
739
+ SetFlag(kDependsOnOsrEntries);
740
+ }
741
+
742
+ virtual void DeleteFromGraph() { Unlink(); }
743
+
744
+ private:
745
+ void InitializeAsFirst(HBasicBlock* block) {
746
+ ASSERT(!IsLinked());
747
+ SetBlock(block);
748
+ }
749
+
750
+ void PrintMnemonicTo(StringStream* stream);
751
+
752
+ HInstruction* next_;
753
+ HInstruction* previous_;
754
+ int position_;
755
+
756
+ friend class HBasicBlock;
757
+ };
758
+
759
+
760
+ class HControlInstruction: public HInstruction {
761
+ public:
762
+ HControlInstruction(HBasicBlock* first, HBasicBlock* second)
763
+ : first_successor_(first), second_successor_(second) {
764
+ }
765
+
766
+ HBasicBlock* FirstSuccessor() const { return first_successor_; }
767
+ HBasicBlock* SecondSuccessor() const { return second_successor_; }
768
+
769
+ virtual void PrintDataTo(StringStream* stream);
770
+
771
+ DECLARE_ABSTRACT_INSTRUCTION(ControlInstruction)
772
+
773
+ private:
774
+ HBasicBlock* first_successor_;
775
+ HBasicBlock* second_successor_;
776
+ };
777
+
778
+
779
+ template<int NumElements>
780
+ class HOperandContainer {
781
+ public:
782
+ HOperandContainer() : elems_() { }
783
+
784
+ int length() { return NumElements; }
785
+ HValue*& operator[](int i) {
786
+ ASSERT(i < length());
787
+ return elems_[i];
788
+ }
789
+
790
+ private:
791
+ HValue* elems_[NumElements];
792
+ };
793
+
794
+
795
+ template<>
796
+ class HOperandContainer<0> {
797
+ public:
798
+ int length() { return 0; }
799
+ HValue*& operator[](int i) {
800
+ UNREACHABLE();
801
+ static HValue* t = 0;
802
+ return t;
803
+ }
804
+ };
805
+
806
+
807
+ template<int V>
808
+ class HTemplateInstruction : public HInstruction {
809
+ public:
810
+ int OperandCount() { return V; }
811
+ HValue* OperandAt(int i) { return inputs_[i]; }
812
+
813
+ protected:
814
+ void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
815
+
816
+ private:
817
+ HOperandContainer<V> inputs_;
818
+ };
819
+
820
+
821
+ template<int V>
822
+ class HTemplateControlInstruction : public HControlInstruction {
823
+ public:
824
+ HTemplateControlInstruction<V>(HBasicBlock* first, HBasicBlock* second)
825
+ : HControlInstruction(first, second) { }
826
+ int OperandCount() { return V; }
827
+ HValue* OperandAt(int i) { return inputs_[i]; }
828
+
829
+ protected:
830
+ void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
831
+
832
+ private:
833
+ HOperandContainer<V> inputs_;
834
+ };
835
+
836
+
837
+ class HBlockEntry: public HTemplateInstruction<0> {
838
+ public:
839
+ virtual Representation RequiredInputRepresentation(int index) const {
840
+ return Representation::None();
841
+ }
842
+
843
+ DECLARE_CONCRETE_INSTRUCTION(BlockEntry)
844
+ };
845
+
846
+
847
+ class HDeoptimize: public HControlInstruction {
848
+ public:
849
+ explicit HDeoptimize(int environment_length)
850
+ : HControlInstruction(NULL, NULL),
851
+ values_(environment_length) { }
852
+
853
+ virtual Representation RequiredInputRepresentation(int index) const {
854
+ return Representation::None();
855
+ }
856
+
857
+ virtual int OperandCount() { return values_.length(); }
858
+ virtual HValue* OperandAt(int index) { return values_[index]; }
859
+
860
+ void AddEnvironmentValue(HValue* value) {
861
+ values_.Add(NULL);
862
+ SetOperandAt(values_.length() - 1, value);
863
+ }
864
+
865
+ DECLARE_CONCRETE_INSTRUCTION(Deoptimize)
866
+
867
+ enum UseEnvironment {
868
+ kNoUses,
869
+ kUseAll
870
+ };
871
+
872
+ protected:
873
+ virtual void InternalSetOperandAt(int index, HValue* value) {
874
+ values_[index] = value;
875
+ }
876
+
877
+ private:
878
+ ZoneList<HValue*> values_;
879
+ };
880
+
881
+
882
+ class HGoto: public HTemplateControlInstruction<0> {
883
+ public:
884
+ explicit HGoto(HBasicBlock* target)
885
+ : HTemplateControlInstruction<0>(target, NULL),
886
+ include_stack_check_(false) { }
887
+
888
+ void set_include_stack_check(bool include_stack_check) {
889
+ include_stack_check_ = include_stack_check;
890
+ }
891
+ bool include_stack_check() const { return include_stack_check_; }
892
+
893
+ virtual Representation RequiredInputRepresentation(int index) const {
894
+ return Representation::None();
895
+ }
896
+
897
+ DECLARE_CONCRETE_INSTRUCTION(Goto)
898
+
899
+ private:
900
+ bool include_stack_check_;
901
+ };
902
+
903
+
904
+ class HUnaryControlInstruction: public HTemplateControlInstruction<1> {
905
+ public:
906
+ explicit HUnaryControlInstruction(HValue* value,
907
+ HBasicBlock* true_target,
908
+ HBasicBlock* false_target)
909
+ : HTemplateControlInstruction<1>(true_target, false_target) {
910
+ SetOperandAt(0, value);
911
+ }
912
+
913
+ virtual void PrintDataTo(StringStream* stream);
914
+
915
+ HValue* value() { return OperandAt(0); }
916
+ };
917
+
918
+
919
+ class HTest: public HUnaryControlInstruction {
920
+ public:
921
+ HTest(HValue* value, HBasicBlock* true_target, HBasicBlock* false_target)
922
+ : HUnaryControlInstruction(value, true_target, false_target) {
923
+ ASSERT(true_target != NULL && false_target != NULL);
924
+ }
925
+
926
+ virtual Representation RequiredInputRepresentation(int index) const {
927
+ return Representation::None();
928
+ }
929
+
930
+ DECLARE_CONCRETE_INSTRUCTION(Test)
931
+ };
932
+
933
+
934
+ class HCompareMap: public HUnaryControlInstruction {
935
+ public:
936
+ HCompareMap(HValue* value,
937
+ Handle<Map> map,
938
+ HBasicBlock* true_target,
939
+ HBasicBlock* false_target)
940
+ : HUnaryControlInstruction(value, true_target, false_target),
941
+ map_(map) {
942
+ ASSERT(true_target != NULL);
943
+ ASSERT(false_target != NULL);
944
+ ASSERT(!map.is_null());
945
+ }
946
+
947
+ virtual void PrintDataTo(StringStream* stream);
948
+
949
+ Handle<Map> map() const { return map_; }
950
+
951
+ virtual Representation RequiredInputRepresentation(int index) const {
952
+ return Representation::Tagged();
953
+ }
954
+
955
+ DECLARE_CONCRETE_INSTRUCTION(CompareMap)
956
+
957
+ private:
958
+ Handle<Map> map_;
959
+ };
960
+
961
+
962
+ class HReturn: public HUnaryControlInstruction {
963
+ public:
964
+ explicit HReturn(HValue* value)
965
+ : HUnaryControlInstruction(value, NULL, NULL) {
966
+ }
967
+
968
+ virtual Representation RequiredInputRepresentation(int index) const {
969
+ return Representation::Tagged();
970
+ }
971
+
972
+ DECLARE_CONCRETE_INSTRUCTION(Return)
973
+ };
974
+
975
+
976
+ class HAbnormalExit: public HTemplateControlInstruction<0> {
977
+ public:
978
+ HAbnormalExit() : HTemplateControlInstruction<0>(NULL, NULL) { }
979
+
980
+ virtual Representation RequiredInputRepresentation(int index) const {
981
+ return Representation::None();
982
+ }
983
+
984
+ DECLARE_CONCRETE_INSTRUCTION(AbnormalExit)
985
+ };
986
+
987
+
988
+ class HUnaryOperation: public HTemplateInstruction<1> {
989
+ public:
990
+ explicit HUnaryOperation(HValue* value) {
991
+ SetOperandAt(0, value);
992
+ }
993
+
994
+ HValue* value() { return OperandAt(0); }
995
+ virtual void PrintDataTo(StringStream* stream);
996
+ };
997
+
998
+
999
+ class HThrow: public HUnaryOperation {
1000
+ public:
1001
+ explicit HThrow(HValue* value) : HUnaryOperation(value) {
1002
+ SetAllSideEffects();
1003
+ }
1004
+
1005
+ virtual Representation RequiredInputRepresentation(int index) const {
1006
+ return Representation::Tagged();
1007
+ }
1008
+
1009
+ DECLARE_CONCRETE_INSTRUCTION(Throw)
1010
+ };
1011
+
1012
+
1013
+ class HForceRepresentation: public HTemplateInstruction<1> {
1014
+ public:
1015
+ HForceRepresentation(HValue* value, Representation required_representation) {
1016
+ SetOperandAt(0, value);
1017
+ set_representation(required_representation);
1018
+ }
1019
+
1020
+ HValue* value() { return OperandAt(0); }
1021
+
1022
+ virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1023
+
1024
+ virtual Representation RequiredInputRepresentation(int index) const {
1025
+ return representation(); // Same as the output representation.
1026
+ }
1027
+
1028
+ DECLARE_CONCRETE_INSTRUCTION(ForceRepresentation)
1029
+ };
1030
+
1031
+
1032
+ class HChange: public HUnaryOperation {
1033
+ public:
1034
+ HChange(HValue* value,
1035
+ Representation from,
1036
+ Representation to,
1037
+ bool is_truncating)
1038
+ : HUnaryOperation(value), from_(from) {
1039
+ ASSERT(!from.IsNone() && !to.IsNone());
1040
+ ASSERT(!from.Equals(to));
1041
+ set_representation(to);
1042
+ SetFlag(kUseGVN);
1043
+ if (is_truncating) SetFlag(kTruncatingToInt32);
1044
+ if (from.IsInteger32() && to.IsTagged() && value->range() != NULL &&
1045
+ value->range()->IsInSmiRange()) {
1046
+ set_type(HType::Smi());
1047
+ }
1048
+ }
1049
+
1050
+ virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1051
+
1052
+ Representation from() const { return from_; }
1053
+ Representation to() const { return representation(); }
1054
+ virtual Representation RequiredInputRepresentation(int index) const {
1055
+ return from_;
1056
+ }
1057
+
1058
+ bool CanTruncateToInt32() const { return CheckFlag(kTruncatingToInt32); }
1059
+
1060
+ virtual void PrintDataTo(StringStream* stream);
1061
+
1062
+ DECLARE_CONCRETE_INSTRUCTION(Change)
1063
+
1064
+ protected:
1065
+ virtual bool DataEquals(HValue* other) {
1066
+ if (!other->IsChange()) return false;
1067
+ HChange* change = HChange::cast(other);
1068
+ return value() == change->value()
1069
+ && to().Equals(change->to());
1070
+ }
1071
+
1072
+ private:
1073
+ Representation from_;
1074
+ };
1075
+
1076
+
1077
+ class HClampToUint8: public HUnaryOperation {
1078
+ public:
1079
+ explicit HClampToUint8(HValue* value)
1080
+ : HUnaryOperation(value),
1081
+ input_rep_(Representation::None()) {
1082
+ SetFlag(kFlexibleRepresentation);
1083
+ set_representation(Representation::Tagged());
1084
+ SetFlag(kUseGVN);
1085
+ }
1086
+
1087
+ virtual Representation RequiredInputRepresentation(int index) const {
1088
+ return input_rep_;
1089
+ }
1090
+
1091
+ virtual Representation InferredRepresentation() {
1092
+ // TODO(danno): Inference on input types should happen separately from
1093
+ // return representation.
1094
+ Representation new_rep = value()->representation();
1095
+ if (input_rep_.IsNone()) {
1096
+ if (!new_rep.IsNone()) {
1097
+ input_rep_ = new_rep;
1098
+ return Representation::Integer32();
1099
+ } else {
1100
+ return Representation::None();
1101
+ }
1102
+ } else {
1103
+ return Representation::Integer32();
1104
+ }
1105
+ }
1106
+
1107
+ DECLARE_CONCRETE_INSTRUCTION(ClampToUint8)
1108
+
1109
+ protected:
1110
+ virtual bool DataEquals(HValue* other) { return true; }
1111
+
1112
+ private:
1113
+ Representation input_rep_;
1114
+ };
1115
+
1116
+
1117
+ class HSimulate: public HInstruction {
1118
+ public:
1119
+ HSimulate(int ast_id, int pop_count)
1120
+ : ast_id_(ast_id),
1121
+ pop_count_(pop_count),
1122
+ values_(2),
1123
+ assigned_indexes_(2) {}
1124
+ virtual ~HSimulate() {}
1125
+
1126
+ virtual void PrintDataTo(StringStream* stream);
1127
+
1128
+ bool HasAstId() const { return ast_id_ != AstNode::kNoNumber; }
1129
+ int ast_id() const { return ast_id_; }
1130
+ void set_ast_id(int id) {
1131
+ ASSERT(!HasAstId());
1132
+ ast_id_ = id;
1133
+ }
1134
+
1135
+ int pop_count() const { return pop_count_; }
1136
+ const ZoneList<HValue*>* values() const { return &values_; }
1137
+ int GetAssignedIndexAt(int index) const {
1138
+ ASSERT(HasAssignedIndexAt(index));
1139
+ return assigned_indexes_[index];
1140
+ }
1141
+ bool HasAssignedIndexAt(int index) const {
1142
+ return assigned_indexes_[index] != kNoIndex;
1143
+ }
1144
+ void AddAssignedValue(int index, HValue* value) {
1145
+ AddValue(index, value);
1146
+ }
1147
+ void AddPushedValue(HValue* value) {
1148
+ AddValue(kNoIndex, value);
1149
+ }
1150
+ virtual int OperandCount() { return values_.length(); }
1151
+ virtual HValue* OperandAt(int index) { return values_[index]; }
1152
+
1153
+ virtual Representation RequiredInputRepresentation(int index) const {
1154
+ return Representation::None();
1155
+ }
1156
+
1157
+ DECLARE_CONCRETE_INSTRUCTION(Simulate)
1158
+
1159
+ #ifdef DEBUG
1160
+ virtual void Verify();
1161
+ #endif
1162
+
1163
+ protected:
1164
+ virtual void InternalSetOperandAt(int index, HValue* value) {
1165
+ values_[index] = value;
1166
+ }
1167
+
1168
+ private:
1169
+ static const int kNoIndex = -1;
1170
+ void AddValue(int index, HValue* value) {
1171
+ assigned_indexes_.Add(index);
1172
+ // Resize the list of pushed values.
1173
+ values_.Add(NULL);
1174
+ // Set the operand through the base method in HValue to make sure that the
1175
+ // use lists are correctly updated.
1176
+ SetOperandAt(values_.length() - 1, value);
1177
+ }
1178
+ int ast_id_;
1179
+ int pop_count_;
1180
+ ZoneList<HValue*> values_;
1181
+ ZoneList<int> assigned_indexes_;
1182
+ };
1183
+
1184
+
1185
+ class HStackCheck: public HTemplateInstruction<0> {
1186
+ public:
1187
+ HStackCheck() { }
1188
+
1189
+ virtual Representation RequiredInputRepresentation(int index) const {
1190
+ return Representation::None();
1191
+ }
1192
+
1193
+ DECLARE_CONCRETE_INSTRUCTION(StackCheck)
1194
+ };
1195
+
1196
+
1197
+ class HEnterInlined: public HTemplateInstruction<0> {
1198
+ public:
1199
+ HEnterInlined(Handle<JSFunction> closure,
1200
+ FunctionLiteral* function,
1201
+ CallKind call_kind)
1202
+ : closure_(closure),
1203
+ function_(function),
1204
+ call_kind_(call_kind) {
1205
+ }
1206
+
1207
+ virtual void PrintDataTo(StringStream* stream);
1208
+
1209
+ Handle<JSFunction> closure() const { return closure_; }
1210
+ FunctionLiteral* function() const { return function_; }
1211
+ CallKind call_kind() const { return call_kind_; }
1212
+
1213
+ virtual Representation RequiredInputRepresentation(int index) const {
1214
+ return Representation::None();
1215
+ }
1216
+
1217
+ DECLARE_CONCRETE_INSTRUCTION(EnterInlined)
1218
+
1219
+ private:
1220
+ Handle<JSFunction> closure_;
1221
+ FunctionLiteral* function_;
1222
+ CallKind call_kind_;
1223
+ };
1224
+
1225
+
1226
+ class HLeaveInlined: public HTemplateInstruction<0> {
1227
+ public:
1228
+ HLeaveInlined() {}
1229
+
1230
+ virtual Representation RequiredInputRepresentation(int index) const {
1231
+ return Representation::None();
1232
+ }
1233
+
1234
+ DECLARE_CONCRETE_INSTRUCTION(LeaveInlined)
1235
+ };
1236
+
1237
+
1238
+ class HPushArgument: public HUnaryOperation {
1239
+ public:
1240
+ explicit HPushArgument(HValue* value) : HUnaryOperation(value) {
1241
+ set_representation(Representation::Tagged());
1242
+ }
1243
+
1244
+ virtual Representation RequiredInputRepresentation(int index) const {
1245
+ return Representation::Tagged();
1246
+ }
1247
+
1248
+ HValue* argument() { return OperandAt(0); }
1249
+
1250
+ DECLARE_CONCRETE_INSTRUCTION(PushArgument)
1251
+ };
1252
+
1253
+
1254
+ class HContext: public HTemplateInstruction<0> {
1255
+ public:
1256
+ HContext() {
1257
+ set_representation(Representation::Tagged());
1258
+ SetFlag(kUseGVN);
1259
+ }
1260
+
1261
+ virtual Representation RequiredInputRepresentation(int index) const {
1262
+ return Representation::None();
1263
+ }
1264
+
1265
+ DECLARE_CONCRETE_INSTRUCTION(Context);
1266
+
1267
+ protected:
1268
+ virtual bool DataEquals(HValue* other) { return true; }
1269
+ };
1270
+
1271
+
1272
+ class HOuterContext: public HUnaryOperation {
1273
+ public:
1274
+ explicit HOuterContext(HValue* inner) : HUnaryOperation(inner) {
1275
+ set_representation(Representation::Tagged());
1276
+ SetFlag(kUseGVN);
1277
+ }
1278
+
1279
+ DECLARE_CONCRETE_INSTRUCTION(OuterContext);
1280
+
1281
+ virtual Representation RequiredInputRepresentation(int index) const {
1282
+ return Representation::Tagged();
1283
+ }
1284
+
1285
+ protected:
1286
+ virtual bool DataEquals(HValue* other) { return true; }
1287
+ };
1288
+
1289
+
1290
+ class HGlobalObject: public HUnaryOperation {
1291
+ public:
1292
+ explicit HGlobalObject(HValue* context) : HUnaryOperation(context) {
1293
+ set_representation(Representation::Tagged());
1294
+ SetFlag(kUseGVN);
1295
+ }
1296
+
1297
+ DECLARE_CONCRETE_INSTRUCTION(GlobalObject)
1298
+
1299
+ virtual Representation RequiredInputRepresentation(int index) const {
1300
+ return Representation::Tagged();
1301
+ }
1302
+
1303
+ protected:
1304
+ virtual bool DataEquals(HValue* other) { return true; }
1305
+ };
1306
+
1307
+
1308
+ class HGlobalReceiver: public HUnaryOperation {
1309
+ public:
1310
+ explicit HGlobalReceiver(HValue* global_object)
1311
+ : HUnaryOperation(global_object) {
1312
+ set_representation(Representation::Tagged());
1313
+ SetFlag(kUseGVN);
1314
+ }
1315
+
1316
+ DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver)
1317
+
1318
+ virtual Representation RequiredInputRepresentation(int index) const {
1319
+ return Representation::Tagged();
1320
+ }
1321
+
1322
+ protected:
1323
+ virtual bool DataEquals(HValue* other) { return true; }
1324
+ };
1325
+
1326
+
1327
+ template <int V>
1328
+ class HCall: public HTemplateInstruction<V> {
1329
+ public:
1330
+ // The argument count includes the receiver.
1331
+ explicit HCall<V>(int argument_count) : argument_count_(argument_count) {
1332
+ this->set_representation(Representation::Tagged());
1333
+ this->SetAllSideEffects();
1334
+ }
1335
+
1336
+ virtual HType CalculateInferredType() { return HType::Tagged(); }
1337
+
1338
+ virtual int argument_count() const { return argument_count_; }
1339
+
1340
+ virtual bool IsCall() { return true; }
1341
+
1342
+ private:
1343
+ int argument_count_;
1344
+ };
1345
+
1346
+
1347
+ class HUnaryCall: public HCall<1> {
1348
+ public:
1349
+ HUnaryCall(HValue* value, int argument_count)
1350
+ : HCall<1>(argument_count) {
1351
+ SetOperandAt(0, value);
1352
+ }
1353
+
1354
+ virtual Representation RequiredInputRepresentation(int index) const {
1355
+ return Representation::Tagged();
1356
+ }
1357
+
1358
+ virtual void PrintDataTo(StringStream* stream);
1359
+
1360
+ HValue* value() { return OperandAt(0); }
1361
+ };
1362
+
1363
+
1364
+ class HBinaryCall: public HCall<2> {
1365
+ public:
1366
+ HBinaryCall(HValue* first, HValue* second, int argument_count)
1367
+ : HCall<2>(argument_count) {
1368
+ SetOperandAt(0, first);
1369
+ SetOperandAt(1, second);
1370
+ }
1371
+
1372
+ virtual void PrintDataTo(StringStream* stream);
1373
+
1374
+ virtual Representation RequiredInputRepresentation(int index) const {
1375
+ return Representation::Tagged();
1376
+ }
1377
+
1378
+ HValue* first() { return OperandAt(0); }
1379
+ HValue* second() { return OperandAt(1); }
1380
+ };
1381
+
1382
+
1383
+ class HInvokeFunction: public HBinaryCall {
1384
+ public:
1385
+ HInvokeFunction(HValue* context, HValue* function, int argument_count)
1386
+ : HBinaryCall(context, function, argument_count) {
1387
+ }
1388
+
1389
+ virtual Representation RequiredInputRepresentation(int index) const {
1390
+ return Representation::Tagged();
1391
+ }
1392
+
1393
+ HValue* context() { return first(); }
1394
+ HValue* function() { return second(); }
1395
+
1396
+ DECLARE_CONCRETE_INSTRUCTION(InvokeFunction)
1397
+ };
1398
+
1399
+
1400
+ class HCallConstantFunction: public HCall<0> {
1401
+ public:
1402
+ HCallConstantFunction(Handle<JSFunction> function, int argument_count)
1403
+ : HCall<0>(argument_count), function_(function) { }
1404
+
1405
+ Handle<JSFunction> function() const { return function_; }
1406
+
1407
+ bool IsApplyFunction() const {
1408
+ return function_->code() ==
1409
+ Isolate::Current()->builtins()->builtin(Builtins::kFunctionApply);
1410
+ }
1411
+
1412
+ virtual void PrintDataTo(StringStream* stream);
1413
+
1414
+ virtual Representation RequiredInputRepresentation(int index) const {
1415
+ return Representation::None();
1416
+ }
1417
+
1418
+ DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction)
1419
+
1420
+ private:
1421
+ Handle<JSFunction> function_;
1422
+ };
1423
+
1424
+
1425
+ class HCallKeyed: public HBinaryCall {
1426
+ public:
1427
+ HCallKeyed(HValue* context, HValue* key, int argument_count)
1428
+ : HBinaryCall(context, key, argument_count) {
1429
+ }
1430
+
1431
+ virtual Representation RequiredInputRepresentation(int index) const {
1432
+ return Representation::Tagged();
1433
+ }
1434
+
1435
+ HValue* context() { return first(); }
1436
+ HValue* key() { return second(); }
1437
+
1438
+ DECLARE_CONCRETE_INSTRUCTION(CallKeyed)
1439
+ };
1440
+
1441
+
1442
+ class HCallNamed: public HUnaryCall {
1443
+ public:
1444
+ HCallNamed(HValue* context, Handle<String> name, int argument_count)
1445
+ : HUnaryCall(context, argument_count), name_(name) {
1446
+ }
1447
+
1448
+ virtual void PrintDataTo(StringStream* stream);
1449
+
1450
+ HValue* context() { return value(); }
1451
+ Handle<String> name() const { return name_; }
1452
+
1453
+ DECLARE_CONCRETE_INSTRUCTION(CallNamed)
1454
+
1455
+ virtual Representation RequiredInputRepresentation(int index) const {
1456
+ return Representation::Tagged();
1457
+ }
1458
+
1459
+ private:
1460
+ Handle<String> name_;
1461
+ };
1462
+
1463
+
1464
+ class HCallFunction: public HUnaryCall {
1465
+ public:
1466
+ HCallFunction(HValue* context, int argument_count)
1467
+ : HUnaryCall(context, argument_count) {
1468
+ }
1469
+
1470
+ HValue* context() { return value(); }
1471
+
1472
+ virtual Representation RequiredInputRepresentation(int index) const {
1473
+ return Representation::Tagged();
1474
+ }
1475
+
1476
+ DECLARE_CONCRETE_INSTRUCTION(CallFunction)
1477
+ };
1478
+
1479
+
1480
+ class HCallGlobal: public HUnaryCall {
1481
+ public:
1482
+ HCallGlobal(HValue* context, Handle<String> name, int argument_count)
1483
+ : HUnaryCall(context, argument_count), name_(name) {
1484
+ }
1485
+
1486
+ virtual void PrintDataTo(StringStream* stream);
1487
+
1488
+ HValue* context() { return value(); }
1489
+ Handle<String> name() const { return name_; }
1490
+
1491
+ virtual Representation RequiredInputRepresentation(int index) const {
1492
+ return Representation::Tagged();
1493
+ }
1494
+
1495
+ DECLARE_CONCRETE_INSTRUCTION(CallGlobal)
1496
+
1497
+ private:
1498
+ Handle<String> name_;
1499
+ };
1500
+
1501
+
1502
+ class HCallKnownGlobal: public HCall<0> {
1503
+ public:
1504
+ HCallKnownGlobal(Handle<JSFunction> target, int argument_count)
1505
+ : HCall<0>(argument_count), target_(target) { }
1506
+
1507
+ virtual void PrintDataTo(StringStream* stream);
1508
+
1509
+ Handle<JSFunction> target() const { return target_; }
1510
+
1511
+ virtual Representation RequiredInputRepresentation(int index) const {
1512
+ return Representation::None();
1513
+ }
1514
+
1515
+ DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal)
1516
+
1517
+ private:
1518
+ Handle<JSFunction> target_;
1519
+ };
1520
+
1521
+
1522
+ class HCallNew: public HBinaryCall {
1523
+ public:
1524
+ HCallNew(HValue* context, HValue* constructor, int argument_count)
1525
+ : HBinaryCall(context, constructor, argument_count) {
1526
+ }
1527
+
1528
+ virtual Representation RequiredInputRepresentation(int index) const {
1529
+ return Representation::Tagged();
1530
+ }
1531
+
1532
+ HValue* context() { return first(); }
1533
+ HValue* constructor() { return second(); }
1534
+
1535
+ DECLARE_CONCRETE_INSTRUCTION(CallNew)
1536
+ };
1537
+
1538
+
1539
+ class HCallRuntime: public HCall<0> {
1540
+ public:
1541
+ HCallRuntime(Handle<String> name,
1542
+ const Runtime::Function* c_function,
1543
+ int argument_count)
1544
+ : HCall<0>(argument_count), c_function_(c_function), name_(name) { }
1545
+ virtual void PrintDataTo(StringStream* stream);
1546
+
1547
+ const Runtime::Function* function() const { return c_function_; }
1548
+ Handle<String> name() const { return name_; }
1549
+
1550
+ virtual Representation RequiredInputRepresentation(int index) const {
1551
+ return Representation::None();
1552
+ }
1553
+
1554
+ DECLARE_CONCRETE_INSTRUCTION(CallRuntime)
1555
+
1556
+ private:
1557
+ const Runtime::Function* c_function_;
1558
+ Handle<String> name_;
1559
+ };
1560
+
1561
+
1562
+ class HJSArrayLength: public HUnaryOperation {
1563
+ public:
1564
+ explicit HJSArrayLength(HValue* value) : HUnaryOperation(value) {
1565
+ // The length of an array is stored as a tagged value in the array
1566
+ // object. It is guaranteed to be 32 bit integer, but it can be
1567
+ // represented as either a smi or heap number.
1568
+ set_representation(Representation::Tagged());
1569
+ SetFlag(kUseGVN);
1570
+ SetFlag(kDependsOnArrayLengths);
1571
+ SetFlag(kDependsOnMaps);
1572
+ }
1573
+
1574
+ virtual Representation RequiredInputRepresentation(int index) const {
1575
+ return Representation::Tagged();
1576
+ }
1577
+
1578
+ DECLARE_CONCRETE_INSTRUCTION(JSArrayLength)
1579
+
1580
+ protected:
1581
+ virtual bool DataEquals(HValue* other) { return true; }
1582
+ };
1583
+
1584
+
1585
+ class HFixedArrayLength: public HUnaryOperation {
1586
+ public:
1587
+ explicit HFixedArrayLength(HValue* value) : HUnaryOperation(value) {
1588
+ set_representation(Representation::Tagged());
1589
+ SetFlag(kUseGVN);
1590
+ SetFlag(kDependsOnArrayLengths);
1591
+ }
1592
+
1593
+ virtual Representation RequiredInputRepresentation(int index) const {
1594
+ return Representation::Tagged();
1595
+ }
1596
+
1597
+ DECLARE_CONCRETE_INSTRUCTION(FixedArrayLength)
1598
+
1599
+ protected:
1600
+ virtual bool DataEquals(HValue* other) { return true; }
1601
+ };
1602
+
1603
+
1604
+ class HExternalArrayLength: public HUnaryOperation {
1605
+ public:
1606
+ explicit HExternalArrayLength(HValue* value) : HUnaryOperation(value) {
1607
+ set_representation(Representation::Integer32());
1608
+ // The result of this instruction is idempotent as long as its inputs don't
1609
+ // change. The length of a pixel array cannot change once set, so it's not
1610
+ // necessary to introduce a kDependsOnArrayLengths or any other dependency.
1611
+ SetFlag(kUseGVN);
1612
+ }
1613
+
1614
+ virtual Representation RequiredInputRepresentation(int index) const {
1615
+ return Representation::Tagged();
1616
+ }
1617
+
1618
+ DECLARE_CONCRETE_INSTRUCTION(ExternalArrayLength)
1619
+
1620
+ protected:
1621
+ virtual bool DataEquals(HValue* other) { return true; }
1622
+ };
1623
+
1624
+
1625
+ class HBitNot: public HUnaryOperation {
1626
+ public:
1627
+ explicit HBitNot(HValue* value) : HUnaryOperation(value) {
1628
+ set_representation(Representation::Integer32());
1629
+ SetFlag(kUseGVN);
1630
+ SetFlag(kTruncatingToInt32);
1631
+ }
1632
+
1633
+ virtual Representation RequiredInputRepresentation(int index) const {
1634
+ return Representation::Integer32();
1635
+ }
1636
+ virtual HType CalculateInferredType();
1637
+
1638
+ DECLARE_CONCRETE_INSTRUCTION(BitNot)
1639
+
1640
+ protected:
1641
+ virtual bool DataEquals(HValue* other) { return true; }
1642
+ };
1643
+
1644
+
1645
+ class HUnaryMathOperation: public HUnaryOperation {
1646
+ public:
1647
+ HUnaryMathOperation(HValue* value, BuiltinFunctionId op)
1648
+ : HUnaryOperation(value), op_(op) {
1649
+ switch (op) {
1650
+ case kMathFloor:
1651
+ case kMathRound:
1652
+ case kMathCeil:
1653
+ set_representation(Representation::Integer32());
1654
+ break;
1655
+ case kMathAbs:
1656
+ set_representation(Representation::Tagged());
1657
+ SetFlag(kFlexibleRepresentation);
1658
+ break;
1659
+ case kMathSqrt:
1660
+ case kMathPowHalf:
1661
+ case kMathLog:
1662
+ case kMathSin:
1663
+ case kMathCos:
1664
+ set_representation(Representation::Double());
1665
+ break;
1666
+ default:
1667
+ UNREACHABLE();
1668
+ }
1669
+ SetFlag(kUseGVN);
1670
+ }
1671
+
1672
+ virtual void PrintDataTo(StringStream* stream);
1673
+
1674
+ virtual HType CalculateInferredType();
1675
+
1676
+ virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1677
+
1678
+ virtual Representation RequiredInputRepresentation(int index) const {
1679
+ switch (op_) {
1680
+ case kMathFloor:
1681
+ case kMathRound:
1682
+ case kMathCeil:
1683
+ case kMathSqrt:
1684
+ case kMathPowHalf:
1685
+ case kMathLog:
1686
+ case kMathSin:
1687
+ case kMathCos:
1688
+ return Representation::Double();
1689
+ case kMathAbs:
1690
+ return representation();
1691
+ default:
1692
+ UNREACHABLE();
1693
+ return Representation::None();
1694
+ }
1695
+ }
1696
+
1697
+ virtual HValue* Canonicalize() {
1698
+ // If the input is integer32 then we replace the floor instruction
1699
+ // with its inputs. This happens before the representation changes are
1700
+ // introduced.
1701
+ if (op() == kMathFloor) {
1702
+ if (value()->representation().IsInteger32()) return value();
1703
+ }
1704
+ return this;
1705
+ }
1706
+
1707
+ BuiltinFunctionId op() const { return op_; }
1708
+ const char* OpName() const;
1709
+
1710
+ DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation)
1711
+
1712
+ protected:
1713
+ virtual bool DataEquals(HValue* other) {
1714
+ HUnaryMathOperation* b = HUnaryMathOperation::cast(other);
1715
+ return op_ == b->op();
1716
+ }
1717
+
1718
+ private:
1719
+ BuiltinFunctionId op_;
1720
+ };
1721
+
1722
+
1723
+ class HLoadElements: public HUnaryOperation {
1724
+ public:
1725
+ explicit HLoadElements(HValue* value) : HUnaryOperation(value) {
1726
+ set_representation(Representation::Tagged());
1727
+ SetFlag(kUseGVN);
1728
+ SetFlag(kDependsOnMaps);
1729
+ }
1730
+
1731
+ virtual Representation RequiredInputRepresentation(int index) const {
1732
+ return Representation::Tagged();
1733
+ }
1734
+
1735
+ DECLARE_CONCRETE_INSTRUCTION(LoadElements)
1736
+
1737
+ protected:
1738
+ virtual bool DataEquals(HValue* other) { return true; }
1739
+ };
1740
+
1741
+
1742
+ class HLoadExternalArrayPointer: public HUnaryOperation {
1743
+ public:
1744
+ explicit HLoadExternalArrayPointer(HValue* value)
1745
+ : HUnaryOperation(value) {
1746
+ set_representation(Representation::External());
1747
+ // The result of this instruction is idempotent as long as its inputs don't
1748
+ // change. The external array of a specialized array elements object cannot
1749
+ // change once set, so it's no necessary to introduce any additional
1750
+ // dependencies on top of the inputs.
1751
+ SetFlag(kUseGVN);
1752
+ }
1753
+
1754
+ virtual Representation RequiredInputRepresentation(int index) const {
1755
+ return Representation::Tagged();
1756
+ }
1757
+
1758
+ DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer)
1759
+
1760
+ protected:
1761
+ virtual bool DataEquals(HValue* other) { return true; }
1762
+ };
1763
+
1764
+
1765
+ class HCheckMap: public HUnaryOperation {
1766
+ public:
1767
+ HCheckMap(HValue* value, Handle<Map> map)
1768
+ : HUnaryOperation(value), map_(map) {
1769
+ set_representation(Representation::Tagged());
1770
+ SetFlag(kUseGVN);
1771
+ SetFlag(kDependsOnMaps);
1772
+ }
1773
+
1774
+ virtual bool IsCheckInstruction() const { return true; }
1775
+
1776
+ virtual Representation RequiredInputRepresentation(int index) const {
1777
+ return Representation::Tagged();
1778
+ }
1779
+ virtual void PrintDataTo(StringStream* stream);
1780
+ virtual HType CalculateInferredType();
1781
+
1782
+ #ifdef DEBUG
1783
+ virtual void Verify();
1784
+ #endif
1785
+
1786
+ Handle<Map> map() const { return map_; }
1787
+
1788
+ DECLARE_CONCRETE_INSTRUCTION(CheckMap)
1789
+
1790
+ protected:
1791
+ virtual bool DataEquals(HValue* other) {
1792
+ HCheckMap* b = HCheckMap::cast(other);
1793
+ return map_.is_identical_to(b->map());
1794
+ }
1795
+
1796
+ private:
1797
+ Handle<Map> map_;
1798
+ };
1799
+
1800
+
1801
+ class HCheckFunction: public HUnaryOperation {
1802
+ public:
1803
+ HCheckFunction(HValue* value, Handle<JSFunction> function)
1804
+ : HUnaryOperation(value), target_(function) {
1805
+ set_representation(Representation::Tagged());
1806
+ SetFlag(kUseGVN);
1807
+ }
1808
+
1809
+ virtual bool IsCheckInstruction() const { return true; }
1810
+
1811
+ virtual Representation RequiredInputRepresentation(int index) const {
1812
+ return Representation::Tagged();
1813
+ }
1814
+ virtual void PrintDataTo(StringStream* stream);
1815
+ virtual HType CalculateInferredType();
1816
+
1817
+ #ifdef DEBUG
1818
+ virtual void Verify();
1819
+ #endif
1820
+
1821
+ Handle<JSFunction> target() const { return target_; }
1822
+
1823
+ DECLARE_CONCRETE_INSTRUCTION(CheckFunction)
1824
+
1825
+ protected:
1826
+ virtual bool DataEquals(HValue* other) {
1827
+ HCheckFunction* b = HCheckFunction::cast(other);
1828
+ return target_.is_identical_to(b->target());
1829
+ }
1830
+
1831
+ private:
1832
+ Handle<JSFunction> target_;
1833
+ };
1834
+
1835
+
1836
+ class HCheckInstanceType: public HUnaryOperation {
1837
+ public:
1838
+ static HCheckInstanceType* NewIsJSObjectOrJSFunction(HValue* value) {
1839
+ return new HCheckInstanceType(value, IS_JS_OBJECT_OR_JS_FUNCTION);
1840
+ }
1841
+ static HCheckInstanceType* NewIsJSArray(HValue* value) {
1842
+ return new HCheckInstanceType(value, IS_JS_ARRAY);
1843
+ }
1844
+ static HCheckInstanceType* NewIsString(HValue* value) {
1845
+ return new HCheckInstanceType(value, IS_STRING);
1846
+ }
1847
+ static HCheckInstanceType* NewIsSymbol(HValue* value) {
1848
+ return new HCheckInstanceType(value, IS_SYMBOL);
1849
+ }
1850
+
1851
+ virtual bool IsCheckInstruction() const { return true; }
1852
+
1853
+ virtual Representation RequiredInputRepresentation(int index) const {
1854
+ return Representation::Tagged();
1855
+ }
1856
+
1857
+ #ifdef DEBUG
1858
+ virtual void Verify();
1859
+ #endif
1860
+
1861
+ virtual HValue* Canonicalize() {
1862
+ if (!value()->type().IsUninitialized() &&
1863
+ value()->type().IsString() &&
1864
+ check_ == IS_STRING) {
1865
+ return NULL;
1866
+ }
1867
+ return this;
1868
+ }
1869
+
1870
+ bool is_interval_check() const { return check_ <= LAST_INTERVAL_CHECK; }
1871
+ void GetCheckInterval(InstanceType* first, InstanceType* last);
1872
+ void GetCheckMaskAndTag(uint8_t* mask, uint8_t* tag);
1873
+
1874
+ DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType)
1875
+
1876
+ protected:
1877
+ // TODO(ager): It could be nice to allow the ommision of instance
1878
+ // type checks if we have already performed an instance type check
1879
+ // with a larger range.
1880
+ virtual bool DataEquals(HValue* other) {
1881
+ HCheckInstanceType* b = HCheckInstanceType::cast(other);
1882
+ return check_ == b->check_;
1883
+ }
1884
+
1885
+ private:
1886
+ enum Check {
1887
+ IS_JS_OBJECT_OR_JS_FUNCTION,
1888
+ IS_JS_ARRAY,
1889
+ IS_STRING,
1890
+ IS_SYMBOL,
1891
+ LAST_INTERVAL_CHECK = IS_JS_ARRAY
1892
+ };
1893
+
1894
+ HCheckInstanceType(HValue* value, Check check)
1895
+ : HUnaryOperation(value), check_(check) {
1896
+ set_representation(Representation::Tagged());
1897
+ SetFlag(kUseGVN);
1898
+ }
1899
+
1900
+ const Check check_;
1901
+ };
1902
+
1903
+
1904
+ class HCheckNonSmi: public HUnaryOperation {
1905
+ public:
1906
+ explicit HCheckNonSmi(HValue* value) : HUnaryOperation(value) {
1907
+ set_representation(Representation::Tagged());
1908
+ SetFlag(kUseGVN);
1909
+ }
1910
+
1911
+ virtual bool IsCheckInstruction() const { return true; }
1912
+
1913
+ virtual Representation RequiredInputRepresentation(int index) const {
1914
+ return Representation::Tagged();
1915
+ }
1916
+
1917
+ virtual HType CalculateInferredType();
1918
+
1919
+ #ifdef DEBUG
1920
+ virtual void Verify();
1921
+ #endif
1922
+
1923
+ virtual HValue* Canonicalize() {
1924
+ HType value_type = value()->type();
1925
+ if (!value_type.IsUninitialized() &&
1926
+ (value_type.IsHeapNumber() ||
1927
+ value_type.IsString() ||
1928
+ value_type.IsBoolean() ||
1929
+ value_type.IsNonPrimitive())) {
1930
+ return NULL;
1931
+ }
1932
+ return this;
1933
+ }
1934
+
1935
+ DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi)
1936
+
1937
+ protected:
1938
+ virtual bool DataEquals(HValue* other) { return true; }
1939
+ };
1940
+
1941
+
1942
+ class HCheckPrototypeMaps: public HTemplateInstruction<0> {
1943
+ public:
1944
+ HCheckPrototypeMaps(Handle<JSObject> prototype, Handle<JSObject> holder)
1945
+ : prototype_(prototype), holder_(holder) {
1946
+ SetFlag(kUseGVN);
1947
+ SetFlag(kDependsOnMaps);
1948
+ }
1949
+
1950
+ virtual bool IsCheckInstruction() const { return true; }
1951
+
1952
+ #ifdef DEBUG
1953
+ virtual void Verify();
1954
+ #endif
1955
+
1956
+ Handle<JSObject> prototype() const { return prototype_; }
1957
+ Handle<JSObject> holder() const { return holder_; }
1958
+
1959
+ DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps)
1960
+
1961
+ virtual Representation RequiredInputRepresentation(int index) const {
1962
+ return Representation::None();
1963
+ }
1964
+
1965
+ virtual intptr_t Hashcode() {
1966
+ ASSERT(!HEAP->IsAllocationAllowed());
1967
+ intptr_t hash = reinterpret_cast<intptr_t>(*prototype());
1968
+ hash = 17 * hash + reinterpret_cast<intptr_t>(*holder());
1969
+ return hash;
1970
+ }
1971
+
1972
+ protected:
1973
+ virtual bool DataEquals(HValue* other) {
1974
+ HCheckPrototypeMaps* b = HCheckPrototypeMaps::cast(other);
1975
+ return prototype_.is_identical_to(b->prototype()) &&
1976
+ holder_.is_identical_to(b->holder());
1977
+ }
1978
+
1979
+ private:
1980
+ Handle<JSObject> prototype_;
1981
+ Handle<JSObject> holder_;
1982
+ };
1983
+
1984
+
1985
+ class HCheckSmi: public HUnaryOperation {
1986
+ public:
1987
+ explicit HCheckSmi(HValue* value) : HUnaryOperation(value) {
1988
+ set_representation(Representation::Tagged());
1989
+ SetFlag(kUseGVN);
1990
+ }
1991
+
1992
+ virtual bool IsCheckInstruction() const { return true; }
1993
+
1994
+ virtual Representation RequiredInputRepresentation(int index) const {
1995
+ return Representation::Tagged();
1996
+ }
1997
+ virtual HType CalculateInferredType();
1998
+
1999
+ #ifdef DEBUG
2000
+ virtual void Verify();
2001
+ #endif
2002
+
2003
+ DECLARE_CONCRETE_INSTRUCTION(CheckSmi)
2004
+
2005
+ protected:
2006
+ virtual bool DataEquals(HValue* other) { return true; }
2007
+ };
2008
+
2009
+
2010
+ class HPhi: public HValue {
2011
+ public:
2012
+ explicit HPhi(int merged_index)
2013
+ : inputs_(2),
2014
+ merged_index_(merged_index),
2015
+ phi_id_(-1),
2016
+ is_live_(false),
2017
+ is_convertible_to_integer_(true) {
2018
+ for (int i = 0; i < Representation::kNumRepresentations; i++) {
2019
+ non_phi_uses_[i] = 0;
2020
+ indirect_uses_[i] = 0;
2021
+ }
2022
+ ASSERT(merged_index >= 0);
2023
+ set_representation(Representation::Tagged());
2024
+ SetFlag(kFlexibleRepresentation);
2025
+ }
2026
+
2027
+ virtual Representation InferredRepresentation() {
2028
+ bool double_occurred = false;
2029
+ bool int32_occurred = false;
2030
+ for (int i = 0; i < OperandCount(); ++i) {
2031
+ HValue* value = OperandAt(i);
2032
+ if (value->representation().IsDouble()) double_occurred = true;
2033
+ if (value->representation().IsInteger32()) int32_occurred = true;
2034
+ if (value->representation().IsTagged()) return Representation::Tagged();
2035
+ }
2036
+
2037
+ if (double_occurred) return Representation::Double();
2038
+ if (int32_occurred) return Representation::Integer32();
2039
+ return Representation::None();
2040
+ }
2041
+
2042
+ virtual Range* InferRange();
2043
+ virtual Representation RequiredInputRepresentation(int index) const {
2044
+ return representation();
2045
+ }
2046
+ virtual HType CalculateInferredType();
2047
+ virtual int OperandCount() { return inputs_.length(); }
2048
+ virtual HValue* OperandAt(int index) { return inputs_[index]; }
2049
+ HValue* GetRedundantReplacement();
2050
+ void AddInput(HValue* value);
2051
+ bool HasRealUses();
2052
+
2053
+ bool IsReceiver() { return merged_index_ == 0; }
2054
+
2055
+ int merged_index() const { return merged_index_; }
2056
+
2057
+ virtual void PrintTo(StringStream* stream);
2058
+
2059
+ #ifdef DEBUG
2060
+ virtual void Verify();
2061
+ #endif
2062
+
2063
+ void InitRealUses(int id);
2064
+ void AddNonPhiUsesFrom(HPhi* other);
2065
+ void AddIndirectUsesTo(int* use_count);
2066
+
2067
+ int tagged_non_phi_uses() const {
2068
+ return non_phi_uses_[Representation::kTagged];
2069
+ }
2070
+ int int32_non_phi_uses() const {
2071
+ return non_phi_uses_[Representation::kInteger32];
2072
+ }
2073
+ int double_non_phi_uses() const {
2074
+ return non_phi_uses_[Representation::kDouble];
2075
+ }
2076
+ int tagged_indirect_uses() const {
2077
+ return indirect_uses_[Representation::kTagged];
2078
+ }
2079
+ int int32_indirect_uses() const {
2080
+ return indirect_uses_[Representation::kInteger32];
2081
+ }
2082
+ int double_indirect_uses() const {
2083
+ return indirect_uses_[Representation::kDouble];
2084
+ }
2085
+ int phi_id() { return phi_id_; }
2086
+ bool is_live() { return is_live_; }
2087
+ void set_is_live(bool b) { is_live_ = b; }
2088
+
2089
+ static HPhi* cast(HValue* value) {
2090
+ ASSERT(value->IsPhi());
2091
+ return reinterpret_cast<HPhi*>(value);
2092
+ }
2093
+ virtual Opcode opcode() const { return HValue::kPhi; }
2094
+
2095
+ virtual bool IsConvertibleToInteger() const {
2096
+ return is_convertible_to_integer_;
2097
+ }
2098
+
2099
+ void set_is_convertible_to_integer(bool b) {
2100
+ is_convertible_to_integer_ = b;
2101
+ }
2102
+
2103
+ protected:
2104
+ virtual void DeleteFromGraph();
2105
+ virtual void InternalSetOperandAt(int index, HValue* value) {
2106
+ inputs_[index] = value;
2107
+ }
2108
+
2109
+ private:
2110
+ ZoneList<HValue*> inputs_;
2111
+ int merged_index_;
2112
+
2113
+ int non_phi_uses_[Representation::kNumRepresentations];
2114
+ int indirect_uses_[Representation::kNumRepresentations];
2115
+ int phi_id_;
2116
+ bool is_live_;
2117
+ bool is_convertible_to_integer_;
2118
+ };
2119
+
2120
+
2121
+ class HArgumentsObject: public HTemplateInstruction<0> {
2122
+ public:
2123
+ HArgumentsObject() {
2124
+ set_representation(Representation::Tagged());
2125
+ SetFlag(kIsArguments);
2126
+ }
2127
+
2128
+ virtual Representation RequiredInputRepresentation(int index) const {
2129
+ return Representation::None();
2130
+ }
2131
+
2132
+ DECLARE_CONCRETE_INSTRUCTION(ArgumentsObject)
2133
+ };
2134
+
2135
+
2136
+ class HConstant: public HTemplateInstruction<0> {
2137
+ public:
2138
+ HConstant(Handle<Object> handle, Representation r);
2139
+
2140
+ Handle<Object> handle() const { return handle_; }
2141
+
2142
+ bool InOldSpace() const { return !HEAP->InNewSpace(*handle_); }
2143
+
2144
+ virtual Representation RequiredInputRepresentation(int index) const {
2145
+ return Representation::None();
2146
+ }
2147
+
2148
+ virtual bool IsConvertibleToInteger() const {
2149
+ if (handle_->IsSmi()) return true;
2150
+ if (handle_->IsHeapNumber() &&
2151
+ (HeapNumber::cast(*handle_)->value() ==
2152
+ static_cast<double>(NumberToInt32(*handle_)))) return true;
2153
+ return false;
2154
+ }
2155
+
2156
+ virtual bool EmitAtUses() { return !representation().IsDouble(); }
2157
+ virtual void PrintDataTo(StringStream* stream);
2158
+ virtual HType CalculateInferredType();
2159
+ bool IsInteger() const { return handle_->IsSmi(); }
2160
+ HConstant* CopyToRepresentation(Representation r) const;
2161
+ HConstant* CopyToTruncatedInt32() const;
2162
+ bool HasInteger32Value() const { return has_int32_value_; }
2163
+ int32_t Integer32Value() const {
2164
+ ASSERT(HasInteger32Value());
2165
+ return int32_value_;
2166
+ }
2167
+ bool HasDoubleValue() const { return has_double_value_; }
2168
+ double DoubleValue() const {
2169
+ ASSERT(HasDoubleValue());
2170
+ return double_value_;
2171
+ }
2172
+ bool HasStringValue() const { return handle_->IsString(); }
2173
+
2174
+ bool ToBoolean() const;
2175
+
2176
+ virtual intptr_t Hashcode() {
2177
+ ASSERT(!HEAP->allow_allocation(false));
2178
+ return reinterpret_cast<intptr_t>(*handle());
2179
+ }
2180
+
2181
+ #ifdef DEBUG
2182
+ virtual void Verify() { }
2183
+ #endif
2184
+
2185
+ DECLARE_CONCRETE_INSTRUCTION(Constant)
2186
+
2187
+ protected:
2188
+ virtual Range* InferRange();
2189
+
2190
+ virtual bool DataEquals(HValue* other) {
2191
+ HConstant* other_constant = HConstant::cast(other);
2192
+ return handle().is_identical_to(other_constant->handle());
2193
+ }
2194
+
2195
+ private:
2196
+ Handle<Object> handle_;
2197
+
2198
+ // The following two values represent the int32 and the double value of the
2199
+ // given constant if there is a lossless conversion between the constant
2200
+ // and the specific representation.
2201
+ bool has_int32_value_ : 1;
2202
+ bool has_double_value_ : 1;
2203
+ int32_t int32_value_;
2204
+ double double_value_;
2205
+ };
2206
+
2207
+
2208
+ class HBinaryOperation: public HTemplateInstruction<2> {
2209
+ public:
2210
+ HBinaryOperation(HValue* left, HValue* right) {
2211
+ ASSERT(left != NULL && right != NULL);
2212
+ SetOperandAt(0, left);
2213
+ SetOperandAt(1, right);
2214
+ }
2215
+
2216
+ HValue* left() { return OperandAt(0); }
2217
+ HValue* right() { return OperandAt(1); }
2218
+
2219
+ // TODO(kasperl): Move these helpers to the IA-32 Lithium
2220
+ // instruction sequence builder.
2221
+ HValue* LeastConstantOperand() {
2222
+ if (IsCommutative() && left()->IsConstant()) return right();
2223
+ return left();
2224
+ }
2225
+ HValue* MostConstantOperand() {
2226
+ if (IsCommutative() && left()->IsConstant()) return left();
2227
+ return right();
2228
+ }
2229
+
2230
+ virtual bool IsCommutative() const { return false; }
2231
+
2232
+ virtual void PrintDataTo(StringStream* stream);
2233
+ };
2234
+
2235
+
2236
+ class HApplyArguments: public HTemplateInstruction<4> {
2237
+ public:
2238
+ HApplyArguments(HValue* function,
2239
+ HValue* receiver,
2240
+ HValue* length,
2241
+ HValue* elements) {
2242
+ set_representation(Representation::Tagged());
2243
+ SetOperandAt(0, function);
2244
+ SetOperandAt(1, receiver);
2245
+ SetOperandAt(2, length);
2246
+ SetOperandAt(3, elements);
2247
+ SetAllSideEffects();
2248
+ }
2249
+
2250
+ virtual Representation RequiredInputRepresentation(int index) const {
2251
+ // The length is untagged, all other inputs are tagged.
2252
+ return (index == 2)
2253
+ ? Representation::Integer32()
2254
+ : Representation::Tagged();
2255
+ }
2256
+
2257
+ HValue* function() { return OperandAt(0); }
2258
+ HValue* receiver() { return OperandAt(1); }
2259
+ HValue* length() { return OperandAt(2); }
2260
+ HValue* elements() { return OperandAt(3); }
2261
+
2262
+ DECLARE_CONCRETE_INSTRUCTION(ApplyArguments)
2263
+ };
2264
+
2265
+
2266
+ class HArgumentsElements: public HTemplateInstruction<0> {
2267
+ public:
2268
+ HArgumentsElements() {
2269
+ // The value produced by this instruction is a pointer into the stack
2270
+ // that looks as if it was a smi because of alignment.
2271
+ set_representation(Representation::Tagged());
2272
+ SetFlag(kUseGVN);
2273
+ }
2274
+
2275
+ DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements)
2276
+
2277
+ virtual Representation RequiredInputRepresentation(int index) const {
2278
+ return Representation::None();
2279
+ }
2280
+
2281
+ protected:
2282
+ virtual bool DataEquals(HValue* other) { return true; }
2283
+ };
2284
+
2285
+
2286
+ class HArgumentsLength: public HUnaryOperation {
2287
+ public:
2288
+ explicit HArgumentsLength(HValue* value) : HUnaryOperation(value) {
2289
+ set_representation(Representation::Integer32());
2290
+ SetFlag(kUseGVN);
2291
+ }
2292
+
2293
+ virtual Representation RequiredInputRepresentation(int index) const {
2294
+ return Representation::Tagged();
2295
+ }
2296
+
2297
+ DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength)
2298
+
2299
+ protected:
2300
+ virtual bool DataEquals(HValue* other) { return true; }
2301
+ };
2302
+
2303
+
2304
+ class HAccessArgumentsAt: public HTemplateInstruction<3> {
2305
+ public:
2306
+ HAccessArgumentsAt(HValue* arguments, HValue* length, HValue* index) {
2307
+ set_representation(Representation::Tagged());
2308
+ SetFlag(kUseGVN);
2309
+ SetOperandAt(0, arguments);
2310
+ SetOperandAt(1, length);
2311
+ SetOperandAt(2, index);
2312
+ }
2313
+
2314
+ virtual void PrintDataTo(StringStream* stream);
2315
+
2316
+ virtual Representation RequiredInputRepresentation(int index) const {
2317
+ // The arguments elements is considered tagged.
2318
+ return index == 0
2319
+ ? Representation::Tagged()
2320
+ : Representation::Integer32();
2321
+ }
2322
+
2323
+ HValue* arguments() { return OperandAt(0); }
2324
+ HValue* length() { return OperandAt(1); }
2325
+ HValue* index() { return OperandAt(2); }
2326
+
2327
+ DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt)
2328
+
2329
+ virtual bool DataEquals(HValue* other) { return true; }
2330
+ };
2331
+
2332
+
2333
+ class HBoundsCheck: public HBinaryOperation {
2334
+ public:
2335
+ HBoundsCheck(HValue* index, HValue* length)
2336
+ : HBinaryOperation(index, length) {
2337
+ SetFlag(kUseGVN);
2338
+ }
2339
+
2340
+ virtual bool IsCheckInstruction() const { return true; }
2341
+
2342
+ virtual Representation RequiredInputRepresentation(int index) const {
2343
+ return Representation::Integer32();
2344
+ }
2345
+
2346
+ #ifdef DEBUG
2347
+ virtual void Verify();
2348
+ #endif
2349
+
2350
+ HValue* index() { return left(); }
2351
+ HValue* length() { return right(); }
2352
+
2353
+ DECLARE_CONCRETE_INSTRUCTION(BoundsCheck)
2354
+
2355
+ protected:
2356
+ virtual bool DataEquals(HValue* other) { return true; }
2357
+ };
2358
+
2359
+
2360
+ class HBitwiseBinaryOperation: public HBinaryOperation {
2361
+ public:
2362
+ HBitwiseBinaryOperation(HValue* left, HValue* right)
2363
+ : HBinaryOperation(left, right) {
2364
+ set_representation(Representation::Tagged());
2365
+ SetFlag(kFlexibleRepresentation);
2366
+ SetAllSideEffects();
2367
+ }
2368
+
2369
+ virtual Representation RequiredInputRepresentation(int index) const {
2370
+ return representation();
2371
+ }
2372
+
2373
+ virtual void RepresentationChanged(Representation to) {
2374
+ if (!to.IsTagged()) {
2375
+ ASSERT(to.IsInteger32());
2376
+ ClearAllSideEffects();
2377
+ SetFlag(kTruncatingToInt32);
2378
+ SetFlag(kUseGVN);
2379
+ }
2380
+ }
2381
+
2382
+ virtual HType CalculateInferredType();
2383
+
2384
+ DECLARE_ABSTRACT_INSTRUCTION(BitwiseBinaryOperation)
2385
+ };
2386
+
2387
+
2388
+ class HArithmeticBinaryOperation: public HBinaryOperation {
2389
+ public:
2390
+ HArithmeticBinaryOperation(HValue* left, HValue* right)
2391
+ : HBinaryOperation(left, right) {
2392
+ set_representation(Representation::Tagged());
2393
+ SetFlag(kFlexibleRepresentation);
2394
+ SetAllSideEffects();
2395
+ }
2396
+
2397
+ virtual void RepresentationChanged(Representation to) {
2398
+ if (!to.IsTagged()) {
2399
+ ClearAllSideEffects();
2400
+ SetFlag(kUseGVN);
2401
+ }
2402
+ }
2403
+
2404
+ virtual HType CalculateInferredType();
2405
+ virtual Representation RequiredInputRepresentation(int index) const {
2406
+ return representation();
2407
+ }
2408
+ virtual Representation InferredRepresentation() {
2409
+ if (left()->representation().Equals(right()->representation())) {
2410
+ return left()->representation();
2411
+ }
2412
+ return HValue::InferredRepresentation();
2413
+ }
2414
+ };
2415
+
2416
+
2417
+ class HCompare: public HBinaryOperation {
2418
+ public:
2419
+ HCompare(HValue* left, HValue* right, Token::Value token)
2420
+ : HBinaryOperation(left, right), token_(token) {
2421
+ ASSERT(Token::IsCompareOp(token));
2422
+ set_representation(Representation::Tagged());
2423
+ SetAllSideEffects();
2424
+ }
2425
+
2426
+ void SetInputRepresentation(Representation r);
2427
+
2428
+ virtual bool EmitAtUses() {
2429
+ return !HasSideEffects() && !HasMultipleUses();
2430
+ }
2431
+
2432
+ virtual Representation RequiredInputRepresentation(int index) const {
2433
+ return input_representation_;
2434
+ }
2435
+ Representation GetInputRepresentation() const {
2436
+ return input_representation_;
2437
+ }
2438
+ Token::Value token() const { return token_; }
2439
+ virtual void PrintDataTo(StringStream* stream);
2440
+
2441
+ virtual HType CalculateInferredType();
2442
+
2443
+ virtual intptr_t Hashcode() {
2444
+ return HValue::Hashcode() * 7 + token_;
2445
+ }
2446
+
2447
+ DECLARE_CONCRETE_INSTRUCTION(Compare)
2448
+
2449
+ protected:
2450
+ virtual bool DataEquals(HValue* other) {
2451
+ HCompare* comp = HCompare::cast(other);
2452
+ return token_ == comp->token();
2453
+ }
2454
+
2455
+ private:
2456
+ Representation input_representation_;
2457
+ Token::Value token_;
2458
+ };
2459
+
2460
+
2461
+ class HCompareJSObjectEq: public HBinaryOperation {
2462
+ public:
2463
+ HCompareJSObjectEq(HValue* left, HValue* right)
2464
+ : HBinaryOperation(left, right) {
2465
+ set_representation(Representation::Tagged());
2466
+ SetFlag(kUseGVN);
2467
+ SetFlag(kDependsOnMaps);
2468
+ }
2469
+
2470
+ virtual bool EmitAtUses() {
2471
+ return !HasSideEffects() && !HasMultipleUses();
2472
+ }
2473
+
2474
+ virtual Representation RequiredInputRepresentation(int index) const {
2475
+ return Representation::Tagged();
2476
+ }
2477
+ virtual HType CalculateInferredType();
2478
+
2479
+ DECLARE_CONCRETE_INSTRUCTION(CompareJSObjectEq)
2480
+
2481
+ protected:
2482
+ virtual bool DataEquals(HValue* other) { return true; }
2483
+ };
2484
+
2485
+
2486
+ class HCompareSymbolEq: public HBinaryOperation {
2487
+ public:
2488
+ HCompareSymbolEq(HValue* left, HValue* right, Token::Value op)
2489
+ : HBinaryOperation(left, right), op_(op) {
2490
+ ASSERT(op == Token::EQ || op == Token::EQ_STRICT);
2491
+ set_representation(Representation::Tagged());
2492
+ SetFlag(kUseGVN);
2493
+ SetFlag(kDependsOnMaps);
2494
+ }
2495
+
2496
+ Token::Value op() const { return op_; }
2497
+
2498
+ virtual bool EmitAtUses() {
2499
+ return !HasSideEffects() && !HasMultipleUses();
2500
+ }
2501
+
2502
+ virtual Representation RequiredInputRepresentation(int index) const {
2503
+ return Representation::Tagged();
2504
+ }
2505
+
2506
+ virtual HType CalculateInferredType() { return HType::Boolean(); }
2507
+
2508
+ DECLARE_CONCRETE_INSTRUCTION(CompareSymbolEq);
2509
+
2510
+ protected:
2511
+ virtual bool DataEquals(HValue* other) {
2512
+ return op_ == HCompareSymbolEq::cast(other)->op_;
2513
+ }
2514
+
2515
+ private:
2516
+ const Token::Value op_;
2517
+ };
2518
+
2519
+
2520
+ class HUnaryPredicate: public HUnaryOperation {
2521
+ public:
2522
+ explicit HUnaryPredicate(HValue* value) : HUnaryOperation(value) {
2523
+ set_representation(Representation::Tagged());
2524
+ SetFlag(kUseGVN);
2525
+ }
2526
+
2527
+ virtual bool EmitAtUses() {
2528
+ return !HasSideEffects() && !HasMultipleUses();
2529
+ }
2530
+
2531
+ virtual Representation RequiredInputRepresentation(int index) const {
2532
+ return Representation::Tagged();
2533
+ }
2534
+ virtual HType CalculateInferredType();
2535
+ };
2536
+
2537
+
2538
+ class HIsNull: public HUnaryPredicate {
2539
+ public:
2540
+ HIsNull(HValue* value, bool is_strict)
2541
+ : HUnaryPredicate(value), is_strict_(is_strict) { }
2542
+
2543
+ bool is_strict() const { return is_strict_; }
2544
+
2545
+ DECLARE_CONCRETE_INSTRUCTION(IsNull)
2546
+
2547
+ protected:
2548
+ virtual bool DataEquals(HValue* other) {
2549
+ HIsNull* b = HIsNull::cast(other);
2550
+ return is_strict_ == b->is_strict();
2551
+ }
2552
+
2553
+ private:
2554
+ bool is_strict_;
2555
+ };
2556
+
2557
+
2558
+ class HIsObject: public HUnaryPredicate {
2559
+ public:
2560
+ explicit HIsObject(HValue* value) : HUnaryPredicate(value) { }
2561
+
2562
+ DECLARE_CONCRETE_INSTRUCTION(IsObject)
2563
+
2564
+ protected:
2565
+ virtual bool DataEquals(HValue* other) { return true; }
2566
+ };
2567
+
2568
+
2569
+ class HIsSmi: public HUnaryPredicate {
2570
+ public:
2571
+ explicit HIsSmi(HValue* value) : HUnaryPredicate(value) { }
2572
+
2573
+ DECLARE_CONCRETE_INSTRUCTION(IsSmi)
2574
+
2575
+ protected:
2576
+ virtual bool DataEquals(HValue* other) { return true; }
2577
+ };
2578
+
2579
+
2580
+ class HIsUndetectable: public HUnaryPredicate {
2581
+ public:
2582
+ explicit HIsUndetectable(HValue* value) : HUnaryPredicate(value) { }
2583
+
2584
+ DECLARE_CONCRETE_INSTRUCTION(IsUndetectable)
2585
+
2586
+ protected:
2587
+ virtual bool DataEquals(HValue* other) { return true; }
2588
+ };
2589
+
2590
+
2591
+ class HIsConstructCall: public HTemplateInstruction<0> {
2592
+ public:
2593
+ HIsConstructCall() {
2594
+ set_representation(Representation::Tagged());
2595
+ SetFlag(kUseGVN);
2596
+ }
2597
+
2598
+ virtual bool EmitAtUses() {
2599
+ return !HasSideEffects() && !HasMultipleUses();
2600
+ }
2601
+
2602
+ virtual Representation RequiredInputRepresentation(int index) const {
2603
+ return Representation::None();
2604
+ }
2605
+
2606
+ DECLARE_CONCRETE_INSTRUCTION(IsConstructCall)
2607
+
2608
+ protected:
2609
+ virtual bool DataEquals(HValue* other) { return true; }
2610
+ };
2611
+
2612
+
2613
+ class HHasInstanceType: public HUnaryPredicate {
2614
+ public:
2615
+ HHasInstanceType(HValue* value, InstanceType type)
2616
+ : HUnaryPredicate(value), from_(type), to_(type) { }
2617
+ HHasInstanceType(HValue* value, InstanceType from, InstanceType to)
2618
+ : HUnaryPredicate(value), from_(from), to_(to) {
2619
+ ASSERT(to == LAST_TYPE); // Others not implemented yet in backend.
2620
+ }
2621
+
2622
+ InstanceType from() { return from_; }
2623
+ InstanceType to() { return to_; }
2624
+
2625
+ virtual void PrintDataTo(StringStream* stream);
2626
+
2627
+ DECLARE_CONCRETE_INSTRUCTION(HasInstanceType)
2628
+
2629
+ protected:
2630
+ virtual bool DataEquals(HValue* other) {
2631
+ HHasInstanceType* b = HHasInstanceType::cast(other);
2632
+ return (from_ == b->from()) && (to_ == b->to());
2633
+ }
2634
+
2635
+ private:
2636
+ InstanceType from_;
2637
+ InstanceType to_; // Inclusive range, not all combinations work.
2638
+ };
2639
+
2640
+
2641
+ class HHasCachedArrayIndex: public HUnaryPredicate {
2642
+ public:
2643
+ explicit HHasCachedArrayIndex(HValue* value) : HUnaryPredicate(value) { }
2644
+
2645
+ DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndex)
2646
+
2647
+ protected:
2648
+ virtual bool DataEquals(HValue* other) { return true; }
2649
+ };
2650
+
2651
+
2652
+ class HGetCachedArrayIndex: public HUnaryPredicate {
2653
+ public:
2654
+ explicit HGetCachedArrayIndex(HValue* value) : HUnaryPredicate(value) { }
2655
+
2656
+ DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex)
2657
+
2658
+ protected:
2659
+ virtual bool DataEquals(HValue* other) { return true; }
2660
+ };
2661
+
2662
+
2663
+ class HClassOfTest: public HUnaryPredicate {
2664
+ public:
2665
+ HClassOfTest(HValue* value, Handle<String> class_name)
2666
+ : HUnaryPredicate(value), class_name_(class_name) { }
2667
+
2668
+ DECLARE_CONCRETE_INSTRUCTION(ClassOfTest)
2669
+
2670
+ virtual void PrintDataTo(StringStream* stream);
2671
+
2672
+ Handle<String> class_name() const { return class_name_; }
2673
+
2674
+ protected:
2675
+ virtual bool DataEquals(HValue* other) {
2676
+ HClassOfTest* b = HClassOfTest::cast(other);
2677
+ return class_name_.is_identical_to(b->class_name_);
2678
+ }
2679
+
2680
+ private:
2681
+ Handle<String> class_name_;
2682
+ };
2683
+
2684
+
2685
+ class HTypeofIs: public HUnaryPredicate {
2686
+ public:
2687
+ HTypeofIs(HValue* value, Handle<String> type_literal)
2688
+ : HUnaryPredicate(value), type_literal_(type_literal) { }
2689
+
2690
+ Handle<String> type_literal() { return type_literal_; }
2691
+ virtual void PrintDataTo(StringStream* stream);
2692
+
2693
+ DECLARE_CONCRETE_INSTRUCTION(TypeofIs)
2694
+
2695
+ protected:
2696
+ virtual bool DataEquals(HValue* other) {
2697
+ HTypeofIs* b = HTypeofIs::cast(other);
2698
+ return type_literal_.is_identical_to(b->type_literal_);
2699
+ }
2700
+
2701
+ private:
2702
+ Handle<String> type_literal_;
2703
+ };
2704
+
2705
+
2706
+ class HInstanceOf: public HTemplateInstruction<3> {
2707
+ public:
2708
+ HInstanceOf(HValue* context, HValue* left, HValue* right) {
2709
+ SetOperandAt(0, context);
2710
+ SetOperandAt(1, left);
2711
+ SetOperandAt(2, right);
2712
+ set_representation(Representation::Tagged());
2713
+ SetAllSideEffects();
2714
+ }
2715
+
2716
+ HValue* context() { return OperandAt(0); }
2717
+ HValue* left() { return OperandAt(1); }
2718
+ HValue* right() { return OperandAt(2); }
2719
+
2720
+ virtual bool EmitAtUses() {
2721
+ return !HasSideEffects() && !HasMultipleUses();
2722
+ }
2723
+
2724
+ virtual Representation RequiredInputRepresentation(int index) const {
2725
+ return Representation::Tagged();
2726
+ }
2727
+
2728
+ virtual void PrintDataTo(StringStream* stream);
2729
+
2730
+ DECLARE_CONCRETE_INSTRUCTION(InstanceOf)
2731
+ };
2732
+
2733
+
2734
+ class HInstanceOfKnownGlobal: public HUnaryOperation {
2735
+ public:
2736
+ HInstanceOfKnownGlobal(HValue* left, Handle<JSFunction> right)
2737
+ : HUnaryOperation(left), function_(right) {
2738
+ set_representation(Representation::Tagged());
2739
+ SetAllSideEffects();
2740
+ }
2741
+
2742
+ Handle<JSFunction> function() { return function_; }
2743
+
2744
+ virtual Representation RequiredInputRepresentation(int index) const {
2745
+ return Representation::Tagged();
2746
+ }
2747
+
2748
+ DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal)
2749
+
2750
+ private:
2751
+ Handle<JSFunction> function_;
2752
+ };
2753
+
2754
+
2755
+ class HPower: public HBinaryOperation {
2756
+ public:
2757
+ HPower(HValue* left, HValue* right)
2758
+ : HBinaryOperation(left, right) {
2759
+ set_representation(Representation::Double());
2760
+ SetFlag(kUseGVN);
2761
+ }
2762
+
2763
+ virtual Representation RequiredInputRepresentation(int index) const {
2764
+ return (index == 1) ? Representation::None() : Representation::Double();
2765
+ }
2766
+
2767
+ DECLARE_CONCRETE_INSTRUCTION(Power)
2768
+
2769
+ protected:
2770
+ virtual bool DataEquals(HValue* other) { return true; }
2771
+ };
2772
+
2773
+
2774
+ class HAdd: public HArithmeticBinaryOperation {
2775
+ public:
2776
+ HAdd(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2777
+ SetFlag(kCanOverflow);
2778
+ }
2779
+
2780
+ // Add is only commutative if two integer values are added and not if two
2781
+ // tagged values are added (because it might be a String concatenation).
2782
+ virtual bool IsCommutative() const {
2783
+ return !representation().IsTagged();
2784
+ }
2785
+
2786
+ virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2787
+
2788
+ virtual HType CalculateInferredType();
2789
+
2790
+ DECLARE_CONCRETE_INSTRUCTION(Add)
2791
+
2792
+ protected:
2793
+ virtual bool DataEquals(HValue* other) { return true; }
2794
+
2795
+ virtual Range* InferRange();
2796
+ };
2797
+
2798
+
2799
+ class HSub: public HArithmeticBinaryOperation {
2800
+ public:
2801
+ HSub(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2802
+ SetFlag(kCanOverflow);
2803
+ }
2804
+
2805
+ virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2806
+
2807
+ DECLARE_CONCRETE_INSTRUCTION(Sub)
2808
+
2809
+ protected:
2810
+ virtual bool DataEquals(HValue* other) { return true; }
2811
+
2812
+ virtual Range* InferRange();
2813
+ };
2814
+
2815
+
2816
+ class HMul: public HArithmeticBinaryOperation {
2817
+ public:
2818
+ HMul(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2819
+ SetFlag(kCanOverflow);
2820
+ }
2821
+
2822
+ virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2823
+
2824
+ // Only commutative if it is certain that not two objects are multiplicated.
2825
+ virtual bool IsCommutative() const {
2826
+ return !representation().IsTagged();
2827
+ }
2828
+
2829
+ DECLARE_CONCRETE_INSTRUCTION(Mul)
2830
+
2831
+ protected:
2832
+ virtual bool DataEquals(HValue* other) { return true; }
2833
+
2834
+ virtual Range* InferRange();
2835
+ };
2836
+
2837
+
2838
+ class HMod: public HArithmeticBinaryOperation {
2839
+ public:
2840
+ HMod(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2841
+ SetFlag(kCanBeDivByZero);
2842
+ }
2843
+
2844
+ bool HasPowerOf2Divisor() {
2845
+ if (right()->IsConstant() &&
2846
+ HConstant::cast(right())->HasInteger32Value()) {
2847
+ int32_t value = HConstant::cast(right())->Integer32Value();
2848
+ return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value));
2849
+ }
2850
+
2851
+ return false;
2852
+ }
2853
+
2854
+ virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2855
+
2856
+ DECLARE_CONCRETE_INSTRUCTION(Mod)
2857
+
2858
+ protected:
2859
+ virtual bool DataEquals(HValue* other) { return true; }
2860
+
2861
+ virtual Range* InferRange();
2862
+ };
2863
+
2864
+
2865
+ class HDiv: public HArithmeticBinaryOperation {
2866
+ public:
2867
+ HDiv(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2868
+ SetFlag(kCanBeDivByZero);
2869
+ SetFlag(kCanOverflow);
2870
+ }
2871
+
2872
+ virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2873
+
2874
+ DECLARE_CONCRETE_INSTRUCTION(Div)
2875
+
2876
+ protected:
2877
+ virtual bool DataEquals(HValue* other) { return true; }
2878
+
2879
+ virtual Range* InferRange();
2880
+ };
2881
+
2882
+
2883
+ class HBitAnd: public HBitwiseBinaryOperation {
2884
+ public:
2885
+ HBitAnd(HValue* left, HValue* right)
2886
+ : HBitwiseBinaryOperation(left, right) { }
2887
+
2888
+ virtual bool IsCommutative() const { return true; }
2889
+ virtual HType CalculateInferredType();
2890
+
2891
+ DECLARE_CONCRETE_INSTRUCTION(BitAnd)
2892
+
2893
+ protected:
2894
+ virtual bool DataEquals(HValue* other) { return true; }
2895
+
2896
+ virtual Range* InferRange();
2897
+ };
2898
+
2899
+
2900
+ class HBitXor: public HBitwiseBinaryOperation {
2901
+ public:
2902
+ HBitXor(HValue* left, HValue* right)
2903
+ : HBitwiseBinaryOperation(left, right) { }
2904
+
2905
+ virtual bool IsCommutative() const { return true; }
2906
+ virtual HType CalculateInferredType();
2907
+
2908
+ DECLARE_CONCRETE_INSTRUCTION(BitXor)
2909
+
2910
+ protected:
2911
+ virtual bool DataEquals(HValue* other) { return true; }
2912
+ };
2913
+
2914
+
2915
+ class HBitOr: public HBitwiseBinaryOperation {
2916
+ public:
2917
+ HBitOr(HValue* left, HValue* right)
2918
+ : HBitwiseBinaryOperation(left, right) { }
2919
+
2920
+ virtual bool IsCommutative() const { return true; }
2921
+ virtual HType CalculateInferredType();
2922
+
2923
+ DECLARE_CONCRETE_INSTRUCTION(BitOr)
2924
+
2925
+ protected:
2926
+ virtual bool DataEquals(HValue* other) { return true; }
2927
+
2928
+ virtual Range* InferRange();
2929
+ };
2930
+
2931
+
2932
+ class HShl: public HBitwiseBinaryOperation {
2933
+ public:
2934
+ HShl(HValue* left, HValue* right)
2935
+ : HBitwiseBinaryOperation(left, right) { }
2936
+
2937
+ virtual Range* InferRange();
2938
+ virtual HType CalculateInferredType();
2939
+
2940
+ DECLARE_CONCRETE_INSTRUCTION(Shl)
2941
+
2942
+ protected:
2943
+ virtual bool DataEquals(HValue* other) { return true; }
2944
+ };
2945
+
2946
+
2947
+ class HShr: public HBitwiseBinaryOperation {
2948
+ public:
2949
+ HShr(HValue* left, HValue* right)
2950
+ : HBitwiseBinaryOperation(left, right) { }
2951
+
2952
+ virtual HType CalculateInferredType();
2953
+
2954
+ DECLARE_CONCRETE_INSTRUCTION(Shr)
2955
+
2956
+ protected:
2957
+ virtual bool DataEquals(HValue* other) { return true; }
2958
+ };
2959
+
2960
+
2961
+ class HSar: public HBitwiseBinaryOperation {
2962
+ public:
2963
+ HSar(HValue* left, HValue* right)
2964
+ : HBitwiseBinaryOperation(left, right) { }
2965
+
2966
+ virtual Range* InferRange();
2967
+ virtual HType CalculateInferredType();
2968
+
2969
+ DECLARE_CONCRETE_INSTRUCTION(Sar)
2970
+
2971
+ protected:
2972
+ virtual bool DataEquals(HValue* other) { return true; }
2973
+ };
2974
+
2975
+
2976
+ class HOsrEntry: public HTemplateInstruction<0> {
2977
+ public:
2978
+ explicit HOsrEntry(int ast_id) : ast_id_(ast_id) {
2979
+ SetFlag(kChangesOsrEntries);
2980
+ }
2981
+
2982
+ int ast_id() const { return ast_id_; }
2983
+
2984
+ virtual Representation RequiredInputRepresentation(int index) const {
2985
+ return Representation::None();
2986
+ }
2987
+
2988
+ DECLARE_CONCRETE_INSTRUCTION(OsrEntry)
2989
+
2990
+ private:
2991
+ int ast_id_;
2992
+ };
2993
+
2994
+
2995
+ class HParameter: public HTemplateInstruction<0> {
2996
+ public:
2997
+ explicit HParameter(unsigned index) : index_(index) {
2998
+ set_representation(Representation::Tagged());
2999
+ }
3000
+
3001
+ unsigned index() const { return index_; }
3002
+
3003
+ virtual void PrintDataTo(StringStream* stream);
3004
+
3005
+ virtual Representation RequiredInputRepresentation(int index) const {
3006
+ return Representation::None();
3007
+ }
3008
+
3009
+ DECLARE_CONCRETE_INSTRUCTION(Parameter)
3010
+
3011
+ private:
3012
+ unsigned index_;
3013
+ };
3014
+
3015
+
3016
+ class HCallStub: public HUnaryCall {
3017
+ public:
3018
+ HCallStub(HValue* context, CodeStub::Major major_key, int argument_count)
3019
+ : HUnaryCall(context, argument_count),
3020
+ major_key_(major_key),
3021
+ transcendental_type_(TranscendentalCache::kNumberOfCaches) {
3022
+ }
3023
+
3024
+ CodeStub::Major major_key() { return major_key_; }
3025
+
3026
+ HValue* context() { return value(); }
3027
+
3028
+ void set_transcendental_type(TranscendentalCache::Type transcendental_type) {
3029
+ transcendental_type_ = transcendental_type;
3030
+ }
3031
+ TranscendentalCache::Type transcendental_type() {
3032
+ return transcendental_type_;
3033
+ }
3034
+
3035
+ virtual void PrintDataTo(StringStream* stream);
3036
+
3037
+ virtual Representation RequiredInputRepresentation(int index) const {
3038
+ return Representation::Tagged();
3039
+ }
3040
+
3041
+ DECLARE_CONCRETE_INSTRUCTION(CallStub)
3042
+
3043
+ private:
3044
+ CodeStub::Major major_key_;
3045
+ TranscendentalCache::Type transcendental_type_;
3046
+ };
3047
+
3048
+
3049
+ class HUnknownOSRValue: public HTemplateInstruction<0> {
3050
+ public:
3051
+ HUnknownOSRValue() { set_representation(Representation::Tagged()); }
3052
+
3053
+ virtual Representation RequiredInputRepresentation(int index) const {
3054
+ return Representation::None();
3055
+ }
3056
+
3057
+ DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue)
3058
+ };
3059
+
3060
+
3061
+ class HLoadGlobalCell: public HTemplateInstruction<0> {
3062
+ public:
3063
+ HLoadGlobalCell(Handle<JSGlobalPropertyCell> cell, bool check_hole_value)
3064
+ : cell_(cell), check_hole_value_(check_hole_value) {
3065
+ set_representation(Representation::Tagged());
3066
+ SetFlag(kUseGVN);
3067
+ SetFlag(kDependsOnGlobalVars);
3068
+ }
3069
+
3070
+ Handle<JSGlobalPropertyCell> cell() const { return cell_; }
3071
+ bool check_hole_value() const { return check_hole_value_; }
3072
+
3073
+ virtual void PrintDataTo(StringStream* stream);
3074
+
3075
+ virtual intptr_t Hashcode() {
3076
+ ASSERT(!HEAP->allow_allocation(false));
3077
+ return reinterpret_cast<intptr_t>(*cell_);
3078
+ }
3079
+
3080
+ virtual Representation RequiredInputRepresentation(int index) const {
3081
+ return Representation::None();
3082
+ }
3083
+
3084
+ DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell)
3085
+
3086
+ protected:
3087
+ virtual bool DataEquals(HValue* other) {
3088
+ HLoadGlobalCell* b = HLoadGlobalCell::cast(other);
3089
+ return cell_.is_identical_to(b->cell());
3090
+ }
3091
+
3092
+ private:
3093
+ Handle<JSGlobalPropertyCell> cell_;
3094
+ bool check_hole_value_;
3095
+ };
3096
+
3097
+
3098
+ class HLoadGlobalGeneric: public HBinaryOperation {
3099
+ public:
3100
+ HLoadGlobalGeneric(HValue* context,
3101
+ HValue* global_object,
3102
+ Handle<Object> name,
3103
+ bool for_typeof)
3104
+ : HBinaryOperation(context, global_object),
3105
+ name_(name),
3106
+ for_typeof_(for_typeof) {
3107
+ set_representation(Representation::Tagged());
3108
+ SetAllSideEffects();
3109
+ }
3110
+
3111
+ HValue* context() { return OperandAt(0); }
3112
+ HValue* global_object() { return OperandAt(1); }
3113
+ Handle<Object> name() const { return name_; }
3114
+ bool for_typeof() const { return for_typeof_; }
3115
+
3116
+ virtual void PrintDataTo(StringStream* stream);
3117
+
3118
+ virtual Representation RequiredInputRepresentation(int index) const {
3119
+ return Representation::Tagged();
3120
+ }
3121
+
3122
+ DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric)
3123
+
3124
+ private:
3125
+ Handle<Object> name_;
3126
+ bool for_typeof_;
3127
+ };
3128
+
3129
+
3130
+ class HStoreGlobalCell: public HUnaryOperation {
3131
+ public:
3132
+ HStoreGlobalCell(HValue* value,
3133
+ Handle<JSGlobalPropertyCell> cell,
3134
+ bool check_hole_value)
3135
+ : HUnaryOperation(value),
3136
+ cell_(cell),
3137
+ check_hole_value_(check_hole_value) {
3138
+ SetFlag(kChangesGlobalVars);
3139
+ }
3140
+
3141
+ Handle<JSGlobalPropertyCell> cell() const { return cell_; }
3142
+ bool check_hole_value() const { return check_hole_value_; }
3143
+
3144
+ virtual Representation RequiredInputRepresentation(int index) const {
3145
+ return Representation::Tagged();
3146
+ }
3147
+ virtual void PrintDataTo(StringStream* stream);
3148
+
3149
+ DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell)
3150
+
3151
+ private:
3152
+ Handle<JSGlobalPropertyCell> cell_;
3153
+ bool check_hole_value_;
3154
+ };
3155
+
3156
+
3157
+ class HStoreGlobalGeneric: public HTemplateInstruction<3> {
3158
+ public:
3159
+ HStoreGlobalGeneric(HValue* context,
3160
+ HValue* global_object,
3161
+ Handle<Object> name,
3162
+ HValue* value,
3163
+ bool strict_mode)
3164
+ : name_(name),
3165
+ strict_mode_(strict_mode) {
3166
+ SetOperandAt(0, context);
3167
+ SetOperandAt(1, global_object);
3168
+ SetOperandAt(2, value);
3169
+ set_representation(Representation::Tagged());
3170
+ SetAllSideEffects();
3171
+ }
3172
+
3173
+ HValue* context() { return OperandAt(0); }
3174
+ HValue* global_object() { return OperandAt(1); }
3175
+ Handle<Object> name() const { return name_; }
3176
+ HValue* value() { return OperandAt(2); }
3177
+ bool strict_mode() { return strict_mode_; }
3178
+
3179
+ virtual void PrintDataTo(StringStream* stream);
3180
+
3181
+ virtual Representation RequiredInputRepresentation(int index) const {
3182
+ return Representation::Tagged();
3183
+ }
3184
+
3185
+ DECLARE_CONCRETE_INSTRUCTION(StoreGlobalGeneric)
3186
+
3187
+ private:
3188
+ Handle<Object> name_;
3189
+ bool strict_mode_;
3190
+ };
3191
+
3192
+
3193
+ class HLoadContextSlot: public HUnaryOperation {
3194
+ public:
3195
+ HLoadContextSlot(HValue* context , int slot_index)
3196
+ : HUnaryOperation(context), slot_index_(slot_index) {
3197
+ set_representation(Representation::Tagged());
3198
+ SetFlag(kUseGVN);
3199
+ SetFlag(kDependsOnContextSlots);
3200
+ }
3201
+
3202
+ int slot_index() const { return slot_index_; }
3203
+
3204
+ virtual Representation RequiredInputRepresentation(int index) const {
3205
+ return Representation::Tagged();
3206
+ }
3207
+
3208
+ virtual void PrintDataTo(StringStream* stream);
3209
+
3210
+ DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot)
3211
+
3212
+ protected:
3213
+ virtual bool DataEquals(HValue* other) {
3214
+ HLoadContextSlot* b = HLoadContextSlot::cast(other);
3215
+ return (slot_index() == b->slot_index());
3216
+ }
3217
+
3218
+ private:
3219
+ int slot_index_;
3220
+ };
3221
+
3222
+
3223
+ static inline bool StoringValueNeedsWriteBarrier(HValue* value) {
3224
+ return !value->type().IsSmi() &&
3225
+ !(value->IsConstant() && HConstant::cast(value)->InOldSpace());
3226
+ }
3227
+
3228
+
3229
+ class HStoreContextSlot: public HBinaryOperation {
3230
+ public:
3231
+ HStoreContextSlot(HValue* context, int slot_index, HValue* value)
3232
+ : HBinaryOperation(context, value), slot_index_(slot_index) {
3233
+ SetFlag(kChangesContextSlots);
3234
+ }
3235
+
3236
+ HValue* context() { return OperandAt(0); }
3237
+ HValue* value() { return OperandAt(1); }
3238
+ int slot_index() const { return slot_index_; }
3239
+
3240
+ bool NeedsWriteBarrier() {
3241
+ return StoringValueNeedsWriteBarrier(value());
3242
+ }
3243
+
3244
+ virtual Representation RequiredInputRepresentation(int index) const {
3245
+ return Representation::Tagged();
3246
+ }
3247
+
3248
+ virtual void PrintDataTo(StringStream* stream);
3249
+
3250
+ DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot)
3251
+
3252
+ private:
3253
+ int slot_index_;
3254
+ };
3255
+
3256
+
3257
+ class HLoadNamedField: public HUnaryOperation {
3258
+ public:
3259
+ HLoadNamedField(HValue* object, bool is_in_object, int offset)
3260
+ : HUnaryOperation(object),
3261
+ is_in_object_(is_in_object),
3262
+ offset_(offset) {
3263
+ set_representation(Representation::Tagged());
3264
+ SetFlag(kUseGVN);
3265
+ SetFlag(kDependsOnMaps);
3266
+ if (is_in_object) {
3267
+ SetFlag(kDependsOnInobjectFields);
3268
+ } else {
3269
+ SetFlag(kDependsOnBackingStoreFields);
3270
+ }
3271
+ }
3272
+
3273
+ HValue* object() { return OperandAt(0); }
3274
+ bool is_in_object() const { return is_in_object_; }
3275
+ int offset() const { return offset_; }
3276
+
3277
+ virtual Representation RequiredInputRepresentation(int index) const {
3278
+ return Representation::Tagged();
3279
+ }
3280
+ virtual void PrintDataTo(StringStream* stream);
3281
+
3282
+ DECLARE_CONCRETE_INSTRUCTION(LoadNamedField)
3283
+
3284
+ protected:
3285
+ virtual bool DataEquals(HValue* other) {
3286
+ HLoadNamedField* b = HLoadNamedField::cast(other);
3287
+ return is_in_object_ == b->is_in_object_ && offset_ == b->offset_;
3288
+ }
3289
+
3290
+ private:
3291
+ bool is_in_object_;
3292
+ int offset_;
3293
+ };
3294
+
3295
+
3296
+ class HLoadNamedFieldPolymorphic: public HUnaryOperation {
3297
+ public:
3298
+ HLoadNamedFieldPolymorphic(HValue* object,
3299
+ ZoneMapList* types,
3300
+ Handle<String> name);
3301
+
3302
+ HValue* object() { return OperandAt(0); }
3303
+ ZoneMapList* types() { return &types_; }
3304
+ Handle<String> name() { return name_; }
3305
+ bool need_generic() { return need_generic_; }
3306
+
3307
+ virtual Representation RequiredInputRepresentation(int index) const {
3308
+ return Representation::Tagged();
3309
+ }
3310
+
3311
+ DECLARE_CONCRETE_INSTRUCTION(LoadNamedFieldPolymorphic)
3312
+
3313
+ static const int kMaxLoadPolymorphism = 4;
3314
+
3315
+ protected:
3316
+ virtual bool DataEquals(HValue* value);
3317
+
3318
+ private:
3319
+ ZoneMapList types_;
3320
+ Handle<String> name_;
3321
+ bool need_generic_;
3322
+ };
3323
+
3324
+
3325
+
3326
+ class HLoadNamedGeneric: public HBinaryOperation {
3327
+ public:
3328
+ HLoadNamedGeneric(HValue* context, HValue* object, Handle<Object> name)
3329
+ : HBinaryOperation(context, object), name_(name) {
3330
+ set_representation(Representation::Tagged());
3331
+ SetAllSideEffects();
3332
+ }
3333
+
3334
+ HValue* context() { return OperandAt(0); }
3335
+ HValue* object() { return OperandAt(1); }
3336
+ Handle<Object> name() const { return name_; }
3337
+
3338
+ virtual Representation RequiredInputRepresentation(int index) const {
3339
+ return Representation::Tagged();
3340
+ }
3341
+
3342
+ DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric)
3343
+
3344
+ private:
3345
+ Handle<Object> name_;
3346
+ };
3347
+
3348
+
3349
+ class HLoadFunctionPrototype: public HUnaryOperation {
3350
+ public:
3351
+ explicit HLoadFunctionPrototype(HValue* function)
3352
+ : HUnaryOperation(function) {
3353
+ set_representation(Representation::Tagged());
3354
+ SetFlag(kUseGVN);
3355
+ SetFlag(kDependsOnCalls);
3356
+ }
3357
+
3358
+ HValue* function() { return OperandAt(0); }
3359
+
3360
+ virtual Representation RequiredInputRepresentation(int index) const {
3361
+ return Representation::Tagged();
3362
+ }
3363
+
3364
+ DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype)
3365
+
3366
+ protected:
3367
+ virtual bool DataEquals(HValue* other) { return true; }
3368
+ };
3369
+
3370
+
3371
+ class HLoadKeyedFastElement: public HBinaryOperation {
3372
+ public:
3373
+ HLoadKeyedFastElement(HValue* obj, HValue* key) : HBinaryOperation(obj, key) {
3374
+ set_representation(Representation::Tagged());
3375
+ SetFlag(kDependsOnArrayElements);
3376
+ SetFlag(kUseGVN);
3377
+ }
3378
+
3379
+ HValue* object() { return OperandAt(0); }
3380
+ HValue* key() { return OperandAt(1); }
3381
+
3382
+ virtual Representation RequiredInputRepresentation(int index) const {
3383
+ // The key is supposed to be Integer32.
3384
+ return (index == 1) ? Representation::Integer32()
3385
+ : Representation::Tagged();
3386
+ }
3387
+
3388
+ virtual void PrintDataTo(StringStream* stream);
3389
+
3390
+ bool RequiresHoleCheck() const;
3391
+
3392
+ DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement)
3393
+
3394
+ protected:
3395
+ virtual bool DataEquals(HValue* other) { return true; }
3396
+ };
3397
+
3398
+
3399
+ class HLoadKeyedSpecializedArrayElement: public HBinaryOperation {
3400
+ public:
3401
+ HLoadKeyedSpecializedArrayElement(HValue* external_elements,
3402
+ HValue* key,
3403
+ ExternalArrayType array_type)
3404
+ : HBinaryOperation(external_elements, key),
3405
+ array_type_(array_type) {
3406
+ if (array_type == kExternalFloatArray ||
3407
+ array_type == kExternalDoubleArray) {
3408
+ set_representation(Representation::Double());
3409
+ } else {
3410
+ set_representation(Representation::Integer32());
3411
+ }
3412
+ SetFlag(kDependsOnSpecializedArrayElements);
3413
+ // Native code could change the specialized array.
3414
+ SetFlag(kDependsOnCalls);
3415
+ SetFlag(kUseGVN);
3416
+ }
3417
+
3418
+ virtual void PrintDataTo(StringStream* stream);
3419
+
3420
+ virtual Representation RequiredInputRepresentation(int index) const {
3421
+ // The key is supposed to be Integer32, but the base pointer
3422
+ // for the element load is a naked pointer.
3423
+ return (index == 1) ? Representation::Integer32()
3424
+ : Representation::External();
3425
+ }
3426
+
3427
+ HValue* external_pointer() { return OperandAt(0); }
3428
+ HValue* key() { return OperandAt(1); }
3429
+ ExternalArrayType array_type() const { return array_type_; }
3430
+
3431
+ DECLARE_CONCRETE_INSTRUCTION(LoadKeyedSpecializedArrayElement)
3432
+
3433
+ protected:
3434
+ virtual bool DataEquals(HValue* other) {
3435
+ if (!other->IsLoadKeyedSpecializedArrayElement()) return false;
3436
+ HLoadKeyedSpecializedArrayElement* cast_other =
3437
+ HLoadKeyedSpecializedArrayElement::cast(other);
3438
+ return array_type_ == cast_other->array_type();
3439
+ }
3440
+
3441
+ private:
3442
+ ExternalArrayType array_type_;
3443
+ };
3444
+
3445
+
3446
+ class HLoadKeyedGeneric: public HTemplateInstruction<3> {
3447
+ public:
3448
+ HLoadKeyedGeneric(HValue* context, HValue* obj, HValue* key) {
3449
+ set_representation(Representation::Tagged());
3450
+ SetOperandAt(0, obj);
3451
+ SetOperandAt(1, key);
3452
+ SetOperandAt(2, context);
3453
+ SetAllSideEffects();
3454
+ }
3455
+
3456
+ HValue* object() { return OperandAt(0); }
3457
+ HValue* key() { return OperandAt(1); }
3458
+ HValue* context() { return OperandAt(2); }
3459
+
3460
+ virtual void PrintDataTo(StringStream* stream);
3461
+
3462
+ virtual Representation RequiredInputRepresentation(int index) const {
3463
+ return Representation::Tagged();
3464
+ }
3465
+
3466
+ DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric)
3467
+ };
3468
+
3469
+
3470
+ class HStoreNamedField: public HBinaryOperation {
3471
+ public:
3472
+ HStoreNamedField(HValue* obj,
3473
+ Handle<String> name,
3474
+ HValue* val,
3475
+ bool in_object,
3476
+ int offset)
3477
+ : HBinaryOperation(obj, val),
3478
+ name_(name),
3479
+ is_in_object_(in_object),
3480
+ offset_(offset) {
3481
+ if (is_in_object_) {
3482
+ SetFlag(kChangesInobjectFields);
3483
+ } else {
3484
+ SetFlag(kChangesBackingStoreFields);
3485
+ }
3486
+ }
3487
+
3488
+ DECLARE_CONCRETE_INSTRUCTION(StoreNamedField)
3489
+
3490
+ virtual Representation RequiredInputRepresentation(int index) const {
3491
+ return Representation::Tagged();
3492
+ }
3493
+ virtual void PrintDataTo(StringStream* stream);
3494
+
3495
+ HValue* object() { return OperandAt(0); }
3496
+ HValue* value() { return OperandAt(1); }
3497
+
3498
+ Handle<String> name() const { return name_; }
3499
+ bool is_in_object() const { return is_in_object_; }
3500
+ int offset() const { return offset_; }
3501
+ Handle<Map> transition() const { return transition_; }
3502
+ void set_transition(Handle<Map> map) { transition_ = map; }
3503
+
3504
+ bool NeedsWriteBarrier() {
3505
+ return StoringValueNeedsWriteBarrier(value());
3506
+ }
3507
+
3508
+ private:
3509
+ Handle<String> name_;
3510
+ bool is_in_object_;
3511
+ int offset_;
3512
+ Handle<Map> transition_;
3513
+ };
3514
+
3515
+
3516
+ class HStoreNamedGeneric: public HTemplateInstruction<3> {
3517
+ public:
3518
+ HStoreNamedGeneric(HValue* context,
3519
+ HValue* object,
3520
+ Handle<String> name,
3521
+ HValue* value,
3522
+ bool strict_mode)
3523
+ : name_(name),
3524
+ strict_mode_(strict_mode) {
3525
+ SetOperandAt(0, object);
3526
+ SetOperandAt(1, value);
3527
+ SetOperandAt(2, context);
3528
+ SetAllSideEffects();
3529
+ }
3530
+
3531
+ HValue* object() { return OperandAt(0); }
3532
+ HValue* value() { return OperandAt(1); }
3533
+ HValue* context() { return OperandAt(2); }
3534
+ Handle<String> name() { return name_; }
3535
+ bool strict_mode() { return strict_mode_; }
3536
+
3537
+ virtual void PrintDataTo(StringStream* stream);
3538
+
3539
+ virtual Representation RequiredInputRepresentation(int index) const {
3540
+ return Representation::Tagged();
3541
+ }
3542
+
3543
+ DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric)
3544
+
3545
+ private:
3546
+ Handle<String> name_;
3547
+ bool strict_mode_;
3548
+ };
3549
+
3550
+
3551
+ class HStoreKeyedFastElement: public HTemplateInstruction<3> {
3552
+ public:
3553
+ HStoreKeyedFastElement(HValue* obj, HValue* key, HValue* val) {
3554
+ SetOperandAt(0, obj);
3555
+ SetOperandAt(1, key);
3556
+ SetOperandAt(2, val);
3557
+ SetFlag(kChangesArrayElements);
3558
+ }
3559
+
3560
+ virtual Representation RequiredInputRepresentation(int index) const {
3561
+ // The key is supposed to be Integer32.
3562
+ return (index == 1) ? Representation::Integer32()
3563
+ : Representation::Tagged();
3564
+ }
3565
+
3566
+ HValue* object() { return OperandAt(0); }
3567
+ HValue* key() { return OperandAt(1); }
3568
+ HValue* value() { return OperandAt(2); }
3569
+
3570
+ bool NeedsWriteBarrier() {
3571
+ return StoringValueNeedsWriteBarrier(value());
3572
+ }
3573
+
3574
+ virtual void PrintDataTo(StringStream* stream);
3575
+
3576
+ DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement)
3577
+ };
3578
+
3579
+
3580
+ class HStoreKeyedSpecializedArrayElement: public HTemplateInstruction<3> {
3581
+ public:
3582
+ HStoreKeyedSpecializedArrayElement(HValue* external_elements,
3583
+ HValue* key,
3584
+ HValue* val,
3585
+ ExternalArrayType array_type)
3586
+ : array_type_(array_type) {
3587
+ SetFlag(kChangesSpecializedArrayElements);
3588
+ SetOperandAt(0, external_elements);
3589
+ SetOperandAt(1, key);
3590
+ SetOperandAt(2, val);
3591
+ }
3592
+
3593
+ virtual void PrintDataTo(StringStream* stream);
3594
+
3595
+ virtual Representation RequiredInputRepresentation(int index) const {
3596
+ if (index == 0) {
3597
+ return Representation::External();
3598
+ } else {
3599
+ if (index == 2 && (array_type() == kExternalFloatArray ||
3600
+ array_type() == kExternalDoubleArray)) {
3601
+ return Representation::Double();
3602
+ } else {
3603
+ return Representation::Integer32();
3604
+ }
3605
+ }
3606
+ }
3607
+
3608
+ HValue* external_pointer() { return OperandAt(0); }
3609
+ HValue* key() { return OperandAt(1); }
3610
+ HValue* value() { return OperandAt(2); }
3611
+ ExternalArrayType array_type() const { return array_type_; }
3612
+
3613
+ DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement)
3614
+
3615
+ private:
3616
+ ExternalArrayType array_type_;
3617
+ };
3618
+
3619
+
3620
+ class HStoreKeyedGeneric: public HTemplateInstruction<4> {
3621
+ public:
3622
+ HStoreKeyedGeneric(HValue* context,
3623
+ HValue* object,
3624
+ HValue* key,
3625
+ HValue* value,
3626
+ bool strict_mode)
3627
+ : strict_mode_(strict_mode) {
3628
+ SetOperandAt(0, object);
3629
+ SetOperandAt(1, key);
3630
+ SetOperandAt(2, value);
3631
+ SetOperandAt(3, context);
3632
+ SetAllSideEffects();
3633
+ }
3634
+
3635
+ HValue* object() { return OperandAt(0); }
3636
+ HValue* key() { return OperandAt(1); }
3637
+ HValue* value() { return OperandAt(2); }
3638
+ HValue* context() { return OperandAt(3); }
3639
+ bool strict_mode() { return strict_mode_; }
3640
+
3641
+ virtual Representation RequiredInputRepresentation(int index) const {
3642
+ return Representation::Tagged();
3643
+ }
3644
+
3645
+ virtual void PrintDataTo(StringStream* stream);
3646
+
3647
+ DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric)
3648
+
3649
+ private:
3650
+ bool strict_mode_;
3651
+ };
3652
+
3653
+
3654
+ class HStringAdd: public HBinaryOperation {
3655
+ public:
3656
+ HStringAdd(HValue* left, HValue* right) : HBinaryOperation(left, right) {
3657
+ set_representation(Representation::Tagged());
3658
+ SetFlag(kUseGVN);
3659
+ SetFlag(kDependsOnMaps);
3660
+ }
3661
+
3662
+ virtual Representation RequiredInputRepresentation(int index) const {
3663
+ return Representation::Tagged();
3664
+ }
3665
+
3666
+ virtual HType CalculateInferredType() {
3667
+ return HType::String();
3668
+ }
3669
+
3670
+ DECLARE_CONCRETE_INSTRUCTION(StringAdd)
3671
+
3672
+ protected:
3673
+ virtual bool DataEquals(HValue* other) { return true; }
3674
+ };
3675
+
3676
+
3677
+ class HStringCharCodeAt: public HBinaryOperation {
3678
+ public:
3679
+ HStringCharCodeAt(HValue* string, HValue* index)
3680
+ : HBinaryOperation(string, index) {
3681
+ set_representation(Representation::Integer32());
3682
+ SetFlag(kUseGVN);
3683
+ SetFlag(kDependsOnMaps);
3684
+ }
3685
+
3686
+ virtual Representation RequiredInputRepresentation(int index) const {
3687
+ // The index is supposed to be Integer32.
3688
+ return (index == 1) ? Representation::Integer32()
3689
+ : Representation::Tagged();
3690
+ }
3691
+
3692
+ HValue* string() { return OperandAt(0); }
3693
+ HValue* index() { return OperandAt(1); }
3694
+
3695
+ DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt)
3696
+
3697
+ protected:
3698
+ virtual bool DataEquals(HValue* other) { return true; }
3699
+
3700
+ virtual Range* InferRange() {
3701
+ return new Range(0, String::kMaxUC16CharCode);
3702
+ }
3703
+ };
3704
+
3705
+
3706
+ class HStringCharFromCode: public HUnaryOperation {
3707
+ public:
3708
+ explicit HStringCharFromCode(HValue* char_code) : HUnaryOperation(char_code) {
3709
+ set_representation(Representation::Tagged());
3710
+ SetFlag(kUseGVN);
3711
+ }
3712
+
3713
+ virtual Representation RequiredInputRepresentation(int index) const {
3714
+ return Representation::Integer32();
3715
+ }
3716
+
3717
+ virtual bool DataEquals(HValue* other) { return true; }
3718
+
3719
+ DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode)
3720
+ };
3721
+
3722
+
3723
+ class HStringLength: public HUnaryOperation {
3724
+ public:
3725
+ explicit HStringLength(HValue* string) : HUnaryOperation(string) {
3726
+ set_representation(Representation::Tagged());
3727
+ SetFlag(kUseGVN);
3728
+ SetFlag(kDependsOnMaps);
3729
+ }
3730
+
3731
+ virtual Representation RequiredInputRepresentation(int index) const {
3732
+ return Representation::Tagged();
3733
+ }
3734
+
3735
+ virtual HType CalculateInferredType() {
3736
+ STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
3737
+ return HType::Smi();
3738
+ }
3739
+
3740
+ DECLARE_CONCRETE_INSTRUCTION(StringLength)
3741
+
3742
+ protected:
3743
+ virtual bool DataEquals(HValue* other) { return true; }
3744
+
3745
+ virtual Range* InferRange() {
3746
+ return new Range(0, String::kMaxLength);
3747
+ }
3748
+ };
3749
+
3750
+
3751
+ template <int V>
3752
+ class HMaterializedLiteral: public HTemplateInstruction<V> {
3753
+ public:
3754
+ HMaterializedLiteral<V>(int index, int depth)
3755
+ : literal_index_(index), depth_(depth) {
3756
+ this->set_representation(Representation::Tagged());
3757
+ }
3758
+
3759
+ int literal_index() const { return literal_index_; }
3760
+ int depth() const { return depth_; }
3761
+
3762
+ private:
3763
+ int literal_index_;
3764
+ int depth_;
3765
+ };
3766
+
3767
+
3768
+ class HArrayLiteral: public HMaterializedLiteral<0> {
3769
+ public:
3770
+ HArrayLiteral(Handle<FixedArray> constant_elements,
3771
+ int length,
3772
+ int literal_index,
3773
+ int depth)
3774
+ : HMaterializedLiteral<0>(literal_index, depth),
3775
+ length_(length),
3776
+ constant_elements_(constant_elements) {}
3777
+
3778
+ Handle<FixedArray> constant_elements() const { return constant_elements_; }
3779
+ int length() const { return length_; }
3780
+
3781
+ bool IsCopyOnWrite() const;
3782
+
3783
+ virtual Representation RequiredInputRepresentation(int index) const {
3784
+ return Representation::None();
3785
+ }
3786
+
3787
+ DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral)
3788
+
3789
+ private:
3790
+ int length_;
3791
+ Handle<FixedArray> constant_elements_;
3792
+ };
3793
+
3794
+
3795
+ class HObjectLiteral: public HMaterializedLiteral<1> {
3796
+ public:
3797
+ HObjectLiteral(HValue* context,
3798
+ Handle<FixedArray> constant_properties,
3799
+ bool fast_elements,
3800
+ int literal_index,
3801
+ int depth,
3802
+ bool has_function)
3803
+ : HMaterializedLiteral<1>(literal_index, depth),
3804
+ constant_properties_(constant_properties),
3805
+ fast_elements_(fast_elements),
3806
+ has_function_(has_function) {
3807
+ SetOperandAt(0, context);
3808
+ }
3809
+
3810
+ HValue* context() { return OperandAt(0); }
3811
+ Handle<FixedArray> constant_properties() const {
3812
+ return constant_properties_;
3813
+ }
3814
+ bool fast_elements() const { return fast_elements_; }
3815
+ bool has_function() const { return has_function_; }
3816
+
3817
+ virtual Representation RequiredInputRepresentation(int index) const {
3818
+ return Representation::Tagged();
3819
+ }
3820
+
3821
+ DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral)
3822
+
3823
+ private:
3824
+ Handle<FixedArray> constant_properties_;
3825
+ bool fast_elements_;
3826
+ bool has_function_;
3827
+ };
3828
+
3829
+
3830
+ class HRegExpLiteral: public HMaterializedLiteral<0> {
3831
+ public:
3832
+ HRegExpLiteral(Handle<String> pattern,
3833
+ Handle<String> flags,
3834
+ int literal_index)
3835
+ : HMaterializedLiteral<0>(literal_index, 0),
3836
+ pattern_(pattern),
3837
+ flags_(flags) { }
3838
+
3839
+ Handle<String> pattern() { return pattern_; }
3840
+ Handle<String> flags() { return flags_; }
3841
+
3842
+ virtual Representation RequiredInputRepresentation(int index) const {
3843
+ return Representation::None();
3844
+ }
3845
+
3846
+ DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral)
3847
+
3848
+ private:
3849
+ Handle<String> pattern_;
3850
+ Handle<String> flags_;
3851
+ };
3852
+
3853
+
3854
+ class HFunctionLiteral: public HTemplateInstruction<0> {
3855
+ public:
3856
+ HFunctionLiteral(Handle<SharedFunctionInfo> shared, bool pretenure)
3857
+ : shared_info_(shared), pretenure_(pretenure) {
3858
+ set_representation(Representation::Tagged());
3859
+ }
3860
+
3861
+ virtual Representation RequiredInputRepresentation(int index) const {
3862
+ return Representation::None();
3863
+ }
3864
+
3865
+ DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral)
3866
+
3867
+ Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
3868
+ bool pretenure() const { return pretenure_; }
3869
+
3870
+ private:
3871
+ Handle<SharedFunctionInfo> shared_info_;
3872
+ bool pretenure_;
3873
+ };
3874
+
3875
+
3876
+ class HTypeof: public HUnaryOperation {
3877
+ public:
3878
+ explicit HTypeof(HValue* value) : HUnaryOperation(value) {
3879
+ set_representation(Representation::Tagged());
3880
+ }
3881
+
3882
+ virtual Representation RequiredInputRepresentation(int index) const {
3883
+ return Representation::Tagged();
3884
+ }
3885
+
3886
+ DECLARE_CONCRETE_INSTRUCTION(Typeof)
3887
+ };
3888
+
3889
+
3890
+ class HToFastProperties: public HUnaryOperation {
3891
+ public:
3892
+ explicit HToFastProperties(HValue* value) : HUnaryOperation(value) {
3893
+ // This instruction is not marked as having side effects, but
3894
+ // changes the map of the input operand. Use it only when creating
3895
+ // object literals.
3896
+ ASSERT(value->IsObjectLiteral());
3897
+ set_representation(Representation::Tagged());
3898
+ }
3899
+
3900
+ virtual Representation RequiredInputRepresentation(int index) const {
3901
+ return Representation::Tagged();
3902
+ }
3903
+
3904
+ DECLARE_CONCRETE_INSTRUCTION(ToFastProperties)
3905
+ };
3906
+
3907
+
3908
+ class HValueOf: public HUnaryOperation {
3909
+ public:
3910
+ explicit HValueOf(HValue* value) : HUnaryOperation(value) {
3911
+ set_representation(Representation::Tagged());
3912
+ }
3913
+
3914
+ virtual Representation RequiredInputRepresentation(int index) const {
3915
+ return Representation::Tagged();
3916
+ }
3917
+
3918
+ DECLARE_CONCRETE_INSTRUCTION(ValueOf)
3919
+ };
3920
+
3921
+
3922
+ class HDeleteProperty: public HBinaryOperation {
3923
+ public:
3924
+ HDeleteProperty(HValue* obj, HValue* key)
3925
+ : HBinaryOperation(obj, key) {
3926
+ set_representation(Representation::Tagged());
3927
+ SetAllSideEffects();
3928
+ }
3929
+
3930
+ virtual Representation RequiredInputRepresentation(int index) const {
3931
+ return Representation::Tagged();
3932
+ }
3933
+
3934
+ DECLARE_CONCRETE_INSTRUCTION(DeleteProperty)
3935
+
3936
+ HValue* object() { return left(); }
3937
+ HValue* key() { return right(); }
3938
+ };
3939
+
3940
+
3941
+ class HIn: public HTemplateInstruction<2> {
3942
+ public:
3943
+ HIn(HValue* key, HValue* object) {
3944
+ SetOperandAt(0, key);
3945
+ SetOperandAt(1, object);
3946
+ set_representation(Representation::Tagged());
3947
+ SetAllSideEffects();
3948
+ }
3949
+
3950
+ HValue* key() { return OperandAt(0); }
3951
+ HValue* object() { return OperandAt(1); }
3952
+
3953
+ virtual Representation RequiredInputRepresentation(int index) const {
3954
+ return Representation::Tagged();
3955
+ }
3956
+
3957
+ virtual HType CalculateInferredType() {
3958
+ return HType::Boolean();
3959
+ }
3960
+
3961
+ virtual void PrintDataTo(StringStream* stream);
3962
+
3963
+ DECLARE_CONCRETE_INSTRUCTION(In)
3964
+ };
3965
+
3966
+ #undef DECLARE_INSTRUCTION
3967
+ #undef DECLARE_CONCRETE_INSTRUCTION
3968
+
3969
+ } } // namespace v8::internal
3970
+
3971
+ #endif // V8_HYDROGEN_INSTRUCTIONS_H_