mustang 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (560) hide show
  1. data/.rspec +1 -0
  2. data/Isolate +9 -0
  3. data/README.md +6 -12
  4. data/Rakefile +30 -4
  5. data/TODO.md +9 -0
  6. data/ext/v8/extconf.rb +56 -0
  7. data/ext/v8/v8.cpp +37 -0
  8. data/ext/v8/v8_array.cpp +161 -0
  9. data/ext/v8/v8_array.h +17 -0
  10. data/ext/v8/v8_base.cpp +147 -0
  11. data/ext/v8/v8_base.h +23 -0
  12. data/ext/v8/v8_cast.cpp +151 -0
  13. data/ext/v8/v8_cast.h +64 -0
  14. data/ext/v8/v8_context.cpp +174 -0
  15. data/ext/v8/v8_context.h +12 -0
  16. data/ext/v8/v8_date.cpp +61 -0
  17. data/ext/v8/v8_date.h +16 -0
  18. data/ext/v8/v8_errors.cpp +147 -0
  19. data/ext/v8/v8_errors.h +19 -0
  20. data/ext/v8/v8_external.cpp +66 -0
  21. data/ext/v8/v8_external.h +16 -0
  22. data/ext/v8/v8_function.cpp +182 -0
  23. data/ext/v8/v8_function.h +14 -0
  24. data/ext/v8/v8_integer.cpp +70 -0
  25. data/ext/v8/v8_integer.h +16 -0
  26. data/ext/v8/v8_macros.h +30 -0
  27. data/ext/v8/v8_main.cpp +53 -0
  28. data/ext/v8/v8_main.h +13 -0
  29. data/ext/v8/v8_number.cpp +62 -0
  30. data/ext/v8/v8_number.h +16 -0
  31. data/ext/v8/v8_object.cpp +172 -0
  32. data/ext/v8/v8_object.h +17 -0
  33. data/ext/v8/v8_ref.cpp +72 -0
  34. data/ext/v8/v8_ref.h +43 -0
  35. data/ext/v8/v8_regexp.cpp +148 -0
  36. data/ext/v8/v8_regexp.h +16 -0
  37. data/ext/v8/v8_string.cpp +78 -0
  38. data/ext/v8/v8_string.h +16 -0
  39. data/ext/v8/v8_value.cpp +370 -0
  40. data/ext/v8/v8_value.h +19 -0
  41. data/gemspec.yml +2 -1
  42. data/lib/core_ext/class.rb +14 -0
  43. data/lib/core_ext/object.rb +12 -0
  44. data/lib/core_ext/symbol.rb +23 -0
  45. data/lib/mustang.rb +44 -0
  46. data/lib/mustang/context.rb +69 -0
  47. data/lib/mustang/errors.rb +36 -0
  48. data/lib/support/delegated.rb +25 -0
  49. data/lib/v8/array.rb +21 -0
  50. data/lib/v8/context.rb +13 -0
  51. data/lib/v8/date.rb +20 -0
  52. data/lib/v8/error.rb +15 -0
  53. data/lib/v8/external.rb +16 -0
  54. data/lib/v8/function.rb +11 -0
  55. data/lib/v8/integer.rb +16 -0
  56. data/lib/v8/number.rb +16 -0
  57. data/lib/v8/object.rb +66 -0
  58. data/lib/v8/regexp.rb +23 -0
  59. data/lib/v8/string.rb +27 -0
  60. data/mustang.gemspec +3 -0
  61. data/spec/core_ext/class_spec.rb +19 -0
  62. data/spec/core_ext/object_spec.rb +19 -0
  63. data/spec/core_ext/symbol_spec.rb +27 -0
  64. data/spec/fixtures/test1.js +2 -0
  65. data/spec/fixtures/test2.js +2 -0
  66. data/spec/spec_helper.rb +20 -0
  67. data/spec/v8/array_spec.rb +88 -0
  68. data/spec/v8/cast_spec.rb +151 -0
  69. data/spec/v8/context_spec.rb +78 -0
  70. data/spec/v8/data_spec.rb +39 -0
  71. data/spec/v8/date_spec.rb +45 -0
  72. data/spec/v8/empty_spec.rb +27 -0
  73. data/spec/v8/errors_spec.rb +142 -0
  74. data/spec/v8/external_spec.rb +44 -0
  75. data/spec/v8/function_spec.rb +170 -0
  76. data/spec/v8/integer_spec.rb +41 -0
  77. data/spec/v8/main_spec.rb +18 -0
  78. data/spec/v8/null_spec.rb +27 -0
  79. data/spec/v8/number_spec.rb +40 -0
  80. data/spec/v8/object_spec.rb +79 -0
  81. data/spec/v8/primitive_spec.rb +9 -0
  82. data/spec/v8/regexp_spec.rb +65 -0
  83. data/spec/v8/string_spec.rb +48 -0
  84. data/spec/v8/undefined_spec.rb +27 -0
  85. data/spec/v8/value_spec.rb +215 -0
  86. data/vendor/v8/.gitignore +2 -0
  87. data/vendor/v8/AUTHORS +3 -1
  88. data/vendor/v8/ChangeLog +117 -0
  89. data/vendor/v8/SConstruct +334 -53
  90. data/vendor/v8/include/v8-debug.h +21 -11
  91. data/vendor/v8/include/v8-preparser.h +1 -1
  92. data/vendor/v8/include/v8-profiler.h +122 -43
  93. data/vendor/v8/include/v8-testing.h +5 -0
  94. data/vendor/v8/include/v8.h +171 -17
  95. data/vendor/v8/preparser/SConscript +38 -0
  96. data/vendor/v8/preparser/preparser-process.cc +77 -114
  97. data/vendor/v8/samples/shell.cc +232 -46
  98. data/vendor/v8/src/SConscript +29 -5
  99. data/vendor/v8/src/accessors.cc +70 -211
  100. data/vendor/v8/{test/cctest/test-mips.cc → src/allocation-inl.h} +15 -18
  101. data/vendor/v8/src/allocation.cc +0 -82
  102. data/vendor/v8/src/allocation.h +9 -42
  103. data/vendor/v8/src/api.cc +1645 -1156
  104. data/vendor/v8/src/api.h +76 -12
  105. data/vendor/v8/src/apiutils.h +0 -7
  106. data/vendor/v8/src/arguments.h +15 -4
  107. data/vendor/v8/src/arm/assembler-arm-inl.h +10 -9
  108. data/vendor/v8/src/arm/assembler-arm.cc +62 -23
  109. data/vendor/v8/src/arm/assembler-arm.h +76 -11
  110. data/vendor/v8/src/arm/builtins-arm.cc +39 -33
  111. data/vendor/v8/src/arm/code-stubs-arm.cc +1182 -402
  112. data/vendor/v8/src/arm/code-stubs-arm.h +20 -54
  113. data/vendor/v8/src/arm/codegen-arm.cc +159 -106
  114. data/vendor/v8/src/arm/codegen-arm.h +6 -6
  115. data/vendor/v8/src/arm/constants-arm.h +16 -1
  116. data/vendor/v8/src/arm/cpu-arm.cc +7 -5
  117. data/vendor/v8/src/arm/debug-arm.cc +6 -4
  118. data/vendor/v8/src/arm/deoptimizer-arm.cc +51 -14
  119. data/vendor/v8/src/arm/disasm-arm.cc +47 -15
  120. data/vendor/v8/src/arm/frames-arm.h +1 -1
  121. data/vendor/v8/src/arm/full-codegen-arm.cc +724 -408
  122. data/vendor/v8/src/arm/ic-arm.cc +90 -85
  123. data/vendor/v8/src/arm/lithium-arm.cc +140 -69
  124. data/vendor/v8/src/arm/lithium-arm.h +161 -46
  125. data/vendor/v8/src/arm/lithium-codegen-arm.cc +567 -297
  126. data/vendor/v8/src/arm/lithium-codegen-arm.h +21 -9
  127. data/vendor/v8/src/arm/lithium-gap-resolver-arm.cc +2 -0
  128. data/vendor/v8/src/arm/macro-assembler-arm.cc +457 -96
  129. data/vendor/v8/src/arm/macro-assembler-arm.h +115 -18
  130. data/vendor/v8/src/arm/regexp-macro-assembler-arm.cc +20 -13
  131. data/vendor/v8/src/arm/regexp-macro-assembler-arm.h +1 -0
  132. data/vendor/v8/src/arm/simulator-arm.cc +184 -101
  133. data/vendor/v8/src/arm/simulator-arm.h +26 -21
  134. data/vendor/v8/src/arm/stub-cache-arm.cc +450 -467
  135. data/vendor/v8/src/arm/virtual-frame-arm.cc +14 -12
  136. data/vendor/v8/src/arm/virtual-frame-arm.h +11 -8
  137. data/vendor/v8/src/array.js +35 -18
  138. data/vendor/v8/src/assembler.cc +186 -92
  139. data/vendor/v8/src/assembler.h +106 -69
  140. data/vendor/v8/src/ast-inl.h +5 -0
  141. data/vendor/v8/src/ast.cc +46 -35
  142. data/vendor/v8/src/ast.h +107 -50
  143. data/vendor/v8/src/atomicops.h +2 -0
  144. data/vendor/v8/src/atomicops_internals_mips_gcc.h +169 -0
  145. data/vendor/v8/src/bootstrapper.cc +649 -399
  146. data/vendor/v8/src/bootstrapper.h +94 -27
  147. data/vendor/v8/src/builtins.cc +359 -227
  148. data/vendor/v8/src/builtins.h +157 -123
  149. data/vendor/v8/src/checks.cc +2 -2
  150. data/vendor/v8/src/checks.h +4 -0
  151. data/vendor/v8/src/code-stubs.cc +27 -17
  152. data/vendor/v8/src/code-stubs.h +38 -17
  153. data/vendor/v8/src/codegen-inl.h +5 -1
  154. data/vendor/v8/src/codegen.cc +27 -17
  155. data/vendor/v8/src/codegen.h +9 -9
  156. data/vendor/v8/src/compilation-cache.cc +92 -206
  157. data/vendor/v8/src/compilation-cache.h +205 -30
  158. data/vendor/v8/src/compiler.cc +107 -120
  159. data/vendor/v8/src/compiler.h +17 -2
  160. data/vendor/v8/src/contexts.cc +22 -15
  161. data/vendor/v8/src/contexts.h +14 -8
  162. data/vendor/v8/src/conversions.cc +86 -30
  163. data/vendor/v8/src/counters.cc +19 -4
  164. data/vendor/v8/src/counters.h +28 -16
  165. data/vendor/v8/src/cpu-profiler-inl.h +4 -3
  166. data/vendor/v8/src/cpu-profiler.cc +123 -72
  167. data/vendor/v8/src/cpu-profiler.h +33 -19
  168. data/vendor/v8/src/cpu.h +2 -0
  169. data/vendor/v8/src/d8-debug.cc +3 -3
  170. data/vendor/v8/src/d8-debug.h +7 -6
  171. data/vendor/v8/src/d8-posix.cc +2 -0
  172. data/vendor/v8/src/d8.cc +22 -12
  173. data/vendor/v8/src/d8.gyp +3 -0
  174. data/vendor/v8/src/d8.js +618 -0
  175. data/vendor/v8/src/data-flow.h +3 -3
  176. data/vendor/v8/src/dateparser.h +4 -2
  177. data/vendor/v8/src/debug-agent.cc +10 -9
  178. data/vendor/v8/src/debug-agent.h +9 -11
  179. data/vendor/v8/src/debug-debugger.js +121 -0
  180. data/vendor/v8/src/debug.cc +331 -227
  181. data/vendor/v8/src/debug.h +248 -219
  182. data/vendor/v8/src/deoptimizer.cc +173 -62
  183. data/vendor/v8/src/deoptimizer.h +119 -19
  184. data/vendor/v8/src/disasm.h +3 -0
  185. data/vendor/v8/src/disassembler.cc +10 -9
  186. data/vendor/v8/src/execution.cc +185 -129
  187. data/vendor/v8/src/execution.h +47 -78
  188. data/vendor/v8/src/extensions/experimental/break-iterator.cc +250 -0
  189. data/vendor/v8/src/extensions/experimental/break-iterator.h +89 -0
  190. data/vendor/v8/src/extensions/experimental/experimental.gyp +2 -0
  191. data/vendor/v8/src/extensions/experimental/i18n-extension.cc +22 -2
  192. data/vendor/v8/src/extensions/externalize-string-extension.cc +2 -2
  193. data/vendor/v8/src/extensions/gc-extension.cc +1 -1
  194. data/vendor/v8/src/factory.cc +261 -154
  195. data/vendor/v8/src/factory.h +162 -158
  196. data/vendor/v8/src/flag-definitions.h +17 -11
  197. data/vendor/v8/src/frame-element.cc +0 -5
  198. data/vendor/v8/src/frame-element.h +9 -13
  199. data/vendor/v8/src/frames-inl.h +7 -0
  200. data/vendor/v8/src/frames.cc +56 -46
  201. data/vendor/v8/src/frames.h +36 -25
  202. data/vendor/v8/src/full-codegen.cc +15 -24
  203. data/vendor/v8/src/full-codegen.h +13 -41
  204. data/vendor/v8/src/func-name-inferrer.cc +7 -6
  205. data/vendor/v8/src/func-name-inferrer.h +1 -1
  206. data/vendor/v8/src/gdb-jit.cc +1 -0
  207. data/vendor/v8/src/global-handles.cc +118 -56
  208. data/vendor/v8/src/global-handles.h +98 -40
  209. data/vendor/v8/src/globals.h +2 -2
  210. data/vendor/v8/src/handles-inl.h +106 -9
  211. data/vendor/v8/src/handles.cc +220 -157
  212. data/vendor/v8/src/handles.h +38 -59
  213. data/vendor/v8/src/hashmap.h +3 -3
  214. data/vendor/v8/src/heap-inl.h +141 -25
  215. data/vendor/v8/src/heap-profiler.cc +117 -63
  216. data/vendor/v8/src/heap-profiler.h +38 -21
  217. data/vendor/v8/src/heap.cc +805 -564
  218. data/vendor/v8/src/heap.h +640 -594
  219. data/vendor/v8/src/hydrogen-instructions.cc +216 -73
  220. data/vendor/v8/src/hydrogen-instructions.h +259 -124
  221. data/vendor/v8/src/hydrogen.cc +996 -1171
  222. data/vendor/v8/src/hydrogen.h +163 -144
  223. data/vendor/v8/src/ia32/assembler-ia32-inl.h +12 -11
  224. data/vendor/v8/src/ia32/assembler-ia32.cc +85 -39
  225. data/vendor/v8/src/ia32/assembler-ia32.h +82 -16
  226. data/vendor/v8/src/ia32/builtins-ia32.cc +64 -58
  227. data/vendor/v8/src/ia32/code-stubs-ia32.cc +248 -324
  228. data/vendor/v8/src/ia32/code-stubs-ia32.h +3 -44
  229. data/vendor/v8/src/ia32/codegen-ia32.cc +217 -165
  230. data/vendor/v8/src/ia32/codegen-ia32.h +3 -0
  231. data/vendor/v8/src/ia32/cpu-ia32.cc +6 -5
  232. data/vendor/v8/src/ia32/debug-ia32.cc +8 -5
  233. data/vendor/v8/src/ia32/deoptimizer-ia32.cc +124 -14
  234. data/vendor/v8/src/ia32/disasm-ia32.cc +85 -62
  235. data/vendor/v8/src/ia32/frames-ia32.h +1 -1
  236. data/vendor/v8/src/ia32/full-codegen-ia32.cc +348 -435
  237. data/vendor/v8/src/ia32/ic-ia32.cc +91 -91
  238. data/vendor/v8/src/ia32/lithium-codegen-ia32.cc +500 -255
  239. data/vendor/v8/src/ia32/lithium-codegen-ia32.h +13 -4
  240. data/vendor/v8/src/ia32/lithium-gap-resolver-ia32.cc +6 -0
  241. data/vendor/v8/src/ia32/lithium-ia32.cc +122 -45
  242. data/vendor/v8/src/ia32/lithium-ia32.h +128 -41
  243. data/vendor/v8/src/ia32/macro-assembler-ia32.cc +109 -84
  244. data/vendor/v8/src/ia32/macro-assembler-ia32.h +18 -9
  245. data/vendor/v8/src/ia32/regexp-macro-assembler-ia32.cc +26 -15
  246. data/vendor/v8/src/ia32/regexp-macro-assembler-ia32.h +1 -0
  247. data/vendor/v8/src/ia32/register-allocator-ia32.cc +30 -30
  248. data/vendor/v8/src/ia32/simulator-ia32.h +4 -4
  249. data/vendor/v8/src/ia32/stub-cache-ia32.cc +383 -400
  250. data/vendor/v8/src/ia32/virtual-frame-ia32.cc +36 -13
  251. data/vendor/v8/src/ia32/virtual-frame-ia32.h +11 -5
  252. data/vendor/v8/src/ic-inl.h +12 -2
  253. data/vendor/v8/src/ic.cc +304 -221
  254. data/vendor/v8/src/ic.h +115 -58
  255. data/vendor/v8/src/interpreter-irregexp.cc +25 -21
  256. data/vendor/v8/src/interpreter-irregexp.h +2 -1
  257. data/vendor/v8/src/isolate.cc +883 -0
  258. data/vendor/v8/src/isolate.h +1304 -0
  259. data/vendor/v8/src/json.js +10 -10
  260. data/vendor/v8/src/jsregexp.cc +111 -80
  261. data/vendor/v8/src/jsregexp.h +6 -7
  262. data/vendor/v8/src/jump-target-heavy.cc +5 -8
  263. data/vendor/v8/src/jump-target-heavy.h +0 -6
  264. data/vendor/v8/src/jump-target-inl.h +1 -1
  265. data/vendor/v8/src/jump-target-light.cc +3 -3
  266. data/vendor/v8/src/lithium-allocator-inl.h +2 -0
  267. data/vendor/v8/src/lithium-allocator.cc +42 -30
  268. data/vendor/v8/src/lithium-allocator.h +8 -22
  269. data/vendor/v8/src/lithium.cc +1 -0
  270. data/vendor/v8/src/liveedit.cc +141 -99
  271. data/vendor/v8/src/liveedit.h +7 -2
  272. data/vendor/v8/src/liveobjectlist-inl.h +90 -0
  273. data/vendor/v8/src/liveobjectlist.cc +2537 -1
  274. data/vendor/v8/src/liveobjectlist.h +245 -35
  275. data/vendor/v8/src/log-utils.cc +122 -35
  276. data/vendor/v8/src/log-utils.h +33 -36
  277. data/vendor/v8/src/log.cc +299 -241
  278. data/vendor/v8/src/log.h +177 -110
  279. data/vendor/v8/src/mark-compact.cc +612 -470
  280. data/vendor/v8/src/mark-compact.h +153 -80
  281. data/vendor/v8/src/messages.cc +16 -14
  282. data/vendor/v8/src/messages.js +30 -7
  283. data/vendor/v8/src/mips/assembler-mips-inl.h +155 -35
  284. data/vendor/v8/src/mips/assembler-mips.cc +1093 -219
  285. data/vendor/v8/src/mips/assembler-mips.h +552 -153
  286. data/vendor/v8/src/mips/builtins-mips.cc +43 -100
  287. data/vendor/v8/src/mips/code-stubs-mips.cc +752 -0
  288. data/vendor/v8/src/mips/code-stubs-mips.h +511 -0
  289. data/vendor/v8/src/mips/codegen-mips-inl.h +8 -14
  290. data/vendor/v8/src/mips/codegen-mips.cc +672 -896
  291. data/vendor/v8/src/mips/codegen-mips.h +271 -69
  292. data/vendor/v8/src/mips/constants-mips.cc +44 -20
  293. data/vendor/v8/src/mips/constants-mips.h +238 -40
  294. data/vendor/v8/src/mips/cpu-mips.cc +20 -3
  295. data/vendor/v8/src/mips/debug-mips.cc +35 -7
  296. data/vendor/v8/src/mips/deoptimizer-mips.cc +91 -0
  297. data/vendor/v8/src/mips/disasm-mips.cc +329 -93
  298. data/vendor/v8/src/mips/frames-mips.cc +2 -50
  299. data/vendor/v8/src/mips/frames-mips.h +24 -9
  300. data/vendor/v8/src/mips/full-codegen-mips.cc +473 -23
  301. data/vendor/v8/src/mips/ic-mips.cc +81 -45
  302. data/vendor/v8/src/mips/jump-target-mips.cc +11 -106
  303. data/vendor/v8/src/mips/lithium-codegen-mips.h +65 -0
  304. data/vendor/v8/src/mips/lithium-mips.h +304 -0
  305. data/vendor/v8/src/mips/macro-assembler-mips.cc +2391 -390
  306. data/vendor/v8/src/mips/macro-assembler-mips.h +718 -121
  307. data/vendor/v8/src/mips/regexp-macro-assembler-mips.cc +478 -0
  308. data/vendor/v8/src/mips/regexp-macro-assembler-mips.h +250 -0
  309. data/vendor/v8/src/mips/register-allocator-mips-inl.h +0 -3
  310. data/vendor/v8/src/mips/register-allocator-mips.h +3 -2
  311. data/vendor/v8/src/mips/simulator-mips.cc +1009 -221
  312. data/vendor/v8/src/mips/simulator-mips.h +119 -36
  313. data/vendor/v8/src/mips/stub-cache-mips.cc +331 -148
  314. data/vendor/v8/src/mips/{fast-codegen-mips.cc → virtual-frame-mips-inl.h} +11 -30
  315. data/vendor/v8/src/mips/virtual-frame-mips.cc +137 -149
  316. data/vendor/v8/src/mips/virtual-frame-mips.h +294 -312
  317. data/vendor/v8/src/mirror-debugger.js +9 -8
  318. data/vendor/v8/src/mksnapshot.cc +2 -2
  319. data/vendor/v8/src/objects-debug.cc +16 -16
  320. data/vendor/v8/src/objects-inl.h +421 -195
  321. data/vendor/v8/src/objects-printer.cc +7 -7
  322. data/vendor/v8/src/objects-visiting.cc +1 -1
  323. data/vendor/v8/src/objects-visiting.h +33 -12
  324. data/vendor/v8/src/objects.cc +935 -658
  325. data/vendor/v8/src/objects.h +234 -139
  326. data/vendor/v8/src/parser.cc +484 -439
  327. data/vendor/v8/src/parser.h +35 -14
  328. data/vendor/v8/src/platform-cygwin.cc +173 -107
  329. data/vendor/v8/src/platform-freebsd.cc +224 -72
  330. data/vendor/v8/src/platform-linux.cc +234 -95
  331. data/vendor/v8/src/platform-macos.cc +215 -82
  332. data/vendor/v8/src/platform-nullos.cc +9 -3
  333. data/vendor/v8/src/platform-openbsd.cc +22 -7
  334. data/vendor/v8/src/platform-posix.cc +30 -5
  335. data/vendor/v8/src/platform-solaris.cc +120 -38
  336. data/vendor/v8/src/platform-tls-mac.h +62 -0
  337. data/vendor/v8/src/platform-tls-win32.h +62 -0
  338. data/vendor/v8/src/platform-tls.h +50 -0
  339. data/vendor/v8/src/platform-win32.cc +195 -97
  340. data/vendor/v8/src/platform.h +72 -15
  341. data/vendor/v8/src/preparse-data.cc +2 -0
  342. data/vendor/v8/src/preparser-api.cc +8 -2
  343. data/vendor/v8/src/preparser.cc +1 -1
  344. data/vendor/v8/src/prettyprinter.cc +43 -52
  345. data/vendor/v8/src/prettyprinter.h +1 -1
  346. data/vendor/v8/src/profile-generator-inl.h +0 -28
  347. data/vendor/v8/src/profile-generator.cc +942 -685
  348. data/vendor/v8/src/profile-generator.h +210 -176
  349. data/vendor/v8/src/property.cc +6 -0
  350. data/vendor/v8/src/property.h +14 -3
  351. data/vendor/v8/src/regexp-macro-assembler-irregexp.cc +1 -1
  352. data/vendor/v8/src/regexp-macro-assembler.cc +28 -19
  353. data/vendor/v8/src/regexp-macro-assembler.h +11 -6
  354. data/vendor/v8/src/regexp-stack.cc +18 -10
  355. data/vendor/v8/src/regexp-stack.h +45 -21
  356. data/vendor/v8/src/regexp.js +3 -3
  357. data/vendor/v8/src/register-allocator-inl.h +3 -3
  358. data/vendor/v8/src/register-allocator.cc +1 -7
  359. data/vendor/v8/src/register-allocator.h +5 -15
  360. data/vendor/v8/src/rewriter.cc +2 -1
  361. data/vendor/v8/src/runtime-profiler.cc +158 -128
  362. data/vendor/v8/src/runtime-profiler.h +131 -15
  363. data/vendor/v8/src/runtime.cc +2409 -1692
  364. data/vendor/v8/src/runtime.h +93 -17
  365. data/vendor/v8/src/safepoint-table.cc +3 -0
  366. data/vendor/v8/src/safepoint-table.h +9 -3
  367. data/vendor/v8/src/scanner-base.cc +21 -28
  368. data/vendor/v8/src/scanner-base.h +22 -11
  369. data/vendor/v8/src/scanner.cc +3 -5
  370. data/vendor/v8/src/scanner.h +4 -2
  371. data/vendor/v8/src/scopeinfo.cc +11 -16
  372. data/vendor/v8/src/scopeinfo.h +26 -15
  373. data/vendor/v8/src/scopes.cc +67 -37
  374. data/vendor/v8/src/scopes.h +26 -12
  375. data/vendor/v8/src/serialize.cc +193 -154
  376. data/vendor/v8/src/serialize.h +41 -36
  377. data/vendor/v8/src/small-pointer-list.h +163 -0
  378. data/vendor/v8/src/snapshot-common.cc +1 -1
  379. data/vendor/v8/src/snapshot.h +3 -1
  380. data/vendor/v8/src/spaces-inl.h +30 -25
  381. data/vendor/v8/src/spaces.cc +263 -370
  382. data/vendor/v8/src/spaces.h +178 -166
  383. data/vendor/v8/src/string-search.cc +4 -3
  384. data/vendor/v8/src/string-search.h +21 -20
  385. data/vendor/v8/src/string-stream.cc +32 -24
  386. data/vendor/v8/src/string.js +7 -7
  387. data/vendor/v8/src/stub-cache.cc +324 -248
  388. data/vendor/v8/src/stub-cache.h +181 -155
  389. data/vendor/v8/src/token.cc +3 -3
  390. data/vendor/v8/src/token.h +3 -3
  391. data/vendor/v8/src/top.cc +218 -390
  392. data/vendor/v8/src/type-info.cc +98 -32
  393. data/vendor/v8/src/type-info.h +10 -3
  394. data/vendor/v8/src/unicode.cc +1 -1
  395. data/vendor/v8/src/unicode.h +1 -1
  396. data/vendor/v8/src/utils.h +3 -0
  397. data/vendor/v8/src/v8-counters.cc +18 -11
  398. data/vendor/v8/src/v8-counters.h +34 -13
  399. data/vendor/v8/src/v8.cc +66 -121
  400. data/vendor/v8/src/v8.h +7 -4
  401. data/vendor/v8/src/v8globals.h +18 -12
  402. data/vendor/v8/src/{memory.h → v8memory.h} +0 -0
  403. data/vendor/v8/src/v8natives.js +59 -18
  404. data/vendor/v8/src/v8threads.cc +127 -114
  405. data/vendor/v8/src/v8threads.h +42 -35
  406. data/vendor/v8/src/v8utils.h +2 -39
  407. data/vendor/v8/src/variables.h +1 -1
  408. data/vendor/v8/src/version.cc +26 -5
  409. data/vendor/v8/src/version.h +4 -0
  410. data/vendor/v8/src/virtual-frame-heavy-inl.h +2 -4
  411. data/vendor/v8/src/virtual-frame-light-inl.h +5 -4
  412. data/vendor/v8/src/vm-state-inl.h +21 -17
  413. data/vendor/v8/src/vm-state.h +7 -5
  414. data/vendor/v8/src/win32-headers.h +1 -0
  415. data/vendor/v8/src/x64/assembler-x64-inl.h +12 -11
  416. data/vendor/v8/src/x64/assembler-x64.cc +80 -40
  417. data/vendor/v8/src/x64/assembler-x64.h +67 -17
  418. data/vendor/v8/src/x64/builtins-x64.cc +34 -33
  419. data/vendor/v8/src/x64/code-stubs-x64.cc +636 -377
  420. data/vendor/v8/src/x64/code-stubs-x64.h +14 -48
  421. data/vendor/v8/src/x64/codegen-x64-inl.h +1 -1
  422. data/vendor/v8/src/x64/codegen-x64.cc +158 -136
  423. data/vendor/v8/src/x64/codegen-x64.h +4 -1
  424. data/vendor/v8/src/x64/cpu-x64.cc +7 -5
  425. data/vendor/v8/src/x64/debug-x64.cc +8 -6
  426. data/vendor/v8/src/x64/deoptimizer-x64.cc +195 -20
  427. data/vendor/v8/src/x64/disasm-x64.cc +42 -23
  428. data/vendor/v8/src/x64/frames-x64.cc +1 -1
  429. data/vendor/v8/src/x64/frames-x64.h +2 -2
  430. data/vendor/v8/src/x64/full-codegen-x64.cc +780 -218
  431. data/vendor/v8/src/x64/ic-x64.cc +77 -79
  432. data/vendor/v8/src/x64/jump-target-x64.cc +1 -1
  433. data/vendor/v8/src/x64/lithium-codegen-x64.cc +698 -181
  434. data/vendor/v8/src/x64/lithium-codegen-x64.h +31 -6
  435. data/vendor/v8/src/x64/lithium-x64.cc +136 -54
  436. data/vendor/v8/src/x64/lithium-x64.h +142 -51
  437. data/vendor/v8/src/x64/macro-assembler-x64.cc +456 -187
  438. data/vendor/v8/src/x64/macro-assembler-x64.h +166 -34
  439. data/vendor/v8/src/x64/regexp-macro-assembler-x64.cc +44 -28
  440. data/vendor/v8/src/x64/regexp-macro-assembler-x64.h +8 -4
  441. data/vendor/v8/src/x64/register-allocator-x64-inl.h +3 -3
  442. data/vendor/v8/src/x64/register-allocator-x64.cc +12 -8
  443. data/vendor/v8/src/x64/simulator-x64.h +5 -5
  444. data/vendor/v8/src/x64/stub-cache-x64.cc +299 -344
  445. data/vendor/v8/src/x64/virtual-frame-x64.cc +37 -13
  446. data/vendor/v8/src/x64/virtual-frame-x64.h +13 -7
  447. data/vendor/v8/src/zone-inl.h +49 -3
  448. data/vendor/v8/src/zone.cc +42 -41
  449. data/vendor/v8/src/zone.h +37 -34
  450. data/vendor/v8/test/benchmarks/testcfg.py +100 -0
  451. data/vendor/v8/test/cctest/SConscript +5 -4
  452. data/vendor/v8/test/cctest/cctest.h +3 -2
  453. data/vendor/v8/test/cctest/cctest.status +6 -11
  454. data/vendor/v8/test/cctest/test-accessors.cc +3 -3
  455. data/vendor/v8/test/cctest/test-alloc.cc +39 -33
  456. data/vendor/v8/test/cctest/test-api.cc +1092 -205
  457. data/vendor/v8/test/cctest/test-assembler-arm.cc +39 -25
  458. data/vendor/v8/test/cctest/test-assembler-ia32.cc +36 -37
  459. data/vendor/v8/test/cctest/test-assembler-mips.cc +1098 -40
  460. data/vendor/v8/test/cctest/test-assembler-x64.cc +32 -25
  461. data/vendor/v8/test/cctest/test-ast.cc +1 -0
  462. data/vendor/v8/test/cctest/test-circular-queue.cc +8 -5
  463. data/vendor/v8/test/cctest/test-compiler.cc +24 -24
  464. data/vendor/v8/test/cctest/test-cpu-profiler.cc +140 -5
  465. data/vendor/v8/test/cctest/test-dataflow.cc +1 -0
  466. data/vendor/v8/test/cctest/test-debug.cc +136 -77
  467. data/vendor/v8/test/cctest/test-decls.cc +1 -1
  468. data/vendor/v8/test/cctest/test-deoptimization.cc +25 -24
  469. data/vendor/v8/test/cctest/test-disasm-arm.cc +9 -4
  470. data/vendor/v8/test/cctest/test-disasm-ia32.cc +10 -8
  471. data/vendor/v8/test/cctest/test-func-name-inference.cc +10 -4
  472. data/vendor/v8/test/cctest/test-heap-profiler.cc +226 -164
  473. data/vendor/v8/test/cctest/test-heap.cc +240 -217
  474. data/vendor/v8/test/cctest/test-liveedit.cc +1 -0
  475. data/vendor/v8/test/cctest/test-log-stack-tracer.cc +18 -20
  476. data/vendor/v8/test/cctest/test-log.cc +114 -108
  477. data/vendor/v8/test/cctest/test-macro-assembler-x64.cc +247 -177
  478. data/vendor/v8/test/cctest/test-mark-compact.cc +129 -90
  479. data/vendor/v8/test/cctest/test-parsing.cc +15 -14
  480. data/vendor/v8/test/cctest/test-platform-linux.cc +1 -0
  481. data/vendor/v8/test/cctest/test-platform-tls.cc +66 -0
  482. data/vendor/v8/test/cctest/test-platform-win32.cc +1 -0
  483. data/vendor/v8/test/cctest/test-profile-generator.cc +1 -1
  484. data/vendor/v8/test/cctest/test-regexp.cc +53 -41
  485. data/vendor/v8/test/cctest/test-reloc-info.cc +18 -11
  486. data/vendor/v8/test/cctest/test-serialize.cc +44 -43
  487. data/vendor/v8/test/cctest/test-sockets.cc +8 -3
  488. data/vendor/v8/test/cctest/test-spaces.cc +47 -29
  489. data/vendor/v8/test/cctest/test-strings.cc +20 -20
  490. data/vendor/v8/test/cctest/test-thread-termination.cc +8 -3
  491. data/vendor/v8/test/cctest/test-threads.cc +5 -3
  492. data/vendor/v8/test/cctest/test-utils.cc +5 -4
  493. data/vendor/v8/test/cctest/testcfg.py +7 -3
  494. data/vendor/v8/test/es5conform/es5conform.status +2 -77
  495. data/vendor/v8/test/es5conform/testcfg.py +1 -1
  496. data/vendor/v8/test/message/testcfg.py +1 -1
  497. data/vendor/v8/test/mjsunit/accessors-on-global-object.js +3 -3
  498. data/vendor/v8/test/mjsunit/array-concat.js +43 -1
  499. data/vendor/v8/test/mjsunit/array-join.js +25 -0
  500. data/vendor/v8/test/mjsunit/bitops-info.js +7 -1
  501. data/vendor/v8/test/mjsunit/compiler/array-length.js +2 -2
  502. data/vendor/v8/test/mjsunit/compiler/global-accessors.js +47 -0
  503. data/vendor/v8/test/mjsunit/compiler/pic.js +1 -1
  504. data/vendor/v8/test/mjsunit/compiler/regress-loadfield.js +65 -0
  505. data/vendor/v8/test/mjsunit/math-sqrt.js +5 -1
  506. data/vendor/v8/test/mjsunit/mjsunit.js +59 -8
  507. data/vendor/v8/test/mjsunit/mjsunit.status +0 -12
  508. data/vendor/v8/test/mjsunit/mul-exhaustive.js +129 -11
  509. data/vendor/v8/test/mjsunit/negate-zero.js +1 -1
  510. data/vendor/v8/test/mjsunit/object-freeze.js +5 -13
  511. data/vendor/v8/test/mjsunit/object-prevent-extensions.js +9 -50
  512. data/vendor/v8/test/mjsunit/object-seal.js +4 -13
  513. data/vendor/v8/test/mjsunit/override-eval-with-non-function.js +36 -0
  514. data/vendor/v8/test/mjsunit/regress/regress-1145.js +54 -0
  515. data/vendor/v8/test/mjsunit/regress/regress-1172-bis.js +37 -0
  516. data/vendor/v8/test/mjsunit/regress/regress-1181.js +54 -0
  517. data/vendor/v8/test/mjsunit/regress/regress-1207.js +35 -0
  518. data/vendor/v8/test/mjsunit/regress/regress-1209.js +34 -0
  519. data/vendor/v8/test/mjsunit/regress/regress-1210.js +48 -0
  520. data/vendor/v8/test/mjsunit/regress/regress-1213.js +43 -0
  521. data/vendor/v8/test/mjsunit/regress/regress-1218.js +29 -0
  522. data/vendor/v8/test/mjsunit/regress/regress-1229.js +79 -0
  523. data/vendor/v8/test/mjsunit/regress/regress-1233.js +47 -0
  524. data/vendor/v8/test/mjsunit/regress/regress-1236.js +34 -0
  525. data/vendor/v8/test/mjsunit/regress/regress-1237.js +36 -0
  526. data/vendor/v8/test/mjsunit/regress/regress-1240.js +39 -0
  527. data/vendor/v8/test/mjsunit/regress/regress-1257.js +58 -0
  528. data/vendor/v8/test/mjsunit/regress/regress-1278.js +69 -0
  529. data/vendor/v8/test/mjsunit/regress/regress-create-exception.js +1 -0
  530. data/vendor/v8/test/mjsunit/regress/regress-lazy-deopt-reloc.js +52 -0
  531. data/vendor/v8/test/mjsunit/sin-cos.js +15 -10
  532. data/vendor/v8/test/mjsunit/smi-negative-zero.js +2 -2
  533. data/vendor/v8/test/mjsunit/str-to-num.js +1 -1
  534. data/vendor/v8/test/mjsunit/strict-mode.js +435 -0
  535. data/vendor/v8/test/mjsunit/testcfg.py +23 -6
  536. data/vendor/v8/test/mozilla/mozilla.status +0 -2
  537. data/vendor/v8/test/mozilla/testcfg.py +1 -1
  538. data/vendor/v8/test/preparser/empty.js +28 -0
  539. data/vendor/v8/test/preparser/functions-only.js +38 -0
  540. data/vendor/v8/test/preparser/non-alphanum.js +34 -0
  541. data/vendor/v8/test/preparser/symbols-only.js +49 -0
  542. data/vendor/v8/test/preparser/testcfg.py +90 -0
  543. data/vendor/v8/test/sputnik/testcfg.py +1 -1
  544. data/vendor/v8/test/test262/README +16 -0
  545. data/vendor/v8/test/test262/harness-adapt.js +80 -0
  546. data/vendor/v8/test/test262/test262.status +1506 -0
  547. data/vendor/v8/test/test262/testcfg.py +123 -0
  548. data/vendor/v8/tools/freebsd-tick-processor +10 -0
  549. data/vendor/v8/tools/gyp/v8.gyp +8 -33
  550. data/vendor/v8/tools/linux-tick-processor +5 -3
  551. data/vendor/v8/tools/test.py +37 -14
  552. data/vendor/v8/tools/tickprocessor.js +22 -8
  553. data/vendor/v8/tools/visual_studio/v8_base.vcproj +13 -1
  554. data/vendor/v8/tools/visual_studio/v8_base_arm.vcproj +5 -1
  555. data/vendor/v8/tools/visual_studio/v8_base_x64.vcproj +5 -1
  556. data/vendor/v8/tools/visual_studio/x64.vsprops +1 -0
  557. metadata +1495 -1341
  558. data/ext/extconf.rb +0 -22
  559. data/ext/mustang.cpp +0 -58
  560. data/vendor/v8/src/top.h +0 -608
@@ -1,4 +1,4 @@
1
- // Copyright 2010 the V8 project authors. All rights reserved.
1
+ // Copyright 2011 the V8 project authors. All rights reserved.
2
2
  // Redistribution and use in source and binary forms, with or without
3
3
  // modification, are permitted provided that the following conditions are
4
4
  // met:
@@ -554,7 +554,7 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
554
554
  // -- rsp[0] : return address
555
555
  // -----------------------------------
556
556
  Label slow, check_string, index_smi, index_string, property_array_property;
557
- Label check_pixel_array, probe_dictionary, check_number_dictionary;
557
+ Label probe_dictionary, check_number_dictionary;
558
558
 
559
559
  // Check that the key is a smi.
560
560
  __ JumpIfNotSmi(rax, &check_string);
@@ -569,7 +569,7 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
569
569
  // now in rcx.
570
570
  __ testb(FieldOperand(rcx, Map::kBitField2Offset),
571
571
  Immediate(1 << Map::kHasFastElements));
572
- __ j(zero, &check_pixel_array);
572
+ __ j(zero, &check_number_dictionary);
573
573
 
574
574
  GenerateFastArrayLoad(masm,
575
575
  rdx,
@@ -579,21 +579,14 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
579
579
  rax,
580
580
  NULL,
581
581
  &slow);
582
- __ IncrementCounter(&Counters::keyed_load_generic_smi, 1);
582
+ Counters* counters = masm->isolate()->counters();
583
+ __ IncrementCounter(counters->keyed_load_generic_smi(), 1);
583
584
  __ ret(0);
584
585
 
585
- __ bind(&check_pixel_array);
586
- GenerateFastPixelArrayLoad(masm,
587
- rdx,
588
- rax,
589
- rcx,
590
- rbx,
591
- rax,
592
- &check_number_dictionary,
593
- NULL,
594
- &slow);
595
-
596
586
  __ bind(&check_number_dictionary);
587
+ __ SmiToInteger32(rbx, rax);
588
+ __ movq(rcx, FieldOperand(rdx, JSObject::kElementsOffset));
589
+
597
590
  // Check whether the elements is a number dictionary.
598
591
  // rdx: receiver
599
592
  // rax: key
@@ -609,7 +602,7 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
609
602
  // Slow case: Jump to runtime.
610
603
  // rdx: receiver
611
604
  // rax: key
612
- __ IncrementCounter(&Counters::keyed_load_generic_slow, 1);
605
+ __ IncrementCounter(counters->keyed_load_generic_slow(), 1);
613
606
  GenerateRuntimeGetProperty(masm);
614
607
 
615
608
  __ bind(&check_string);
@@ -638,10 +631,10 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
638
631
  // Load the key (consisting of map and symbol) from the cache and
639
632
  // check for match.
640
633
  ExternalReference cache_keys
641
- = ExternalReference::keyed_lookup_cache_keys();
634
+ = ExternalReference::keyed_lookup_cache_keys(masm->isolate());
642
635
  __ movq(rdi, rcx);
643
636
  __ shl(rdi, Immediate(kPointerSizeLog2 + 1));
644
- __ movq(kScratchRegister, cache_keys);
637
+ __ LoadAddress(kScratchRegister, cache_keys);
645
638
  __ cmpq(rbx, Operand(kScratchRegister, rdi, times_1, 0));
646
639
  __ j(not_equal, &slow);
647
640
  __ cmpq(rax, Operand(kScratchRegister, rdi, times_1, kPointerSize));
@@ -649,8 +642,8 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
649
642
 
650
643
  // Get field offset, which is a 32-bit integer.
651
644
  ExternalReference cache_field_offsets
652
- = ExternalReference::keyed_lookup_cache_field_offsets();
653
- __ movq(kScratchRegister, cache_field_offsets);
645
+ = ExternalReference::keyed_lookup_cache_field_offsets(masm->isolate());
646
+ __ LoadAddress(kScratchRegister, cache_field_offsets);
654
647
  __ movl(rdi, Operand(kScratchRegister, rcx, times_4, 0));
655
648
  __ movzxbq(rcx, FieldOperand(rbx, Map::kInObjectPropertiesOffset));
656
649
  __ subq(rdi, rcx);
@@ -660,7 +653,7 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
660
653
  __ movzxbq(rcx, FieldOperand(rbx, Map::kInstanceSizeOffset));
661
654
  __ addq(rcx, rdi);
662
655
  __ movq(rax, FieldOperand(rdx, rcx, times_pointer_size, 0));
663
- __ IncrementCounter(&Counters::keyed_load_generic_lookup_cache, 1);
656
+ __ IncrementCounter(counters->keyed_load_generic_lookup_cache(), 1);
664
657
  __ ret(0);
665
658
 
666
659
  // Load property array property.
@@ -668,7 +661,7 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
668
661
  __ movq(rax, FieldOperand(rdx, JSObject::kPropertiesOffset));
669
662
  __ movq(rax, FieldOperand(rax, rdi, times_pointer_size,
670
663
  FixedArray::kHeaderSize));
671
- __ IncrementCounter(&Counters::keyed_load_generic_lookup_cache, 1);
664
+ __ IncrementCounter(counters->keyed_load_generic_lookup_cache(), 1);
672
665
  __ ret(0);
673
666
 
674
667
  // Do a quick inline probe of the receiver's dictionary, if it
@@ -683,7 +676,7 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
683
676
  GenerateGlobalInstanceTypeCheck(masm, rcx, &slow);
684
677
 
685
678
  GenerateDictionaryLoad(masm, &slow, rbx, rax, rcx, rdi, rax);
686
- __ IncrementCounter(&Counters::keyed_load_generic_symbol, 1);
679
+ __ IncrementCounter(counters->keyed_load_generic_symbol(), 1);
687
680
  __ ret(0);
688
681
 
689
682
  __ bind(&index_string);
@@ -758,22 +751,26 @@ void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) {
758
751
  __ push(rcx); // return address
759
752
 
760
753
  // Perform tail call to the entry.
761
- __ TailCallExternalReference(ExternalReference(
762
- IC_Utility(kKeyedLoadPropertyWithInterceptor)), 2, 1);
754
+ __ TailCallExternalReference(
755
+ ExternalReference(IC_Utility(kKeyedLoadPropertyWithInterceptor),
756
+ masm->isolate()),
757
+ 2,
758
+ 1);
763
759
 
764
760
  __ bind(&slow);
765
761
  GenerateMiss(masm);
766
762
  }
767
763
 
768
764
 
769
- void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm) {
765
+ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
766
+ StrictModeFlag strict_mode) {
770
767
  // ----------- S t a t e -------------
771
768
  // -- rax : value
772
769
  // -- rcx : key
773
770
  // -- rdx : receiver
774
771
  // -- rsp[0] : return address
775
772
  // -----------------------------------
776
- Label slow, slow_with_tagged_index, fast, array, extra, check_pixel_array;
773
+ Label slow, slow_with_tagged_index, fast, array, extra;
777
774
 
778
775
  // Check that the object isn't a smi.
779
776
  __ JumpIfSmi(rdx, &slow_with_tagged_index);
@@ -802,7 +799,7 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm) {
802
799
  // Check that the object is in fast mode and writable.
803
800
  __ CompareRoot(FieldOperand(rbx, HeapObject::kMapOffset),
804
801
  Heap::kFixedArrayMapRootIndex);
805
- __ j(not_equal, &check_pixel_array);
802
+ __ j(not_equal, &slow);
806
803
  __ SmiCompareInteger32(FieldOperand(rbx, FixedArray::kLengthOffset), rcx);
807
804
  // rax: value
808
805
  // rbx: FixedArray
@@ -813,28 +810,9 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm) {
813
810
  __ bind(&slow);
814
811
  __ Integer32ToSmi(rcx, rcx);
815
812
  __ bind(&slow_with_tagged_index);
816
- GenerateRuntimeSetProperty(masm);
813
+ GenerateRuntimeSetProperty(masm, strict_mode);
817
814
  // Never returns to here.
818
815
 
819
- // Check whether the elements is a pixel array.
820
- // rax: value
821
- // rdx: receiver
822
- // rbx: receiver's elements array
823
- // rcx: index, zero-extended.
824
- __ bind(&check_pixel_array);
825
- GenerateFastPixelArrayStore(masm,
826
- rdx,
827
- rcx,
828
- rax,
829
- rbx,
830
- rdi,
831
- false,
832
- true,
833
- NULL,
834
- &slow,
835
- &slow,
836
- &slow);
837
-
838
816
  // Extra capacity case: Check if there is extra capacity to
839
817
  // perform the store and update the length. Used for adding one
840
818
  // element to the array by writing to array[array.length].
@@ -906,7 +884,8 @@ static void GenerateMonomorphicCacheProbe(MacroAssembler* masm,
906
884
  Code::kNoExtraICState,
907
885
  NORMAL,
908
886
  argc);
909
- StubCache::GenerateProbe(masm, flags, rdx, rcx, rbx, rax);
887
+ Isolate::Current()->stub_cache()->GenerateProbe(masm, flags, rdx, rcx, rbx,
888
+ rax);
910
889
 
911
890
  // If the stub cache probing failed, the receiver might be a value.
912
891
  // For value objects, we use the map of the prototype objects for
@@ -942,7 +921,8 @@ static void GenerateMonomorphicCacheProbe(MacroAssembler* masm,
942
921
 
943
922
  // Probe the stub cache for the value object.
944
923
  __ bind(&probe);
945
- StubCache::GenerateProbe(masm, flags, rdx, rcx, rbx, no_reg);
924
+ Isolate::Current()->stub_cache()->GenerateProbe(masm, flags, rdx, rcx, rbx,
925
+ no_reg);
946
926
 
947
927
  __ bind(&miss);
948
928
  }
@@ -1011,10 +991,11 @@ static void GenerateCallMiss(MacroAssembler* masm, int argc, IC::UtilityId id) {
1011
991
  // rsp[(argc + 1) * 8] : argument 0 = receiver
1012
992
  // -----------------------------------
1013
993
 
994
+ Counters* counters = masm->isolate()->counters();
1014
995
  if (id == IC::kCallIC_Miss) {
1015
- __ IncrementCounter(&Counters::call_miss, 1);
996
+ __ IncrementCounter(counters->call_miss(), 1);
1016
997
  } else {
1017
- __ IncrementCounter(&Counters::keyed_call_miss, 1);
998
+ __ IncrementCounter(counters->keyed_call_miss(), 1);
1018
999
  }
1019
1000
 
1020
1001
  // Get the receiver of the function from the stack; 1 ~ return address.
@@ -1030,7 +1011,7 @@ static void GenerateCallMiss(MacroAssembler* masm, int argc, IC::UtilityId id) {
1030
1011
  // Call the entry.
1031
1012
  CEntryStub stub(1);
1032
1013
  __ movq(rax, Immediate(2));
1033
- __ movq(rbx, ExternalReference(IC_Utility(id)));
1014
+ __ LoadAddress(rbx, ExternalReference(IC_Utility(id), masm->isolate()));
1034
1015
  __ CallStub(&stub);
1035
1016
 
1036
1017
  // Move result to rdi and exit the internal frame.
@@ -1140,7 +1121,8 @@ void KeyedCallIC::GenerateMegamorphic(MacroAssembler* masm, int argc) {
1140
1121
 
1141
1122
  GenerateFastArrayLoad(
1142
1123
  masm, rdx, rcx, rax, rbx, rdi, &check_number_dictionary, &slow_load);
1143
- __ IncrementCounter(&Counters::keyed_call_generic_smi_fast, 1);
1124
+ Counters* counters = masm->isolate()->counters();
1125
+ __ IncrementCounter(counters->keyed_call_generic_smi_fast(), 1);
1144
1126
 
1145
1127
  __ bind(&do_call);
1146
1128
  // receiver in rdx is not used after this point.
@@ -1158,13 +1140,13 @@ void KeyedCallIC::GenerateMegamorphic(MacroAssembler* masm, int argc) {
1158
1140
  __ SmiToInteger32(rbx, rcx);
1159
1141
  // ebx: untagged index
1160
1142
  GenerateNumberDictionaryLoad(masm, &slow_load, rax, rcx, rbx, r9, rdi, rdi);
1161
- __ IncrementCounter(&Counters::keyed_call_generic_smi_dict, 1);
1143
+ __ IncrementCounter(counters->keyed_call_generic_smi_dict(), 1);
1162
1144
  __ jmp(&do_call);
1163
1145
 
1164
1146
  __ bind(&slow_load);
1165
1147
  // This branch is taken when calling KeyedCallIC_Miss is neither required
1166
1148
  // nor beneficial.
1167
- __ IncrementCounter(&Counters::keyed_call_generic_slow_load, 1);
1149
+ __ IncrementCounter(counters->keyed_call_generic_slow_load(), 1);
1168
1150
  __ EnterInternalFrame();
1169
1151
  __ push(rcx); // save the key
1170
1152
  __ push(rdx); // pass the receiver
@@ -1191,11 +1173,11 @@ void KeyedCallIC::GenerateMegamorphic(MacroAssembler* masm, int argc) {
1191
1173
  __ j(not_equal, &lookup_monomorphic_cache);
1192
1174
 
1193
1175
  GenerateDictionaryLoad(masm, &slow_load, rbx, rcx, rax, rdi, rdi);
1194
- __ IncrementCounter(&Counters::keyed_call_generic_lookup_dict, 1);
1176
+ __ IncrementCounter(counters->keyed_call_generic_lookup_dict(), 1);
1195
1177
  __ jmp(&do_call);
1196
1178
 
1197
1179
  __ bind(&lookup_monomorphic_cache);
1198
- __ IncrementCounter(&Counters::keyed_call_generic_lookup_cache, 1);
1180
+ __ IncrementCounter(counters->keyed_call_generic_lookup_cache(), 1);
1199
1181
  GenerateMonomorphicCacheProbe(masm, argc, Code::KEYED_CALL_IC);
1200
1182
  // Fall through on miss.
1201
1183
 
@@ -1206,7 +1188,7 @@ void KeyedCallIC::GenerateMegamorphic(MacroAssembler* masm, int argc) {
1206
1188
  // - the value loaded is not a function,
1207
1189
  // - there is hope that the runtime will create a monomorphic call stub
1208
1190
  // that will get fetched next time.
1209
- __ IncrementCounter(&Counters::keyed_call_generic_slow, 1);
1191
+ __ IncrementCounter(counters->keyed_call_generic_slow(), 1);
1210
1192
  GenerateMiss(masm, argc);
1211
1193
 
1212
1194
  __ bind(&index_string);
@@ -1264,7 +1246,8 @@ void LoadIC::GenerateMegamorphic(MacroAssembler* masm) {
1264
1246
  Code::Flags flags = Code::ComputeFlags(Code::LOAD_IC,
1265
1247
  NOT_IN_LOOP,
1266
1248
  MONOMORPHIC);
1267
- StubCache::GenerateProbe(masm, flags, rax, rcx, rbx, rdx);
1249
+ Isolate::Current()->stub_cache()->GenerateProbe(masm, flags, rax, rcx, rbx,
1250
+ rdx);
1268
1251
 
1269
1252
  // Cache miss: Jump to runtime.
1270
1253
  StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC);
@@ -1299,7 +1282,8 @@ void LoadIC::GenerateMiss(MacroAssembler* masm) {
1299
1282
  // -- rsp[0] : return address
1300
1283
  // -----------------------------------
1301
1284
 
1302
- __ IncrementCounter(&Counters::load_miss, 1);
1285
+ Counters* counters = masm->isolate()->counters();
1286
+ __ IncrementCounter(counters->load_miss(), 1);
1303
1287
 
1304
1288
  __ pop(rbx);
1305
1289
  __ push(rax); // receiver
@@ -1307,7 +1291,8 @@ void LoadIC::GenerateMiss(MacroAssembler* masm) {
1307
1291
  __ push(rbx); // return address
1308
1292
 
1309
1293
  // Perform tail call to the entry.
1310
- ExternalReference ref = ExternalReference(IC_Utility(kLoadIC_Miss));
1294
+ ExternalReference ref =
1295
+ ExternalReference(IC_Utility(kLoadIC_Miss), masm->isolate());
1311
1296
  __ TailCallExternalReference(ref, 2, 1);
1312
1297
  }
1313
1298
 
@@ -1382,7 +1367,7 @@ bool StoreIC::PatchInlinedStore(Address address, Object* map, int offset) {
1382
1367
  // (-1) or we should be clearing the inlined version.
1383
1368
  ASSERT(*reinterpret_cast<int*>(offset_address) == kMaxInt - 1 ||
1384
1369
  *reinterpret_cast<int*>(offset_address) == -1 ||
1385
- (offset == 0 && map == Heap::null_value()));
1370
+ (offset == 0 && map == HEAP->null_value()));
1386
1371
  *reinterpret_cast<int*>(offset_address) = offset - kHeapObjectTag;
1387
1372
 
1388
1373
  // Patch the offset in the write-barrier code. The offset is the
@@ -1392,7 +1377,7 @@ bool StoreIC::PatchInlinedStore(Address address, Object* map, int offset) {
1392
1377
  // (-1) or we should be clearing the inlined version.
1393
1378
  ASSERT(*reinterpret_cast<int*>(offset_address) == kMaxInt ||
1394
1379
  *reinterpret_cast<int*>(offset_address) == -1 ||
1395
- (offset == 0 && map == Heap::null_value()));
1380
+ (offset == 0 && map == HEAP->null_value()));
1396
1381
  *reinterpret_cast<int*>(offset_address) = offset - kHeapObjectTag;
1397
1382
 
1398
1383
  return true;
@@ -1443,7 +1428,8 @@ void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
1443
1428
  // -- rsp[0] : return address
1444
1429
  // -----------------------------------
1445
1430
 
1446
- __ IncrementCounter(&Counters::keyed_load_miss, 1);
1431
+ Counters* counters = masm->isolate()->counters();
1432
+ __ IncrementCounter(counters->keyed_load_miss(), 1);
1447
1433
 
1448
1434
  __ pop(rbx);
1449
1435
  __ push(rdx); // receiver
@@ -1451,7 +1437,8 @@ void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
1451
1437
  __ push(rbx); // return address
1452
1438
 
1453
1439
  // Perform tail call to the entry.
1454
- ExternalReference ref = ExternalReference(IC_Utility(kKeyedLoadIC_Miss));
1440
+ ExternalReference ref
1441
+ = ExternalReference(IC_Utility(kKeyedLoadIC_Miss), masm->isolate());
1455
1442
  __ TailCallExternalReference(ref, 2, 1);
1456
1443
  }
1457
1444
 
@@ -1474,7 +1461,7 @@ void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
1474
1461
 
1475
1462
 
1476
1463
  void StoreIC::GenerateMegamorphic(MacroAssembler* masm,
1477
- Code::ExtraICState extra_ic_state) {
1464
+ StrictModeFlag strict_mode) {
1478
1465
  // ----------- S t a t e -------------
1479
1466
  // -- rax : value
1480
1467
  // -- rcx : name
@@ -1486,8 +1473,9 @@ void StoreIC::GenerateMegamorphic(MacroAssembler* masm,
1486
1473
  Code::Flags flags = Code::ComputeFlags(Code::STORE_IC,
1487
1474
  NOT_IN_LOOP,
1488
1475
  MONOMORPHIC,
1489
- extra_ic_state);
1490
- StubCache::GenerateProbe(masm, flags, rdx, rcx, rbx, no_reg);
1476
+ strict_mode);
1477
+ Isolate::Current()->stub_cache()->GenerateProbe(masm, flags, rdx, rcx, rbx,
1478
+ no_reg);
1491
1479
 
1492
1480
  // Cache miss: Jump to runtime.
1493
1481
  GenerateMiss(masm);
@@ -1509,7 +1497,8 @@ void StoreIC::GenerateMiss(MacroAssembler* masm) {
1509
1497
  __ push(rbx); // return address
1510
1498
 
1511
1499
  // Perform tail call to the entry.
1512
- ExternalReference ref = ExternalReference(IC_Utility(kStoreIC_Miss));
1500
+ ExternalReference ref =
1501
+ ExternalReference(IC_Utility(kStoreIC_Miss), masm->isolate());
1513
1502
  __ TailCallExternalReference(ref, 3, 1);
1514
1503
  }
1515
1504
 
@@ -1562,7 +1551,8 @@ void StoreIC::GenerateArrayLength(MacroAssembler* masm) {
1562
1551
  __ push(value);
1563
1552
  __ push(scratch); // return address
1564
1553
 
1565
- ExternalReference ref = ExternalReference(IC_Utility(kStoreIC_ArrayLength));
1554
+ ExternalReference ref =
1555
+ ExternalReference(IC_Utility(kStoreIC_ArrayLength), masm->isolate());
1566
1556
  __ TailCallExternalReference(ref, 2, 1);
1567
1557
 
1568
1558
  __ bind(&miss);
@@ -1584,16 +1574,18 @@ void StoreIC::GenerateNormal(MacroAssembler* masm) {
1584
1574
  GenerateStringDictionaryReceiverCheck(masm, rdx, rbx, rdi, &miss);
1585
1575
 
1586
1576
  GenerateDictionaryStore(masm, &miss, rbx, rcx, rax, r8, r9);
1587
- __ IncrementCounter(&Counters::store_normal_hit, 1);
1577
+ Counters* counters = masm->isolate()->counters();
1578
+ __ IncrementCounter(counters->store_normal_hit(), 1);
1588
1579
  __ ret(0);
1589
1580
 
1590
1581
  __ bind(&miss);
1591
- __ IncrementCounter(&Counters::store_normal_miss, 1);
1582
+ __ IncrementCounter(counters->store_normal_miss(), 1);
1592
1583
  GenerateMiss(masm);
1593
1584
  }
1594
1585
 
1595
1586
 
1596
- void StoreIC::GenerateGlobalProxy(MacroAssembler* masm) {
1587
+ void StoreIC::GenerateGlobalProxy(MacroAssembler* masm,
1588
+ StrictModeFlag strict_mode) {
1597
1589
  // ----------- S t a t e -------------
1598
1590
  // -- rax : value
1599
1591
  // -- rcx : name
@@ -1604,14 +1596,17 @@ void StoreIC::GenerateGlobalProxy(MacroAssembler* masm) {
1604
1596
  __ push(rdx);
1605
1597
  __ push(rcx);
1606
1598
  __ push(rax);
1607
- __ push(rbx);
1599
+ __ Push(Smi::FromInt(NONE)); // PropertyAttributes
1600
+ __ Push(Smi::FromInt(strict_mode));
1601
+ __ push(rbx); // return address
1608
1602
 
1609
1603
  // Do tail-call to runtime routine.
1610
- __ TailCallRuntime(Runtime::kSetProperty, 3, 1);
1604
+ __ TailCallRuntime(Runtime::kSetProperty, 5, 1);
1611
1605
  }
1612
1606
 
1613
1607
 
1614
- void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm) {
1608
+ void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm,
1609
+ StrictModeFlag strict_mode) {
1615
1610
  // ----------- S t a t e -------------
1616
1611
  // -- rax : value
1617
1612
  // -- rcx : key
@@ -1623,10 +1618,12 @@ void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm) {
1623
1618
  __ push(rdx); // receiver
1624
1619
  __ push(rcx); // key
1625
1620
  __ push(rax); // value
1621
+ __ Push(Smi::FromInt(NONE)); // PropertyAttributes
1622
+ __ Push(Smi::FromInt(strict_mode)); // Strict mode.
1626
1623
  __ push(rbx); // return address
1627
1624
 
1628
1625
  // Do tail-call to runtime routine.
1629
- __ TailCallRuntime(Runtime::kSetProperty, 3, 1);
1626
+ __ TailCallRuntime(Runtime::kSetProperty, 5, 1);
1630
1627
  }
1631
1628
 
1632
1629
 
@@ -1645,7 +1642,8 @@ void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) {
1645
1642
  __ push(rbx); // return address
1646
1643
 
1647
1644
  // Do tail-call to runtime routine.
1648
- ExternalReference ref = ExternalReference(IC_Utility(kKeyedStoreIC_Miss));
1645
+ ExternalReference ref =
1646
+ ExternalReference(IC_Utility(kKeyedStoreIC_Miss), masm->isolate());
1649
1647
  __ TailCallExternalReference(ref, 3, 1);
1650
1648
  }
1651
1649
 
@@ -1,4 +1,4 @@
1
- // Copyright 2009 the V8 project authors. All rights reserved.
1
+ // Copyright 2010 the V8 project authors. All rights reserved.
2
2
  // Redistribution and use in source and binary forms, with or without
3
3
  // modification, are permitted provided that the following conditions are
4
4
  // met:
@@ -39,32 +39,39 @@ namespace internal {
39
39
 
40
40
  // When invoking builtins, we need to record the safepoint in the middle of
41
41
  // the invoke instruction sequence generated by the macro assembler.
42
- class SafepointGenerator : public PostCallGenerator {
42
+ class SafepointGenerator : public CallWrapper {
43
43
  public:
44
44
  SafepointGenerator(LCodeGen* codegen,
45
45
  LPointerMap* pointers,
46
- int deoptimization_index,
47
- bool ensure_reloc_space = false)
46
+ int deoptimization_index)
48
47
  : codegen_(codegen),
49
48
  pointers_(pointers),
50
- deoptimization_index_(deoptimization_index),
51
- ensure_reloc_space_(ensure_reloc_space) { }
49
+ deoptimization_index_(deoptimization_index) { }
52
50
  virtual ~SafepointGenerator() { }
53
51
 
54
- virtual void Generate() {
55
- // Ensure that we have enough space in the reloc info to patch
56
- // this with calls when doing deoptimization.
57
- if (ensure_reloc_space_) {
58
- codegen_->masm()->RecordComment(RelocInfo::kFillerCommentString, true);
52
+ virtual void BeforeCall(int call_size) {
53
+ ASSERT(call_size >= 0);
54
+ // Ensure that we have enough space after the previous safepoint position
55
+ // for the jump generated there.
56
+ int call_end = codegen_->masm()->pc_offset() + call_size;
57
+ int prev_jump_end = codegen_->LastSafepointEnd() + kMinSafepointSize;
58
+ if (call_end < prev_jump_end) {
59
+ int padding_size = prev_jump_end - call_end;
60
+ STATIC_ASSERT(kMinSafepointSize <= 9); // One multibyte nop is enough.
61
+ codegen_->masm()->nop(padding_size);
59
62
  }
63
+ }
64
+
65
+ virtual void AfterCall() {
60
66
  codegen_->RecordSafepoint(pointers_, deoptimization_index_);
61
67
  }
62
68
 
63
69
  private:
70
+ static const int kMinSafepointSize =
71
+ MacroAssembler::kShortCallInstructionLength;
64
72
  LCodeGen* codegen_;
65
73
  LPointerMap* pointers_;
66
74
  int deoptimization_index_;
67
- bool ensure_reloc_space_;
68
75
  };
69
76
 
70
77
 
@@ -77,6 +84,7 @@ bool LCodeGen::GenerateCode() {
77
84
  return GeneratePrologue() &&
78
85
  GenerateBody() &&
79
86
  GenerateDeferredCode() &&
87
+ GenerateJumpTable() &&
80
88
  GenerateSafepointTable();
81
89
  }
82
90
 
@@ -86,13 +94,14 @@ void LCodeGen::FinishCode(Handle<Code> code) {
86
94
  code->set_stack_slots(StackSlotCount());
87
95
  code->set_safepoint_table_offset(safepoints_.GetCodeOffset());
88
96
  PopulateDeoptimizationData(code);
97
+ Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(code);
89
98
  }
90
99
 
91
100
 
92
101
  void LCodeGen::Abort(const char* format, ...) {
93
102
  if (FLAG_trace_bailout) {
94
- SmartPointer<char> debug_name = graph()->debug_name()->ToCString();
95
- PrintF("Aborting LCodeGen in @\"%s\": ", *debug_name);
103
+ SmartPointer<char> name(info()->shared_info()->DebugName()->ToCString());
104
+ PrintF("Aborting LCodeGen in @\"%s\": ", *name);
96
105
  va_list arguments;
97
106
  va_start(arguments, format);
98
107
  OS::VPrint(format, arguments);
@@ -240,6 +249,15 @@ LInstruction* LCodeGen::GetNextInstruction() {
240
249
  }
241
250
 
242
251
 
252
+ bool LCodeGen::GenerateJumpTable() {
253
+ for (int i = 0; i < jump_table_.length(); i++) {
254
+ __ bind(&jump_table_[i].label);
255
+ __ Jump(jump_table_[i].address, RelocInfo::RUNTIME_ENTRY);
256
+ }
257
+ return !is_aborted();
258
+ }
259
+
260
+
243
261
  bool LCodeGen::GenerateDeferredCode() {
244
262
  ASSERT(is_generating());
245
263
  for (int i = 0; !is_aborted() && i < deferred_.length(); i++) {
@@ -440,7 +458,7 @@ void LCodeGen::CallCode(Handle<Code> code,
440
458
  }
441
459
 
442
460
 
443
- void LCodeGen::CallRuntime(Runtime::Function* function,
461
+ void LCodeGen::CallRuntime(const Runtime::Function* function,
444
462
  int num_arguments,
445
463
  LInstruction* instr) {
446
464
  ASSERT(instr != NULL);
@@ -512,10 +530,13 @@ void LCodeGen::DeoptimizeIf(Condition cc, LEnvironment* environment) {
512
530
  if (cc == no_condition) {
513
531
  __ Jump(entry, RelocInfo::RUNTIME_ENTRY);
514
532
  } else {
515
- NearLabel done;
516
- __ j(NegateCondition(cc), &done);
517
- __ Jump(entry, RelocInfo::RUNTIME_ENTRY);
518
- __ bind(&done);
533
+ // We often have several deopts to the same entry, reuse the last
534
+ // jump entry if this is the case.
535
+ if (jump_table_.is_empty() ||
536
+ jump_table_.last().address != entry) {
537
+ jump_table_.Add(entry);
538
+ }
539
+ __ j(cc, &jump_table_.last().label);
519
540
  }
520
541
  }
521
542
 
@@ -525,13 +546,14 @@ void LCodeGen::PopulateDeoptimizationData(Handle<Code> code) {
525
546
  if (length == 0) return;
526
547
  ASSERT(FLAG_deopt);
527
548
  Handle<DeoptimizationInputData> data =
528
- Factory::NewDeoptimizationInputData(length, TENURED);
549
+ factory()->NewDeoptimizationInputData(length, TENURED);
529
550
 
530
- data->SetTranslationByteArray(*translations_.CreateByteArray());
551
+ Handle<ByteArray> translations = translations_.CreateByteArray();
552
+ data->SetTranslationByteArray(*translations);
531
553
  data->SetInlinedFunctionCount(Smi::FromInt(inlined_function_count_));
532
554
 
533
555
  Handle<FixedArray> literals =
534
- Factory::NewFixedArray(deoptimization_literals_.length(), TENURED);
556
+ factory()->NewFixedArray(deoptimization_literals_.length(), TENURED);
535
557
  for (int i = 0; i < deoptimization_literals_.length(); i++) {
536
558
  literals->set(i, *deoptimization_literals_[i]);
537
559
  }
@@ -685,16 +707,6 @@ void LCodeGen::DoCallStub(LCallStub* instr) {
685
707
  CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
686
708
  break;
687
709
  }
688
- case CodeStub::StringCharAt: {
689
- // TODO(1116): Add StringCharAt stub to x64.
690
- Abort("Unimplemented: %s", "StringCharAt Stub");
691
- break;
692
- }
693
- case CodeStub::MathPow: {
694
- // TODO(1115): Add MathPow stub to x64.
695
- Abort("Unimplemented: %s", "MathPow Stub");
696
- break;
697
- }
698
710
  case CodeStub::NumberToString: {
699
711
  NumberToStringStub stub;
700
712
  CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
@@ -711,7 +723,8 @@ void LCodeGen::DoCallStub(LCallStub* instr) {
711
723
  break;
712
724
  }
713
725
  case CodeStub::TranscendentalCache: {
714
- TranscendentalCacheStub stub(instr->transcendental_type());
726
+ TranscendentalCacheStub stub(instr->transcendental_type(),
727
+ TranscendentalCacheStub::TAGGED);
715
728
  CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
716
729
  break;
717
730
  }
@@ -727,41 +740,65 @@ void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) {
727
740
 
728
741
 
729
742
  void LCodeGen::DoModI(LModI* instr) {
730
- LOperand* right = instr->InputAt(1);
731
- ASSERT(ToRegister(instr->result()).is(rdx));
732
- ASSERT(ToRegister(instr->InputAt(0)).is(rax));
733
- ASSERT(!ToRegister(instr->InputAt(1)).is(rax));
734
- ASSERT(!ToRegister(instr->InputAt(1)).is(rdx));
743
+ if (instr->hydrogen()->HasPowerOf2Divisor()) {
744
+ Register dividend = ToRegister(instr->InputAt(0));
735
745
 
736
- Register right_reg = ToRegister(right);
746
+ int32_t divisor =
747
+ HConstant::cast(instr->hydrogen()->right())->Integer32Value();
737
748
 
738
- // Check for x % 0.
739
- if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) {
740
- __ testl(right_reg, right_reg);
741
- DeoptimizeIf(zero, instr->environment());
742
- }
749
+ if (divisor < 0) divisor = -divisor;
743
750
 
744
- // Sign extend eax to edx. (We are using only the low 32 bits of the values.)
745
- __ cdq();
751
+ NearLabel positive_dividend, done;
752
+ __ testl(dividend, dividend);
753
+ __ j(not_sign, &positive_dividend);
754
+ __ negl(dividend);
755
+ __ andl(dividend, Immediate(divisor - 1));
756
+ __ negl(dividend);
757
+ if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
758
+ __ j(not_zero, &done);
759
+ DeoptimizeIf(no_condition, instr->environment());
760
+ }
761
+ __ bind(&positive_dividend);
762
+ __ andl(dividend, Immediate(divisor - 1));
763
+ __ bind(&done);
764
+ } else {
765
+ LOperand* right = instr->InputAt(1);
766
+ Register right_reg = ToRegister(right);
767
+
768
+ ASSERT(ToRegister(instr->result()).is(rdx));
769
+ ASSERT(ToRegister(instr->InputAt(0)).is(rax));
770
+ ASSERT(!right_reg.is(rax));
771
+ ASSERT(!right_reg.is(rdx));
772
+
773
+ // Check for x % 0.
774
+ if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) {
775
+ __ testl(right_reg, right_reg);
776
+ DeoptimizeIf(zero, instr->environment());
777
+ }
746
778
 
747
- // Check for (0 % -x) that will produce negative zero.
748
- if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
749
- NearLabel positive_left;
750
- NearLabel done;
751
- __ testl(rax, rax);
752
- __ j(not_sign, &positive_left);
753
- __ idivl(right_reg);
779
+ // Sign extend eax to edx.
780
+ // (We are using only the low 32 bits of the values.)
781
+ __ cdq();
754
782
 
755
- // Test the remainder for 0, because then the result would be -0.
756
- __ testl(rdx, rdx);
757
- __ j(not_zero, &done);
783
+ // Check for (0 % -x) that will produce negative zero.
784
+ if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
785
+ NearLabel positive_left;
786
+ NearLabel done;
787
+ __ testl(rax, rax);
788
+ __ j(not_sign, &positive_left);
789
+ __ idivl(right_reg);
758
790
 
759
- DeoptimizeIf(no_condition, instr->environment());
760
- __ bind(&positive_left);
761
- __ idivl(right_reg);
762
- __ bind(&done);
763
- } else {
764
- __ idivl(right_reg);
791
+ // Test the remainder for 0, because then the result would be -0.
792
+ __ testl(rdx, rdx);
793
+ __ j(not_zero, &done);
794
+
795
+ DeoptimizeIf(no_condition, instr->environment());
796
+ __ bind(&positive_left);
797
+ __ idivl(right_reg);
798
+ __ bind(&done);
799
+ } else {
800
+ __ idivl(right_reg);
801
+ }
765
802
  }
766
803
  }
767
804
 
@@ -820,16 +857,56 @@ void LCodeGen::DoMulI(LMulI* instr) {
820
857
  __ movl(kScratchRegister, left);
821
858
  }
822
859
 
860
+ bool can_overflow =
861
+ instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
823
862
  if (right->IsConstantOperand()) {
824
863
  int right_value = ToInteger32(LConstantOperand::cast(right));
825
- __ imull(left, left, Immediate(right_value));
864
+ if (right_value == -1) {
865
+ __ negl(left);
866
+ } else if (right_value == 0) {
867
+ __ xorl(left, left);
868
+ } else if (right_value == 2) {
869
+ __ addl(left, left);
870
+ } else if (!can_overflow) {
871
+ // If the multiplication is known to not overflow, we
872
+ // can use operations that don't set the overflow flag
873
+ // correctly.
874
+ switch (right_value) {
875
+ case 1:
876
+ // Do nothing.
877
+ break;
878
+ case 3:
879
+ __ leal(left, Operand(left, left, times_2, 0));
880
+ break;
881
+ case 4:
882
+ __ shll(left, Immediate(2));
883
+ break;
884
+ case 5:
885
+ __ leal(left, Operand(left, left, times_4, 0));
886
+ break;
887
+ case 8:
888
+ __ shll(left, Immediate(3));
889
+ break;
890
+ case 9:
891
+ __ leal(left, Operand(left, left, times_8, 0));
892
+ break;
893
+ case 16:
894
+ __ shll(left, Immediate(4));
895
+ break;
896
+ default:
897
+ __ imull(left, left, Immediate(right_value));
898
+ break;
899
+ }
900
+ } else {
901
+ __ imull(left, left, Immediate(right_value));
902
+ }
826
903
  } else if (right->IsStackSlot()) {
827
904
  __ imull(left, ToOperand(right));
828
905
  } else {
829
906
  __ imull(left, ToRegister(right));
830
907
  }
831
908
 
832
- if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
909
+ if (can_overflow) {
833
910
  DeoptimizeIf(overflow, instr->environment());
834
911
  }
835
912
 
@@ -1031,10 +1108,10 @@ void LCodeGen::DoFixedArrayLength(LFixedArrayLength* instr) {
1031
1108
  }
1032
1109
 
1033
1110
 
1034
- void LCodeGen::DoPixelArrayLength(LPixelArrayLength* instr) {
1111
+ void LCodeGen::DoExternalArrayLength(LExternalArrayLength* instr) {
1035
1112
  Register result = ToRegister(instr->result());
1036
1113
  Register array = ToRegister(instr->InputAt(0));
1037
- __ movq(result, FieldOperand(array, PixelArray::kLengthOffset));
1114
+ __ movl(result, FieldOperand(array, ExternalPixelArray::kLengthOffset));
1038
1115
  }
1039
1116
 
1040
1117
 
@@ -1094,25 +1171,32 @@ void LCodeGen::DoAddI(LAddI* instr) {
1094
1171
 
1095
1172
 
1096
1173
  void LCodeGen::DoArithmeticD(LArithmeticD* instr) {
1097
- LOperand* left = instr->InputAt(0);
1098
- LOperand* right = instr->InputAt(1);
1174
+ XMMRegister left = ToDoubleRegister(instr->InputAt(0));
1175
+ XMMRegister right = ToDoubleRegister(instr->InputAt(1));
1176
+ XMMRegister result = ToDoubleRegister(instr->result());
1099
1177
  // All operations except MOD are computed in-place.
1100
- ASSERT(instr->op() == Token::MOD || left->Equals(instr->result()));
1178
+ ASSERT(instr->op() == Token::MOD || left.is(result));
1101
1179
  switch (instr->op()) {
1102
1180
  case Token::ADD:
1103
- __ addsd(ToDoubleRegister(left), ToDoubleRegister(right));
1181
+ __ addsd(left, right);
1104
1182
  break;
1105
1183
  case Token::SUB:
1106
- __ subsd(ToDoubleRegister(left), ToDoubleRegister(right));
1184
+ __ subsd(left, right);
1107
1185
  break;
1108
1186
  case Token::MUL:
1109
- __ mulsd(ToDoubleRegister(left), ToDoubleRegister(right));
1187
+ __ mulsd(left, right);
1110
1188
  break;
1111
1189
  case Token::DIV:
1112
- __ divsd(ToDoubleRegister(left), ToDoubleRegister(right));
1190
+ __ divsd(left, right);
1113
1191
  break;
1114
1192
  case Token::MOD:
1115
- Abort("Unimplemented: %s", "DoArithmeticD MOD");
1193
+ __ PrepareCallCFunction(2);
1194
+ __ movsd(xmm0, left);
1195
+ ASSERT(right.is(xmm1));
1196
+ __ CallCFunction(
1197
+ ExternalReference::double_fp_operation(Token::MOD, isolate()), 2);
1198
+ __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
1199
+ __ movsd(result, xmm0);
1116
1200
  break;
1117
1201
  default:
1118
1202
  UNREACHABLE();
@@ -1179,7 +1263,7 @@ void LCodeGen::DoBranch(LBranch* instr) {
1179
1263
  Register reg = ToRegister(instr->InputAt(0));
1180
1264
  HType type = instr->hydrogen()->type();
1181
1265
  if (type.IsBoolean()) {
1182
- __ Cmp(reg, Factory::true_value());
1266
+ __ CompareRoot(reg, Heap::kTrueValueRootIndex);
1183
1267
  EmitBranch(true_block, false_block, equal);
1184
1268
  } else if (type.IsSmi()) {
1185
1269
  __ SmiCompare(reg, Smi::FromInt(0));
@@ -1194,7 +1278,7 @@ void LCodeGen::DoBranch(LBranch* instr) {
1194
1278
  __ j(equal, true_label);
1195
1279
  __ CompareRoot(reg, Heap::kFalseValueRootIndex);
1196
1280
  __ j(equal, false_label);
1197
- __ SmiCompare(reg, Smi::FromInt(0));
1281
+ __ Cmp(reg, Smi::FromInt(0));
1198
1282
  __ j(equal, false_label);
1199
1283
  __ JumpIfSmi(reg, true_label);
1200
1284
 
@@ -1406,7 +1490,7 @@ void LCodeGen::DoIsNull(LIsNull* instr) {
1406
1490
  __ j(equal, &load);
1407
1491
  __ movl(result, Immediate(Heap::kFalseValueRootIndex));
1408
1492
  __ bind(&load);
1409
- __ movq(result, Operand(kRootRegister, result, times_pointer_size, 0));
1493
+ __ LoadRootIndexed(result, result, 0);
1410
1494
  } else {
1411
1495
  NearLabel true_value, false_value, done;
1412
1496
  __ j(equal, &true_value);
@@ -1446,14 +1530,14 @@ void LCodeGen::DoIsNullAndBranch(LIsNullAndBranch* instr) {
1446
1530
 
1447
1531
  int true_block = chunk_->LookupDestination(instr->true_block_id());
1448
1532
 
1449
- __ Cmp(reg, Factory::null_value());
1533
+ __ CompareRoot(reg, Heap::kNullValueRootIndex);
1450
1534
  if (instr->is_strict()) {
1451
1535
  EmitBranch(true_block, false_block, equal);
1452
1536
  } else {
1453
1537
  Label* true_label = chunk_->GetAssemblyLabel(true_block);
1454
1538
  Label* false_label = chunk_->GetAssemblyLabel(false_block);
1455
1539
  __ j(equal, true_label);
1456
- __ Cmp(reg, Factory::undefined_value());
1540
+ __ CompareRoot(reg, Heap::kUndefinedValueRootIndex);
1457
1541
  __ j(equal, true_label);
1458
1542
  __ JumpIfSmi(reg, false_label);
1459
1543
  // Check for undetectable objects by looking in the bit field in
@@ -1537,8 +1621,7 @@ void LCodeGen::DoIsSmi(LIsSmi* instr) {
1537
1621
  }
1538
1622
  // result is zero if input is a smi, and one otherwise.
1539
1623
  ASSERT(Heap::kFalseValueRootIndex == Heap::kTrueValueRootIndex + 1);
1540
- __ movq(result, Operand(kRootRegister, result, times_pointer_size,
1541
- Heap::kTrueValueRootIndex * kPointerSize));
1624
+ __ LoadRootIndexed(result, result, Heap::kTrueValueRootIndex);
1542
1625
  }
1543
1626
 
1544
1627
 
@@ -1579,7 +1662,20 @@ static Condition BranchCondition(HHasInstanceType* instr) {
1579
1662
 
1580
1663
 
1581
1664
  void LCodeGen::DoHasInstanceType(LHasInstanceType* instr) {
1582
- Abort("Unimplemented: %s", "DoHasInstanceType");
1665
+ Register input = ToRegister(instr->InputAt(0));
1666
+ Register result = ToRegister(instr->result());
1667
+
1668
+ ASSERT(instr->hydrogen()->value()->representation().IsTagged());
1669
+ __ testl(input, Immediate(kSmiTagMask));
1670
+ NearLabel done, is_false;
1671
+ __ j(zero, &is_false);
1672
+ __ CmpObjectType(input, TestType(instr->hydrogen()), result);
1673
+ __ j(NegateCondition(BranchCondition(instr->hydrogen())), &is_false);
1674
+ __ LoadRoot(result, Heap::kTrueValueRootIndex);
1675
+ __ jmp(&done);
1676
+ __ bind(&is_false);
1677
+ __ LoadRoot(result, Heap::kFalseValueRootIndex);
1678
+ __ bind(&done);
1583
1679
  }
1584
1680
 
1585
1681
 
@@ -1598,8 +1694,32 @@ void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) {
1598
1694
  }
1599
1695
 
1600
1696
 
1697
+ void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) {
1698
+ Register input = ToRegister(instr->InputAt(0));
1699
+ Register result = ToRegister(instr->result());
1700
+
1701
+ if (FLAG_debug_code) {
1702
+ __ AbortIfNotString(input);
1703
+ }
1704
+
1705
+ __ movl(result, FieldOperand(input, String::kHashFieldOffset));
1706
+ ASSERT(String::kHashShift >= kSmiTagSize);
1707
+ __ IndexFromHash(result, result);
1708
+ }
1709
+
1710
+
1601
1711
  void LCodeGen::DoHasCachedArrayIndex(LHasCachedArrayIndex* instr) {
1602
- Abort("Unimplemented: %s", "DoHasCachedArrayIndex");
1712
+ Register input = ToRegister(instr->InputAt(0));
1713
+ Register result = ToRegister(instr->result());
1714
+
1715
+ ASSERT(instr->hydrogen()->value()->representation().IsTagged());
1716
+ __ LoadRoot(result, Heap::kTrueValueRootIndex);
1717
+ __ testl(FieldOperand(input, String::kHashFieldOffset),
1718
+ Immediate(String::kContainsCachedArrayIndexMask));
1719
+ NearLabel done;
1720
+ __ j(zero, &done);
1721
+ __ LoadRoot(result, Heap::kFalseValueRootIndex);
1722
+ __ bind(&done);
1603
1723
  }
1604
1724
 
1605
1725
 
@@ -1612,7 +1732,7 @@ void LCodeGen::DoHasCachedArrayIndexAndBranch(
1612
1732
 
1613
1733
  __ testl(FieldOperand(input, String::kHashFieldOffset),
1614
1734
  Immediate(String::kContainsCachedArrayIndexMask));
1615
- EmitBranch(true_block, false_block, not_equal);
1735
+ EmitBranch(true_block, false_block, equal);
1616
1736
  }
1617
1737
 
1618
1738
 
@@ -1756,24 +1876,51 @@ void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) {
1756
1876
  LInstanceOfKnownGlobal* instr)
1757
1877
  : LDeferredCode(codegen), instr_(instr) { }
1758
1878
  virtual void Generate() {
1759
- codegen()->DoDeferredLInstanceOfKnownGlobal(instr_);
1879
+ codegen()->DoDeferredLInstanceOfKnownGlobal(instr_, &map_check_);
1760
1880
  }
1761
1881
 
1882
+ Label* map_check() { return &map_check_; }
1883
+
1762
1884
  private:
1763
1885
  LInstanceOfKnownGlobal* instr_;
1886
+ Label map_check_;
1764
1887
  };
1765
1888
 
1766
1889
 
1767
1890
  DeferredInstanceOfKnownGlobal* deferred;
1768
1891
  deferred = new DeferredInstanceOfKnownGlobal(this, instr);
1769
1892
 
1770
- Label false_result;
1893
+ Label done, false_result;
1771
1894
  Register object = ToRegister(instr->InputAt(0));
1772
1895
 
1773
1896
  // A Smi is not an instance of anything.
1774
1897
  __ JumpIfSmi(object, &false_result);
1775
1898
 
1776
- // Null is not an instance of anything.
1899
+ // This is the inlined call site instanceof cache. The two occurences of the
1900
+ // hole value will be patched to the last map/result pair generated by the
1901
+ // instanceof stub.
1902
+ NearLabel cache_miss;
1903
+ // Use a temp register to avoid memory operands with variable lengths.
1904
+ Register map = ToRegister(instr->TempAt(0));
1905
+ __ movq(map, FieldOperand(object, HeapObject::kMapOffset));
1906
+ __ bind(deferred->map_check()); // Label for calculating code patching.
1907
+ __ movq(kScratchRegister, factory()->the_hole_value(),
1908
+ RelocInfo::EMBEDDED_OBJECT);
1909
+ __ cmpq(map, kScratchRegister); // Patched to cached map.
1910
+ __ j(not_equal, &cache_miss);
1911
+ // Patched to load either true or false.
1912
+ __ LoadRoot(ToRegister(instr->result()), Heap::kTheHoleValueRootIndex);
1913
+ #ifdef DEBUG
1914
+ // Check that the code size between patch label and patch sites is invariant.
1915
+ Label end_of_patched_code;
1916
+ __ bind(&end_of_patched_code);
1917
+ ASSERT(true);
1918
+ #endif
1919
+ __ jmp(&done);
1920
+
1921
+ // The inlined call site cache did not match. Check for null and string
1922
+ // before calling the deferred code.
1923
+ __ bind(&cache_miss); // Null is not an instance of anything.
1777
1924
  __ CompareRoot(object, Heap::kNullValueRootIndex);
1778
1925
  __ j(equal, &false_result);
1779
1926
 
@@ -1784,20 +1931,27 @@ void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) {
1784
1931
  __ LoadRoot(ToRegister(instr->result()), Heap::kFalseValueRootIndex);
1785
1932
 
1786
1933
  __ bind(deferred->exit());
1934
+ __ bind(&done);
1787
1935
  }
1788
1936
 
1789
1937
 
1790
- void LCodeGen::DoDeferredLInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) {
1938
+ void LCodeGen::DoDeferredLInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
1939
+ Label* map_check) {
1791
1940
  __ PushSafepointRegisters();
1792
-
1793
- InstanceofStub stub(InstanceofStub::kNoFlags);
1941
+ InstanceofStub::Flags flags = static_cast<InstanceofStub::Flags>(
1942
+ InstanceofStub::kNoFlags | InstanceofStub::kCallSiteInlineCheck);
1943
+ InstanceofStub stub(flags);
1794
1944
 
1795
1945
  __ push(ToRegister(instr->InputAt(0)));
1796
1946
  __ Push(instr->function());
1797
- __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
1798
- __ Call(stub.GetCode(), RelocInfo::CODE_TARGET);
1799
- RecordSafepointWithRegisters(
1800
- instr->pointer_map(), 0, Safepoint::kNoDeoptimizationIndex);
1947
+ Register temp = ToRegister(instr->TempAt(0));
1948
+ ASSERT(temp.is(rdi));
1949
+ static const int kAdditionalDelta = 16;
1950
+ int delta =
1951
+ masm_->SizeOfCodeGeneratedSince(map_check) + kAdditionalDelta;
1952
+ __ movq(temp, Immediate(delta));
1953
+ __ push(temp);
1954
+ CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
1801
1955
  __ movq(kScratchRegister, rax);
1802
1956
  __ PopSafepointRegisters();
1803
1957
  __ testq(kScratchRegister, kScratchRegister);
@@ -1865,7 +2019,7 @@ void LCodeGen::DoReturn(LReturn* instr) {
1865
2019
  }
1866
2020
 
1867
2021
 
1868
- void LCodeGen::DoLoadGlobal(LLoadGlobal* instr) {
2022
+ void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) {
1869
2023
  Register result = ToRegister(instr->result());
1870
2024
  if (result.is(rax)) {
1871
2025
  __ load_rax(instr->hydrogen()->cell().location(),
@@ -1881,6 +2035,18 @@ void LCodeGen::DoLoadGlobal(LLoadGlobal* instr) {
1881
2035
  }
1882
2036
 
1883
2037
 
2038
+ void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
2039
+ ASSERT(ToRegister(instr->global_object()).is(rax));
2040
+ ASSERT(ToRegister(instr->result()).is(rax));
2041
+
2042
+ __ Move(rcx, instr->name());
2043
+ RelocInfo::Mode mode = instr->for_typeof() ? RelocInfo::CODE_TARGET :
2044
+ RelocInfo::CODE_TARGET_CONTEXT;
2045
+ Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
2046
+ CallCode(ic, mode, instr);
2047
+ }
2048
+
2049
+
1884
2050
  void LCodeGen::DoStoreGlobal(LStoreGlobal* instr) {
1885
2051
  Register value = ToRegister(instr->InputAt(0));
1886
2052
  Register temp = ToRegister(instr->TempAt(0));
@@ -1917,7 +2083,8 @@ void LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) {
1917
2083
  __ movq(ContextOperand(context, instr->slot_index()), value);
1918
2084
  if (instr->needs_write_barrier()) {
1919
2085
  int offset = Context::SlotOffset(instr->slot_index());
1920
- __ RecordWrite(context, offset, value, kScratchRegister);
2086
+ Register scratch = ToRegister(instr->TempAt(0));
2087
+ __ RecordWrite(context, offset, value, scratch);
1921
2088
  }
1922
2089
  }
1923
2090
 
@@ -1934,12 +2101,76 @@ void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
1934
2101
  }
1935
2102
 
1936
2103
 
2104
+ void LCodeGen::EmitLoadField(Register result,
2105
+ Register object,
2106
+ Handle<Map> type,
2107
+ Handle<String> name) {
2108
+ LookupResult lookup;
2109
+ type->LookupInDescriptors(NULL, *name, &lookup);
2110
+ ASSERT(lookup.IsProperty() && lookup.type() == FIELD);
2111
+ int index = lookup.GetLocalFieldIndexFromMap(*type);
2112
+ int offset = index * kPointerSize;
2113
+ if (index < 0) {
2114
+ // Negative property indices are in-object properties, indexed
2115
+ // from the end of the fixed part of the object.
2116
+ __ movq(result, FieldOperand(object, offset + type->instance_size()));
2117
+ } else {
2118
+ // Non-negative property indices are in the properties array.
2119
+ __ movq(result, FieldOperand(object, JSObject::kPropertiesOffset));
2120
+ __ movq(result, FieldOperand(result, offset + FixedArray::kHeaderSize));
2121
+ }
2122
+ }
2123
+
2124
+
2125
+ void LCodeGen::DoLoadNamedFieldPolymorphic(LLoadNamedFieldPolymorphic* instr) {
2126
+ Register object = ToRegister(instr->object());
2127
+ Register result = ToRegister(instr->result());
2128
+
2129
+ int map_count = instr->hydrogen()->types()->length();
2130
+ Handle<String> name = instr->hydrogen()->name();
2131
+
2132
+ if (map_count == 0) {
2133
+ ASSERT(instr->hydrogen()->need_generic());
2134
+ __ Move(rcx, instr->hydrogen()->name());
2135
+ Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
2136
+ CallCode(ic, RelocInfo::CODE_TARGET, instr);
2137
+ } else {
2138
+ NearLabel done;
2139
+ for (int i = 0; i < map_count - 1; ++i) {
2140
+ Handle<Map> map = instr->hydrogen()->types()->at(i);
2141
+ NearLabel next;
2142
+ __ Cmp(FieldOperand(object, HeapObject::kMapOffset), map);
2143
+ __ j(not_equal, &next);
2144
+ EmitLoadField(result, object, map, name);
2145
+ __ jmp(&done);
2146
+ __ bind(&next);
2147
+ }
2148
+ Handle<Map> map = instr->hydrogen()->types()->last();
2149
+ __ Cmp(FieldOperand(object, HeapObject::kMapOffset), map);
2150
+ if (instr->hydrogen()->need_generic()) {
2151
+ NearLabel generic;
2152
+ __ j(not_equal, &generic);
2153
+ EmitLoadField(result, object, map, name);
2154
+ __ jmp(&done);
2155
+ __ bind(&generic);
2156
+ __ Move(rcx, instr->hydrogen()->name());
2157
+ Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
2158
+ CallCode(ic, RelocInfo::CODE_TARGET, instr);
2159
+ } else {
2160
+ DeoptimizeIf(not_equal, instr->environment());
2161
+ EmitLoadField(result, object, map, name);
2162
+ }
2163
+ __ bind(&done);
2164
+ }
2165
+ }
2166
+
2167
+
1937
2168
  void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
1938
2169
  ASSERT(ToRegister(instr->object()).is(rax));
1939
2170
  ASSERT(ToRegister(instr->result()).is(rax));
1940
2171
 
1941
2172
  __ Move(rcx, instr->name());
1942
- Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
2173
+ Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
1943
2174
  CallCode(ic, RelocInfo::CODE_TARGET, instr);
1944
2175
  }
1945
2176
 
@@ -1991,25 +2222,31 @@ void LCodeGen::DoLoadElements(LLoadElements* instr) {
1991
2222
  __ movq(result, FieldOperand(input, JSObject::kElementsOffset));
1992
2223
  if (FLAG_debug_code) {
1993
2224
  NearLabel done;
1994
- __ Cmp(FieldOperand(result, HeapObject::kMapOffset),
1995
- Factory::fixed_array_map());
2225
+ __ CompareRoot(FieldOperand(result, HeapObject::kMapOffset),
2226
+ Heap::kFixedArrayMapRootIndex);
1996
2227
  __ j(equal, &done);
1997
- __ Cmp(FieldOperand(result, HeapObject::kMapOffset),
1998
- Factory::pixel_array_map());
2228
+ __ CompareRoot(FieldOperand(result, HeapObject::kMapOffset),
2229
+ Heap::kFixedCOWArrayMapRootIndex);
1999
2230
  __ j(equal, &done);
2000
- __ Cmp(FieldOperand(result, HeapObject::kMapOffset),
2001
- Factory::fixed_cow_array_map());
2002
- __ Check(equal, "Check for fast elements failed.");
2231
+ Register temp((result.is(rax)) ? rbx : rax);
2232
+ __ push(temp);
2233
+ __ movq(temp, FieldOperand(result, HeapObject::kMapOffset));
2234
+ __ movzxbq(temp, FieldOperand(temp, Map::kInstanceTypeOffset));
2235
+ __ subq(temp, Immediate(FIRST_EXTERNAL_ARRAY_TYPE));
2236
+ __ cmpq(temp, Immediate(kExternalArrayTypeCount));
2237
+ __ pop(temp);
2238
+ __ Check(below, "Check for fast elements failed.");
2003
2239
  __ bind(&done);
2004
2240
  }
2005
2241
  }
2006
2242
 
2007
2243
 
2008
- void LCodeGen::DoLoadPixelArrayExternalPointer(
2009
- LLoadPixelArrayExternalPointer* instr) {
2244
+ void LCodeGen::DoLoadExternalArrayPointer(
2245
+ LLoadExternalArrayPointer* instr) {
2010
2246
  Register result = ToRegister(instr->result());
2011
2247
  Register input = ToRegister(instr->InputAt(0));
2012
- __ movq(result, FieldOperand(input, PixelArray::kExternalPointerOffset));
2248
+ __ movq(result, FieldOperand(input,
2249
+ ExternalPixelArray::kExternalPointerOffset));
2013
2250
  }
2014
2251
 
2015
2252
 
@@ -2044,19 +2281,52 @@ void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) {
2044
2281
  FixedArray::kHeaderSize));
2045
2282
 
2046
2283
  // Check for the hole value.
2047
- __ Cmp(result, Factory::the_hole_value());
2284
+ __ CompareRoot(result, Heap::kTheHoleValueRootIndex);
2048
2285
  DeoptimizeIf(equal, instr->environment());
2049
2286
  }
2050
2287
 
2051
2288
 
2052
- void LCodeGen::DoLoadPixelArrayElement(LLoadPixelArrayElement* instr) {
2053
- Register external_elements = ToRegister(instr->external_pointer());
2289
+ void LCodeGen::DoLoadKeyedSpecializedArrayElement(
2290
+ LLoadKeyedSpecializedArrayElement* instr) {
2291
+ Register external_pointer = ToRegister(instr->external_pointer());
2054
2292
  Register key = ToRegister(instr->key());
2055
- Register result = ToRegister(instr->result());
2056
- ASSERT(result.is(external_elements));
2057
-
2058
- // Load the result.
2059
- __ movzxbq(result, Operand(external_elements, key, times_1, 0));
2293
+ ExternalArrayType array_type = instr->array_type();
2294
+ if (array_type == kExternalFloatArray) {
2295
+ XMMRegister result(ToDoubleRegister(instr->result()));
2296
+ __ movss(result, Operand(external_pointer, key, times_4, 0));
2297
+ __ cvtss2sd(result, result);
2298
+ } else {
2299
+ Register result(ToRegister(instr->result()));
2300
+ switch (array_type) {
2301
+ case kExternalByteArray:
2302
+ __ movsxbq(result, Operand(external_pointer, key, times_1, 0));
2303
+ break;
2304
+ case kExternalUnsignedByteArray:
2305
+ case kExternalPixelArray:
2306
+ __ movzxbq(result, Operand(external_pointer, key, times_1, 0));
2307
+ break;
2308
+ case kExternalShortArray:
2309
+ __ movsxwq(result, Operand(external_pointer, key, times_2, 0));
2310
+ break;
2311
+ case kExternalUnsignedShortArray:
2312
+ __ movzxwq(result, Operand(external_pointer, key, times_2, 0));
2313
+ break;
2314
+ case kExternalIntArray:
2315
+ __ movsxlq(result, Operand(external_pointer, key, times_4, 0));
2316
+ break;
2317
+ case kExternalUnsignedIntArray:
2318
+ __ movl(result, Operand(external_pointer, key, times_4, 0));
2319
+ __ testl(result, result);
2320
+ // TODO(danno): we could be more clever here, perhaps having a special
2321
+ // version of the stub that detects if the overflow case actually
2322
+ // happens, and generate code that returns a double rather than int.
2323
+ DeoptimizeIf(negative, instr->environment());
2324
+ break;
2325
+ case kExternalFloatArray:
2326
+ UNREACHABLE();
2327
+ break;
2328
+ }
2329
+ }
2060
2330
  }
2061
2331
 
2062
2332
 
@@ -2064,7 +2334,7 @@ void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) {
2064
2334
  ASSERT(ToRegister(instr->object()).is(rdx));
2065
2335
  ASSERT(ToRegister(instr->key()).is(rax));
2066
2336
 
2067
- Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
2337
+ Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
2068
2338
  CallCode(ic, RelocInfo::CODE_TARGET, instr);
2069
2339
  }
2070
2340
 
@@ -2075,8 +2345,8 @@ void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) {
2075
2345
  // Check for arguments adapter frame.
2076
2346
  NearLabel done, adapted;
2077
2347
  __ movq(result, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
2078
- __ SmiCompare(Operand(result, StandardFrameConstants::kContextOffset),
2079
- Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
2348
+ __ Cmp(Operand(result, StandardFrameConstants::kContextOffset),
2349
+ Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
2080
2350
  __ j(equal, &adapted);
2081
2351
 
2082
2352
  // No arguments adaptor frame.
@@ -2179,8 +2449,7 @@ void LCodeGen::DoApplyArguments(LApplyArguments* instr) {
2179
2449
  RegisterEnvironmentForDeoptimization(env);
2180
2450
  SafepointGenerator safepoint_generator(this,
2181
2451
  pointers,
2182
- env->deoptimization_index(),
2183
- true);
2452
+ env->deoptimization_index());
2184
2453
  v8::internal::ParameterCount actual(rax);
2185
2454
  __ InvokeFunction(function, actual, CALL_FUNCTION, &safepoint_generator);
2186
2455
  }
@@ -2221,9 +2490,9 @@ void LCodeGen::DoGlobalObject(LGlobalObject* instr) {
2221
2490
 
2222
2491
 
2223
2492
  void LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) {
2493
+ Register global = ToRegister(instr->global());
2224
2494
  Register result = ToRegister(instr->result());
2225
- __ movq(result, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX)));
2226
- __ movq(result, FieldOperand(result, GlobalObject::kGlobalReceiverOffset));
2495
+ __ movq(result, FieldOperand(global, GlobalObject::kGlobalReceiverOffset));
2227
2496
  }
2228
2497
 
2229
2498
 
@@ -2232,7 +2501,7 @@ void LCodeGen::CallKnownFunction(Handle<JSFunction> function,
2232
2501
  LInstruction* instr) {
2233
2502
  // Change context if needed.
2234
2503
  bool change_context =
2235
- (graph()->info()->closure()->context() != function->context()) ||
2504
+ (info()->closure()->context() != function->context()) ||
2236
2505
  scope()->contains_with() ||
2237
2506
  (scope()->num_heap_slots() > 0);
2238
2507
  if (change_context) {
@@ -2249,7 +2518,7 @@ void LCodeGen::CallKnownFunction(Handle<JSFunction> function,
2249
2518
  RecordPosition(pointers->position());
2250
2519
 
2251
2520
  // Invoke function.
2252
- if (*function == *graph()->info()->closure()) {
2521
+ if (*function == *info()->closure()) {
2253
2522
  __ CallSelf();
2254
2523
  } else {
2255
2524
  __ call(FieldOperand(rdi, JSFunction::kCodeEntryOffset));
@@ -2271,12 +2540,105 @@ void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) {
2271
2540
 
2272
2541
 
2273
2542
  void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) {
2274
- Abort("Unimplemented: %s", "DoDeferredMathAbsTaggedHeapNumber");
2543
+ Register input_reg = ToRegister(instr->InputAt(0));
2544
+ __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset),
2545
+ Heap::kHeapNumberMapRootIndex);
2546
+ DeoptimizeIf(not_equal, instr->environment());
2547
+
2548
+ Label done;
2549
+ Register tmp = input_reg.is(rax) ? rcx : rax;
2550
+ Register tmp2 = tmp.is(rcx) ? rdx : input_reg.is(rcx) ? rdx : rcx;
2551
+
2552
+ // Preserve the value of all registers.
2553
+ __ PushSafepointRegisters();
2554
+
2555
+ Label negative;
2556
+ __ movl(tmp, FieldOperand(input_reg, HeapNumber::kExponentOffset));
2557
+ // Check the sign of the argument. If the argument is positive, just
2558
+ // return it. We do not need to patch the stack since |input| and
2559
+ // |result| are the same register and |input| will be restored
2560
+ // unchanged by popping safepoint registers.
2561
+ __ testl(tmp, Immediate(HeapNumber::kSignMask));
2562
+ __ j(not_zero, &negative);
2563
+ __ jmp(&done);
2564
+
2565
+ __ bind(&negative);
2566
+
2567
+ Label allocated, slow;
2568
+ __ AllocateHeapNumber(tmp, tmp2, &slow);
2569
+ __ jmp(&allocated);
2570
+
2571
+ // Slow case: Call the runtime system to do the number allocation.
2572
+ __ bind(&slow);
2573
+
2574
+ __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber);
2575
+ RecordSafepointWithRegisters(
2576
+ instr->pointer_map(), 0, Safepoint::kNoDeoptimizationIndex);
2577
+ // Set the pointer to the new heap number in tmp.
2578
+ if (!tmp.is(rax)) {
2579
+ __ movq(tmp, rax);
2580
+ }
2581
+
2582
+ // Restore input_reg after call to runtime.
2583
+ __ LoadFromSafepointRegisterSlot(input_reg, input_reg);
2584
+
2585
+ __ bind(&allocated);
2586
+ __ movq(tmp2, FieldOperand(input_reg, HeapNumber::kValueOffset));
2587
+ __ shl(tmp2, Immediate(1));
2588
+ __ shr(tmp2, Immediate(1));
2589
+ __ movq(FieldOperand(tmp, HeapNumber::kValueOffset), tmp2);
2590
+ __ StoreToSafepointRegisterSlot(input_reg, tmp);
2591
+
2592
+ __ bind(&done);
2593
+ __ PopSafepointRegisters();
2594
+ }
2595
+
2596
+
2597
+ void LCodeGen::EmitIntegerMathAbs(LUnaryMathOperation* instr) {
2598
+ Register input_reg = ToRegister(instr->InputAt(0));
2599
+ __ testl(input_reg, input_reg);
2600
+ Label is_positive;
2601
+ __ j(not_sign, &is_positive);
2602
+ __ negl(input_reg); // Sets flags.
2603
+ DeoptimizeIf(negative, instr->environment());
2604
+ __ bind(&is_positive);
2275
2605
  }
2276
2606
 
2277
2607
 
2278
2608
  void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) {
2279
- Abort("Unimplemented: %s", "DoMathAbs");
2609
+ // Class for deferred case.
2610
+ class DeferredMathAbsTaggedHeapNumber: public LDeferredCode {
2611
+ public:
2612
+ DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen,
2613
+ LUnaryMathOperation* instr)
2614
+ : LDeferredCode(codegen), instr_(instr) { }
2615
+ virtual void Generate() {
2616
+ codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_);
2617
+ }
2618
+ private:
2619
+ LUnaryMathOperation* instr_;
2620
+ };
2621
+
2622
+ ASSERT(instr->InputAt(0)->Equals(instr->result()));
2623
+ Representation r = instr->hydrogen()->value()->representation();
2624
+
2625
+ if (r.IsDouble()) {
2626
+ XMMRegister scratch = xmm0;
2627
+ XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
2628
+ __ xorpd(scratch, scratch);
2629
+ __ subsd(scratch, input_reg);
2630
+ __ andpd(input_reg, scratch);
2631
+ } else if (r.IsInteger32()) {
2632
+ EmitIntegerMathAbs(instr);
2633
+ } else { // Tagged case.
2634
+ DeferredMathAbsTaggedHeapNumber* deferred =
2635
+ new DeferredMathAbsTaggedHeapNumber(this, instr);
2636
+ Register input_reg = ToRegister(instr->InputAt(0));
2637
+ // Smi check.
2638
+ __ JumpIfNotSmi(input_reg, deferred->entry());
2639
+ EmitIntegerMathAbs(instr);
2640
+ __ bind(deferred->exit());
2641
+ }
2280
2642
  }
2281
2643
 
2282
2644
 
@@ -2355,22 +2717,83 @@ void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) {
2355
2717
 
2356
2718
 
2357
2719
  void LCodeGen::DoPower(LPower* instr) {
2358
- Abort("Unimplemented: %s", "DoPower");
2720
+ LOperand* left = instr->InputAt(0);
2721
+ XMMRegister left_reg = ToDoubleRegister(left);
2722
+ ASSERT(!left_reg.is(xmm1));
2723
+ LOperand* right = instr->InputAt(1);
2724
+ XMMRegister result_reg = ToDoubleRegister(instr->result());
2725
+ Representation exponent_type = instr->hydrogen()->right()->representation();
2726
+ if (exponent_type.IsDouble()) {
2727
+ __ PrepareCallCFunction(2);
2728
+ // Move arguments to correct registers
2729
+ __ movsd(xmm0, left_reg);
2730
+ ASSERT(ToDoubleRegister(right).is(xmm1));
2731
+ __ CallCFunction(
2732
+ ExternalReference::power_double_double_function(isolate()), 2);
2733
+ } else if (exponent_type.IsInteger32()) {
2734
+ __ PrepareCallCFunction(2);
2735
+ // Move arguments to correct registers: xmm0 and edi (not rdi).
2736
+ // On Windows, the registers are xmm0 and edx.
2737
+ __ movsd(xmm0, left_reg);
2738
+ #ifdef _WIN64
2739
+ ASSERT(ToRegister(right).is(rdx));
2740
+ #else
2741
+ ASSERT(ToRegister(right).is(rdi));
2742
+ #endif
2743
+ __ CallCFunction(
2744
+ ExternalReference::power_double_int_function(isolate()), 2);
2745
+ } else {
2746
+ ASSERT(exponent_type.IsTagged());
2747
+ CpuFeatures::Scope scope(SSE2);
2748
+ Register right_reg = ToRegister(right);
2749
+
2750
+ Label non_smi, call;
2751
+ __ JumpIfNotSmi(right_reg, &non_smi);
2752
+ __ SmiToInteger32(right_reg, right_reg);
2753
+ __ cvtlsi2sd(xmm1, right_reg);
2754
+ __ jmp(&call);
2755
+
2756
+ __ bind(&non_smi);
2757
+ __ CmpObjectType(right_reg, HEAP_NUMBER_TYPE , kScratchRegister);
2758
+ DeoptimizeIf(not_equal, instr->environment());
2759
+ __ movsd(xmm1, FieldOperand(right_reg, HeapNumber::kValueOffset));
2760
+
2761
+ __ bind(&call);
2762
+ __ PrepareCallCFunction(2);
2763
+ // Move arguments to correct registers xmm0 and xmm1.
2764
+ __ movsd(xmm0, left_reg);
2765
+ // Right argument is already in xmm1.
2766
+ __ CallCFunction(
2767
+ ExternalReference::power_double_double_function(isolate()), 2);
2768
+ }
2769
+ // Return value is in xmm0.
2770
+ __ movsd(result_reg, xmm0);
2771
+ // Restore context register.
2772
+ __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
2359
2773
  }
2360
2774
 
2361
2775
 
2362
2776
  void LCodeGen::DoMathLog(LUnaryMathOperation* instr) {
2363
- Abort("Unimplemented: %s", "DoMathLog");
2777
+ ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
2778
+ TranscendentalCacheStub stub(TranscendentalCache::LOG,
2779
+ TranscendentalCacheStub::UNTAGGED);
2780
+ CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
2364
2781
  }
2365
2782
 
2366
2783
 
2367
2784
  void LCodeGen::DoMathCos(LUnaryMathOperation* instr) {
2368
- Abort("Unimplemented: %s", "DoMathCos");
2785
+ ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
2786
+ TranscendentalCacheStub stub(TranscendentalCache::COS,
2787
+ TranscendentalCacheStub::UNTAGGED);
2788
+ CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
2369
2789
  }
2370
2790
 
2371
2791
 
2372
2792
  void LCodeGen::DoMathSin(LUnaryMathOperation* instr) {
2373
- Abort("Unimplemented: %s", "DoMathSin");
2793
+ ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
2794
+ TranscendentalCacheStub stub(TranscendentalCache::SIN,
2795
+ TranscendentalCacheStub::UNTAGGED);
2796
+ CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
2374
2797
  }
2375
2798
 
2376
2799
 
@@ -2412,8 +2835,10 @@ void LCodeGen::DoCallKeyed(LCallKeyed* instr) {
2412
2835
  ASSERT(ToRegister(instr->result()).is(rax));
2413
2836
 
2414
2837
  int arity = instr->arity();
2415
- Handle<Code> ic = StubCache::ComputeKeyedCallInitialize(arity, NOT_IN_LOOP);
2838
+ Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize(
2839
+ arity, NOT_IN_LOOP);
2416
2840
  CallCode(ic, RelocInfo::CODE_TARGET, instr);
2841
+ __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
2417
2842
  }
2418
2843
 
2419
2844
 
@@ -2421,7 +2846,8 @@ void LCodeGen::DoCallNamed(LCallNamed* instr) {
2421
2846
  ASSERT(ToRegister(instr->result()).is(rax));
2422
2847
 
2423
2848
  int arity = instr->arity();
2424
- Handle<Code> ic = StubCache::ComputeCallInitialize(arity, NOT_IN_LOOP);
2849
+ Handle<Code> ic = isolate()->stub_cache()->ComputeCallInitialize(
2850
+ arity, NOT_IN_LOOP);
2425
2851
  __ Move(rcx, instr->name());
2426
2852
  CallCode(ic, RelocInfo::CODE_TARGET, instr);
2427
2853
  __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
@@ -2442,7 +2868,8 @@ void LCodeGen::DoCallFunction(LCallFunction* instr) {
2442
2868
  void LCodeGen::DoCallGlobal(LCallGlobal* instr) {
2443
2869
  ASSERT(ToRegister(instr->result()).is(rax));
2444
2870
  int arity = instr->arity();
2445
- Handle<Code> ic = StubCache::ComputeCallInitialize(arity, NOT_IN_LOOP);
2871
+ Handle<Code> ic = isolate()->stub_cache()->ComputeCallInitialize(
2872
+ arity, NOT_IN_LOOP);
2446
2873
  __ Move(rcx, instr->name());
2447
2874
  CallCode(ic, RelocInfo::CODE_TARGET_CONTEXT, instr);
2448
2875
  __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
@@ -2460,7 +2887,7 @@ void LCodeGen::DoCallNew(LCallNew* instr) {
2460
2887
  ASSERT(ToRegister(instr->InputAt(0)).is(rdi));
2461
2888
  ASSERT(ToRegister(instr->result()).is(rax));
2462
2889
 
2463
- Handle<Code> builtin(Builtins::builtin(Builtins::JSConstructCall));
2890
+ Handle<Code> builtin = isolate()->builtins()->JSConstructCall();
2464
2891
  __ Set(rax, instr->arity());
2465
2892
  CallCode(builtin, RelocInfo::CONSTRUCT_CALL, instr);
2466
2893
  }
@@ -2506,26 +2933,53 @@ void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) {
2506
2933
  ASSERT(ToRegister(instr->value()).is(rax));
2507
2934
 
2508
2935
  __ Move(rcx, instr->hydrogen()->name());
2509
- Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
2936
+ Handle<Code> ic = info_->is_strict()
2937
+ ? isolate()->builtins()->StoreIC_Initialize_Strict()
2938
+ : isolate()->builtins()->StoreIC_Initialize();
2510
2939
  CallCode(ic, RelocInfo::CODE_TARGET, instr);
2511
2940
  }
2512
2941
 
2513
2942
 
2514
- void LCodeGen::DoStorePixelArrayElement(LStorePixelArrayElement* instr) {
2943
+ void LCodeGen::DoStoreKeyedSpecializedArrayElement(
2944
+ LStoreKeyedSpecializedArrayElement* instr) {
2515
2945
  Register external_pointer = ToRegister(instr->external_pointer());
2516
2946
  Register key = ToRegister(instr->key());
2517
- Register value = ToRegister(instr->value());
2518
-
2519
- { // Clamp the value to [0..255].
2520
- NearLabel done;
2521
- __ testl(value, Immediate(0xFFFFFF00));
2522
- __ j(zero, &done);
2523
- __ setcc(negative, value); // 1 if negative, 0 if positive.
2524
- __ decb(value); // 0 if negative, 255 if positive.
2525
- __ bind(&done);
2947
+ ExternalArrayType array_type = instr->array_type();
2948
+ if (array_type == kExternalFloatArray) {
2949
+ XMMRegister value(ToDoubleRegister(instr->value()));
2950
+ __ cvtsd2ss(value, value);
2951
+ __ movss(Operand(external_pointer, key, times_4, 0), value);
2952
+ } else {
2953
+ Register value(ToRegister(instr->value()));
2954
+ switch (array_type) {
2955
+ case kExternalPixelArray:
2956
+ { // Clamp the value to [0..255].
2957
+ NearLabel done;
2958
+ __ testl(value, Immediate(0xFFFFFF00));
2959
+ __ j(zero, &done);
2960
+ __ setcc(negative, value); // 1 if negative, 0 if positive.
2961
+ __ decb(value); // 0 if negative, 255 if positive.
2962
+ __ bind(&done);
2963
+ __ movb(Operand(external_pointer, key, times_1, 0), value);
2964
+ }
2965
+ break;
2966
+ case kExternalByteArray:
2967
+ case kExternalUnsignedByteArray:
2968
+ __ movb(Operand(external_pointer, key, times_1, 0), value);
2969
+ break;
2970
+ case kExternalShortArray:
2971
+ case kExternalUnsignedShortArray:
2972
+ __ movw(Operand(external_pointer, key, times_2, 0), value);
2973
+ break;
2974
+ case kExternalIntArray:
2975
+ case kExternalUnsignedIntArray:
2976
+ __ movl(Operand(external_pointer, key, times_4, 0), value);
2977
+ break;
2978
+ case kExternalFloatArray:
2979
+ UNREACHABLE();
2980
+ break;
2981
+ }
2526
2982
  }
2527
-
2528
- __ movb(Operand(external_pointer, key, times_1, 0), value);
2529
2983
  }
2530
2984
 
2531
2985
 
@@ -2575,7 +3029,9 @@ void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) {
2575
3029
  ASSERT(ToRegister(instr->key()).is(rcx));
2576
3030
  ASSERT(ToRegister(instr->value()).is(rax));
2577
3031
 
2578
- Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
3032
+ Handle<Code> ic = info_->is_strict()
3033
+ ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
3034
+ : isolate()->builtins()->KeyedStoreIC_Initialize();
2579
3035
  CallCode(ic, RelocInfo::CODE_TARGET, instr);
2580
3036
  }
2581
3037
 
@@ -2720,6 +3176,56 @@ void LCodeGen::DoDeferredStringCharCodeAt(LStringCharCodeAt* instr) {
2720
3176
  }
2721
3177
 
2722
3178
 
3179
+ void LCodeGen::DoStringCharFromCode(LStringCharFromCode* instr) {
3180
+ class DeferredStringCharFromCode: public LDeferredCode {
3181
+ public:
3182
+ DeferredStringCharFromCode(LCodeGen* codegen, LStringCharFromCode* instr)
3183
+ : LDeferredCode(codegen), instr_(instr) { }
3184
+ virtual void Generate() { codegen()->DoDeferredStringCharFromCode(instr_); }
3185
+ private:
3186
+ LStringCharFromCode* instr_;
3187
+ };
3188
+
3189
+ DeferredStringCharFromCode* deferred =
3190
+ new DeferredStringCharFromCode(this, instr);
3191
+
3192
+ ASSERT(instr->hydrogen()->value()->representation().IsInteger32());
3193
+ Register char_code = ToRegister(instr->char_code());
3194
+ Register result = ToRegister(instr->result());
3195
+ ASSERT(!char_code.is(result));
3196
+
3197
+ __ cmpl(char_code, Immediate(String::kMaxAsciiCharCode));
3198
+ __ j(above, deferred->entry());
3199
+ __ LoadRoot(result, Heap::kSingleCharacterStringCacheRootIndex);
3200
+ __ movq(result, FieldOperand(result,
3201
+ char_code, times_pointer_size,
3202
+ FixedArray::kHeaderSize));
3203
+ __ CompareRoot(result, Heap::kUndefinedValueRootIndex);
3204
+ __ j(equal, deferred->entry());
3205
+ __ bind(deferred->exit());
3206
+ }
3207
+
3208
+
3209
+ void LCodeGen::DoDeferredStringCharFromCode(LStringCharFromCode* instr) {
3210
+ Register char_code = ToRegister(instr->char_code());
3211
+ Register result = ToRegister(instr->result());
3212
+
3213
+ // TODO(3095996): Get rid of this. For now, we need to make the
3214
+ // result register contain a valid pointer because it is already
3215
+ // contained in the register pointer map.
3216
+ __ Set(result, 0);
3217
+
3218
+ __ PushSafepointRegisters();
3219
+ __ Integer32ToSmi(char_code, char_code);
3220
+ __ push(char_code);
3221
+ __ CallRuntimeSaveDoubles(Runtime::kCharFromCode);
3222
+ RecordSafepointWithRegisters(
3223
+ instr->pointer_map(), 1, Safepoint::kNoDeoptimizationIndex);
3224
+ __ StoreToSafepointRegisterSlot(result, rax);
3225
+ __ PopSafepointRegisters();
3226
+ }
3227
+
3228
+
2723
3229
  void LCodeGen::DoStringLength(LStringLength* instr) {
2724
3230
  Register string = ToRegister(instr->string());
2725
3231
  Register result = ToRegister(instr->result());
@@ -2970,11 +3476,14 @@ void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
2970
3476
 
2971
3477
  void LCodeGen::DoCheckSmi(LCheckSmi* instr) {
2972
3478
  LOperand* input = instr->InputAt(0);
2973
- ASSERT(input->IsRegister());
2974
3479
  Condition cc = masm()->CheckSmi(ToRegister(input));
2975
- if (instr->condition() != equal) {
2976
- cc = NegateCondition(cc);
2977
- }
3480
+ DeoptimizeIf(NegateCondition(cc), instr->environment());
3481
+ }
3482
+
3483
+
3484
+ void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) {
3485
+ LOperand* input = instr->InputAt(0);
3486
+ Condition cc = masm()->CheckSmi(ToRegister(input));
2978
3487
  DeoptimizeIf(cc, instr->environment());
2979
3488
  }
2980
3489
 
@@ -3029,9 +3538,9 @@ void LCodeGen::DoCheckMap(LCheckMap* instr) {
3029
3538
 
3030
3539
 
3031
3540
  void LCodeGen::LoadHeapObject(Register result, Handle<HeapObject> object) {
3032
- if (Heap::InNewSpace(*object)) {
3541
+ if (heap()->InNewSpace(*object)) {
3033
3542
  Handle<JSGlobalPropertyCell> cell =
3034
- Factory::NewJSGlobalPropertyCell(object);
3543
+ factory()->NewJSGlobalPropertyCell(object);
3035
3544
  __ movq(result, cell, RelocInfo::GLOBAL_PROPERTY_CELL);
3036
3545
  __ movq(result, Operand(result, 0));
3037
3546
  } else {
@@ -3112,6 +3621,13 @@ void LCodeGen::DoObjectLiteral(LObjectLiteral* instr) {
3112
3621
  }
3113
3622
 
3114
3623
 
3624
+ void LCodeGen::DoToFastProperties(LToFastProperties* instr) {
3625
+ ASSERT(ToRegister(instr->InputAt(0)).is(rax));
3626
+ __ push(rax);
3627
+ CallRuntime(Runtime::kToFastProperties, 1, instr);
3628
+ }
3629
+
3630
+
3115
3631
  void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) {
3116
3632
  NearLabel materialized;
3117
3633
  // Registers will be used as follows:
@@ -3169,14 +3685,17 @@ void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) {
3169
3685
  // space for nested functions that don't need literals cloning.
3170
3686
  Handle<SharedFunctionInfo> shared_info = instr->shared_info();
3171
3687
  bool pretenure = instr->hydrogen()->pretenure();
3172
- if (shared_info->num_literals() == 0 && !pretenure) {
3173
- FastNewClosureStub stub;
3688
+ if (!pretenure && shared_info->num_literals() == 0) {
3689
+ FastNewClosureStub stub(
3690
+ shared_info->strict_mode() ? kStrictMode : kNonStrictMode);
3174
3691
  __ Push(shared_info);
3175
3692
  CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
3176
3693
  } else {
3177
3694
  __ push(rsi);
3178
3695
  __ Push(shared_info);
3179
- __ Push(pretenure ? Factory::true_value() : Factory::false_value());
3696
+ __ PushRoot(pretenure ?
3697
+ Heap::kTrueValueRootIndex :
3698
+ Heap::kFalseValueRootIndex);
3180
3699
  CallRuntime(Runtime::kNewClosure, 3, instr);
3181
3700
  }
3182
3701
  }
@@ -3257,28 +3776,28 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label,
3257
3776
  Register input,
3258
3777
  Handle<String> type_name) {
3259
3778
  Condition final_branch_condition = no_condition;
3260
- if (type_name->Equals(Heap::number_symbol())) {
3779
+ if (type_name->Equals(heap()->number_symbol())) {
3261
3780
  __ JumpIfSmi(input, true_label);
3262
- __ Cmp(FieldOperand(input, HeapObject::kMapOffset),
3263
- Factory::heap_number_map());
3781
+ __ CompareRoot(FieldOperand(input, HeapObject::kMapOffset),
3782
+ Heap::kHeapNumberMapRootIndex);
3783
+
3264
3784
  final_branch_condition = equal;
3265
3785
 
3266
- } else if (type_name->Equals(Heap::string_symbol())) {
3786
+ } else if (type_name->Equals(heap()->string_symbol())) {
3267
3787
  __ JumpIfSmi(input, false_label);
3268
- __ movq(input, FieldOperand(input, HeapObject::kMapOffset));
3788
+ __ CmpObjectType(input, FIRST_NONSTRING_TYPE, input);
3789
+ __ j(above_equal, false_label);
3269
3790
  __ testb(FieldOperand(input, Map::kBitFieldOffset),
3270
3791
  Immediate(1 << Map::kIsUndetectable));
3271
- __ j(not_zero, false_label);
3272
- __ CmpInstanceType(input, FIRST_NONSTRING_TYPE);
3273
- final_branch_condition = below;
3792
+ final_branch_condition = zero;
3274
3793
 
3275
- } else if (type_name->Equals(Heap::boolean_symbol())) {
3794
+ } else if (type_name->Equals(heap()->boolean_symbol())) {
3276
3795
  __ CompareRoot(input, Heap::kTrueValueRootIndex);
3277
3796
  __ j(equal, true_label);
3278
3797
  __ CompareRoot(input, Heap::kFalseValueRootIndex);
3279
3798
  final_branch_condition = equal;
3280
3799
 
3281
- } else if (type_name->Equals(Heap::undefined_symbol())) {
3800
+ } else if (type_name->Equals(heap()->undefined_symbol())) {
3282
3801
  __ CompareRoot(input, Heap::kUndefinedValueRootIndex);
3283
3802
  __ j(equal, true_label);
3284
3803
  __ JumpIfSmi(input, false_label);
@@ -3288,24 +3807,23 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label,
3288
3807
  Immediate(1 << Map::kIsUndetectable));
3289
3808
  final_branch_condition = not_zero;
3290
3809
 
3291
- } else if (type_name->Equals(Heap::function_symbol())) {
3810
+ } else if (type_name->Equals(heap()->function_symbol())) {
3292
3811
  __ JumpIfSmi(input, false_label);
3293
3812
  __ CmpObjectType(input, FIRST_FUNCTION_CLASS_TYPE, input);
3294
3813
  final_branch_condition = above_equal;
3295
3814
 
3296
- } else if (type_name->Equals(Heap::object_symbol())) {
3815
+ } else if (type_name->Equals(heap()->object_symbol())) {
3297
3816
  __ JumpIfSmi(input, false_label);
3298
- __ Cmp(input, Factory::null_value());
3817
+ __ CompareRoot(input, Heap::kNullValueRootIndex);
3299
3818
  __ j(equal, true_label);
3819
+ __ CmpObjectType(input, FIRST_JS_OBJECT_TYPE, input);
3820
+ __ j(below, false_label);
3821
+ __ CmpInstanceType(input, FIRST_FUNCTION_CLASS_TYPE);
3822
+ __ j(above_equal, false_label);
3300
3823
  // Check for undetectable objects => false.
3301
3824
  __ testb(FieldOperand(input, Map::kBitFieldOffset),
3302
3825
  Immediate(1 << Map::kIsUndetectable));
3303
- __ j(not_zero, false_label);
3304
- // Check for JS objects that are not RegExp or Function => true.
3305
- __ CmpInstanceType(input, FIRST_JS_OBJECT_TYPE);
3306
- __ j(below, false_label);
3307
- __ CmpInstanceType(input, FIRST_FUNCTION_CLASS_TYPE);
3308
- final_branch_condition = below_equal;
3826
+ final_branch_condition = zero;
3309
3827
 
3310
3828
  } else {
3311
3829
  final_branch_condition = never;
@@ -3352,15 +3870,15 @@ void LCodeGen::EmitIsConstructCall(Register temp) {
3352
3870
 
3353
3871
  // Skip the arguments adaptor frame if it exists.
3354
3872
  NearLabel check_frame_marker;
3355
- __ SmiCompare(Operand(temp, StandardFrameConstants::kContextOffset),
3356
- Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
3873
+ __ Cmp(Operand(temp, StandardFrameConstants::kContextOffset),
3874
+ Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
3357
3875
  __ j(not_equal, &check_frame_marker);
3358
3876
  __ movq(temp, Operand(rax, StandardFrameConstants::kCallerFPOffset));
3359
3877
 
3360
3878
  // Check the marker in the calling frame.
3361
3879
  __ bind(&check_frame_marker);
3362
- __ SmiCompare(Operand(temp, StandardFrameConstants::kMarkerOffset),
3363
- Smi::FromInt(StackFrame::CONSTRUCT));
3880
+ __ Cmp(Operand(temp, StandardFrameConstants::kMarkerOffset),
3881
+ Smi::FromInt(StackFrame::CONSTRUCT));
3364
3882
  }
3365
3883
 
3366
3884
 
@@ -3402,8 +3920,7 @@ void LCodeGen::DoDeleteProperty(LDeleteProperty* instr) {
3402
3920
  // builtin)
3403
3921
  SafepointGenerator safepoint_generator(this,
3404
3922
  pointers,
3405
- env->deoptimization_index(),
3406
- true);
3923
+ env->deoptimization_index());
3407
3924
  __ Push(Smi::FromInt(strict_mode_flag()));
3408
3925
  __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION, &safepoint_generator);
3409
3926
  }