libv8 3.11.8.17 → 3.16.14.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (754) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -2
  3. data/Gemfile +1 -1
  4. data/Rakefile +6 -7
  5. data/lib/libv8/version.rb +1 -1
  6. data/vendor/v8/.gitignore +24 -3
  7. data/vendor/v8/AUTHORS +7 -0
  8. data/vendor/v8/ChangeLog +839 -0
  9. data/vendor/v8/DEPS +1 -1
  10. data/vendor/v8/Makefile.android +92 -0
  11. data/vendor/v8/OWNERS +11 -0
  12. data/vendor/v8/PRESUBMIT.py +71 -0
  13. data/vendor/v8/SConstruct +34 -39
  14. data/vendor/v8/build/android.gypi +56 -37
  15. data/vendor/v8/build/common.gypi +112 -30
  16. data/vendor/v8/build/gyp_v8 +1 -1
  17. data/vendor/v8/build/standalone.gypi +15 -11
  18. data/vendor/v8/include/v8-debug.h +9 -1
  19. data/vendor/v8/include/v8-preparser.h +4 -3
  20. data/vendor/v8/include/v8-profiler.h +25 -25
  21. data/vendor/v8/include/v8-testing.h +4 -3
  22. data/vendor/v8/include/v8.h +994 -540
  23. data/vendor/v8/preparser/preparser-process.cc +3 -3
  24. data/vendor/v8/samples/lineprocessor.cc +20 -27
  25. data/vendor/v8/samples/process.cc +18 -14
  26. data/vendor/v8/samples/shell.cc +16 -15
  27. data/vendor/v8/src/SConscript +15 -14
  28. data/vendor/v8/src/accessors.cc +169 -77
  29. data/vendor/v8/src/accessors.h +4 -0
  30. data/vendor/v8/src/allocation-inl.h +2 -2
  31. data/vendor/v8/src/allocation.h +7 -7
  32. data/vendor/v8/src/api.cc +810 -497
  33. data/vendor/v8/src/api.h +85 -60
  34. data/vendor/v8/src/arm/assembler-arm-inl.h +179 -22
  35. data/vendor/v8/src/arm/assembler-arm.cc +633 -264
  36. data/vendor/v8/src/arm/assembler-arm.h +264 -197
  37. data/vendor/v8/src/arm/builtins-arm.cc +117 -27
  38. data/vendor/v8/src/arm/code-stubs-arm.cc +1241 -700
  39. data/vendor/v8/src/arm/code-stubs-arm.h +35 -138
  40. data/vendor/v8/src/arm/codegen-arm.cc +285 -16
  41. data/vendor/v8/src/arm/codegen-arm.h +22 -0
  42. data/vendor/v8/src/arm/constants-arm.cc +5 -3
  43. data/vendor/v8/src/arm/constants-arm.h +24 -11
  44. data/vendor/v8/src/arm/debug-arm.cc +3 -3
  45. data/vendor/v8/src/arm/deoptimizer-arm.cc +382 -92
  46. data/vendor/v8/src/arm/disasm-arm.cc +61 -12
  47. data/vendor/v8/src/arm/frames-arm.h +0 -14
  48. data/vendor/v8/src/arm/full-codegen-arm.cc +332 -304
  49. data/vendor/v8/src/arm/ic-arm.cc +180 -259
  50. data/vendor/v8/src/arm/lithium-arm.cc +364 -316
  51. data/vendor/v8/src/arm/lithium-arm.h +512 -275
  52. data/vendor/v8/src/arm/lithium-codegen-arm.cc +1768 -809
  53. data/vendor/v8/src/arm/lithium-codegen-arm.h +97 -35
  54. data/vendor/v8/src/arm/lithium-gap-resolver-arm.cc +12 -5
  55. data/vendor/v8/src/arm/macro-assembler-arm.cc +439 -228
  56. data/vendor/v8/src/arm/macro-assembler-arm.h +116 -70
  57. data/vendor/v8/src/arm/regexp-macro-assembler-arm.cc +54 -44
  58. data/vendor/v8/src/arm/regexp-macro-assembler-arm.h +3 -10
  59. data/vendor/v8/src/arm/simulator-arm.cc +272 -238
  60. data/vendor/v8/src/arm/simulator-arm.h +38 -8
  61. data/vendor/v8/src/arm/stub-cache-arm.cc +522 -895
  62. data/vendor/v8/src/array.js +101 -70
  63. data/vendor/v8/src/assembler.cc +270 -19
  64. data/vendor/v8/src/assembler.h +110 -15
  65. data/vendor/v8/src/ast.cc +79 -69
  66. data/vendor/v8/src/ast.h +255 -301
  67. data/vendor/v8/src/atomicops.h +7 -1
  68. data/vendor/v8/src/atomicops_internals_tsan.h +335 -0
  69. data/vendor/v8/src/bootstrapper.cc +481 -418
  70. data/vendor/v8/src/bootstrapper.h +4 -4
  71. data/vendor/v8/src/builtins.cc +498 -311
  72. data/vendor/v8/src/builtins.h +75 -47
  73. data/vendor/v8/src/checks.cc +2 -1
  74. data/vendor/v8/src/checks.h +8 -0
  75. data/vendor/v8/src/code-stubs-hydrogen.cc +253 -0
  76. data/vendor/v8/src/code-stubs.cc +249 -84
  77. data/vendor/v8/src/code-stubs.h +501 -169
  78. data/vendor/v8/src/codegen.cc +36 -18
  79. data/vendor/v8/src/codegen.h +25 -3
  80. data/vendor/v8/src/collection.js +54 -17
  81. data/vendor/v8/src/compilation-cache.cc +24 -16
  82. data/vendor/v8/src/compilation-cache.h +15 -6
  83. data/vendor/v8/src/compiler.cc +497 -195
  84. data/vendor/v8/src/compiler.h +246 -38
  85. data/vendor/v8/src/contexts.cc +64 -24
  86. data/vendor/v8/src/contexts.h +60 -29
  87. data/vendor/v8/src/conversions-inl.h +24 -14
  88. data/vendor/v8/src/conversions.h +7 -4
  89. data/vendor/v8/src/counters.cc +21 -12
  90. data/vendor/v8/src/counters.h +44 -16
  91. data/vendor/v8/src/cpu-profiler.h +1 -1
  92. data/vendor/v8/src/d8-debug.cc +2 -2
  93. data/vendor/v8/src/d8-readline.cc +13 -2
  94. data/vendor/v8/src/d8.cc +681 -273
  95. data/vendor/v8/src/d8.gyp +4 -4
  96. data/vendor/v8/src/d8.h +38 -18
  97. data/vendor/v8/src/d8.js +0 -617
  98. data/vendor/v8/src/data-flow.h +55 -0
  99. data/vendor/v8/src/date.js +1 -42
  100. data/vendor/v8/src/dateparser-inl.h +5 -1
  101. data/vendor/v8/src/debug-agent.cc +10 -15
  102. data/vendor/v8/src/debug-debugger.js +147 -149
  103. data/vendor/v8/src/debug.cc +323 -164
  104. data/vendor/v8/src/debug.h +26 -14
  105. data/vendor/v8/src/deoptimizer.cc +765 -290
  106. data/vendor/v8/src/deoptimizer.h +130 -28
  107. data/vendor/v8/src/disassembler.cc +10 -4
  108. data/vendor/v8/src/elements-kind.cc +7 -2
  109. data/vendor/v8/src/elements-kind.h +19 -0
  110. data/vendor/v8/src/elements.cc +607 -285
  111. data/vendor/v8/src/elements.h +36 -13
  112. data/vendor/v8/src/execution.cc +52 -31
  113. data/vendor/v8/src/execution.h +4 -4
  114. data/vendor/v8/src/extensions/externalize-string-extension.cc +5 -4
  115. data/vendor/v8/src/extensions/gc-extension.cc +5 -1
  116. data/vendor/v8/src/extensions/statistics-extension.cc +153 -0
  117. data/vendor/v8/src/{inspector.h → extensions/statistics-extension.h} +12 -23
  118. data/vendor/v8/src/factory.cc +101 -134
  119. data/vendor/v8/src/factory.h +36 -31
  120. data/vendor/v8/src/flag-definitions.h +102 -25
  121. data/vendor/v8/src/flags.cc +9 -5
  122. data/vendor/v8/src/frames-inl.h +10 -0
  123. data/vendor/v8/src/frames.cc +116 -26
  124. data/vendor/v8/src/frames.h +96 -12
  125. data/vendor/v8/src/full-codegen.cc +219 -74
  126. data/vendor/v8/src/full-codegen.h +63 -21
  127. data/vendor/v8/src/func-name-inferrer.cc +8 -7
  128. data/vendor/v8/src/func-name-inferrer.h +5 -3
  129. data/vendor/v8/src/gdb-jit.cc +71 -57
  130. data/vendor/v8/src/global-handles.cc +230 -101
  131. data/vendor/v8/src/global-handles.h +26 -27
  132. data/vendor/v8/src/globals.h +17 -19
  133. data/vendor/v8/src/handles-inl.h +59 -12
  134. data/vendor/v8/src/handles.cc +180 -200
  135. data/vendor/v8/src/handles.h +80 -11
  136. data/vendor/v8/src/hashmap.h +60 -40
  137. data/vendor/v8/src/heap-inl.h +107 -45
  138. data/vendor/v8/src/heap-profiler.cc +38 -19
  139. data/vendor/v8/src/heap-profiler.h +24 -14
  140. data/vendor/v8/src/heap.cc +1123 -738
  141. data/vendor/v8/src/heap.h +385 -146
  142. data/vendor/v8/src/hydrogen-instructions.cc +700 -217
  143. data/vendor/v8/src/hydrogen-instructions.h +1158 -472
  144. data/vendor/v8/src/hydrogen.cc +3319 -1662
  145. data/vendor/v8/src/hydrogen.h +411 -170
  146. data/vendor/v8/src/ia32/assembler-ia32-inl.h +46 -16
  147. data/vendor/v8/src/ia32/assembler-ia32.cc +131 -61
  148. data/vendor/v8/src/ia32/assembler-ia32.h +115 -57
  149. data/vendor/v8/src/ia32/builtins-ia32.cc +99 -5
  150. data/vendor/v8/src/ia32/code-stubs-ia32.cc +787 -495
  151. data/vendor/v8/src/ia32/code-stubs-ia32.h +10 -100
  152. data/vendor/v8/src/ia32/codegen-ia32.cc +227 -23
  153. data/vendor/v8/src/ia32/codegen-ia32.h +14 -0
  154. data/vendor/v8/src/ia32/deoptimizer-ia32.cc +428 -87
  155. data/vendor/v8/src/ia32/disasm-ia32.cc +28 -1
  156. data/vendor/v8/src/ia32/frames-ia32.h +6 -16
  157. data/vendor/v8/src/ia32/full-codegen-ia32.cc +280 -272
  158. data/vendor/v8/src/ia32/ic-ia32.cc +150 -250
  159. data/vendor/v8/src/ia32/lithium-codegen-ia32.cc +1600 -517
  160. data/vendor/v8/src/ia32/lithium-codegen-ia32.h +90 -24
  161. data/vendor/v8/src/ia32/lithium-gap-resolver-ia32.cc +10 -6
  162. data/vendor/v8/src/ia32/lithium-gap-resolver-ia32.h +2 -2
  163. data/vendor/v8/src/ia32/lithium-ia32.cc +405 -302
  164. data/vendor/v8/src/ia32/lithium-ia32.h +526 -271
  165. data/vendor/v8/src/ia32/macro-assembler-ia32.cc +378 -119
  166. data/vendor/v8/src/ia32/macro-assembler-ia32.h +62 -28
  167. data/vendor/v8/src/ia32/regexp-macro-assembler-ia32.cc +43 -30
  168. data/vendor/v8/src/ia32/regexp-macro-assembler-ia32.h +2 -10
  169. data/vendor/v8/src/ia32/stub-cache-ia32.cc +492 -678
  170. data/vendor/v8/src/ic-inl.h +9 -4
  171. data/vendor/v8/src/ic.cc +836 -923
  172. data/vendor/v8/src/ic.h +228 -247
  173. data/vendor/v8/src/incremental-marking-inl.h +26 -30
  174. data/vendor/v8/src/incremental-marking.cc +276 -248
  175. data/vendor/v8/src/incremental-marking.h +29 -37
  176. data/vendor/v8/src/interface.cc +34 -25
  177. data/vendor/v8/src/interface.h +69 -25
  178. data/vendor/v8/src/interpreter-irregexp.cc +2 -2
  179. data/vendor/v8/src/isolate.cc +382 -76
  180. data/vendor/v8/src/isolate.h +109 -56
  181. data/vendor/v8/src/json-parser.h +217 -104
  182. data/vendor/v8/src/json-stringifier.h +745 -0
  183. data/vendor/v8/src/json.js +10 -132
  184. data/vendor/v8/src/jsregexp-inl.h +106 -0
  185. data/vendor/v8/src/jsregexp.cc +517 -285
  186. data/vendor/v8/src/jsregexp.h +145 -117
  187. data/vendor/v8/src/list-inl.h +35 -22
  188. data/vendor/v8/src/list.h +46 -19
  189. data/vendor/v8/src/lithium-allocator-inl.h +22 -2
  190. data/vendor/v8/src/lithium-allocator.cc +85 -70
  191. data/vendor/v8/src/lithium-allocator.h +21 -39
  192. data/vendor/v8/src/lithium.cc +259 -5
  193. data/vendor/v8/src/lithium.h +131 -32
  194. data/vendor/v8/src/liveedit-debugger.js +52 -3
  195. data/vendor/v8/src/liveedit.cc +393 -113
  196. data/vendor/v8/src/liveedit.h +7 -3
  197. data/vendor/v8/src/log-utils.cc +4 -2
  198. data/vendor/v8/src/log.cc +170 -140
  199. data/vendor/v8/src/log.h +62 -11
  200. data/vendor/v8/src/macro-assembler.h +17 -0
  201. data/vendor/v8/src/macros.py +2 -0
  202. data/vendor/v8/src/mark-compact-inl.h +3 -23
  203. data/vendor/v8/src/mark-compact.cc +801 -830
  204. data/vendor/v8/src/mark-compact.h +154 -47
  205. data/vendor/v8/src/marking-thread.cc +85 -0
  206. data/vendor/v8/src/{inspector.cc → marking-thread.h} +32 -24
  207. data/vendor/v8/src/math.js +12 -18
  208. data/vendor/v8/src/messages.cc +18 -8
  209. data/vendor/v8/src/messages.js +314 -261
  210. data/vendor/v8/src/mips/assembler-mips-inl.h +58 -6
  211. data/vendor/v8/src/mips/assembler-mips.cc +92 -75
  212. data/vendor/v8/src/mips/assembler-mips.h +54 -60
  213. data/vendor/v8/src/mips/builtins-mips.cc +116 -17
  214. data/vendor/v8/src/mips/code-stubs-mips.cc +919 -556
  215. data/vendor/v8/src/mips/code-stubs-mips.h +22 -131
  216. data/vendor/v8/src/mips/codegen-mips.cc +281 -6
  217. data/vendor/v8/src/mips/codegen-mips.h +22 -0
  218. data/vendor/v8/src/mips/constants-mips.cc +2 -0
  219. data/vendor/v8/src/mips/constants-mips.h +12 -2
  220. data/vendor/v8/src/mips/deoptimizer-mips.cc +286 -50
  221. data/vendor/v8/src/mips/disasm-mips.cc +13 -0
  222. data/vendor/v8/src/mips/full-codegen-mips.cc +297 -284
  223. data/vendor/v8/src/mips/ic-mips.cc +182 -263
  224. data/vendor/v8/src/mips/lithium-codegen-mips.cc +1208 -556
  225. data/vendor/v8/src/mips/lithium-codegen-mips.h +72 -19
  226. data/vendor/v8/src/mips/lithium-gap-resolver-mips.cc +9 -2
  227. data/vendor/v8/src/mips/lithium-mips.cc +290 -302
  228. data/vendor/v8/src/mips/lithium-mips.h +463 -266
  229. data/vendor/v8/src/mips/macro-assembler-mips.cc +208 -115
  230. data/vendor/v8/src/mips/macro-assembler-mips.h +67 -24
  231. data/vendor/v8/src/mips/regexp-macro-assembler-mips.cc +40 -25
  232. data/vendor/v8/src/mips/regexp-macro-assembler-mips.h +3 -9
  233. data/vendor/v8/src/mips/simulator-mips.cc +112 -40
  234. data/vendor/v8/src/mips/simulator-mips.h +5 -0
  235. data/vendor/v8/src/mips/stub-cache-mips.cc +502 -884
  236. data/vendor/v8/src/mirror-debugger.js +157 -30
  237. data/vendor/v8/src/mksnapshot.cc +88 -14
  238. data/vendor/v8/src/object-observe.js +235 -0
  239. data/vendor/v8/src/objects-debug.cc +178 -176
  240. data/vendor/v8/src/objects-inl.h +1333 -486
  241. data/vendor/v8/src/objects-printer.cc +125 -43
  242. data/vendor/v8/src/objects-visiting-inl.h +578 -6
  243. data/vendor/v8/src/objects-visiting.cc +2 -2
  244. data/vendor/v8/src/objects-visiting.h +172 -79
  245. data/vendor/v8/src/objects.cc +3533 -2885
  246. data/vendor/v8/src/objects.h +1352 -1131
  247. data/vendor/v8/src/optimizing-compiler-thread.cc +152 -0
  248. data/vendor/v8/src/optimizing-compiler-thread.h +111 -0
  249. data/vendor/v8/src/parser.cc +390 -500
  250. data/vendor/v8/src/parser.h +45 -33
  251. data/vendor/v8/src/platform-cygwin.cc +10 -21
  252. data/vendor/v8/src/platform-freebsd.cc +36 -41
  253. data/vendor/v8/src/platform-linux.cc +160 -124
  254. data/vendor/v8/src/platform-macos.cc +30 -27
  255. data/vendor/v8/src/platform-nullos.cc +17 -1
  256. data/vendor/v8/src/platform-openbsd.cc +19 -50
  257. data/vendor/v8/src/platform-posix.cc +14 -0
  258. data/vendor/v8/src/platform-solaris.cc +20 -53
  259. data/vendor/v8/src/platform-win32.cc +49 -26
  260. data/vendor/v8/src/platform.h +40 -1
  261. data/vendor/v8/src/preparser.cc +8 -5
  262. data/vendor/v8/src/preparser.h +2 -2
  263. data/vendor/v8/src/prettyprinter.cc +16 -0
  264. data/vendor/v8/src/prettyprinter.h +2 -0
  265. data/vendor/v8/src/profile-generator-inl.h +1 -0
  266. data/vendor/v8/src/profile-generator.cc +209 -147
  267. data/vendor/v8/src/profile-generator.h +15 -12
  268. data/vendor/v8/src/property-details.h +46 -31
  269. data/vendor/v8/src/property.cc +27 -46
  270. data/vendor/v8/src/property.h +163 -83
  271. data/vendor/v8/src/proxy.js +7 -2
  272. data/vendor/v8/src/regexp-macro-assembler-irregexp.cc +4 -13
  273. data/vendor/v8/src/regexp-macro-assembler-irregexp.h +1 -2
  274. data/vendor/v8/src/regexp-macro-assembler-tracer.cc +1 -11
  275. data/vendor/v8/src/regexp-macro-assembler-tracer.h +0 -1
  276. data/vendor/v8/src/regexp-macro-assembler.cc +31 -14
  277. data/vendor/v8/src/regexp-macro-assembler.h +14 -11
  278. data/vendor/v8/src/regexp-stack.cc +1 -0
  279. data/vendor/v8/src/regexp.js +9 -8
  280. data/vendor/v8/src/rewriter.cc +18 -7
  281. data/vendor/v8/src/runtime-profiler.cc +52 -43
  282. data/vendor/v8/src/runtime-profiler.h +0 -25
  283. data/vendor/v8/src/runtime.cc +2006 -2023
  284. data/vendor/v8/src/runtime.h +56 -49
  285. data/vendor/v8/src/safepoint-table.cc +12 -18
  286. data/vendor/v8/src/safepoint-table.h +11 -8
  287. data/vendor/v8/src/scanner.cc +1 -0
  288. data/vendor/v8/src/scanner.h +4 -10
  289. data/vendor/v8/src/scopeinfo.cc +35 -9
  290. data/vendor/v8/src/scopeinfo.h +64 -3
  291. data/vendor/v8/src/scopes.cc +251 -156
  292. data/vendor/v8/src/scopes.h +61 -27
  293. data/vendor/v8/src/serialize.cc +348 -396
  294. data/vendor/v8/src/serialize.h +125 -114
  295. data/vendor/v8/src/small-pointer-list.h +11 -11
  296. data/vendor/v8/src/{smart-array-pointer.h → smart-pointers.h} +64 -15
  297. data/vendor/v8/src/snapshot-common.cc +64 -15
  298. data/vendor/v8/src/snapshot-empty.cc +7 -1
  299. data/vendor/v8/src/snapshot.h +9 -2
  300. data/vendor/v8/src/spaces-inl.h +17 -0
  301. data/vendor/v8/src/spaces.cc +477 -183
  302. data/vendor/v8/src/spaces.h +238 -58
  303. data/vendor/v8/src/splay-tree-inl.h +8 -7
  304. data/vendor/v8/src/splay-tree.h +24 -10
  305. data/vendor/v8/src/store-buffer.cc +12 -5
  306. data/vendor/v8/src/store-buffer.h +2 -4
  307. data/vendor/v8/src/string-search.h +22 -6
  308. data/vendor/v8/src/string-stream.cc +11 -8
  309. data/vendor/v8/src/string.js +47 -15
  310. data/vendor/v8/src/stub-cache.cc +461 -224
  311. data/vendor/v8/src/stub-cache.h +164 -102
  312. data/vendor/v8/src/sweeper-thread.cc +105 -0
  313. data/vendor/v8/src/sweeper-thread.h +81 -0
  314. data/vendor/v8/src/token.h +1 -0
  315. data/vendor/v8/src/transitions-inl.h +220 -0
  316. data/vendor/v8/src/transitions.cc +160 -0
  317. data/vendor/v8/src/transitions.h +207 -0
  318. data/vendor/v8/src/type-info.cc +182 -181
  319. data/vendor/v8/src/type-info.h +31 -19
  320. data/vendor/v8/src/unicode-inl.h +62 -106
  321. data/vendor/v8/src/unicode.cc +57 -67
  322. data/vendor/v8/src/unicode.h +45 -91
  323. data/vendor/v8/src/uri.js +57 -29
  324. data/vendor/v8/src/utils.h +105 -5
  325. data/vendor/v8/src/v8-counters.cc +54 -11
  326. data/vendor/v8/src/v8-counters.h +134 -19
  327. data/vendor/v8/src/v8.cc +29 -29
  328. data/vendor/v8/src/v8.h +1 -0
  329. data/vendor/v8/src/v8conversions.cc +26 -22
  330. data/vendor/v8/src/v8globals.h +56 -43
  331. data/vendor/v8/src/v8natives.js +83 -30
  332. data/vendor/v8/src/v8threads.cc +42 -21
  333. data/vendor/v8/src/v8threads.h +4 -1
  334. data/vendor/v8/src/v8utils.cc +9 -93
  335. data/vendor/v8/src/v8utils.h +37 -33
  336. data/vendor/v8/src/variables.cc +6 -3
  337. data/vendor/v8/src/variables.h +6 -13
  338. data/vendor/v8/src/version.cc +2 -2
  339. data/vendor/v8/src/vm-state-inl.h +11 -0
  340. data/vendor/v8/src/x64/assembler-x64-inl.h +39 -8
  341. data/vendor/v8/src/x64/assembler-x64.cc +78 -64
  342. data/vendor/v8/src/x64/assembler-x64.h +38 -33
  343. data/vendor/v8/src/x64/builtins-x64.cc +105 -7
  344. data/vendor/v8/src/x64/code-stubs-x64.cc +790 -413
  345. data/vendor/v8/src/x64/code-stubs-x64.h +10 -106
  346. data/vendor/v8/src/x64/codegen-x64.cc +210 -8
  347. data/vendor/v8/src/x64/codegen-x64.h +20 -1
  348. data/vendor/v8/src/x64/deoptimizer-x64.cc +336 -75
  349. data/vendor/v8/src/x64/disasm-x64.cc +15 -0
  350. data/vendor/v8/src/x64/frames-x64.h +0 -14
  351. data/vendor/v8/src/x64/full-codegen-x64.cc +293 -270
  352. data/vendor/v8/src/x64/ic-x64.cc +153 -251
  353. data/vendor/v8/src/x64/lithium-codegen-x64.cc +1379 -531
  354. data/vendor/v8/src/x64/lithium-codegen-x64.h +67 -23
  355. data/vendor/v8/src/x64/lithium-gap-resolver-x64.cc +2 -2
  356. data/vendor/v8/src/x64/lithium-x64.cc +349 -289
  357. data/vendor/v8/src/x64/lithium-x64.h +460 -250
  358. data/vendor/v8/src/x64/macro-assembler-x64.cc +350 -177
  359. data/vendor/v8/src/x64/macro-assembler-x64.h +67 -49
  360. data/vendor/v8/src/x64/regexp-macro-assembler-x64.cc +46 -33
  361. data/vendor/v8/src/x64/regexp-macro-assembler-x64.h +2 -3
  362. data/vendor/v8/src/x64/stub-cache-x64.cc +484 -653
  363. data/vendor/v8/src/zone-inl.h +9 -27
  364. data/vendor/v8/src/zone.cc +5 -5
  365. data/vendor/v8/src/zone.h +53 -27
  366. data/vendor/v8/test/benchmarks/testcfg.py +5 -0
  367. data/vendor/v8/test/cctest/cctest.cc +4 -0
  368. data/vendor/v8/test/cctest/cctest.gyp +3 -1
  369. data/vendor/v8/test/cctest/cctest.h +57 -9
  370. data/vendor/v8/test/cctest/cctest.status +15 -15
  371. data/vendor/v8/test/cctest/test-accessors.cc +26 -0
  372. data/vendor/v8/test/cctest/test-alloc.cc +22 -30
  373. data/vendor/v8/test/cctest/test-api.cc +1943 -314
  374. data/vendor/v8/test/cctest/test-assembler-arm.cc +133 -13
  375. data/vendor/v8/test/cctest/test-assembler-ia32.cc +1 -1
  376. data/vendor/v8/test/cctest/test-assembler-mips.cc +12 -0
  377. data/vendor/v8/test/cctest/test-ast.cc +4 -2
  378. data/vendor/v8/test/cctest/test-compiler.cc +61 -29
  379. data/vendor/v8/test/cctest/test-dataflow.cc +2 -2
  380. data/vendor/v8/test/cctest/test-debug.cc +212 -33
  381. data/vendor/v8/test/cctest/test-decls.cc +257 -11
  382. data/vendor/v8/test/cctest/test-dictionary.cc +24 -10
  383. data/vendor/v8/test/cctest/test-disasm-arm.cc +118 -1
  384. data/vendor/v8/test/cctest/test-disasm-ia32.cc +3 -2
  385. data/vendor/v8/test/cctest/test-flags.cc +14 -1
  386. data/vendor/v8/test/cctest/test-func-name-inference.cc +7 -4
  387. data/vendor/v8/test/cctest/test-global-object.cc +51 -0
  388. data/vendor/v8/test/cctest/test-hashing.cc +32 -23
  389. data/vendor/v8/test/cctest/test-heap-profiler.cc +131 -77
  390. data/vendor/v8/test/cctest/test-heap.cc +1084 -143
  391. data/vendor/v8/test/cctest/test-list.cc +1 -1
  392. data/vendor/v8/test/cctest/test-liveedit.cc +3 -2
  393. data/vendor/v8/test/cctest/test-lockers.cc +12 -13
  394. data/vendor/v8/test/cctest/test-log.cc +10 -8
  395. data/vendor/v8/test/cctest/test-macro-assembler-x64.cc +2 -2
  396. data/vendor/v8/test/cctest/test-mark-compact.cc +44 -22
  397. data/vendor/v8/test/cctest/test-object-observe.cc +434 -0
  398. data/vendor/v8/test/cctest/test-parsing.cc +86 -39
  399. data/vendor/v8/test/cctest/test-platform-linux.cc +6 -0
  400. data/vendor/v8/test/cctest/test-platform-win32.cc +7 -0
  401. data/vendor/v8/test/cctest/test-random.cc +5 -4
  402. data/vendor/v8/test/cctest/test-regexp.cc +137 -101
  403. data/vendor/v8/test/cctest/test-serialize.cc +150 -230
  404. data/vendor/v8/test/cctest/test-sockets.cc +1 -1
  405. data/vendor/v8/test/cctest/test-spaces.cc +139 -0
  406. data/vendor/v8/test/cctest/test-strings.cc +736 -74
  407. data/vendor/v8/test/cctest/test-thread-termination.cc +10 -11
  408. data/vendor/v8/test/cctest/test-threads.cc +4 -4
  409. data/vendor/v8/test/cctest/test-utils.cc +16 -0
  410. data/vendor/v8/test/cctest/test-weakmaps.cc +7 -3
  411. data/vendor/v8/test/cctest/testcfg.py +64 -5
  412. data/vendor/v8/test/es5conform/testcfg.py +5 -0
  413. data/vendor/v8/test/message/message.status +1 -1
  414. data/vendor/v8/test/message/overwritten-builtins.out +3 -0
  415. data/vendor/v8/test/message/testcfg.py +89 -8
  416. data/vendor/v8/test/message/try-catch-finally-no-message.out +26 -26
  417. data/vendor/v8/test/mjsunit/accessor-map-sharing.js +18 -2
  418. data/vendor/v8/test/mjsunit/allocation-site-info.js +126 -0
  419. data/vendor/v8/test/mjsunit/array-bounds-check-removal.js +62 -1
  420. data/vendor/v8/test/mjsunit/array-iteration.js +1 -1
  421. data/vendor/v8/test/mjsunit/array-literal-transitions.js +2 -0
  422. data/vendor/v8/test/mjsunit/array-natives-elements.js +317 -0
  423. data/vendor/v8/test/mjsunit/array-reduce.js +8 -8
  424. data/vendor/v8/test/mjsunit/array-slice.js +12 -0
  425. data/vendor/v8/test/mjsunit/array-store-and-grow.js +4 -1
  426. data/vendor/v8/test/mjsunit/assert-opt-and-deopt.js +1 -1
  427. data/vendor/v8/test/mjsunit/bugs/bug-2337.js +53 -0
  428. data/vendor/v8/test/mjsunit/compare-known-objects-slow.js +69 -0
  429. data/vendor/v8/test/mjsunit/compiler/alloc-object-huge.js +3 -1
  430. data/vendor/v8/test/mjsunit/compiler/inline-accessors.js +368 -0
  431. data/vendor/v8/test/mjsunit/compiler/inline-arguments.js +87 -1
  432. data/vendor/v8/test/mjsunit/compiler/inline-closures.js +49 -0
  433. data/vendor/v8/test/mjsunit/compiler/inline-construct.js +55 -43
  434. data/vendor/v8/test/mjsunit/compiler/inline-literals.js +39 -0
  435. data/vendor/v8/test/mjsunit/compiler/multiply-add.js +69 -0
  436. data/vendor/v8/test/mjsunit/compiler/optimized-closures.js +57 -0
  437. data/vendor/v8/test/mjsunit/compiler/parallel-proto-change.js +44 -0
  438. data/vendor/v8/test/mjsunit/compiler/property-static.js +69 -0
  439. data/vendor/v8/test/mjsunit/compiler/proto-chain-constant.js +55 -0
  440. data/vendor/v8/test/mjsunit/compiler/proto-chain-load.js +44 -0
  441. data/vendor/v8/test/mjsunit/compiler/regress-gvn.js +3 -2
  442. data/vendor/v8/test/mjsunit/compiler/regress-or.js +6 -2
  443. data/vendor/v8/test/mjsunit/compiler/rotate.js +224 -0
  444. data/vendor/v8/test/mjsunit/compiler/uint32.js +173 -0
  445. data/vendor/v8/test/mjsunit/count-based-osr.js +2 -1
  446. data/vendor/v8/test/mjsunit/d8-os.js +3 -3
  447. data/vendor/v8/test/mjsunit/date-parse.js +3 -0
  448. data/vendor/v8/test/mjsunit/date.js +22 -0
  449. data/vendor/v8/test/mjsunit/debug-break-inline.js +1 -0
  450. data/vendor/v8/test/mjsunit/debug-evaluate-locals-optimized-double.js +22 -12
  451. data/vendor/v8/test/mjsunit/debug-evaluate-locals-optimized.js +21 -10
  452. data/vendor/v8/test/mjsunit/debug-liveedit-compile-error.js +60 -0
  453. data/vendor/v8/test/mjsunit/debug-liveedit-double-call.js +142 -0
  454. data/vendor/v8/test/mjsunit/debug-liveedit-literals.js +94 -0
  455. data/vendor/v8/test/mjsunit/debug-liveedit-restart-frame.js +153 -0
  456. data/vendor/v8/test/mjsunit/debug-multiple-breakpoints.js +1 -1
  457. data/vendor/v8/test/mjsunit/debug-script-breakpoints-closure.js +67 -0
  458. data/vendor/v8/test/mjsunit/debug-script-breakpoints-nested.js +82 -0
  459. data/vendor/v8/test/mjsunit/debug-script.js +4 -2
  460. data/vendor/v8/test/mjsunit/debug-set-variable-value.js +308 -0
  461. data/vendor/v8/test/mjsunit/debug-stepout-scope-part1.js +190 -0
  462. data/vendor/v8/test/mjsunit/debug-stepout-scope-part2.js +83 -0
  463. data/vendor/v8/test/mjsunit/debug-stepout-scope-part3.js +80 -0
  464. data/vendor/v8/test/mjsunit/debug-stepout-scope-part4.js +80 -0
  465. data/vendor/v8/test/mjsunit/debug-stepout-scope-part5.js +77 -0
  466. data/vendor/v8/test/mjsunit/debug-stepout-scope-part6.js +79 -0
  467. data/vendor/v8/test/mjsunit/debug-stepout-scope-part7.js +79 -0
  468. data/vendor/v8/test/mjsunit/{debug-stepout-scope.js → debug-stepout-scope-part8.js} +0 -189
  469. data/vendor/v8/test/mjsunit/delete-non-configurable.js +74 -0
  470. data/vendor/v8/test/mjsunit/deopt-minus-zero.js +56 -0
  471. data/vendor/v8/test/mjsunit/elements-kind.js +6 -4
  472. data/vendor/v8/test/mjsunit/elements-length-no-holey.js +33 -0
  473. data/vendor/v8/test/mjsunit/elements-transition-hoisting.js +46 -19
  474. data/vendor/v8/test/mjsunit/error-accessors.js +54 -0
  475. data/vendor/v8/test/mjsunit/error-constructors.js +1 -14
  476. data/vendor/v8/test/mjsunit/error-tostring.js +8 -0
  477. data/vendor/v8/test/mjsunit/eval-stack-trace.js +204 -0
  478. data/vendor/v8/test/mjsunit/external-array.js +364 -1
  479. data/vendor/v8/test/mjsunit/fast-array-length.js +37 -0
  480. data/vendor/v8/test/mjsunit/fast-non-keyed.js +113 -0
  481. data/vendor/v8/test/mjsunit/fast-prototype.js +117 -0
  482. data/vendor/v8/test/mjsunit/function-call.js +14 -18
  483. data/vendor/v8/test/mjsunit/fuzz-natives-part1.js +230 -0
  484. data/vendor/v8/test/mjsunit/fuzz-natives-part2.js +229 -0
  485. data/vendor/v8/test/mjsunit/fuzz-natives-part3.js +229 -0
  486. data/vendor/v8/test/mjsunit/{fuzz-natives.js → fuzz-natives-part4.js} +12 -2
  487. data/vendor/v8/test/mjsunit/generated-transition-stub.js +218 -0
  488. data/vendor/v8/test/mjsunit/greedy.js +1 -1
  489. data/vendor/v8/test/mjsunit/harmony/block-conflicts.js +2 -1
  490. data/vendor/v8/test/mjsunit/harmony/block-let-crankshaft.js +1 -1
  491. data/vendor/v8/test/mjsunit/harmony/collections.js +69 -11
  492. data/vendor/v8/test/mjsunit/harmony/debug-blockscopes.js +2 -2
  493. data/vendor/v8/test/mjsunit/harmony/module-linking.js +180 -3
  494. data/vendor/v8/test/mjsunit/harmony/module-parsing.js +31 -0
  495. data/vendor/v8/test/mjsunit/harmony/module-recompile.js +87 -0
  496. data/vendor/v8/test/mjsunit/harmony/module-resolution.js +15 -2
  497. data/vendor/v8/test/mjsunit/harmony/object-observe.js +1056 -0
  498. data/vendor/v8/test/mjsunit/harmony/proxies-json.js +178 -0
  499. data/vendor/v8/test/mjsunit/harmony/proxies.js +25 -10
  500. data/vendor/v8/test/mjsunit/json-parser-recursive.js +33 -0
  501. data/vendor/v8/test/mjsunit/json-stringify-recursive.js +52 -0
  502. data/vendor/v8/test/mjsunit/json.js +38 -2
  503. data/vendor/v8/test/mjsunit/json2.js +153 -0
  504. data/vendor/v8/test/mjsunit/limit-locals.js +5 -4
  505. data/vendor/v8/test/mjsunit/manual-parallel-recompile.js +79 -0
  506. data/vendor/v8/test/mjsunit/math-exp-precision.js +64 -0
  507. data/vendor/v8/test/mjsunit/math-floor-negative.js +59 -0
  508. data/vendor/v8/test/mjsunit/math-floor-of-div-minus-zero.js +41 -0
  509. data/vendor/v8/test/mjsunit/math-floor-of-div-nosudiv.js +288 -0
  510. data/vendor/v8/test/mjsunit/math-floor-of-div.js +81 -9
  511. data/vendor/v8/test/mjsunit/{math-floor.js → math-floor-part1.js} +1 -72
  512. data/vendor/v8/test/mjsunit/math-floor-part2.js +76 -0
  513. data/vendor/v8/test/mjsunit/math-floor-part3.js +78 -0
  514. data/vendor/v8/test/mjsunit/math-floor-part4.js +76 -0
  515. data/vendor/v8/test/mjsunit/mirror-object.js +43 -9
  516. data/vendor/v8/test/mjsunit/mjsunit.js +1 -1
  517. data/vendor/v8/test/mjsunit/mjsunit.status +52 -27
  518. data/vendor/v8/test/mjsunit/mul-exhaustive-part1.js +491 -0
  519. data/vendor/v8/test/mjsunit/mul-exhaustive-part10.js +470 -0
  520. data/vendor/v8/test/mjsunit/mul-exhaustive-part2.js +525 -0
  521. data/vendor/v8/test/mjsunit/mul-exhaustive-part3.js +532 -0
  522. data/vendor/v8/test/mjsunit/mul-exhaustive-part4.js +509 -0
  523. data/vendor/v8/test/mjsunit/mul-exhaustive-part5.js +505 -0
  524. data/vendor/v8/test/mjsunit/mul-exhaustive-part6.js +554 -0
  525. data/vendor/v8/test/mjsunit/mul-exhaustive-part7.js +497 -0
  526. data/vendor/v8/test/mjsunit/mul-exhaustive-part8.js +526 -0
  527. data/vendor/v8/test/mjsunit/mul-exhaustive-part9.js +533 -0
  528. data/vendor/v8/test/mjsunit/new-function.js +34 -0
  529. data/vendor/v8/test/mjsunit/numops-fuzz-part1.js +1172 -0
  530. data/vendor/v8/test/mjsunit/numops-fuzz-part2.js +1178 -0
  531. data/vendor/v8/test/mjsunit/numops-fuzz-part3.js +1178 -0
  532. data/vendor/v8/test/mjsunit/numops-fuzz-part4.js +1177 -0
  533. data/vendor/v8/test/mjsunit/object-define-property.js +107 -2
  534. data/vendor/v8/test/mjsunit/override-read-only-property.js +6 -4
  535. data/vendor/v8/test/mjsunit/packed-elements.js +2 -2
  536. data/vendor/v8/test/mjsunit/parse-int-float.js +4 -4
  537. data/vendor/v8/test/mjsunit/pixel-array-rounding.js +1 -1
  538. data/vendor/v8/test/mjsunit/readonly.js +228 -0
  539. data/vendor/v8/test/mjsunit/regexp-capture-3.js +16 -18
  540. data/vendor/v8/test/mjsunit/regexp-capture.js +2 -0
  541. data/vendor/v8/test/mjsunit/regexp-global.js +122 -0
  542. data/vendor/v8/test/mjsunit/regexp-results-cache.js +78 -0
  543. data/vendor/v8/test/mjsunit/regress/regress-1117.js +12 -3
  544. data/vendor/v8/test/mjsunit/regress/regress-1118.js +1 -1
  545. data/vendor/v8/test/mjsunit/regress/regress-115100.js +36 -0
  546. data/vendor/v8/test/mjsunit/regress/regress-1199637.js +1 -3
  547. data/vendor/v8/test/mjsunit/regress/regress-121407.js +1 -1
  548. data/vendor/v8/test/mjsunit/regress/regress-131923.js +30 -0
  549. data/vendor/v8/test/mjsunit/regress/regress-131994.js +70 -0
  550. data/vendor/v8/test/mjsunit/regress/regress-133211.js +35 -0
  551. data/vendor/v8/test/mjsunit/regress/regress-133211b.js +39 -0
  552. data/vendor/v8/test/mjsunit/regress/regress-136048.js +34 -0
  553. data/vendor/v8/test/mjsunit/regress/regress-137768.js +73 -0
  554. data/vendor/v8/test/mjsunit/regress/regress-143967.js +34 -0
  555. data/vendor/v8/test/mjsunit/regress/regress-145201.js +107 -0
  556. data/vendor/v8/test/mjsunit/regress/regress-147497.js +45 -0
  557. data/vendor/v8/test/mjsunit/regress/regress-148378.js +38 -0
  558. data/vendor/v8/test/mjsunit/regress/regress-1563.js +1 -1
  559. data/vendor/v8/test/mjsunit/regress/regress-1591.js +48 -0
  560. data/vendor/v8/test/mjsunit/regress/regress-164442.js +45 -0
  561. data/vendor/v8/test/mjsunit/regress/regress-165637.js +61 -0
  562. data/vendor/v8/test/mjsunit/regress/regress-166379.js +39 -0
  563. data/vendor/v8/test/mjsunit/regress/regress-166553.js +33 -0
  564. data/vendor/v8/test/mjsunit/regress/regress-1692.js +1 -1
  565. data/vendor/v8/test/mjsunit/regress/regress-171641.js +40 -0
  566. data/vendor/v8/test/mjsunit/regress/regress-1980.js +1 -1
  567. data/vendor/v8/test/mjsunit/regress/regress-2073.js +99 -0
  568. data/vendor/v8/test/mjsunit/regress/regress-2119.js +36 -0
  569. data/vendor/v8/test/mjsunit/regress/regress-2156.js +39 -0
  570. data/vendor/v8/test/mjsunit/regress/regress-2163.js +70 -0
  571. data/vendor/v8/test/mjsunit/regress/regress-2170.js +58 -0
  572. data/vendor/v8/test/mjsunit/regress/regress-2172.js +35 -0
  573. data/vendor/v8/test/mjsunit/regress/regress-2185-2.js +145 -0
  574. data/vendor/v8/test/mjsunit/regress/regress-2185.js +38 -0
  575. data/vendor/v8/test/mjsunit/regress/regress-2186.js +49 -0
  576. data/vendor/v8/test/mjsunit/regress/regress-2193.js +58 -0
  577. data/vendor/v8/test/mjsunit/regress/regress-2219.js +32 -0
  578. data/vendor/v8/test/mjsunit/regress/regress-2225.js +65 -0
  579. data/vendor/v8/test/mjsunit/regress/regress-2226.js +36 -0
  580. data/vendor/v8/test/mjsunit/regress/regress-2234.js +41 -0
  581. data/vendor/v8/test/mjsunit/regress/regress-2243.js +31 -0
  582. data/vendor/v8/test/mjsunit/regress/regress-2249.js +33 -0
  583. data/vendor/v8/test/mjsunit/regress/regress-2250.js +68 -0
  584. data/vendor/v8/test/mjsunit/regress/regress-2261.js +113 -0
  585. data/vendor/v8/test/mjsunit/regress/regress-2263.js +30 -0
  586. data/vendor/v8/test/mjsunit/regress/regress-2284.js +32 -0
  587. data/vendor/v8/test/mjsunit/regress/regress-2285.js +32 -0
  588. data/vendor/v8/test/mjsunit/regress/regress-2286.js +32 -0
  589. data/vendor/v8/test/mjsunit/regress/regress-2289.js +34 -0
  590. data/vendor/v8/test/mjsunit/regress/regress-2291.js +36 -0
  591. data/vendor/v8/test/mjsunit/regress/regress-2294.js +70 -0
  592. data/vendor/v8/test/mjsunit/regress/regress-2296.js +40 -0
  593. data/vendor/v8/test/mjsunit/regress/regress-2315.js +40 -0
  594. data/vendor/v8/test/mjsunit/regress/regress-2318.js +66 -0
  595. data/vendor/v8/test/mjsunit/regress/regress-2322.js +36 -0
  596. data/vendor/v8/test/mjsunit/regress/regress-2326.js +54 -0
  597. data/vendor/v8/test/mjsunit/regress/regress-2336.js +53 -0
  598. data/vendor/v8/test/mjsunit/regress/regress-2339.js +59 -0
  599. data/vendor/v8/test/mjsunit/regress/regress-2346.js +123 -0
  600. data/vendor/v8/test/mjsunit/regress/regress-2373.js +29 -0
  601. data/vendor/v8/test/mjsunit/regress/regress-2374.js +33 -0
  602. data/vendor/v8/test/mjsunit/regress/regress-2398.js +41 -0
  603. data/vendor/v8/test/mjsunit/regress/regress-2410.js +36 -0
  604. data/vendor/v8/test/mjsunit/regress/regress-2416.js +75 -0
  605. data/vendor/v8/test/mjsunit/regress/regress-2419.js +37 -0
  606. data/vendor/v8/test/mjsunit/regress/regress-2433.js +36 -0
  607. data/vendor/v8/test/mjsunit/regress/regress-2437.js +156 -0
  608. data/vendor/v8/test/mjsunit/regress/regress-2438.js +52 -0
  609. data/vendor/v8/test/mjsunit/regress/regress-2443.js +129 -0
  610. data/vendor/v8/test/mjsunit/regress/regress-2444.js +120 -0
  611. data/vendor/v8/test/mjsunit/regress/regress-2489.js +50 -0
  612. data/vendor/v8/test/mjsunit/regress/regress-2499.js +40 -0
  613. data/vendor/v8/test/mjsunit/regress/regress-334.js +1 -1
  614. data/vendor/v8/test/mjsunit/regress/regress-492.js +39 -1
  615. data/vendor/v8/test/mjsunit/regress/regress-builtin-array-op.js +38 -0
  616. data/vendor/v8/test/mjsunit/regress/regress-cnlt-elements.js +43 -0
  617. data/vendor/v8/test/mjsunit/regress/regress-cnlt-enum-indices.js +45 -0
  618. data/vendor/v8/test/mjsunit/regress/regress-cntl-descriptors-enum.js +46 -0
  619. data/vendor/v8/test/mjsunit/regress/regress-convert-enum.js +60 -0
  620. data/vendor/v8/test/mjsunit/regress/regress-convert-enum2.js +46 -0
  621. data/vendor/v8/test/mjsunit/regress/regress-convert-transition.js +40 -0
  622. data/vendor/v8/test/mjsunit/regress/regress-crbug-119926.js +3 -1
  623. data/vendor/v8/test/mjsunit/regress/regress-crbug-125148.js +90 -0
  624. data/vendor/v8/test/mjsunit/regress/regress-crbug-134055.js +63 -0
  625. data/vendor/v8/test/mjsunit/regress/regress-crbug-134609.js +59 -0
  626. data/vendor/v8/test/mjsunit/regress/regress-crbug-135008.js +45 -0
  627. data/vendor/v8/test/mjsunit/regress/regress-crbug-135066.js +55 -0
  628. data/vendor/v8/test/mjsunit/regress/regress-crbug-137689.js +47 -0
  629. data/vendor/v8/test/mjsunit/regress/regress-crbug-138887.js +48 -0
  630. data/vendor/v8/test/mjsunit/regress/regress-crbug-140083.js +44 -0
  631. data/vendor/v8/test/mjsunit/regress/regress-crbug-142087.js +38 -0
  632. data/vendor/v8/test/mjsunit/regress/regress-crbug-142218.js +44 -0
  633. data/vendor/v8/test/mjsunit/regress/regress-crbug-145961.js +39 -0
  634. data/vendor/v8/test/mjsunit/regress/regress-crbug-146910.js +33 -0
  635. data/vendor/v8/test/mjsunit/regress/regress-crbug-147475.js +48 -0
  636. data/vendor/v8/test/mjsunit/regress/regress-crbug-148376.js +35 -0
  637. data/vendor/v8/test/mjsunit/regress/regress-crbug-150545.js +53 -0
  638. data/vendor/v8/test/mjsunit/regress/regress-crbug-150729.js +39 -0
  639. data/vendor/v8/test/mjsunit/regress/regress-crbug-157019.js +54 -0
  640. data/vendor/v8/test/mjsunit/regress/regress-crbug-157520.js +38 -0
  641. data/vendor/v8/test/mjsunit/regress/regress-crbug-158185.js +39 -0
  642. data/vendor/v8/test/mjsunit/regress/regress-crbug-160010.js +35 -0
  643. data/vendor/v8/test/mjsunit/regress/regress-crbug-162085.js +71 -0
  644. data/vendor/v8/test/mjsunit/regress/regress-crbug-168545.js +34 -0
  645. data/vendor/v8/test/mjsunit/regress/regress-crbug-170856.js +33 -0
  646. data/vendor/v8/test/mjsunit/regress/regress-crbug-172345.js +34 -0
  647. data/vendor/v8/test/mjsunit/regress/regress-crbug-173974.js +36 -0
  648. data/vendor/v8/test/mjsunit/regress/regress-crbug-18639.js +9 -5
  649. data/vendor/v8/test/mjsunit/regress/regress-debug-code-recompilation.js +2 -1
  650. data/vendor/v8/test/mjsunit/regress/regress-deep-proto.js +45 -0
  651. data/vendor/v8/test/mjsunit/regress/regress-delete-empty-double.js +40 -0
  652. data/vendor/v8/test/mjsunit/regress/regress-iteration-order.js +42 -0
  653. data/vendor/v8/test/mjsunit/regress/regress-json-stringify-gc.js +41 -0
  654. data/vendor/v8/test/mjsunit/regress/regress-latin-1.js +78 -0
  655. data/vendor/v8/test/mjsunit/regress/regress-load-elements.js +49 -0
  656. data/vendor/v8/test/mjsunit/regress/regress-observe-empty-double-array.js +38 -0
  657. data/vendor/v8/test/mjsunit/regress/regress-undefined-store-keyed-fast-element.js +37 -0
  658. data/vendor/v8/test/mjsunit/shift-for-integer-div.js +59 -0
  659. data/vendor/v8/test/mjsunit/stack-traces-gc.js +119 -0
  660. data/vendor/v8/test/mjsunit/stack-traces-overflow.js +122 -0
  661. data/vendor/v8/test/mjsunit/stack-traces.js +39 -1
  662. data/vendor/v8/test/mjsunit/str-to-num.js +7 -2
  663. data/vendor/v8/test/mjsunit/strict-mode.js +36 -11
  664. data/vendor/v8/test/mjsunit/string-charcodeat.js +3 -0
  665. data/vendor/v8/test/mjsunit/string-natives.js +72 -0
  666. data/vendor/v8/test/mjsunit/string-split.js +17 -0
  667. data/vendor/v8/test/mjsunit/testcfg.py +76 -6
  668. data/vendor/v8/test/mjsunit/tools/tickprocessor.js +4 -1
  669. data/vendor/v8/test/mjsunit/try-finally-continue.js +72 -0
  670. data/vendor/v8/test/mjsunit/typed-array-slice.js +61 -0
  671. data/vendor/v8/test/mjsunit/unbox-double-arrays.js +2 -0
  672. data/vendor/v8/test/mjsunit/uri.js +12 -0
  673. data/vendor/v8/test/mjsunit/with-readonly.js +4 -2
  674. data/vendor/v8/test/mozilla/mozilla.status +19 -113
  675. data/vendor/v8/test/mozilla/testcfg.py +122 -3
  676. data/vendor/v8/test/preparser/preparser.status +5 -0
  677. data/vendor/v8/test/preparser/strict-identifiers.pyt +1 -1
  678. data/vendor/v8/test/preparser/testcfg.py +101 -5
  679. data/vendor/v8/test/sputnik/sputnik.status +1 -1
  680. data/vendor/v8/test/sputnik/testcfg.py +5 -0
  681. data/vendor/v8/test/test262/README +2 -2
  682. data/vendor/v8/test/test262/test262.status +13 -36
  683. data/vendor/v8/test/test262/testcfg.py +102 -8
  684. data/vendor/v8/tools/android-build.sh +0 -0
  685. data/vendor/v8/tools/android-ll-prof.sh +69 -0
  686. data/vendor/v8/tools/android-run.py +109 -0
  687. data/vendor/v8/tools/android-sync.sh +105 -0
  688. data/vendor/v8/tools/bash-completion.sh +0 -0
  689. data/vendor/v8/tools/check-static-initializers.sh +0 -0
  690. data/vendor/v8/tools/common-includes.sh +15 -22
  691. data/vendor/v8/tools/disasm.py +4 -4
  692. data/vendor/v8/tools/fuzz-harness.sh +0 -0
  693. data/vendor/v8/tools/gen-postmortem-metadata.py +6 -8
  694. data/vendor/v8/tools/grokdump.py +404 -129
  695. data/vendor/v8/tools/gyp/v8.gyp +105 -43
  696. data/vendor/v8/tools/linux-tick-processor +5 -5
  697. data/vendor/v8/tools/ll_prof.py +75 -15
  698. data/vendor/v8/tools/merge-to-branch.sh +2 -2
  699. data/vendor/v8/tools/plot-timer-events +70 -0
  700. data/vendor/v8/tools/plot-timer-events.js +510 -0
  701. data/vendor/v8/tools/presubmit.py +1 -0
  702. data/vendor/v8/tools/push-to-trunk.sh +14 -4
  703. data/vendor/v8/tools/run-llprof.sh +69 -0
  704. data/vendor/v8/tools/run-tests.py +372 -0
  705. data/vendor/v8/tools/run-valgrind.py +1 -1
  706. data/vendor/v8/tools/status-file-converter.py +39 -0
  707. data/vendor/v8/tools/test-server.py +224 -0
  708. data/vendor/v8/tools/test-wrapper-gypbuild.py +13 -16
  709. data/vendor/v8/tools/test.py +10 -19
  710. data/vendor/v8/tools/testrunner/README +174 -0
  711. data/vendor/v8/tools/testrunner/__init__.py +26 -0
  712. data/vendor/v8/tools/testrunner/local/__init__.py +26 -0
  713. data/vendor/v8/tools/testrunner/local/commands.py +153 -0
  714. data/vendor/v8/tools/testrunner/local/execution.py +182 -0
  715. data/vendor/v8/tools/testrunner/local/old_statusfile.py +460 -0
  716. data/vendor/v8/tools/testrunner/local/progress.py +238 -0
  717. data/vendor/v8/tools/testrunner/local/statusfile.py +145 -0
  718. data/vendor/v8/tools/testrunner/local/testsuite.py +187 -0
  719. data/vendor/v8/tools/testrunner/local/utils.py +108 -0
  720. data/vendor/v8/tools/testrunner/local/verbose.py +99 -0
  721. data/vendor/v8/tools/testrunner/network/__init__.py +26 -0
  722. data/vendor/v8/tools/testrunner/network/distro.py +90 -0
  723. data/vendor/v8/tools/testrunner/network/endpoint.py +124 -0
  724. data/vendor/v8/tools/testrunner/network/network_execution.py +253 -0
  725. data/vendor/v8/tools/testrunner/network/perfdata.py +120 -0
  726. data/vendor/v8/tools/testrunner/objects/__init__.py +26 -0
  727. data/vendor/v8/tools/testrunner/objects/context.py +50 -0
  728. data/vendor/v8/tools/testrunner/objects/output.py +60 -0
  729. data/vendor/v8/tools/testrunner/objects/peer.py +80 -0
  730. data/vendor/v8/tools/testrunner/objects/testcase.py +83 -0
  731. data/vendor/v8/tools/testrunner/objects/workpacket.py +90 -0
  732. data/vendor/v8/tools/testrunner/server/__init__.py +26 -0
  733. data/vendor/v8/tools/testrunner/server/compression.py +111 -0
  734. data/vendor/v8/tools/testrunner/server/constants.py +51 -0
  735. data/vendor/v8/tools/testrunner/server/daemon.py +147 -0
  736. data/vendor/v8/tools/testrunner/server/local_handler.py +119 -0
  737. data/vendor/v8/tools/testrunner/server/main.py +245 -0
  738. data/vendor/v8/tools/testrunner/server/presence_handler.py +120 -0
  739. data/vendor/v8/tools/testrunner/server/signatures.py +63 -0
  740. data/vendor/v8/tools/testrunner/server/status_handler.py +112 -0
  741. data/vendor/v8/tools/testrunner/server/work_handler.py +150 -0
  742. data/vendor/v8/tools/tick-processor.html +168 -0
  743. data/vendor/v8/tools/tickprocessor-driver.js +5 -3
  744. data/vendor/v8/tools/tickprocessor.js +58 -15
  745. metadata +534 -30
  746. data/patches/add-freebsd9-and-freebsd10-to-gyp-GetFlavor.patch +0 -11
  747. data/patches/do-not-imply-vfp3-and-armv7.patch +0 -44
  748. data/patches/fPIC-on-x64.patch +0 -14
  749. data/vendor/v8/src/liveobjectlist-inl.h +0 -126
  750. data/vendor/v8/src/liveobjectlist.cc +0 -2631
  751. data/vendor/v8/src/liveobjectlist.h +0 -319
  752. data/vendor/v8/test/mjsunit/mul-exhaustive.js +0 -4629
  753. data/vendor/v8/test/mjsunit/numops-fuzz.js +0 -4609
  754. data/vendor/v8/test/mjsunit/regress/regress-1969.js +0 -5045
@@ -40,10 +40,11 @@ namespace internal {
40
40
 
41
41
  Address IC::address() const {
42
42
  // Get the address of the call.
43
- Address result = pc() - Assembler::kCallTargetAddressOffset;
43
+ Address result = Assembler::target_address_from_return_address(pc());
44
44
 
45
45
  #ifdef ENABLE_DEBUGGER_SUPPORT
46
- Debug* debug = Isolate::Current()->debug();
46
+ ASSERT(Isolate::Current() == isolate());
47
+ Debug* debug = isolate()->debug();
47
48
  // First check if any break points are active if not just return the address
48
49
  // of the call.
49
50
  if (!debug->has_break_points()) return result;
@@ -79,6 +80,7 @@ Code* IC::GetTargetAtAddress(Address address) {
79
80
 
80
81
  void IC::SetTargetAtAddress(Address address, Code* target) {
81
82
  ASSERT(target->is_inline_cache_stub() || target->is_compare_ic_stub());
83
+ Heap* heap = target->GetHeap();
82
84
  Code* old_target = GetTargetAtAddress(address);
83
85
  #ifdef DEBUG
84
86
  // STORE_IC and KEYED_STORE_IC use Code::extra_ic_state() to mark
@@ -90,8 +92,11 @@ void IC::SetTargetAtAddress(Address address, Code* target) {
90
92
  }
91
93
  #endif
92
94
  Assembler::set_target_address_at(address, target->instruction_start());
93
- target->GetHeap()->incremental_marking()->RecordCodeTargetPatch(address,
94
- target);
95
+ if (heap->gc_state() == Heap::MARK_COMPACT) {
96
+ heap->mark_compact_collector()->RecordCodeTargetPatch(address, target);
97
+ } else {
98
+ heap->incremental_marking()->RecordCodeTargetPatch(address, target);
99
+ }
95
100
  PostPatching(address, target, old_target);
96
101
  }
97
102
 
data/vendor/v8/src/ic.cc CHANGED
@@ -43,16 +43,17 @@ namespace internal {
43
43
  char IC::TransitionMarkFromState(IC::State state) {
44
44
  switch (state) {
45
45
  case UNINITIALIZED: return '0';
46
- case PREMONOMORPHIC: return 'P';
46
+ case PREMONOMORPHIC: return '.';
47
47
  case MONOMORPHIC: return '1';
48
48
  case MONOMORPHIC_PROTOTYPE_FAILURE: return '^';
49
- case MEGAMORPHIC: return IsGeneric() ? 'G' : 'N';
49
+ case POLYMORPHIC: return 'P';
50
+ case MEGAMORPHIC: return 'N';
51
+ case GENERIC: return 'G';
50
52
 
51
53
  // We never see the debugger states here, because the state is
52
54
  // computed from the original code - not the patched code. Let
53
55
  // these cases fall through to the unreachable code below.
54
- case DEBUG_BREAK: break;
55
- case DEBUG_PREPARE_STEP_IN: break;
56
+ case DEBUG_STUB: break;
56
57
  }
57
58
  UNREACHABLE();
58
59
  return 0;
@@ -110,18 +111,17 @@ void IC::TraceIC(const char* type,
110
111
  ASSERT((TraceIC(type, name, old_state, new_target), true))
111
112
 
112
113
  IC::IC(FrameDepth depth, Isolate* isolate) : isolate_(isolate) {
113
- ASSERT(isolate == Isolate::Current());
114
- // To improve the performance of the (much used) IC code, we unfold
115
- // a few levels of the stack frame iteration code. This yields a
116
- // ~35% speedup when running DeltaBlue with the '--nouse-ic' flag.
114
+ // To improve the performance of the (much used) IC code, we unfold a few
115
+ // levels of the stack frame iteration code. This yields a ~35% speedup when
116
+ // running DeltaBlue and a ~25% speedup of gbemu with the '--nouse-ic' flag.
117
117
  const Address entry =
118
118
  Isolate::c_entry_fp(isolate->thread_local_top());
119
119
  Address* pc_address =
120
120
  reinterpret_cast<Address*>(entry + ExitFrameConstants::kCallerPCOffset);
121
121
  Address fp = Memory::Address_at(entry + ExitFrameConstants::kCallerFPOffset);
122
- // If there's another JavaScript frame on the stack, we need to look
123
- // one frame further down the stack to find the frame pointer and
124
- // the return address stack slot.
122
+ // If there's another JavaScript frame on the stack or a
123
+ // StubFailureTrampoline, we need to look one frame further down the stack to
124
+ // find the frame pointer and the return address stack slot.
125
125
  if (depth == EXTRA_CALL_FRAME) {
126
126
  const int kCallerPCOffset = StandardFrameConstants::kCallerPCOffset;
127
127
  pc_address = reinterpret_cast<Address*>(fp + kCallerPCOffset);
@@ -158,7 +158,7 @@ Address IC::OriginalCodeAddress() const {
158
158
  // Get the address of the call site in the active code. This is the
159
159
  // place where the call to DebugBreakXXX is and where the IC
160
160
  // normally would be.
161
- Address addr = pc() - Assembler::kCallTargetAddressOffset;
161
+ Address addr = Assembler::target_address_from_return_address(pc());
162
162
  // Return the address in the original code. This is the place where
163
163
  // the call which has been overwritten by the DebugBreakXXX resides
164
164
  // and the place where the inline cache system should look.
@@ -169,26 +169,6 @@ Address IC::OriginalCodeAddress() const {
169
169
  #endif
170
170
 
171
171
 
172
- static bool HasNormalObjectsInPrototypeChain(Isolate* isolate,
173
- LookupResult* lookup,
174
- Object* receiver) {
175
- Object* end = lookup->IsProperty()
176
- ? lookup->holder() : Object::cast(isolate->heap()->null_value());
177
- for (Object* current = receiver;
178
- current != end;
179
- current = current->GetPrototype()) {
180
- if (current->IsJSObject() &&
181
- !JSObject::cast(current)->HasFastProperties() &&
182
- !current->IsJSGlobalProxy() &&
183
- !current->IsJSGlobalObject()) {
184
- return true;
185
- }
186
- }
187
-
188
- return false;
189
- }
190
-
191
-
192
172
  static bool TryRemoveInvalidPrototypeDependentStub(Code* target,
193
173
  Object* receiver,
194
174
  Object* name) {
@@ -273,7 +253,7 @@ RelocInfo::Mode IC::ComputeMode() {
273
253
  if (info->pc() == addr) return info->rmode();
274
254
  }
275
255
  UNREACHABLE();
276
- return RelocInfo::NONE;
256
+ return RelocInfo::NONE32;
277
257
  }
278
258
 
279
259
 
@@ -310,7 +290,8 @@ void IC::PostPatching(Address address, Code* target, Code* old_target) {
310
290
  if (FLAG_type_info_threshold == 0 && !FLAG_watch_ic_patching) {
311
291
  return;
312
292
  }
313
- Code* host = target->GetHeap()->isolate()->
293
+ Isolate* isolate = target->GetHeap()->isolate();
294
+ Code* host = isolate->
314
295
  inner_pointer_to_code_cache()->GetCacheEntry(address)->code;
315
296
  if (host->kind() != Code::FUNCTION) return;
316
297
 
@@ -320,16 +301,20 @@ void IC::PostPatching(Address address, Code* target, Code* old_target) {
320
301
  int delta = ComputeTypeInfoCountDelta(old_target->ic_state(),
321
302
  target->ic_state());
322
303
  // Not all Code objects have TypeFeedbackInfo.
323
- if (delta != 0 && host->type_feedback_info()->IsTypeFeedbackInfo()) {
304
+ if (host->type_feedback_info()->IsTypeFeedbackInfo() && delta != 0) {
324
305
  TypeFeedbackInfo* info =
325
306
  TypeFeedbackInfo::cast(host->type_feedback_info());
326
- info->set_ic_with_type_info_count(
327
- info->ic_with_type_info_count() + delta);
307
+ info->change_ic_with_type_info_count(delta);
328
308
  }
329
309
  }
310
+ if (host->type_feedback_info()->IsTypeFeedbackInfo()) {
311
+ TypeFeedbackInfo* info =
312
+ TypeFeedbackInfo::cast(host->type_feedback_info());
313
+ info->change_own_type_change_checksum();
314
+ }
330
315
  if (FLAG_watch_ic_patching) {
331
316
  host->set_profiler_ticks(0);
332
- Isolate::Current()->runtime_profiler()->NotifyICChanged();
317
+ isolate->runtime_profiler()->NotifyICChanged();
333
318
  }
334
319
  // TODO(2029): When an optimized function is patched, it would
335
320
  // be nice to propagate the corresponding type information to its
@@ -341,15 +326,13 @@ void IC::Clear(Address address) {
341
326
  Code* target = GetTargetAtAddress(address);
342
327
 
343
328
  // Don't clear debug break inline cache as it will remove the break point.
344
- if (target->ic_state() == DEBUG_BREAK) return;
329
+ if (target->is_debug_break()) return;
345
330
 
346
331
  switch (target->kind()) {
347
332
  case Code::LOAD_IC: return LoadIC::Clear(address, target);
348
- case Code::KEYED_LOAD_IC:
349
- return KeyedLoadIC::Clear(address, target);
333
+ case Code::KEYED_LOAD_IC: return KeyedLoadIC::Clear(address, target);
350
334
  case Code::STORE_IC: return StoreIC::Clear(address, target);
351
- case Code::KEYED_STORE_IC:
352
- return KeyedStoreIC::Clear(address, target);
335
+ case Code::KEYED_STORE_IC: return KeyedStoreIC::Clear(address, target);
353
336
  case Code::CALL_IC: return CallIC::Clear(address, target);
354
337
  case Code::KEYED_CALL_IC: return KeyedCallIC::Clear(address, target);
355
338
  case Code::COMPARE_IC: return CompareIC::Clear(address, target);
@@ -381,13 +364,13 @@ void KeyedLoadIC::Clear(Address address, Code* target) {
381
364
  // Make sure to also clear the map used in inline fast cases. If we
382
365
  // do not clear these maps, cached code can keep objects alive
383
366
  // through the embedded maps.
384
- SetTargetAtAddress(address, initialize_stub());
367
+ SetTargetAtAddress(address, *initialize_stub());
385
368
  }
386
369
 
387
370
 
388
371
  void LoadIC::Clear(Address address, Code* target) {
389
372
  if (target->ic_state() == UNINITIALIZED) return;
390
- SetTargetAtAddress(address, initialize_stub());
373
+ SetTargetAtAddress(address, *initialize_stub());
391
374
  }
392
375
 
393
376
 
@@ -395,8 +378,8 @@ void StoreIC::Clear(Address address, Code* target) {
395
378
  if (target->ic_state() == UNINITIALIZED) return;
396
379
  SetTargetAtAddress(address,
397
380
  (Code::GetStrictMode(target->extra_ic_state()) == kStrictMode)
398
- ? initialize_stub_strict()
399
- : initialize_stub());
381
+ ? *initialize_stub_strict()
382
+ : *initialize_stub());
400
383
  }
401
384
 
402
385
 
@@ -404,17 +387,19 @@ void KeyedStoreIC::Clear(Address address, Code* target) {
404
387
  if (target->ic_state() == UNINITIALIZED) return;
405
388
  SetTargetAtAddress(address,
406
389
  (Code::GetStrictMode(target->extra_ic_state()) == kStrictMode)
407
- ? initialize_stub_strict()
408
- : initialize_stub());
390
+ ? *initialize_stub_strict()
391
+ : *initialize_stub());
409
392
  }
410
393
 
411
394
 
412
395
  void CompareIC::Clear(Address address, Code* target) {
413
- // Only clear ICCompareStubs, we currently cannot clear generic CompareStubs.
414
- if (target->major_key() != CodeStub::CompareIC) return;
396
+ ASSERT(target->major_key() == CodeStub::CompareIC);
397
+ CompareIC::State handler_state;
398
+ Token::Value op;
399
+ ICCompareStub::DecodeMinorKey(target->stub_info(), NULL, NULL,
400
+ &handler_state, &op);
415
401
  // Only clear CompareICs that can retain objects.
416
- if (target->compare_state() != KNOWN_OBJECTS) return;
417
- Token::Value op = CompareIC::ComputeOperation(target);
402
+ if (handler_state != KNOWN_OBJECTS) return;
418
403
  SetTargetAtAddress(address, GetRawUninitialized(op));
419
404
  PatchInlinedSmiCode(address, DISABLE_INLINED_SMI_CHECK);
420
405
  }
@@ -435,9 +420,7 @@ static void LookupForRead(Handle<Object> object,
435
420
  // Besides normal conditions (property not found or it's not
436
421
  // an interceptor), bail out if lookup is not cacheable: we won't
437
422
  // be able to IC it anyway and regular lookup should work fine.
438
- if (!lookup->IsFound()
439
- || (lookup->type() != INTERCEPTOR)
440
- || !lookup->IsCacheable()) {
423
+ if (!lookup->IsInterceptor() || !lookup->IsCacheable()) {
441
424
  return;
442
425
  }
443
426
 
@@ -447,14 +430,14 @@ static void LookupForRead(Handle<Object> object,
447
430
  }
448
431
 
449
432
  holder->LocalLookupRealNamedProperty(*name, lookup);
450
- if (lookup->IsProperty()) {
451
- ASSERT(lookup->type() != INTERCEPTOR);
433
+ if (lookup->IsFound()) {
434
+ ASSERT(!lookup->IsInterceptor());
452
435
  return;
453
436
  }
454
437
 
455
438
  Handle<Object> proto(holder->GetPrototype());
456
439
  if (proto->IsNull()) {
457
- lookup->NotFound();
440
+ ASSERT(!lookup->IsFound());
458
441
  return;
459
442
  }
460
443
 
@@ -535,10 +518,10 @@ MaybeObject* CallICBase::LoadFunction(State state,
535
518
  LookupResult lookup(isolate());
536
519
  LookupForRead(object, name, &lookup);
537
520
 
538
- if (!lookup.IsProperty()) {
521
+ if (!lookup.IsFound()) {
539
522
  // If the object does not have the requested property, check which
540
523
  // exception we need to throw.
541
- return IsContextual(object)
524
+ return IsUndeclaredGlobal(object)
542
525
  ? ReferenceError("not_defined", name)
543
526
  : TypeError("undefined_method", object, name);
544
527
  }
@@ -554,10 +537,10 @@ MaybeObject* CallICBase::LoadFunction(State state,
554
537
  Object::GetProperty(object, object, &lookup, name, &attr);
555
538
  RETURN_IF_EMPTY_HANDLE(isolate(), result);
556
539
 
557
- if (lookup.type() == INTERCEPTOR && attr == ABSENT) {
540
+ if (lookup.IsInterceptor() && attr == ABSENT) {
558
541
  // If the object does not have the requested property, check which
559
542
  // exception we need to throw.
560
- return IsContextual(object)
543
+ return IsUndeclaredGlobal(object)
561
544
  ? ReferenceError("not_defined", name)
562
545
  : TypeError("undefined_method", object, name);
563
546
  }
@@ -644,7 +627,7 @@ Handle<Code> CallICBase::ComputeMonomorphicStub(LookupResult* lookup,
644
627
  Handle<JSObject> holder(lookup->holder());
645
628
  switch (lookup->type()) {
646
629
  case FIELD: {
647
- int index = lookup->GetFieldIndex();
630
+ PropertyIndex index = lookup->GetFieldIndex();
648
631
  return isolate()->stub_cache()->ComputeCallField(
649
632
  argc, kind_, extra_state, name, object, holder, index);
650
633
  }
@@ -697,17 +680,8 @@ void CallICBase::UpdateCaches(LookupResult* lookup,
697
680
  // Bail out if we didn't find a result.
698
681
  if (!lookup->IsProperty() || !lookup->IsCacheable()) return;
699
682
 
700
- if (lookup->holder() != *object &&
701
- HasNormalObjectsInPrototypeChain(
702
- isolate(), lookup, object->GetPrototype())) {
703
- // Suppress optimization for prototype chains with slow properties objects
704
- // in the middle.
705
- return;
706
- }
707
-
708
683
  // Compute the number of arguments.
709
684
  int argc = target()->arguments_count();
710
- bool had_proto_failure = false;
711
685
  Handle<Code> code;
712
686
  if (state == UNINITIALIZED) {
713
687
  // This is the first time we execute this inline cache.
@@ -724,7 +698,7 @@ void CallICBase::UpdateCaches(LookupResult* lookup,
724
698
  TryRemoveInvalidPrototypeDependentStub(target(),
725
699
  *object,
726
700
  *name)) {
727
- had_proto_failure = true;
701
+ state = MONOMORPHIC_PROTOTYPE_FAILURE;
728
702
  code = ComputeMonomorphicStub(lookup, state, extra_ic_state,
729
703
  object, name);
730
704
  } else {
@@ -740,22 +714,39 @@ void CallICBase::UpdateCaches(LookupResult* lookup,
740
714
  if (code.is_null()) return;
741
715
 
742
716
  // Patch the call site depending on the state of the cache.
743
- if (state == UNINITIALIZED ||
744
- state == PREMONOMORPHIC ||
745
- state == MONOMORPHIC ||
746
- state == MONOMORPHIC_PROTOTYPE_FAILURE) {
747
- set_target(*code);
748
- } else if (state == MEGAMORPHIC) {
749
- // Cache code holding map should be consistent with
750
- // GenerateMonomorphicCacheProbe. It is not the map which holds the stub.
751
- Handle<JSObject> cache_object = object->IsJSObject()
752
- ? Handle<JSObject>::cast(object)
753
- : Handle<JSObject>(JSObject::cast(object->GetPrototype()));
754
- // Update the stub cache.
755
- isolate()->stub_cache()->Set(*name, cache_object->map(), *code);
756
- }
757
-
758
- if (had_proto_failure) state = MONOMORPHIC_PROTOTYPE_FAILURE;
717
+ switch (state) {
718
+ case UNINITIALIZED:
719
+ case MONOMORPHIC_PROTOTYPE_FAILURE:
720
+ case PREMONOMORPHIC:
721
+ set_target(*code);
722
+ break;
723
+ case MONOMORPHIC:
724
+ if (code->ic_state() != MONOMORPHIC) {
725
+ Map* map = target()->FindFirstMap();
726
+ if (map != NULL) {
727
+ UpdateMegamorphicCache(map, *name, target());
728
+ }
729
+ }
730
+ set_target(*code);
731
+ break;
732
+ case MEGAMORPHIC: {
733
+ // Cache code holding map should be consistent with
734
+ // GenerateMonomorphicCacheProbe. It is not the map which holds the stub.
735
+ Handle<JSObject> cache_object = object->IsJSObject()
736
+ ? Handle<JSObject>::cast(object)
737
+ : Handle<JSObject>(JSObject::cast(object->GetPrototype()));
738
+ // Update the stub cache.
739
+ UpdateMegamorphicCache(cache_object->map(), *name, *code);
740
+ break;
741
+ }
742
+ case DEBUG_STUB:
743
+ break;
744
+ case POLYMORPHIC:
745
+ case GENERIC:
746
+ UNREACHABLE();
747
+ break;
748
+ }
749
+
759
750
  TRACE_IC(kind_ == Code::CALL_IC ? "CallIC" : "KeyedCallIC",
760
751
  name, state, target());
761
752
  }
@@ -775,22 +766,23 @@ MaybeObject* KeyedCallIC::LoadFunction(State state,
775
766
  return TypeError("non_object_property_call", object, key);
776
767
  }
777
768
 
778
- if (FLAG_use_ic && state != MEGAMORPHIC && object->IsHeapObject()) {
769
+ bool use_ic = FLAG_use_ic && !object->IsAccessCheckNeeded();
770
+ ASSERT(!(use_ic && object->IsJSGlobalProxy()));
771
+
772
+ if (use_ic && state != MEGAMORPHIC) {
779
773
  int argc = target()->arguments_count();
780
- Handle<Map> map =
781
- isolate()->factory()->non_strict_arguments_elements_map();
782
- if (object->IsJSObject() &&
783
- Handle<JSObject>::cast(object)->elements()->map() == *map) {
784
- Handle<Code> code = isolate()->stub_cache()->ComputeCallArguments(
785
- argc, Code::KEYED_CALL_IC);
786
- set_target(*code);
787
- TRACE_IC("KeyedCallIC", key, state, target());
788
- } else if (!object->IsAccessCheckNeeded()) {
789
- Handle<Code> code = isolate()->stub_cache()->ComputeCallMegamorphic(
790
- argc, Code::KEYED_CALL_IC, Code::kNoExtraICState);
791
- set_target(*code);
792
- TRACE_IC("KeyedCallIC", key, state, target());
774
+ Handle<Code> stub = isolate()->stub_cache()->ComputeCallMegamorphic(
775
+ argc, Code::KEYED_CALL_IC, Code::kNoExtraICState);
776
+ if (object->IsJSObject()) {
777
+ Handle<JSObject> receiver = Handle<JSObject>::cast(object);
778
+ if (receiver->elements()->map() ==
779
+ isolate()->heap()->non_strict_arguments_elements_map()) {
780
+ stub = isolate()->stub_cache()->ComputeCallArguments(argc);
781
+ }
793
782
  }
783
+ ASSERT(!stub.is_null());
784
+ set_target(*stub);
785
+ TRACE_IC("KeyedCallIC", key, state, target());
794
786
  }
795
787
 
796
788
  Handle<Object> result = GetProperty(object, key);
@@ -829,12 +821,13 @@ MaybeObject* LoadIC::Load(State state,
829
821
  if (state == UNINITIALIZED) {
830
822
  stub = pre_monomorphic_stub();
831
823
  } else if (state == PREMONOMORPHIC) {
832
- stub = object->IsString()
833
- ? isolate()->builtins()->LoadIC_StringLength()
834
- : isolate()->builtins()->LoadIC_StringWrapperLength();
824
+ StringLengthStub string_length_stub(kind(), !object->IsString());
825
+ stub = string_length_stub.GetCode();
835
826
  } else if (state == MONOMORPHIC && object->IsStringWrapper()) {
836
- stub = isolate()->builtins()->LoadIC_StringWrapperLength();
827
+ StringLengthStub string_length_stub(kind(), true);
828
+ stub = string_length_stub.GetCode();
837
829
  } else if (state != MEGAMORPHIC) {
830
+ ASSERT(state != GENERIC);
838
831
  stub = megamorphic_stub();
839
832
  }
840
833
  if (!stub.is_null()) {
@@ -857,8 +850,10 @@ MaybeObject* LoadIC::Load(State state,
857
850
  if (state == UNINITIALIZED) {
858
851
  stub = pre_monomorphic_stub();
859
852
  } else if (state == PREMONOMORPHIC) {
860
- stub = isolate()->builtins()->LoadIC_ArrayLength();
853
+ ArrayLengthStub array_length_stub(kind());
854
+ stub = array_length_stub.GetCode();
861
855
  } else if (state != MEGAMORPHIC) {
856
+ ASSERT(state != GENERIC);
862
857
  stub = megamorphic_stub();
863
858
  }
864
859
  if (!stub.is_null()) {
@@ -878,8 +873,10 @@ MaybeObject* LoadIC::Load(State state,
878
873
  if (state == UNINITIALIZED) {
879
874
  stub = pre_monomorphic_stub();
880
875
  } else if (state == PREMONOMORPHIC) {
881
- stub = isolate()->builtins()->LoadIC_FunctionPrototype();
876
+ FunctionPrototypeStub function_prototype_stub(kind());
877
+ stub = function_prototype_stub.GetCode();
882
878
  } else if (state != MEGAMORPHIC) {
879
+ ASSERT(state != GENERIC);
883
880
  stub = megamorphic_stub();
884
881
  }
885
882
  if (!stub.is_null()) {
@@ -893,17 +890,21 @@ MaybeObject* LoadIC::Load(State state,
893
890
  }
894
891
 
895
892
  // Check if the name is trivially convertible to an index and get
896
- // the element if so.
893
+ // the element or char if so.
897
894
  uint32_t index;
898
- if (name->AsArrayIndex(&index)) return object->GetElement(index);
895
+ if (kind() == Code::KEYED_LOAD_IC && name->AsArrayIndex(&index)) {
896
+ // Rewrite to the generic keyed load stub.
897
+ if (FLAG_use_ic) set_target(*generic_stub());
898
+ return Runtime::GetElementOrCharAt(isolate(), object, index);
899
+ }
899
900
 
900
901
  // Named lookup in the object.
901
902
  LookupResult lookup(isolate());
902
903
  LookupForRead(object, name, &lookup);
903
904
 
904
905
  // If we did not find a property, check if we need to throw an exception.
905
- if (!lookup.IsProperty()) {
906
- if (IsContextual(object)) {
906
+ if (!lookup.IsFound()) {
907
+ if (IsUndeclaredGlobal(object)) {
907
908
  return ReferenceError("not_defined", name);
908
909
  }
909
910
  LOG(isolate(), SuspectReadEvent(*name, *object));
@@ -915,15 +916,14 @@ MaybeObject* LoadIC::Load(State state,
915
916
  }
916
917
 
917
918
  PropertyAttributes attr;
918
- if (lookup.IsFound() &&
919
- (lookup.type() == INTERCEPTOR || lookup.type() == HANDLER)) {
919
+ if (lookup.IsInterceptor() || lookup.IsHandler()) {
920
920
  // Get the property.
921
921
  Handle<Object> result =
922
922
  Object::GetProperty(object, object, &lookup, name, &attr);
923
923
  RETURN_IF_EMPTY_HANDLE(isolate(), result);
924
924
  // If the property is not present, check if we need to throw an
925
925
  // exception.
926
- if (attr == ABSENT && IsContextual(object)) {
926
+ if (attr == ABSENT && IsUndeclaredGlobal(object)) {
927
927
  return ReferenceError("not_defined", name);
928
928
  }
929
929
  return *result;
@@ -934,6 +934,56 @@ MaybeObject* LoadIC::Load(State state,
934
934
  }
935
935
 
936
936
 
937
+ void IC::PatchCache(State state,
938
+ StrictModeFlag strict_mode,
939
+ Handle<JSObject> receiver,
940
+ Handle<String> name,
941
+ Handle<Code> code) {
942
+ switch (state) {
943
+ case UNINITIALIZED:
944
+ case PREMONOMORPHIC:
945
+ case MONOMORPHIC_PROTOTYPE_FAILURE:
946
+ set_target(*code);
947
+ break;
948
+ case MONOMORPHIC:
949
+ // Only move to megamorphic if the target changes.
950
+ if (target() != *code) {
951
+ // We are transitioning from monomorphic to megamorphic case.
952
+ // Place the current monomorphic stub and stub compiled for
953
+ // the receiver into stub cache.
954
+ Map* map = target()->FindFirstMap();
955
+ if (map != NULL) {
956
+ UpdateMegamorphicCache(map, *name, target());
957
+ }
958
+ UpdateMegamorphicCache(receiver->map(), *name, *code);
959
+ set_target((strict_mode == kStrictMode)
960
+ ? *megamorphic_stub_strict()
961
+ : *megamorphic_stub());
962
+ }
963
+ break;
964
+ case MEGAMORPHIC:
965
+ // Update the stub cache.
966
+ UpdateMegamorphicCache(receiver->map(), *name, *code);
967
+ break;
968
+ case POLYMORPHIC:
969
+ // When trying to patch a polymorphic stub with anything other than
970
+ // another polymorphic stub, go generic.
971
+ // TODO(verwaest): Currently we always go generic since no polymorphic
972
+ // stubs enter this code path. Replace with proper updating once named
973
+ // load/store can also be polymorphic.
974
+ set_target((strict_mode == kStrictMode)
975
+ ? *generic_stub_strict()
976
+ : *generic_stub());
977
+ break;
978
+ case DEBUG_STUB:
979
+ break;
980
+ case GENERIC:
981
+ UNREACHABLE();
982
+ break;
983
+ }
984
+ }
985
+
986
+
937
987
  void LoadIC::UpdateCaches(LookupResult* lookup,
938
988
  State state,
939
989
  Handle<Object> object,
@@ -944,122 +994,91 @@ void LoadIC::UpdateCaches(LookupResult* lookup,
944
994
  // Loading properties from values is not common, so don't try to
945
995
  // deal with non-JS objects here.
946
996
  if (!object->IsJSObject()) return;
947
- Handle<JSObject> receiver = Handle<JSObject>::cast(object);
948
997
 
949
- if (HasNormalObjectsInPrototypeChain(isolate(), lookup, *object)) return;
950
-
951
- // Compute the code stub for this load.
998
+ Handle<JSObject> receiver = Handle<JSObject>::cast(object);
952
999
  Handle<Code> code;
953
1000
  if (state == UNINITIALIZED) {
954
1001
  // This is the first time we execute this inline cache.
955
1002
  // Set the target to the pre monomorphic stub to delay
956
1003
  // setting the monomorphic state.
957
1004
  code = pre_monomorphic_stub();
958
- } else if (!lookup->IsProperty()) {
959
- // Nonexistent property. The result is undefined.
960
- code = isolate()->stub_cache()->ComputeLoadNonexistent(name, receiver);
961
1005
  } else {
962
- // Compute monomorphic stub.
963
- Handle<JSObject> holder(lookup->holder());
964
- switch (lookup->type()) {
965
- case FIELD:
966
- code = isolate()->stub_cache()->ComputeLoadField(
967
- name, receiver, holder, lookup->GetFieldIndex());
968
- break;
969
- case CONSTANT_FUNCTION: {
970
- Handle<JSFunction> constant(lookup->GetConstantFunction());
971
- code = isolate()->stub_cache()->ComputeLoadConstant(
972
- name, receiver, holder, constant);
973
- break;
974
- }
975
- case NORMAL:
976
- if (holder->IsGlobalObject()) {
977
- Handle<GlobalObject> global = Handle<GlobalObject>::cast(holder);
978
- Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(lookup));
979
- code = isolate()->stub_cache()->ComputeLoadGlobal(
980
- name, receiver, global, cell, lookup->IsDontDelete());
981
- } else {
982
- // There is only one shared stub for loading normalized
983
- // properties. It does not traverse the prototype chain, so the
984
- // property must be found in the receiver for the stub to be
985
- // applicable.
986
- if (!holder.is_identical_to(receiver)) return;
987
- code = isolate()->stub_cache()->ComputeLoadNormal();
988
- }
989
- break;
990
- case CALLBACKS: {
991
- Handle<Object> callback_object(lookup->GetCallbackObject());
992
- if (!callback_object->IsAccessorInfo()) return;
993
- Handle<AccessorInfo> callback =
994
- Handle<AccessorInfo>::cast(callback_object);
995
- if (v8::ToCData<Address>(callback->getter()) == 0) return;
996
- code = isolate()->stub_cache()->ComputeLoadCallback(
997
- name, receiver, holder, callback);
998
- break;
999
- }
1000
- case INTERCEPTOR:
1001
- ASSERT(HasInterceptorGetter(*holder));
1002
- code = isolate()->stub_cache()->ComputeLoadInterceptor(
1003
- name, receiver, holder);
1004
- break;
1005
- default:
1006
- return;
1007
- }
1008
- }
1009
-
1010
- // Patch the call site depending on the state of the cache.
1011
- if (state == UNINITIALIZED ||
1012
- state == PREMONOMORPHIC ||
1013
- state == MONOMORPHIC_PROTOTYPE_FAILURE) {
1014
- set_target(*code);
1015
- } else if (state == MONOMORPHIC) {
1016
- // We are transitioning from monomorphic to megamorphic case.
1017
- // Place the current monomorphic stub and stub compiled for
1018
- // the receiver into stub cache.
1019
- Map* map = target()->FindFirstMap();
1020
- if (map != NULL) {
1021
- isolate()->stub_cache()->Set(*name, map, target());
1022
- }
1023
- isolate()->stub_cache()->Set(*name, receiver->map(), *code);
1024
-
1025
- set_target(*megamorphic_stub());
1026
- } else if (state == MEGAMORPHIC) {
1027
- // Cache code holding map should be consistent with
1028
- // GenerateMonomorphicCacheProbe.
1029
- isolate()->stub_cache()->Set(*name, receiver->map(), *code);
1006
+ code = ComputeLoadMonomorphic(lookup, receiver, name);
1007
+ if (code.is_null()) return;
1030
1008
  }
1031
1009
 
1010
+ PatchCache(state, kNonStrictMode, receiver, name, code);
1032
1011
  TRACE_IC("LoadIC", name, state, target());
1033
1012
  }
1034
1013
 
1035
1014
 
1036
- Handle<Code> KeyedLoadIC::GetElementStubWithoutMapCheck(
1037
- bool is_js_array,
1038
- ElementsKind elements_kind,
1039
- KeyedAccessGrowMode grow_mode) {
1040
- ASSERT(grow_mode == DO_NOT_ALLOW_JSARRAY_GROWTH);
1041
- return KeyedLoadElementStub(elements_kind).GetCode();
1015
+ void IC::UpdateMegamorphicCache(Map* map, String* name, Code* code) {
1016
+ // Cache code holding map should be consistent with
1017
+ // GenerateMonomorphicCacheProbe.
1018
+ isolate()->stub_cache()->Set(name, map, code);
1042
1019
  }
1043
1020
 
1044
1021
 
1045
- Handle<Code> KeyedLoadIC::ComputePolymorphicStub(
1046
- MapHandleList* receiver_maps,
1047
- StrictModeFlag strict_mode,
1048
- KeyedAccessGrowMode growth_mode) {
1049
- CodeHandleList handler_ics(receiver_maps->length());
1050
- for (int i = 0; i < receiver_maps->length(); ++i) {
1051
- Handle<Map> receiver_map = receiver_maps->at(i);
1052
- Handle<Code> cached_stub = ComputeMonomorphicStubWithoutMapCheck(
1053
- receiver_map, strict_mode, growth_mode);
1054
- handler_ics.Add(cached_stub);
1022
+ Handle<Code> LoadIC::ComputeLoadMonomorphic(LookupResult* lookup,
1023
+ Handle<JSObject> receiver,
1024
+ Handle<String> name) {
1025
+ if (!lookup->IsProperty()) {
1026
+ // Nonexistent property. The result is undefined.
1027
+ return isolate()->stub_cache()->ComputeLoadNonexistent(name, receiver);
1055
1028
  }
1056
- KeyedLoadStubCompiler compiler(isolate());
1057
- Handle<Code> code = compiler.CompileLoadPolymorphic(
1058
- receiver_maps, &handler_ics);
1059
- isolate()->counters()->keyed_load_polymorphic_stubs()->Increment();
1060
- PROFILE(isolate(),
1061
- CodeCreateEvent(Logger::KEYED_LOAD_MEGAMORPHIC_IC_TAG, *code, 0));
1062
- return code;
1029
+
1030
+ // Compute monomorphic stub.
1031
+ Handle<JSObject> holder(lookup->holder());
1032
+ switch (lookup->type()) {
1033
+ case FIELD:
1034
+ return isolate()->stub_cache()->ComputeLoadField(
1035
+ name, receiver, holder, lookup->GetFieldIndex());
1036
+ case CONSTANT_FUNCTION: {
1037
+ Handle<JSFunction> constant(lookup->GetConstantFunction());
1038
+ return isolate()->stub_cache()->ComputeLoadConstant(
1039
+ name, receiver, holder, constant);
1040
+ }
1041
+ case NORMAL:
1042
+ if (holder->IsGlobalObject()) {
1043
+ Handle<GlobalObject> global = Handle<GlobalObject>::cast(holder);
1044
+ Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(lookup));
1045
+ return isolate()->stub_cache()->ComputeLoadGlobal(
1046
+ name, receiver, global, cell, lookup->IsDontDelete());
1047
+ }
1048
+ // There is only one shared stub for loading normalized
1049
+ // properties. It does not traverse the prototype chain, so the
1050
+ // property must be found in the receiver for the stub to be
1051
+ // applicable.
1052
+ if (!holder.is_identical_to(receiver)) break;
1053
+ return isolate()->stub_cache()->ComputeLoadNormal();
1054
+ case CALLBACKS: {
1055
+ Handle<Object> callback(lookup->GetCallbackObject());
1056
+ if (callback->IsAccessorInfo()) {
1057
+ Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(callback);
1058
+ if (v8::ToCData<Address>(info->getter()) == 0) break;
1059
+ if (!info->IsCompatibleReceiver(*receiver)) break;
1060
+ return isolate()->stub_cache()->ComputeLoadCallback(
1061
+ name, receiver, holder, info);
1062
+ } else if (callback->IsAccessorPair()) {
1063
+ Handle<Object> getter(Handle<AccessorPair>::cast(callback)->getter());
1064
+ if (!getter->IsJSFunction()) break;
1065
+ if (holder->IsGlobalObject()) break;
1066
+ if (!holder->HasFastProperties()) break;
1067
+ return isolate()->stub_cache()->ComputeLoadViaGetter(
1068
+ name, receiver, holder, Handle<JSFunction>::cast(getter));
1069
+ }
1070
+ ASSERT(callback->IsForeign());
1071
+ // No IC support for old-style native accessors.
1072
+ break;
1073
+ }
1074
+ case INTERCEPTOR:
1075
+ ASSERT(HasInterceptorGetter(*holder));
1076
+ return isolate()->stub_cache()->ComputeLoadInterceptor(
1077
+ name, receiver, holder);
1078
+ default:
1079
+ break;
1080
+ }
1081
+ return Handle<Code>::null();
1063
1082
  }
1064
1083
 
1065
1084
 
@@ -1083,111 +1102,139 @@ static Handle<Object> TryConvertKey(Handle<Object> key, Isolate* isolate) {
1083
1102
  }
1084
1103
 
1085
1104
 
1086
- MaybeObject* KeyedLoadIC::Load(State state,
1087
- Handle<Object> object,
1088
- Handle<Object> key,
1089
- bool force_generic_stub) {
1090
- // Check for values that can be converted into a symbol directly or
1091
- // is representable as a smi.
1092
- key = TryConvertKey(key, isolate());
1093
-
1094
- if (key->IsSymbol()) {
1095
- Handle<String> name = Handle<String>::cast(key);
1096
-
1097
- // If the object is undefined or null it's illegal to try to get any
1098
- // of its properties; throw a TypeError in that case.
1099
- if (object->IsUndefined() || object->IsNull()) {
1100
- return TypeError("non_object_property_load", object, name);
1105
+ static bool AddOneReceiverMapIfMissing(MapHandleList* receiver_maps,
1106
+ Handle<Map> new_receiver_map) {
1107
+ ASSERT(!new_receiver_map.is_null());
1108
+ for (int current = 0; current < receiver_maps->length(); ++current) {
1109
+ if (!receiver_maps->at(current).is_null() &&
1110
+ receiver_maps->at(current).is_identical_to(new_receiver_map)) {
1111
+ return false;
1101
1112
  }
1113
+ }
1114
+ receiver_maps->Add(new_receiver_map);
1115
+ return true;
1116
+ }
1102
1117
 
1103
- if (FLAG_use_ic) {
1104
- // TODO(1073): don't ignore the current stub state.
1105
-
1106
- // Use specialized code for getting the length of strings.
1107
- if (object->IsString() &&
1108
- name->Equals(isolate()->heap()->length_symbol())) {
1109
- Handle<String> string = Handle<String>::cast(object);
1110
- Handle<Code> code =
1111
- isolate()->stub_cache()->ComputeKeyedLoadStringLength(name, string);
1112
- ASSERT(!code.is_null());
1113
- set_target(*code);
1114
- TRACE_IC("KeyedLoadIC", name, state, target());
1115
- return Smi::FromInt(string->length());
1116
- }
1117
1118
 
1118
- // Use specialized code for getting the length of arrays.
1119
- if (object->IsJSArray() &&
1120
- name->Equals(isolate()->heap()->length_symbol())) {
1121
- Handle<JSArray> array = Handle<JSArray>::cast(object);
1122
- Handle<Code> code =
1123
- isolate()->stub_cache()->ComputeKeyedLoadArrayLength(name, array);
1124
- ASSERT(!code.is_null());
1125
- set_target(*code);
1126
- TRACE_IC("KeyedLoadIC", name, state, target());
1127
- return array->length();
1119
+ static void GetReceiverMapsForStub(Handle<Code> stub,
1120
+ MapHandleList* result) {
1121
+ ASSERT(stub->is_inline_cache_stub());
1122
+ ASSERT(stub->is_keyed_load_stub() || stub->is_keyed_store_stub());
1123
+ switch (stub->ic_state()) {
1124
+ case MONOMORPHIC: {
1125
+ Map* map = stub->FindFirstMap();
1126
+ if (map != NULL) {
1127
+ result->Add(Handle<Map>(map));
1128
1128
  }
1129
-
1130
- // Use specialized code for getting prototype of functions.
1131
- if (object->IsJSFunction() &&
1132
- name->Equals(isolate()->heap()->prototype_symbol()) &&
1133
- Handle<JSFunction>::cast(object)->should_have_prototype()) {
1134
- Handle<JSFunction> function = Handle<JSFunction>::cast(object);
1135
- Handle<Code> code =
1136
- isolate()->stub_cache()->ComputeKeyedLoadFunctionPrototype(
1137
- name, function);
1138
- ASSERT(!code.is_null());
1139
- set_target(*code);
1140
- TRACE_IC("KeyedLoadIC", name, state, target());
1141
- return Accessors::FunctionGetPrototype(*object, 0);
1129
+ break;
1130
+ }
1131
+ case POLYMORPHIC: {
1132
+ AssertNoAllocation no_allocation;
1133
+ int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
1134
+ for (RelocIterator it(*stub, mask); !it.done(); it.next()) {
1135
+ RelocInfo* info = it.rinfo();
1136
+ Handle<Object> object(info->target_object());
1137
+ ASSERT(object->IsMap());
1138
+ AddOneReceiverMapIfMissing(result, Handle<Map>::cast(object));
1142
1139
  }
1140
+ break;
1143
1141
  }
1142
+ case MEGAMORPHIC:
1143
+ break;
1144
+ case UNINITIALIZED:
1145
+ case PREMONOMORPHIC:
1146
+ case MONOMORPHIC_PROTOTYPE_FAILURE:
1147
+ case GENERIC:
1148
+ case DEBUG_STUB:
1149
+ UNREACHABLE();
1150
+ break;
1151
+ }
1152
+ }
1144
1153
 
1145
- // Check if the name is trivially convertible to an index and get
1146
- // the element or char if so.
1147
- uint32_t index = 0;
1148
- if (name->AsArrayIndex(&index)) {
1149
- // Rewrite to the generic keyed load stub.
1150
- if (FLAG_use_ic) set_target(*generic_stub());
1151
- return Runtime::GetElementOrCharAt(isolate(), object, index);
1152
- }
1153
1154
 
1154
- // Named lookup.
1155
- LookupResult lookup(isolate());
1156
- LookupForRead(object, name, &lookup);
1155
+ Handle<Code> KeyedLoadIC::LoadElementStub(Handle<JSObject> receiver) {
1156
+ State ic_state = target()->ic_state();
1157
1157
 
1158
- // If we did not find a property, check if we need to throw an exception.
1159
- if (!lookup.IsProperty() && IsContextual(object)) {
1160
- return ReferenceError("not_defined", name);
1161
- }
1158
+ // Don't handle megamorphic property accesses for INTERCEPTORS or CALLBACKS
1159
+ // via megamorphic stubs, since they don't have a map in their relocation info
1160
+ // and so the stubs can't be harvested for the object needed for a map check.
1161
+ if (target()->type() != Code::NORMAL) {
1162
+ TRACE_GENERIC_IC("KeyedIC", "non-NORMAL target type");
1163
+ return generic_stub();
1164
+ }
1162
1165
 
1163
- if (FLAG_use_ic) {
1164
- UpdateCaches(&lookup, state, object, name);
1165
- }
1166
+ Handle<Map> receiver_map(receiver->map());
1167
+ MapHandleList target_receiver_maps;
1168
+ if (ic_state == UNINITIALIZED || ic_state == PREMONOMORPHIC) {
1169
+ // Optimistically assume that ICs that haven't reached the MONOMORPHIC state
1170
+ // yet will do so and stay there.
1171
+ return isolate()->stub_cache()->ComputeKeyedLoadElement(receiver_map);
1172
+ }
1166
1173
 
1167
- PropertyAttributes attr;
1168
- if (lookup.IsFound() && lookup.type() == INTERCEPTOR) {
1169
- // Get the property.
1170
- Handle<Object> result =
1171
- Object::GetProperty(object, object, &lookup, name, &attr);
1172
- RETURN_IF_EMPTY_HANDLE(isolate(), result);
1173
- // If the property is not present, check if we need to throw an
1174
- // exception.
1175
- if (attr == ABSENT && IsContextual(object)) {
1176
- return ReferenceError("not_defined", name);
1177
- }
1178
- return *result;
1174
+ if (target() == *string_stub()) {
1175
+ target_receiver_maps.Add(isolate()->factory()->string_map());
1176
+ } else {
1177
+ GetReceiverMapsForStub(Handle<Code>(target()), &target_receiver_maps);
1178
+ if (target_receiver_maps.length() == 0) {
1179
+ return isolate()->stub_cache()->ComputeKeyedLoadElement(receiver_map);
1179
1180
  }
1181
+ }
1182
+
1183
+ // The first time a receiver is seen that is a transitioned version of the
1184
+ // previous monomorphic receiver type, assume the new ElementsKind is the
1185
+ // monomorphic type. This benefits global arrays that only transition
1186
+ // once, and all call sites accessing them are faster if they remain
1187
+ // monomorphic. If this optimistic assumption is not true, the IC will
1188
+ // miss again and it will become polymorphic and support both the
1189
+ // untransitioned and transitioned maps.
1190
+ if (ic_state == MONOMORPHIC &&
1191
+ IsMoreGeneralElementsKindTransition(
1192
+ target_receiver_maps.at(0)->elements_kind(),
1193
+ receiver->GetElementsKind())) {
1194
+ return isolate()->stub_cache()->ComputeKeyedLoadElement(receiver_map);
1195
+ }
1196
+
1197
+ ASSERT(ic_state != GENERIC);
1198
+
1199
+ // Determine the list of receiver maps that this call site has seen,
1200
+ // adding the map that was just encountered.
1201
+ if (!AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map)) {
1202
+ // If the miss wasn't due to an unseen map, a polymorphic stub
1203
+ // won't help, use the generic stub.
1204
+ TRACE_GENERIC_IC("KeyedIC", "same map added twice");
1205
+ return generic_stub();
1206
+ }
1180
1207
 
1181
- return object->GetProperty(*object, &lookup, *name, &attr);
1208
+ // If the maximum number of receiver maps has been exceeded, use the generic
1209
+ // version of the IC.
1210
+ if (target_receiver_maps.length() > kMaxKeyedPolymorphism) {
1211
+ TRACE_GENERIC_IC("KeyedIC", "max polymorph exceeded");
1212
+ return generic_stub();
1213
+ }
1214
+
1215
+ return isolate()->stub_cache()->ComputeLoadElementPolymorphic(
1216
+ &target_receiver_maps);
1217
+ }
1218
+
1219
+
1220
+ MaybeObject* KeyedLoadIC::Load(State state,
1221
+ Handle<Object> object,
1222
+ Handle<Object> key,
1223
+ ICMissMode miss_mode) {
1224
+ // Check for values that can be converted into a symbol directly or
1225
+ // is representable as a smi.
1226
+ key = TryConvertKey(key, isolate());
1227
+
1228
+ if (key->IsSymbol()) {
1229
+ return LoadIC::Load(state, object, Handle<String>::cast(key));
1182
1230
  }
1183
1231
 
1184
- // Do not use ICs for objects that require access checks (including
1185
- // the global object).
1186
1232
  bool use_ic = FLAG_use_ic && !object->IsAccessCheckNeeded();
1233
+ ASSERT(!(use_ic && object->IsJSGlobalProxy()));
1187
1234
 
1188
1235
  if (use_ic) {
1189
1236
  Handle<Code> stub = generic_stub();
1190
- if (!force_generic_stub) {
1237
+ if (miss_mode != MISS_FORCE_GENERIC) {
1191
1238
  if (object->IsString() && key->IsNumber()) {
1192
1239
  if (state == UNINITIALIZED) {
1193
1240
  stub = string_stub();
@@ -1200,103 +1247,74 @@ MaybeObject* KeyedLoadIC::Load(State state,
1200
1247
  } else if (receiver->HasIndexedInterceptor()) {
1201
1248
  stub = indexed_interceptor_stub();
1202
1249
  } else if (key->IsSmi() && (target() != *non_strict_arguments_stub())) {
1203
- stub = ComputeStub(receiver, LOAD, kNonStrictMode, stub);
1250
+ stub = LoadElementStub(receiver);
1204
1251
  }
1205
1252
  }
1206
1253
  } else {
1207
1254
  TRACE_GENERIC_IC("KeyedLoadIC", "force generic");
1208
1255
  }
1209
- if (!stub.is_null()) set_target(*stub);
1256
+ ASSERT(!stub.is_null());
1257
+ set_target(*stub);
1258
+ TRACE_IC("KeyedLoadIC", key, state, target());
1210
1259
  }
1211
1260
 
1212
- TRACE_IC("KeyedLoadIC", key, state, target());
1213
1261
 
1214
- // Get the property.
1215
1262
  return Runtime::GetObjectProperty(isolate(), object, key);
1216
1263
  }
1217
1264
 
1218
1265
 
1219
- void KeyedLoadIC::UpdateCaches(LookupResult* lookup,
1220
- State state,
1221
- Handle<Object> object,
1222
- Handle<String> name) {
1266
+ Handle<Code> KeyedLoadIC::ComputeLoadMonomorphic(LookupResult* lookup,
1267
+ Handle<JSObject> receiver,
1268
+ Handle<String> name) {
1223
1269
  // Bail out if we didn't find a result.
1224
- if (!lookup->IsProperty() || !lookup->IsCacheable()) return;
1225
-
1226
- if (!object->IsJSObject()) return;
1227
- Handle<JSObject> receiver = Handle<JSObject>::cast(object);
1228
-
1229
- if (HasNormalObjectsInPrototypeChain(isolate(), lookup, *object)) return;
1230
-
1231
- // Compute the code stub for this load.
1232
- Handle<Code> code;
1270
+ if (!lookup->IsProperty()) return Handle<Code>::null();
1233
1271
 
1234
- if (state == UNINITIALIZED) {
1235
- // This is the first time we execute this inline cache.
1236
- // Set the target to the pre monomorphic stub to delay
1237
- // setting the monomorphic state.
1238
- code = pre_monomorphic_stub();
1239
- } else {
1240
- // Compute a monomorphic stub.
1241
- Handle<JSObject> holder(lookup->holder());
1242
- switch (lookup->type()) {
1243
- case FIELD:
1244
- code = isolate()->stub_cache()->ComputeKeyedLoadField(
1245
- name, receiver, holder, lookup->GetFieldIndex());
1246
- break;
1247
- case CONSTANT_FUNCTION: {
1248
- Handle<JSFunction> constant(lookup->GetConstantFunction());
1249
- code = isolate()->stub_cache()->ComputeKeyedLoadConstant(
1250
- name, receiver, holder, constant);
1251
- break;
1252
- }
1253
- case CALLBACKS: {
1254
- Handle<Object> callback_object(lookup->GetCallbackObject());
1255
- if (!callback_object->IsAccessorInfo()) return;
1256
- Handle<AccessorInfo> callback =
1257
- Handle<AccessorInfo>::cast(callback_object);
1258
- if (v8::ToCData<Address>(callback->getter()) == 0) return;
1259
- code = isolate()->stub_cache()->ComputeKeyedLoadCallback(
1260
- name, receiver, holder, callback);
1261
- break;
1262
- }
1263
- case INTERCEPTOR:
1264
- ASSERT(HasInterceptorGetter(lookup->holder()));
1265
- code = isolate()->stub_cache()->ComputeKeyedLoadInterceptor(
1266
- name, receiver, holder);
1267
- break;
1268
- default:
1269
- // Always rewrite to the generic case so that we do not
1270
- // repeatedly try to rewrite.
1271
- code = generic_stub();
1272
- break;
1272
+ // Compute a monomorphic stub.
1273
+ Handle<JSObject> holder(lookup->holder());
1274
+ switch (lookup->type()) {
1275
+ case FIELD:
1276
+ return isolate()->stub_cache()->ComputeKeyedLoadField(
1277
+ name, receiver, holder, lookup->GetFieldIndex());
1278
+ case CONSTANT_FUNCTION: {
1279
+ Handle<JSFunction> constant(lookup->GetConstantFunction());
1280
+ return isolate()->stub_cache()->ComputeKeyedLoadConstant(
1281
+ name, receiver, holder, constant);
1273
1282
  }
1283
+ case CALLBACKS: {
1284
+ Handle<Object> callback_object(lookup->GetCallbackObject());
1285
+ if (!callback_object->IsAccessorInfo()) break;
1286
+ Handle<AccessorInfo> callback =
1287
+ Handle<AccessorInfo>::cast(callback_object);
1288
+ if (v8::ToCData<Address>(callback->getter()) == 0) break;
1289
+ if (!callback->IsCompatibleReceiver(*receiver)) break;
1290
+ return isolate()->stub_cache()->ComputeKeyedLoadCallback(
1291
+ name, receiver, holder, callback);
1292
+ }
1293
+ case INTERCEPTOR:
1294
+ ASSERT(HasInterceptorGetter(lookup->holder()));
1295
+ return isolate()->stub_cache()->ComputeKeyedLoadInterceptor(
1296
+ name, receiver, holder);
1297
+ default:
1298
+ // Always rewrite to the generic case so that we do not
1299
+ // repeatedly try to rewrite.
1300
+ return generic_stub();
1274
1301
  }
1275
-
1276
- // Patch the call site depending on the state of the cache. Make
1277
- // sure to always rewrite from monomorphic to megamorphic.
1278
- ASSERT(state != MONOMORPHIC_PROTOTYPE_FAILURE);
1279
- if (state == UNINITIALIZED || state == PREMONOMORPHIC) {
1280
- set_target(*code);
1281
- } else if (state == MONOMORPHIC) {
1282
- set_target(*megamorphic_stub());
1283
- }
1284
-
1285
- TRACE_IC("KeyedLoadIC", name, state, target());
1302
+ return Handle<Code>::null();
1286
1303
  }
1287
1304
 
1288
1305
 
1289
1306
  static bool StoreICableLookup(LookupResult* lookup) {
1290
1307
  // Bail out if we didn't find a result.
1291
- if (!lookup->IsFound() || lookup->type() == NULL_DESCRIPTOR) return false;
1308
+ if (!lookup->IsFound()) return false;
1292
1309
 
1293
1310
  // Bail out if inline caching is not allowed.
1294
1311
  if (!lookup->IsCacheable()) return false;
1295
1312
 
1296
1313
  // If the property is read-only, we leave the IC in its current state.
1297
- if (lookup->IsReadOnly()) return false;
1298
-
1299
- return true;
1314
+ if (lookup->IsTransition()) {
1315
+ return !lookup->GetTransitionDetails().IsReadOnly();
1316
+ }
1317
+ return !lookup->IsReadOnly();
1300
1318
  }
1301
1319
 
1302
1320
 
@@ -1304,11 +1322,16 @@ static bool LookupForWrite(Handle<JSObject> receiver,
1304
1322
  Handle<String> name,
1305
1323
  LookupResult* lookup) {
1306
1324
  receiver->LocalLookup(*name, lookup);
1325
+ if (!lookup->IsFound()) {
1326
+ receiver->map()->LookupTransition(*receiver, *name, lookup);
1327
+ }
1307
1328
  if (!StoreICableLookup(lookup)) {
1308
- return false;
1329
+ // 2nd chance: There can be accessors somewhere in the prototype chain.
1330
+ receiver->Lookup(*name, lookup);
1331
+ return lookup->IsPropertyCallbacks() && StoreICableLookup(lookup);
1309
1332
  }
1310
1333
 
1311
- if (lookup->type() == INTERCEPTOR &&
1334
+ if (lookup->IsInterceptor() &&
1312
1335
  receiver->GetNamedInterceptor()->setter()->IsUndefined()) {
1313
1336
  receiver->LocalLookupRealNamedProperty(*name, lookup);
1314
1337
  return StoreICableLookup(lookup);
@@ -1322,30 +1345,30 @@ MaybeObject* StoreIC::Store(State state,
1322
1345
  StrictModeFlag strict_mode,
1323
1346
  Handle<Object> object,
1324
1347
  Handle<String> name,
1325
- Handle<Object> value) {
1326
- if (!object->IsJSObject()) {
1327
- // Handle proxies.
1328
- if (object->IsJSProxy()) {
1329
- return JSProxy::cast(*object)->
1330
- SetProperty(*name, *value, NONE, strict_mode);
1331
- }
1348
+ Handle<Object> value,
1349
+ JSReceiver::StoreFromKeyed store_mode) {
1350
+ // Handle proxies.
1351
+ if (object->IsJSProxy()) {
1352
+ return JSProxy::cast(*object)->
1353
+ SetProperty(*name, *value, NONE, strict_mode);
1354
+ }
1332
1355
 
1333
- // If the object is undefined or null it's illegal to try to set any
1334
- // properties on it; throw a TypeError in that case.
1335
- if (object->IsUndefined() || object->IsNull()) {
1336
- return TypeError("non_object_property_store", object, name);
1337
- }
1356
+ // If the object is undefined or null it's illegal to try to set any
1357
+ // properties on it; throw a TypeError in that case.
1358
+ if (object->IsUndefined() || object->IsNull()) {
1359
+ return TypeError("non_object_property_store", object, name);
1360
+ }
1338
1361
 
1339
- // The length property of string values is read-only. Throw in strict mode.
1340
- if (strict_mode == kStrictMode && object->IsString() &&
1341
- name->Equals(isolate()->heap()->length_symbol())) {
1342
- return TypeError("strict_read_only_property", object, name);
1343
- }
1344
- // Ignore other stores where the receiver is not a JSObject.
1345
- // TODO(1475): Must check prototype chains of object wrappers.
1346
- return *value;
1362
+ // The length property of string values is read-only. Throw in strict mode.
1363
+ if (strict_mode == kStrictMode && object->IsString() &&
1364
+ name->Equals(isolate()->heap()->length_symbol())) {
1365
+ return TypeError("strict_read_only_property", object, name);
1347
1366
  }
1348
1367
 
1368
+ // Ignore other stores where the receiver is not a JSObject.
1369
+ // TODO(1475): Must check prototype chains of object wrappers.
1370
+ if (!object->IsJSObject()) return *value;
1371
+
1349
1372
  Handle<JSObject> receiver = Handle<JSObject>::cast(object);
1350
1373
 
1351
1374
  // Check if the given name is an array index.
@@ -1357,58 +1380,52 @@ MaybeObject* StoreIC::Store(State state,
1357
1380
  return *value;
1358
1381
  }
1359
1382
 
1383
+ // Observed objects are always modified through the runtime.
1384
+ if (FLAG_harmony_observation && receiver->map()->is_observed()) {
1385
+ return receiver->SetProperty(*name, *value, NONE, strict_mode, store_mode);
1386
+ }
1387
+
1360
1388
  // Use specialized code for setting the length of arrays with fast
1361
- // properties. Slow properties might indicate redefinition of the
1362
- // length property.
1363
- if (receiver->IsJSArray() &&
1389
+ // properties. Slow properties might indicate redefinition of the length
1390
+ // property.
1391
+ if (FLAG_use_ic &&
1392
+ receiver->IsJSArray() &&
1364
1393
  name->Equals(isolate()->heap()->length_symbol()) &&
1365
1394
  Handle<JSArray>::cast(receiver)->AllowsSetElementsLength() &&
1366
1395
  receiver->HasFastProperties()) {
1367
- #ifdef DEBUG
1368
- if (FLAG_trace_ic) PrintF("[StoreIC : +#length /array]\n");
1369
- #endif
1370
- Handle<Code> stub = (strict_mode == kStrictMode)
1371
- ? isolate()->builtins()->StoreIC_ArrayLength_Strict()
1372
- : isolate()->builtins()->StoreIC_ArrayLength();
1396
+ Handle<Code> stub = StoreArrayLengthStub(kind(), strict_mode).GetCode();
1373
1397
  set_target(*stub);
1374
- return receiver->SetProperty(*name, *value, NONE, strict_mode);
1398
+ TRACE_IC("StoreIC", name, state, *stub);
1399
+ return receiver->SetProperty(*name, *value, NONE, strict_mode, store_mode);
1375
1400
  }
1376
1401
 
1377
- // Lookup the property locally in the receiver.
1378
- if (FLAG_use_ic && !receiver->IsJSGlobalProxy()) {
1379
- LookupResult lookup(isolate());
1380
-
1381
- if (LookupForWrite(receiver, name, &lookup)) {
1382
- // Generate a stub for this store.
1383
- UpdateCaches(&lookup, state, strict_mode, receiver, name, value);
1384
- } else {
1385
- // Strict mode doesn't allow setting non-existent global property
1386
- // or an assignment to a read only property.
1387
- if (strict_mode == kStrictMode) {
1388
- if (lookup.IsProperty() && lookup.IsReadOnly()) {
1389
- return TypeError("strict_read_only_property", object, name);
1390
- } else if (IsContextual(object)) {
1391
- return ReferenceError("not_defined", name);
1392
- }
1393
- }
1402
+ if (receiver->IsJSGlobalProxy()) {
1403
+ if (FLAG_use_ic && kind() != Code::KEYED_STORE_IC) {
1404
+ // Generate a generic stub that goes to the runtime when we see a global
1405
+ // proxy as receiver.
1406
+ Handle<Code> stub = (strict_mode == kStrictMode)
1407
+ ? global_proxy_stub_strict()
1408
+ : global_proxy_stub();
1409
+ set_target(*stub);
1410
+ TRACE_IC("StoreIC", name, state, *stub);
1394
1411
  }
1412
+ return receiver->SetProperty(*name, *value, NONE, strict_mode, store_mode);
1395
1413
  }
1396
1414
 
1397
- if (receiver->IsJSGlobalProxy()) {
1398
- // TODO(ulan): find out why we patch this site even with --no-use-ic
1399
- // Generate a generic stub that goes to the runtime when we see a global
1400
- // proxy as receiver.
1401
- Handle<Code> stub = (strict_mode == kStrictMode)
1402
- ? global_proxy_stub_strict()
1403
- : global_proxy_stub();
1404
- if (target() != *stub) {
1405
- set_target(*stub);
1406
- TRACE_IC("StoreIC", name, state, target());
1415
+ LookupResult lookup(isolate());
1416
+ if (LookupForWrite(receiver, name, &lookup)) {
1417
+ if (FLAG_use_ic) {
1418
+ UpdateCaches(&lookup, state, strict_mode, receiver, name, value);
1407
1419
  }
1420
+ } else if (strict_mode == kStrictMode &&
1421
+ !(lookup.IsProperty() && lookup.IsReadOnly()) &&
1422
+ IsUndeclaredGlobal(object)) {
1423
+ // Strict mode doesn't allow setting non-existent global property.
1424
+ return ReferenceError("not_defined", name);
1408
1425
  }
1409
1426
 
1410
1427
  // Set the property.
1411
- return receiver->SetProperty(*name, *value, NONE, strict_mode);
1428
+ return receiver->SetProperty(*name, *value, NONE, strict_mode, store_mode);
1412
1429
  }
1413
1430
 
1414
1431
 
@@ -1420,36 +1437,30 @@ void StoreIC::UpdateCaches(LookupResult* lookup,
1420
1437
  Handle<Object> value) {
1421
1438
  ASSERT(!receiver->IsJSGlobalProxy());
1422
1439
  ASSERT(StoreICableLookup(lookup));
1440
+ ASSERT(lookup->IsFound());
1441
+
1423
1442
  // These are not cacheable, so we never see such LookupResults here.
1424
- ASSERT(lookup->type() != HANDLER);
1425
- // We get only called for properties or transitions, see StoreICableLookup.
1426
- ASSERT(lookup->type() != NULL_DESCRIPTOR);
1443
+ ASSERT(!lookup->IsHandler());
1427
1444
 
1428
- // If the property has a non-field type allowing map transitions
1429
- // where there is extra room in the object, we leave the IC in its
1430
- // current state.
1431
- PropertyType type = lookup->type();
1445
+ Handle<Code> code =
1446
+ ComputeStoreMonomorphic(lookup, strict_mode, receiver, name);
1447
+ if (code.is_null()) return;
1432
1448
 
1433
- // Compute the code stub for this store; used for rewriting to
1434
- // monomorphic state and making sure that the code stub is in the
1435
- // stub cache.
1436
- Handle<Code> code;
1437
- switch (type) {
1449
+ PatchCache(state, strict_mode, receiver, name, code);
1450
+ TRACE_IC("StoreIC", name, state, target());
1451
+ }
1452
+
1453
+
1454
+ Handle<Code> StoreIC::ComputeStoreMonomorphic(LookupResult* lookup,
1455
+ StrictModeFlag strict_mode,
1456
+ Handle<JSObject> receiver,
1457
+ Handle<String> name) {
1458
+ Handle<JSObject> holder(lookup->holder());
1459
+ switch (lookup->type()) {
1438
1460
  case FIELD:
1439
- code = isolate()->stub_cache()->ComputeStoreField(name,
1440
- receiver,
1441
- lookup->GetFieldIndex(),
1442
- Handle<Map>::null(),
1443
- strict_mode);
1444
- break;
1445
- case MAP_TRANSITION: {
1446
- if (lookup->GetAttributes() != NONE) return;
1447
- Handle<Map> transition(lookup->GetTransitionMap());
1448
- int index = transition->PropertyIndexFor(*name);
1449
- code = isolate()->stub_cache()->ComputeStoreField(
1450
- name, receiver, index, transition, strict_mode);
1451
- break;
1452
- }
1461
+ return isolate()->stub_cache()->ComputeStoreField(
1462
+ name, receiver, lookup->GetFieldIndex().field_index(),
1463
+ Handle<Map>::null(), strict_mode);
1453
1464
  case NORMAL:
1454
1465
  if (receiver->IsGlobalObject()) {
1455
1466
  // The stub generated for the global object picks the value directly
@@ -1457,98 +1468,64 @@ void StoreIC::UpdateCaches(LookupResult* lookup,
1457
1468
  // global object.
1458
1469
  Handle<GlobalObject> global = Handle<GlobalObject>::cast(receiver);
1459
1470
  Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(lookup));
1460
- code = isolate()->stub_cache()->ComputeStoreGlobal(
1471
+ return isolate()->stub_cache()->ComputeStoreGlobal(
1461
1472
  name, global, cell, strict_mode);
1462
- } else {
1463
- if (lookup->holder() != *receiver) return;
1464
- code = isolate()->stub_cache()->ComputeStoreNormal(strict_mode);
1465
1473
  }
1466
- break;
1474
+ if (!holder.is_identical_to(receiver)) break;
1475
+ return isolate()->stub_cache()->ComputeStoreNormal(strict_mode);
1467
1476
  case CALLBACKS: {
1468
- Handle<Object> callback_object(lookup->GetCallbackObject());
1469
- if (!callback_object->IsAccessorInfo()) return;
1470
- Handle<AccessorInfo> callback =
1471
- Handle<AccessorInfo>::cast(callback_object);
1472
- if (v8::ToCData<Address>(callback->setter()) == 0) return;
1473
- code = isolate()->stub_cache()->ComputeStoreCallback(
1474
- name, receiver, callback, strict_mode);
1477
+ Handle<Object> callback(lookup->GetCallbackObject());
1478
+ if (callback->IsAccessorInfo()) {
1479
+ Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(callback);
1480
+ if (v8::ToCData<Address>(info->setter()) == 0) break;
1481
+ if (!holder->HasFastProperties()) break;
1482
+ if (!info->IsCompatibleReceiver(*receiver)) break;
1483
+ return isolate()->stub_cache()->ComputeStoreCallback(
1484
+ name, receiver, holder, info, strict_mode);
1485
+ } else if (callback->IsAccessorPair()) {
1486
+ Handle<Object> setter(Handle<AccessorPair>::cast(callback)->setter());
1487
+ if (!setter->IsJSFunction()) break;
1488
+ if (holder->IsGlobalObject()) break;
1489
+ if (!holder->HasFastProperties()) break;
1490
+ return isolate()->stub_cache()->ComputeStoreViaSetter(
1491
+ name, receiver, holder, Handle<JSFunction>::cast(setter),
1492
+ strict_mode);
1493
+ }
1494
+ ASSERT(callback->IsForeign());
1495
+ // No IC support for old-style native accessors.
1475
1496
  break;
1476
1497
  }
1477
1498
  case INTERCEPTOR:
1478
1499
  ASSERT(!receiver->GetNamedInterceptor()->setter()->IsUndefined());
1479
- code = isolate()->stub_cache()->ComputeStoreInterceptor(
1500
+ return isolate()->stub_cache()->ComputeStoreInterceptor(
1480
1501
  name, receiver, strict_mode);
1481
- break;
1482
1502
  case CONSTANT_FUNCTION:
1483
- case CONSTANT_TRANSITION:
1484
- case ELEMENTS_TRANSITION:
1485
- return;
1486
- case HANDLER:
1487
- case NULL_DESCRIPTOR:
1488
- UNREACHABLE();
1489
- return;
1490
- }
1491
-
1492
- // Patch the call site depending on the state of the cache.
1493
- if (state == UNINITIALIZED || state == MONOMORPHIC_PROTOTYPE_FAILURE) {
1494
- set_target(*code);
1495
- } else if (state == MONOMORPHIC) {
1496
- // Only move to megamorphic if the target changes.
1497
- if (target() != *code) {
1498
- set_target((strict_mode == kStrictMode)
1499
- ? megamorphic_stub_strict()
1500
- : megamorphic_stub());
1501
- }
1502
- } else if (state == MEGAMORPHIC) {
1503
- // Update the stub cache.
1504
- isolate()->stub_cache()->Set(*name, receiver->map(), *code);
1505
- }
1503
+ break;
1504
+ case TRANSITION: {
1505
+ Handle<Map> transition(lookup->GetTransitionTarget());
1506
+ int descriptor = transition->LastAdded();
1506
1507
 
1507
- TRACE_IC("StoreIC", name, state, target());
1508
- }
1508
+ DescriptorArray* target_descriptors = transition->instance_descriptors();
1509
+ PropertyDetails details = target_descriptors->GetDetails(descriptor);
1509
1510
 
1511
+ if (details.type() != FIELD || details.attributes() != NONE) break;
1510
1512
 
1511
- static bool AddOneReceiverMapIfMissing(MapHandleList* receiver_maps,
1512
- Handle<Map> new_receiver_map) {
1513
- ASSERT(!new_receiver_map.is_null());
1514
- for (int current = 0; current < receiver_maps->length(); ++current) {
1515
- if (!receiver_maps->at(current).is_null() &&
1516
- receiver_maps->at(current).is_identical_to(new_receiver_map)) {
1517
- return false;
1518
- }
1519
- }
1520
- receiver_maps->Add(new_receiver_map);
1521
- return true;
1522
- }
1523
-
1524
-
1525
- void KeyedIC::GetReceiverMapsForStub(Handle<Code> stub,
1526
- MapHandleList* result) {
1527
- ASSERT(stub->is_inline_cache_stub());
1528
- if (!string_stub().is_null() && stub.is_identical_to(string_stub())) {
1529
- return result->Add(isolate()->factory()->string_map());
1530
- } else if (stub->is_keyed_load_stub() || stub->is_keyed_store_stub()) {
1531
- if (stub->ic_state() == MONOMORPHIC) {
1532
- result->Add(Handle<Map>(stub->FindFirstMap()));
1533
- } else {
1534
- ASSERT(stub->ic_state() == MEGAMORPHIC);
1535
- AssertNoAllocation no_allocation;
1536
- int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
1537
- for (RelocIterator it(*stub, mask); !it.done(); it.next()) {
1538
- RelocInfo* info = it.rinfo();
1539
- Handle<Object> object(info->target_object());
1540
- ASSERT(object->IsMap());
1541
- AddOneReceiverMapIfMissing(result, Handle<Map>::cast(object));
1542
- }
1513
+ int field_index = target_descriptors->GetFieldIndex(descriptor);
1514
+ return isolate()->stub_cache()->ComputeStoreField(
1515
+ name, receiver, field_index, transition, strict_mode);
1543
1516
  }
1517
+ case NONEXISTENT:
1518
+ case HANDLER:
1519
+ UNREACHABLE();
1520
+ break;
1544
1521
  }
1522
+ return Handle<Code>::null();
1545
1523
  }
1546
1524
 
1547
1525
 
1548
- Handle<Code> KeyedIC::ComputeStub(Handle<JSObject> receiver,
1549
- StubKind stub_kind,
1550
- StrictModeFlag strict_mode,
1551
- Handle<Code> generic_stub) {
1526
+ Handle<Code> KeyedStoreIC::StoreElementStub(Handle<JSObject> receiver,
1527
+ StubKind stub_kind,
1528
+ StrictModeFlag strict_mode) {
1552
1529
  State ic_state = target()->ic_state();
1553
1530
  KeyedAccessGrowMode grow_mode = IsGrowStubKind(stub_kind)
1554
1531
  ? ALLOW_JSARRAY_GROWTH
@@ -1557,62 +1534,70 @@ Handle<Code> KeyedIC::ComputeStub(Handle<JSObject> receiver,
1557
1534
  // Don't handle megamorphic property accesses for INTERCEPTORS or CALLBACKS
1558
1535
  // via megamorphic stubs, since they don't have a map in their relocation info
1559
1536
  // and so the stubs can't be harvested for the object needed for a map check.
1560
- if (target()->type() != NORMAL) {
1537
+ if (target()->type() != Code::NORMAL) {
1561
1538
  TRACE_GENERIC_IC("KeyedIC", "non-NORMAL target type");
1562
- return generic_stub;
1539
+ return strict_mode == kStrictMode ? generic_stub_strict() : generic_stub();
1563
1540
  }
1564
1541
 
1565
- bool monomorphic = false;
1542
+ Handle<Map> receiver_map(receiver->map());
1566
1543
  MapHandleList target_receiver_maps;
1567
- if (ic_state != UNINITIALIZED && ic_state != PREMONOMORPHIC) {
1568
- GetReceiverMapsForStub(Handle<Code>(target()), &target_receiver_maps);
1569
- }
1570
- if (!IsTransitionStubKind(stub_kind)) {
1571
- if (ic_state == UNINITIALIZED || ic_state == PREMONOMORPHIC) {
1572
- monomorphic = true;
1573
- } else {
1574
- if (ic_state == MONOMORPHIC) {
1575
- // The first time a receiver is seen that is a transitioned version of
1576
- // the previous monomorphic receiver type, assume the new ElementsKind
1577
- // is the monomorphic type. This benefits global arrays that only
1578
- // transition once, and all call sites accessing them are faster if they
1579
- // remain monomorphic. If this optimistic assumption is not true, the IC
1580
- // will miss again and it will become polymorphic and support both the
1581
- // untransitioned and transitioned maps.
1582
- monomorphic = IsMoreGeneralElementsKindTransition(
1583
- target_receiver_maps.at(0)->elements_kind(),
1584
- receiver->GetElementsKind());
1585
- }
1586
- }
1587
- }
1588
-
1589
- if (monomorphic) {
1590
- return ComputeMonomorphicStub(
1591
- receiver, stub_kind, strict_mode, generic_stub);
1592
- }
1593
- ASSERT(target() != *generic_stub);
1544
+ if (ic_state == UNINITIALIZED || ic_state == PREMONOMORPHIC) {
1545
+ // Optimistically assume that ICs that haven't reached the MONOMORPHIC state
1546
+ // yet will do so and stay there.
1547
+ stub_kind = GetNoTransitionStubKind(stub_kind);
1548
+ return isolate()->stub_cache()->ComputeKeyedStoreElement(
1549
+ receiver_map, stub_kind, strict_mode, grow_mode);
1550
+ }
1551
+
1552
+ GetReceiverMapsForStub(Handle<Code>(target()), &target_receiver_maps);
1553
+ if (target_receiver_maps.length() == 0) {
1554
+ // Optimistically assume that ICs that haven't reached the MONOMORPHIC state
1555
+ // yet will do so and stay there.
1556
+ stub_kind = GetNoTransitionStubKind(stub_kind);
1557
+ return isolate()->stub_cache()->ComputeKeyedStoreElement(
1558
+ receiver_map, stub_kind, strict_mode, grow_mode);
1559
+ }
1560
+ // The first time a receiver is seen that is a transitioned version of the
1561
+ // previous monomorphic receiver type, assume the new ElementsKind is the
1562
+ // monomorphic type. This benefits global arrays that only transition
1563
+ // once, and all call sites accessing them are faster if they remain
1564
+ // monomorphic. If this optimistic assumption is not true, the IC will
1565
+ // miss again and it will become polymorphic and support both the
1566
+ // untransitioned and transitioned maps.
1567
+ if (ic_state == MONOMORPHIC &&
1568
+ IsTransitionStubKind(stub_kind) &&
1569
+ IsMoreGeneralElementsKindTransition(
1570
+ target_receiver_maps.at(0)->elements_kind(),
1571
+ receiver->GetElementsKind())) {
1572
+ Handle<Map> monomorphic_map = ComputeTransitionedMap(receiver, stub_kind);
1573
+ ASSERT(*monomorphic_map != *receiver_map);
1574
+ stub_kind = GetNoTransitionStubKind(stub_kind);
1575
+ return isolate()->stub_cache()->ComputeKeyedStoreElement(
1576
+ monomorphic_map, stub_kind, strict_mode, grow_mode);
1577
+ }
1578
+
1579
+ ASSERT(ic_state != GENERIC);
1594
1580
 
1595
- // Determine the list of receiver maps that this call site has seen,
1596
- // adding the map that was just encountered.
1597
- Handle<Map> receiver_map(receiver->map());
1598
1581
  bool map_added =
1599
1582
  AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map);
1583
+
1600
1584
  if (IsTransitionStubKind(stub_kind)) {
1601
1585
  Handle<Map> new_map = ComputeTransitionedMap(receiver, stub_kind);
1602
1586
  map_added |= AddOneReceiverMapIfMissing(&target_receiver_maps, new_map);
1603
1587
  }
1588
+
1604
1589
  if (!map_added) {
1605
1590
  // If the miss wasn't due to an unseen map, a polymorphic stub
1606
1591
  // won't help, use the generic stub.
1607
1592
  TRACE_GENERIC_IC("KeyedIC", "same map added twice");
1608
- return generic_stub;
1593
+ return strict_mode == kStrictMode ? generic_stub_strict() : generic_stub();
1609
1594
  }
1610
1595
 
1611
1596
  // If the maximum number of receiver maps has been exceeded, use the generic
1612
1597
  // version of the IC.
1613
1598
  if (target_receiver_maps.length() > kMaxKeyedPolymorphism) {
1614
1599
  TRACE_GENERIC_IC("KeyedIC", "max polymorph exceeded");
1615
- return generic_stub;
1600
+ return strict_mode == kStrictMode ? generic_stub_strict() : generic_stub();
1616
1601
  }
1617
1602
 
1618
1603
  if ((Code::GetKeyedAccessGrowMode(target()->extra_ic_state()) ==
@@ -1620,81 +1605,34 @@ Handle<Code> KeyedIC::ComputeStub(Handle<JSObject> receiver,
1620
1605
  grow_mode = ALLOW_JSARRAY_GROWTH;
1621
1606
  }
1622
1607
 
1623
- Handle<PolymorphicCodeCache> cache =
1624
- isolate()->factory()->polymorphic_code_cache();
1625
- Code::ExtraICState extra_state = Code::ComputeExtraICState(grow_mode,
1626
- strict_mode);
1627
- Code::Flags flags = Code::ComputeFlags(kind(), MEGAMORPHIC, extra_state);
1628
- Handle<Object> probe = cache->Lookup(&target_receiver_maps, flags);
1629
- if (probe->IsCode()) return Handle<Code>::cast(probe);
1630
-
1631
- Handle<Code> stub =
1632
- ComputePolymorphicStub(&target_receiver_maps, strict_mode, grow_mode);
1633
- PolymorphicCodeCache::Update(cache, &target_receiver_maps, flags, stub);
1634
- return stub;
1608
+ return isolate()->stub_cache()->ComputeStoreElementPolymorphic(
1609
+ &target_receiver_maps, grow_mode, strict_mode);
1635
1610
  }
1636
1611
 
1637
1612
 
1638
- Handle<Code> KeyedIC::ComputeMonomorphicStubWithoutMapCheck(
1639
- Handle<Map> receiver_map,
1640
- StrictModeFlag strict_mode,
1641
- KeyedAccessGrowMode grow_mode) {
1642
- if ((receiver_map->instance_type() & kNotStringTag) == 0) {
1643
- ASSERT(!string_stub().is_null());
1644
- return string_stub();
1645
- } else {
1646
- ASSERT(receiver_map->has_dictionary_elements() ||
1647
- receiver_map->has_fast_smi_or_object_elements() ||
1648
- receiver_map->has_fast_double_elements() ||
1649
- receiver_map->has_external_array_elements());
1650
- bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE;
1651
- return GetElementStubWithoutMapCheck(is_js_array,
1652
- receiver_map->elements_kind(),
1653
- grow_mode);
1654
- }
1655
- }
1656
-
1657
-
1658
- Handle<Code> KeyedIC::ComputeMonomorphicStub(Handle<JSObject> receiver,
1659
- StubKind stub_kind,
1660
- StrictModeFlag strict_mode,
1661
- Handle<Code> generic_stub) {
1662
- if (receiver->HasFastSmiOrObjectElements() ||
1663
- receiver->HasExternalArrayElements() ||
1664
- receiver->HasFastDoubleElements() ||
1665
- receiver->HasDictionaryElements()) {
1666
- return isolate()->stub_cache()->ComputeKeyedLoadOrStoreElement(
1667
- receiver, stub_kind, strict_mode);
1668
- } else {
1669
- return generic_stub;
1670
- }
1671
- }
1672
-
1673
-
1674
- Handle<Map> KeyedIC::ComputeTransitionedMap(Handle<JSObject> receiver,
1675
- StubKind stub_kind) {
1613
+ Handle<Map> KeyedStoreIC::ComputeTransitionedMap(Handle<JSObject> receiver,
1614
+ StubKind stub_kind) {
1676
1615
  switch (stub_kind) {
1677
- case KeyedIC::STORE_TRANSITION_SMI_TO_OBJECT:
1678
- case KeyedIC::STORE_TRANSITION_DOUBLE_TO_OBJECT:
1679
- case KeyedIC::STORE_AND_GROW_TRANSITION_SMI_TO_OBJECT:
1680
- case KeyedIC::STORE_AND_GROW_TRANSITION_DOUBLE_TO_OBJECT:
1616
+ case STORE_TRANSITION_SMI_TO_OBJECT:
1617
+ case STORE_TRANSITION_DOUBLE_TO_OBJECT:
1618
+ case STORE_AND_GROW_TRANSITION_SMI_TO_OBJECT:
1619
+ case STORE_AND_GROW_TRANSITION_DOUBLE_TO_OBJECT:
1681
1620
  return JSObject::GetElementsTransitionMap(receiver, FAST_ELEMENTS);
1682
- case KeyedIC::STORE_TRANSITION_SMI_TO_DOUBLE:
1683
- case KeyedIC::STORE_AND_GROW_TRANSITION_SMI_TO_DOUBLE:
1621
+ case STORE_TRANSITION_SMI_TO_DOUBLE:
1622
+ case STORE_AND_GROW_TRANSITION_SMI_TO_DOUBLE:
1684
1623
  return JSObject::GetElementsTransitionMap(receiver, FAST_DOUBLE_ELEMENTS);
1685
- case KeyedIC::STORE_TRANSITION_HOLEY_SMI_TO_OBJECT:
1686
- case KeyedIC::STORE_TRANSITION_HOLEY_DOUBLE_TO_OBJECT:
1687
- case KeyedIC::STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_OBJECT:
1688
- case KeyedIC::STORE_AND_GROW_TRANSITION_HOLEY_DOUBLE_TO_OBJECT:
1624
+ case STORE_TRANSITION_HOLEY_SMI_TO_OBJECT:
1625
+ case STORE_TRANSITION_HOLEY_DOUBLE_TO_OBJECT:
1626
+ case STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_OBJECT:
1627
+ case STORE_AND_GROW_TRANSITION_HOLEY_DOUBLE_TO_OBJECT:
1689
1628
  return JSObject::GetElementsTransitionMap(receiver,
1690
1629
  FAST_HOLEY_ELEMENTS);
1691
- case KeyedIC::STORE_TRANSITION_HOLEY_SMI_TO_DOUBLE:
1692
- case KeyedIC::STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_DOUBLE:
1630
+ case STORE_TRANSITION_HOLEY_SMI_TO_DOUBLE:
1631
+ case STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_DOUBLE:
1693
1632
  return JSObject::GetElementsTransitionMap(receiver,
1694
1633
  FAST_HOLEY_DOUBLE_ELEMENTS);
1695
- case KeyedIC::LOAD:
1696
- case KeyedIC::STORE_NO_TRANSITION:
1697
- case KeyedIC::STORE_AND_GROW_NO_TRANSITION:
1634
+ case STORE_NO_TRANSITION:
1635
+ case STORE_AND_GROW_NO_TRANSITION:
1698
1636
  UNREACHABLE();
1699
1637
  break;
1700
1638
  }
@@ -1702,54 +1640,9 @@ Handle<Map> KeyedIC::ComputeTransitionedMap(Handle<JSObject> receiver,
1702
1640
  }
1703
1641
 
1704
1642
 
1705
- Handle<Code> KeyedStoreIC::GetElementStubWithoutMapCheck(
1706
- bool is_js_array,
1707
- ElementsKind elements_kind,
1708
- KeyedAccessGrowMode grow_mode) {
1709
- return KeyedStoreElementStub(is_js_array, elements_kind, grow_mode).GetCode();
1710
- }
1711
-
1712
-
1713
- Handle<Code> KeyedStoreIC::ComputePolymorphicStub(
1714
- MapHandleList* receiver_maps,
1715
- StrictModeFlag strict_mode,
1716
- KeyedAccessGrowMode grow_mode) {
1717
- // Collect MONOMORPHIC stubs for all target_receiver_maps.
1718
- CodeHandleList handler_ics(receiver_maps->length());
1719
- MapHandleList transitioned_maps(receiver_maps->length());
1720
- for (int i = 0; i < receiver_maps->length(); ++i) {
1721
- Handle<Map> receiver_map(receiver_maps->at(i));
1722
- Handle<Code> cached_stub;
1723
- Handle<Map> transitioned_map =
1724
- receiver_map->FindTransitionedMap(receiver_maps);
1725
- if (!transitioned_map.is_null()) {
1726
- cached_stub = ElementsTransitionAndStoreStub(
1727
- receiver_map->elements_kind(), // original elements_kind
1728
- transitioned_map->elements_kind(),
1729
- receiver_map->instance_type() == JS_ARRAY_TYPE, // is_js_array
1730
- strict_mode, grow_mode).GetCode();
1731
- } else {
1732
- cached_stub = ComputeMonomorphicStubWithoutMapCheck(receiver_map,
1733
- strict_mode,
1734
- grow_mode);
1735
- }
1736
- ASSERT(!cached_stub.is_null());
1737
- handler_ics.Add(cached_stub);
1738
- transitioned_maps.Add(transitioned_map);
1739
- }
1740
- KeyedStoreStubCompiler compiler(isolate(), strict_mode, grow_mode);
1741
- Handle<Code> code = compiler.CompileStorePolymorphic(
1742
- receiver_maps, &handler_ics, &transitioned_maps);
1743
- isolate()->counters()->keyed_store_polymorphic_stubs()->Increment();
1744
- PROFILE(isolate(),
1745
- CodeCreateEvent(Logger::KEYED_STORE_MEGAMORPHIC_IC_TAG, *code, 0));
1746
- return code;
1747
- }
1748
-
1749
-
1750
- KeyedIC::StubKind KeyedStoreIC::GetStubKind(Handle<JSObject> receiver,
1751
- Handle<Object> key,
1752
- Handle<Object> value) {
1643
+ KeyedStoreIC::StubKind KeyedStoreIC::GetStubKind(Handle<JSObject> receiver,
1644
+ Handle<Object> key,
1645
+ Handle<Object> value) {
1753
1646
  ASSERT(key->IsSmi());
1754
1647
  int index = Smi::cast(*key)->value();
1755
1648
  bool allow_growth = receiver->IsJSArray() &&
@@ -1818,155 +1711,94 @@ MaybeObject* KeyedStoreIC::Store(State state,
1818
1711
  Handle<Object> object,
1819
1712
  Handle<Object> key,
1820
1713
  Handle<Object> value,
1821
- bool force_generic) {
1714
+ ICMissMode miss_mode) {
1822
1715
  // Check for values that can be converted into a symbol directly or
1823
1716
  // is representable as a smi.
1824
1717
  key = TryConvertKey(key, isolate());
1825
1718
 
1826
1719
  if (key->IsSymbol()) {
1827
- Handle<String> name = Handle<String>::cast(key);
1828
-
1829
- // Handle proxies.
1830
- if (object->IsJSProxy()) {
1831
- return JSProxy::cast(*object)->SetProperty(
1832
- *name, *value, NONE, strict_mode);
1833
- }
1834
-
1835
- // If the object is undefined or null it's illegal to try to set any
1836
- // properties on it; throw a TypeError in that case.
1837
- if (object->IsUndefined() || object->IsNull()) {
1838
- return TypeError("non_object_property_store", object, name);
1839
- }
1840
-
1841
- // Ignore stores where the receiver is not a JSObject.
1842
- if (!object->IsJSObject()) return *value;
1843
- Handle<JSObject> receiver = Handle<JSObject>::cast(object);
1844
-
1845
- // Check if the given name is an array index.
1846
- uint32_t index;
1847
- if (name->AsArrayIndex(&index)) {
1848
- Handle<Object> result =
1849
- JSObject::SetElement(receiver, index, value, NONE, strict_mode);
1850
- RETURN_IF_EMPTY_HANDLE(isolate(), result);
1851
- return *value;
1852
- }
1853
-
1854
- // Update inline cache and stub cache.
1855
- if (FLAG_use_ic && !receiver->IsJSGlobalProxy()) {
1856
- LookupResult lookup(isolate());
1857
- if (LookupForWrite(receiver, name, &lookup)) {
1858
- UpdateCaches(&lookup, state, strict_mode, receiver, name, value);
1859
- }
1860
- }
1861
-
1862
- // Set the property.
1863
- return receiver->SetProperty(*name, *value, NONE, strict_mode);
1720
+ return StoreIC::Store(state,
1721
+ strict_mode,
1722
+ object,
1723
+ Handle<String>::cast(key),
1724
+ value,
1725
+ JSReceiver::MAY_BE_STORE_FROM_KEYED);
1864
1726
  }
1865
1727
 
1866
- // Do not use ICs for objects that require access checks (including
1867
- // the global object).
1868
- bool use_ic = FLAG_use_ic && !object->IsAccessCheckNeeded();
1728
+ bool use_ic = FLAG_use_ic && !object->IsAccessCheckNeeded() &&
1729
+ !(FLAG_harmony_observation && object->IsJSObject() &&
1730
+ JSObject::cast(*object)->map()->is_observed());
1869
1731
  ASSERT(!(use_ic && object->IsJSGlobalProxy()));
1870
1732
 
1871
1733
  if (use_ic) {
1872
1734
  Handle<Code> stub = (strict_mode == kStrictMode)
1873
1735
  ? generic_stub_strict()
1874
1736
  : generic_stub();
1875
- if (object->IsJSObject()) {
1876
- Handle<JSObject> receiver = Handle<JSObject>::cast(object);
1877
- if (receiver->elements()->map() ==
1878
- isolate()->heap()->non_strict_arguments_elements_map()) {
1879
- stub = non_strict_arguments_stub();
1880
- } else if (!force_generic) {
1881
- if (key->IsSmi() && (target() != *non_strict_arguments_stub())) {
1737
+ if (miss_mode != MISS_FORCE_GENERIC) {
1738
+ if (object->IsJSObject()) {
1739
+ Handle<JSObject> receiver = Handle<JSObject>::cast(object);
1740
+ if (receiver->elements()->map() ==
1741
+ isolate()->heap()->non_strict_arguments_elements_map()) {
1742
+ stub = non_strict_arguments_stub();
1743
+ } else if (key->IsSmi() && (target() != *non_strict_arguments_stub())) {
1882
1744
  StubKind stub_kind = GetStubKind(receiver, key, value);
1883
- stub = ComputeStub(receiver, stub_kind, strict_mode, stub);
1745
+ stub = StoreElementStub(receiver, stub_kind, strict_mode);
1884
1746
  }
1885
- } else {
1886
- TRACE_GENERIC_IC("KeyedStoreIC", "force generic");
1887
1747
  }
1748
+ } else {
1749
+ TRACE_GENERIC_IC("KeyedStoreIC", "force generic");
1888
1750
  }
1889
- if (!stub.is_null()) set_target(*stub);
1751
+ ASSERT(!stub.is_null());
1752
+ set_target(*stub);
1753
+ TRACE_IC("KeyedStoreIC", key, state, target());
1890
1754
  }
1891
1755
 
1892
- TRACE_IC("KeyedStoreIC", key, state, target());
1893
-
1894
- // Set the property.
1895
1756
  return Runtime::SetObjectProperty(
1896
1757
  isolate(), object , key, value, NONE, strict_mode);
1897
1758
  }
1898
1759
 
1899
1760
 
1900
- void KeyedStoreIC::UpdateCaches(LookupResult* lookup,
1901
- State state,
1902
- StrictModeFlag strict_mode,
1903
- Handle<JSObject> receiver,
1904
- Handle<String> name,
1905
- Handle<Object> value) {
1906
- ASSERT(!receiver->IsJSGlobalProxy());
1907
- ASSERT(StoreICableLookup(lookup));
1908
- // These are not cacheable, so we never see such LookupResults here.
1909
- ASSERT(lookup->type() != HANDLER);
1910
- // We get only called for properties or transitions, see StoreICableLookup.
1911
- ASSERT(lookup->type() != NULL_DESCRIPTOR);
1912
-
1761
+ Handle<Code> KeyedStoreIC::ComputeStoreMonomorphic(LookupResult* lookup,
1762
+ StrictModeFlag strict_mode,
1763
+ Handle<JSObject> receiver,
1764
+ Handle<String> name) {
1913
1765
  // If the property has a non-field type allowing map transitions
1914
1766
  // where there is extra room in the object, we leave the IC in its
1915
1767
  // current state.
1916
- PropertyType type = lookup->type();
1917
-
1918
- // Compute the code stub for this store; used for rewriting to
1919
- // monomorphic state and making sure that the code stub is in the
1920
- // stub cache.
1921
- Handle<Code> code;
1922
-
1923
- switch (type) {
1768
+ switch (lookup->type()) {
1924
1769
  case FIELD:
1925
- code = isolate()->stub_cache()->ComputeKeyedStoreField(
1926
- name, receiver, lookup->GetFieldIndex(),
1770
+ return isolate()->stub_cache()->ComputeKeyedStoreField(
1771
+ name, receiver, lookup->GetFieldIndex().field_index(),
1927
1772
  Handle<Map>::null(), strict_mode);
1928
- break;
1929
- case MAP_TRANSITION:
1930
- if (lookup->GetAttributes() == NONE) {
1931
- Handle<Map> transition(lookup->GetTransitionMap());
1932
- int index = transition->PropertyIndexFor(*name);
1933
- code = isolate()->stub_cache()->ComputeKeyedStoreField(
1934
- name, receiver, index, transition, strict_mode);
1935
- break;
1773
+ case TRANSITION: {
1774
+ Handle<Map> transition(lookup->GetTransitionTarget());
1775
+ int descriptor = transition->LastAdded();
1776
+
1777
+ DescriptorArray* target_descriptors = transition->instance_descriptors();
1778
+ PropertyDetails details = target_descriptors->GetDetails(descriptor);
1779
+
1780
+ if (details.type() == FIELD && details.attributes() == NONE) {
1781
+ int field_index = target_descriptors->GetFieldIndex(descriptor);
1782
+ return isolate()->stub_cache()->ComputeKeyedStoreField(
1783
+ name, receiver, field_index, transition, strict_mode);
1936
1784
  }
1937
1785
  // fall through.
1786
+ }
1938
1787
  case NORMAL:
1939
1788
  case CONSTANT_FUNCTION:
1940
1789
  case CALLBACKS:
1941
1790
  case INTERCEPTOR:
1942
- case CONSTANT_TRANSITION:
1943
- case ELEMENTS_TRANSITION:
1944
1791
  // Always rewrite to the generic case so that we do not
1945
1792
  // repeatedly try to rewrite.
1946
- code = (strict_mode == kStrictMode)
1793
+ return (strict_mode == kStrictMode)
1947
1794
  ? generic_stub_strict()
1948
1795
  : generic_stub();
1949
- break;
1950
1796
  case HANDLER:
1951
- case NULL_DESCRIPTOR:
1797
+ case NONEXISTENT:
1952
1798
  UNREACHABLE();
1953
- return;
1954
- }
1955
-
1956
- ASSERT(!code.is_null());
1957
-
1958
- // Patch the call site depending on the state of the cache. Make
1959
- // sure to always rewrite from monomorphic to megamorphic.
1960
- ASSERT(state != MONOMORPHIC_PROTOTYPE_FAILURE);
1961
- if (state == UNINITIALIZED || state == PREMONOMORPHIC) {
1962
- set_target(*code);
1963
- } else if (state == MONOMORPHIC) {
1964
- set_target((strict_mode == kStrictMode)
1965
- ? *megamorphic_stub_strict()
1966
- : *megamorphic_stub());
1799
+ break;
1967
1800
  }
1968
-
1969
- TRACE_IC("KeyedStoreIC", name, state, target());
1801
+ return Handle<Code>::null();
1970
1802
  }
1971
1803
 
1972
1804
 
@@ -1988,13 +1820,12 @@ RUNTIME_FUNCTION(MaybeObject*, CallIC_Miss) {
1988
1820
  extra_ic_state,
1989
1821
  args.at<Object>(0),
1990
1822
  args.at<String>(1));
1991
- // Result could be a function or a failure.
1992
- JSFunction* raw_function = NULL;
1823
+ JSFunction* raw_function;
1993
1824
  if (!maybe_result->To(&raw_function)) return maybe_result;
1994
1825
 
1995
1826
  // The first time the inline cache is updated may be the first time the
1996
- // function it references gets called. If the function is lazily compiled
1997
- // then the first call will trigger a compilation. We check for this case
1827
+ // function it references gets called. If the function is lazily compiled
1828
+ // then the first call will trigger a compilation. We check for this case
1998
1829
  // and we do the compilation immediately, instead of waiting for the stub
1999
1830
  // currently attached to the JSFunction object to trigger compilation.
2000
1831
  if (raw_function->is_compiled()) return raw_function;
@@ -2029,7 +1860,7 @@ RUNTIME_FUNCTION(MaybeObject*, KeyedCallIC_Miss) {
2029
1860
  RUNTIME_FUNCTION(MaybeObject*, LoadIC_Miss) {
2030
1861
  HandleScope scope(isolate);
2031
1862
  ASSERT(args.length() == 2);
2032
- LoadIC ic(isolate);
1863
+ LoadIC ic(IC::NO_EXTRA_FRAME, isolate);
2033
1864
  IC::State state = IC::StateFrom(ic.target(), args[0], args[1]);
2034
1865
  return ic.Load(state, args.at<Object>(0), args.at<String>(1));
2035
1866
  }
@@ -2039,18 +1870,30 @@ RUNTIME_FUNCTION(MaybeObject*, LoadIC_Miss) {
2039
1870
  RUNTIME_FUNCTION(MaybeObject*, KeyedLoadIC_Miss) {
2040
1871
  HandleScope scope(isolate);
2041
1872
  ASSERT(args.length() == 2);
2042
- KeyedLoadIC ic(isolate);
1873
+ KeyedLoadIC ic(IC::NO_EXTRA_FRAME, isolate);
2043
1874
  IC::State state = IC::StateFrom(ic.target(), args[0], args[1]);
2044
- return ic.Load(state, args.at<Object>(0), args.at<Object>(1), false);
1875
+ return ic.Load(state, args.at<Object>(0), args.at<Object>(1), MISS);
1876
+ }
1877
+
1878
+
1879
+ RUNTIME_FUNCTION(MaybeObject*, KeyedLoadIC_MissFromStubFailure) {
1880
+ HandleScope scope(isolate);
1881
+ ASSERT(args.length() == 2);
1882
+ KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate);
1883
+ IC::State state = IC::StateFrom(ic.target(), args[0], args[1]);
1884
+ return ic.Load(state, args.at<Object>(0), args.at<Object>(1), MISS);
2045
1885
  }
2046
1886
 
2047
1887
 
2048
1888
  RUNTIME_FUNCTION(MaybeObject*, KeyedLoadIC_MissForceGeneric) {
2049
1889
  HandleScope scope(isolate);
2050
1890
  ASSERT(args.length() == 2);
2051
- KeyedLoadIC ic(isolate);
1891
+ KeyedLoadIC ic(IC::NO_EXTRA_FRAME, isolate);
2052
1892
  IC::State state = IC::StateFrom(ic.target(), args[0], args[1]);
2053
- return ic.Load(state, args.at<Object>(0), args.at<Object>(1), true);
1893
+ return ic.Load(state,
1894
+ args.at<Object>(0),
1895
+ args.at<Object>(1),
1896
+ MISS_FORCE_GENERIC);
2054
1897
  }
2055
1898
 
2056
1899
 
@@ -2083,13 +1926,13 @@ RUNTIME_FUNCTION(MaybeObject*, StoreIC_ArrayLength) {
2083
1926
  // The length property has to be a writable callback property.
2084
1927
  LookupResult debug_lookup(isolate);
2085
1928
  receiver->LocalLookup(isolate->heap()->length_symbol(), &debug_lookup);
2086
- ASSERT(debug_lookup.type() == CALLBACKS && !debug_lookup.IsReadOnly());
1929
+ ASSERT(debug_lookup.IsPropertyCallbacks() && !debug_lookup.IsReadOnly());
2087
1930
  #endif
2088
1931
 
2089
1932
  Object* result;
2090
- { MaybeObject* maybe_result = receiver->SetElementsLength(len);
2091
- if (!maybe_result->ToObject(&result)) return maybe_result;
2092
- }
1933
+ MaybeObject* maybe_result = receiver->SetElementsLength(len);
1934
+ if (!maybe_result->To(&result)) return maybe_result;
1935
+
2093
1936
  return len;
2094
1937
  }
2095
1938
 
@@ -2142,7 +1985,7 @@ RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_Miss) {
2142
1985
  args.at<Object>(0),
2143
1986
  args.at<Object>(1),
2144
1987
  args.at<Object>(2),
2145
- false);
1988
+ MISS);
2146
1989
  }
2147
1990
 
2148
1991
 
@@ -2175,7 +2018,7 @@ RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_MissForceGeneric) {
2175
2018
  args.at<Object>(0),
2176
2019
  args.at<Object>(1),
2177
2020
  args.at<Object>(2),
2178
- true);
2021
+ MISS_FORCE_GENERIC);
2179
2022
  }
2180
2023
 
2181
2024
 
@@ -2203,7 +2046,7 @@ UnaryOpIC::State UnaryOpIC::ToState(TypeInfo type_info) {
2203
2046
  case HEAP_NUMBER:
2204
2047
  return MONOMORPHIC;
2205
2048
  case GENERIC:
2206
- return MEGAMORPHIC;
2049
+ return ::v8::internal::GENERIC;
2207
2050
  }
2208
2051
  UNREACHABLE();
2209
2052
  return ::v8::internal::UNINITIALIZED;
@@ -2253,11 +2096,10 @@ const char* BinaryOpIC::GetName(TypeInfo type_info) {
2253
2096
  switch (type_info) {
2254
2097
  case UNINITIALIZED: return "Uninitialized";
2255
2098
  case SMI: return "SMI";
2256
- case INT32: return "Int32s";
2257
- case HEAP_NUMBER: return "HeapNumbers";
2099
+ case INT32: return "Int32";
2100
+ case HEAP_NUMBER: return "HeapNumber";
2258
2101
  case ODDBALL: return "Oddball";
2259
- case BOTH_STRING: return "BothStrings";
2260
- case STRING: return "Strings";
2102
+ case STRING: return "String";
2261
2103
  case GENERIC: return "Generic";
2262
2104
  default: return "Invalid";
2263
2105
  }
@@ -2272,69 +2114,16 @@ BinaryOpIC::State BinaryOpIC::ToState(TypeInfo type_info) {
2272
2114
  case INT32:
2273
2115
  case HEAP_NUMBER:
2274
2116
  case ODDBALL:
2275
- case BOTH_STRING:
2276
2117
  case STRING:
2277
2118
  return MONOMORPHIC;
2278
2119
  case GENERIC:
2279
- return MEGAMORPHIC;
2120
+ return ::v8::internal::GENERIC;
2280
2121
  }
2281
2122
  UNREACHABLE();
2282
2123
  return ::v8::internal::UNINITIALIZED;
2283
2124
  }
2284
2125
 
2285
2126
 
2286
- BinaryOpIC::TypeInfo BinaryOpIC::JoinTypes(BinaryOpIC::TypeInfo x,
2287
- BinaryOpIC::TypeInfo y) {
2288
- if (x == UNINITIALIZED) return y;
2289
- if (y == UNINITIALIZED) return x;
2290
- if (x == y) return x;
2291
- if (x == BOTH_STRING && y == STRING) return STRING;
2292
- if (x == STRING && y == BOTH_STRING) return STRING;
2293
- if (x == STRING || x == BOTH_STRING || y == STRING || y == BOTH_STRING) {
2294
- return GENERIC;
2295
- }
2296
- if (x > y) return x;
2297
- return y;
2298
- }
2299
-
2300
-
2301
- BinaryOpIC::TypeInfo BinaryOpIC::GetTypeInfo(Handle<Object> left,
2302
- Handle<Object> right) {
2303
- ::v8::internal::TypeInfo left_type =
2304
- ::v8::internal::TypeInfo::TypeFromValue(left);
2305
- ::v8::internal::TypeInfo right_type =
2306
- ::v8::internal::TypeInfo::TypeFromValue(right);
2307
-
2308
- if (left_type.IsSmi() && right_type.IsSmi()) {
2309
- return SMI;
2310
- }
2311
-
2312
- if (left_type.IsInteger32() && right_type.IsInteger32()) {
2313
- // Platforms with 32-bit Smis have no distinct INT32 type.
2314
- if (kSmiValueSize == 32) return SMI;
2315
- return INT32;
2316
- }
2317
-
2318
- if (left_type.IsNumber() && right_type.IsNumber()) {
2319
- return HEAP_NUMBER;
2320
- }
2321
-
2322
- // Patching for fast string ADD makes sense even if only one of the
2323
- // arguments is a string.
2324
- if (left_type.IsString()) {
2325
- return right_type.IsString() ? BOTH_STRING : STRING;
2326
- } else if (right_type.IsString()) {
2327
- return STRING;
2328
- }
2329
-
2330
- // Check for oddball objects.
2331
- if (left->IsUndefined() && right->IsNumber()) return ODDBALL;
2332
- if (left->IsNumber() && right->IsUndefined()) return ODDBALL;
2333
-
2334
- return GENERIC;
2335
- }
2336
-
2337
-
2338
2127
  RUNTIME_FUNCTION(MaybeObject*, UnaryOp_Patch) {
2339
2128
  ASSERT(args.length() == 4);
2340
2129
 
@@ -2352,10 +2141,13 @@ RUNTIME_FUNCTION(MaybeObject*, UnaryOp_Patch) {
2352
2141
  Handle<Code> code = stub.GetCode();
2353
2142
  if (!code.is_null()) {
2354
2143
  if (FLAG_trace_ic) {
2355
- PrintF("[UnaryOpIC (%s->%s)#%s]\n",
2144
+ PrintF("[UnaryOpIC in ");
2145
+ JavaScriptFrame::PrintTop(stdout, false, true);
2146
+ PrintF(" (%s->%s)#%s @ %p]\n",
2356
2147
  UnaryOpIC::GetName(previous_type),
2357
2148
  UnaryOpIC::GetName(type),
2358
- Token::Name(op));
2149
+ Token::Name(op),
2150
+ static_cast<void*>(*code));
2359
2151
  }
2360
2152
  UnaryOpIC ic(isolate);
2361
2153
  ic.patch(*code);
@@ -2386,25 +2178,72 @@ RUNTIME_FUNCTION(MaybeObject*, UnaryOp_Patch) {
2386
2178
  return *result;
2387
2179
  }
2388
2180
 
2181
+
2182
+ static BinaryOpIC::TypeInfo TypeInfoFromValue(Handle<Object> value,
2183
+ Token::Value op) {
2184
+ ::v8::internal::TypeInfo type =
2185
+ ::v8::internal::TypeInfo::TypeFromValue(value);
2186
+ if (type.IsSmi()) return BinaryOpIC::SMI;
2187
+ if (type.IsInteger32()) {
2188
+ if (kSmiValueSize == 32) return BinaryOpIC::SMI;
2189
+ return BinaryOpIC::INT32;
2190
+ }
2191
+ if (type.IsNumber()) return BinaryOpIC::HEAP_NUMBER;
2192
+ if (type.IsString()) return BinaryOpIC::STRING;
2193
+ if (value->IsUndefined()) {
2194
+ if (op == Token::BIT_AND ||
2195
+ op == Token::BIT_OR ||
2196
+ op == Token::BIT_XOR ||
2197
+ op == Token::SAR ||
2198
+ op == Token::SHL ||
2199
+ op == Token::SHR) {
2200
+ if (kSmiValueSize == 32) return BinaryOpIC::SMI;
2201
+ return BinaryOpIC::INT32;
2202
+ }
2203
+ return BinaryOpIC::ODDBALL;
2204
+ }
2205
+ return BinaryOpIC::GENERIC;
2206
+ }
2207
+
2208
+
2209
+ static BinaryOpIC::TypeInfo InputState(BinaryOpIC::TypeInfo old_type,
2210
+ Handle<Object> value,
2211
+ Token::Value op) {
2212
+ BinaryOpIC::TypeInfo new_type = TypeInfoFromValue(value, op);
2213
+ if (old_type == BinaryOpIC::STRING) {
2214
+ if (new_type == BinaryOpIC::STRING) return new_type;
2215
+ return BinaryOpIC::GENERIC;
2216
+ }
2217
+ return Max(old_type, new_type);
2218
+ }
2219
+
2220
+
2389
2221
  RUNTIME_FUNCTION(MaybeObject*, BinaryOp_Patch) {
2390
- ASSERT(args.length() == 5);
2222
+ ASSERT(args.length() == 3);
2391
2223
 
2392
2224
  HandleScope scope(isolate);
2393
2225
  Handle<Object> left = args.at<Object>(0);
2394
2226
  Handle<Object> right = args.at<Object>(1);
2395
2227
  int key = args.smi_at(2);
2396
- Token::Value op = static_cast<Token::Value>(args.smi_at(3));
2397
- BinaryOpIC::TypeInfo previous_type =
2398
- static_cast<BinaryOpIC::TypeInfo>(args.smi_at(4));
2228
+ Token::Value op = BinaryOpStub::decode_op_from_minor_key(key);
2229
+ BinaryOpIC::TypeInfo previous_left, previous_right, unused_previous_result;
2230
+ BinaryOpStub::decode_types_from_minor_key(
2231
+ key, &previous_left, &previous_right, &unused_previous_result);
2399
2232
 
2400
- BinaryOpIC::TypeInfo type = BinaryOpIC::GetTypeInfo(left, right);
2401
- type = BinaryOpIC::JoinTypes(type, previous_type);
2233
+ BinaryOpIC::TypeInfo new_left = InputState(previous_left, left, op);
2234
+ BinaryOpIC::TypeInfo new_right = InputState(previous_right, right, op);
2402
2235
  BinaryOpIC::TypeInfo result_type = BinaryOpIC::UNINITIALIZED;
2403
- if ((type == BinaryOpIC::STRING || type == BinaryOpIC::BOTH_STRING) &&
2236
+
2237
+ // STRING is only used for ADD operations.
2238
+ if ((new_left == BinaryOpIC::STRING || new_right == BinaryOpIC::STRING) &&
2404
2239
  op != Token::ADD) {
2405
- type = BinaryOpIC::GENERIC;
2240
+ new_left = new_right = BinaryOpIC::GENERIC;
2406
2241
  }
2407
- if (type == BinaryOpIC::SMI && previous_type == BinaryOpIC::SMI) {
2242
+
2243
+ BinaryOpIC::TypeInfo new_overall = Max(new_left, new_right);
2244
+ BinaryOpIC::TypeInfo previous_overall = Max(previous_left, previous_right);
2245
+
2246
+ if (new_overall == BinaryOpIC::SMI && previous_overall == BinaryOpIC::SMI) {
2408
2247
  if (op == Token::DIV ||
2409
2248
  op == Token::MUL ||
2410
2249
  op == Token::SHR ||
@@ -2419,26 +2258,35 @@ RUNTIME_FUNCTION(MaybeObject*, BinaryOp_Patch) {
2419
2258
  result_type = BinaryOpIC::INT32;
2420
2259
  }
2421
2260
  }
2422
- if (type == BinaryOpIC::INT32 && previous_type == BinaryOpIC::INT32) {
2423
- // We must be here because an operation on two INT32 types overflowed.
2424
- result_type = BinaryOpIC::HEAP_NUMBER;
2261
+ if (new_overall == BinaryOpIC::INT32 &&
2262
+ previous_overall == BinaryOpIC::INT32) {
2263
+ if (new_left == previous_left && new_right == previous_right) {
2264
+ result_type = BinaryOpIC::HEAP_NUMBER;
2265
+ }
2425
2266
  }
2426
2267
 
2427
- BinaryOpStub stub(key, type, result_type);
2268
+ BinaryOpStub stub(key, new_left, new_right, result_type);
2428
2269
  Handle<Code> code = stub.GetCode();
2429
2270
  if (!code.is_null()) {
2271
+ #ifdef DEBUG
2430
2272
  if (FLAG_trace_ic) {
2431
- PrintF("[BinaryOpIC (%s->(%s->%s))#%s]\n",
2432
- BinaryOpIC::GetName(previous_type),
2433
- BinaryOpIC::GetName(type),
2273
+ PrintF("[BinaryOpIC in ");
2274
+ JavaScriptFrame::PrintTop(stdout, false, true);
2275
+ PrintF(" ((%s+%s)->((%s+%s)->%s))#%s @ %p]\n",
2276
+ BinaryOpIC::GetName(previous_left),
2277
+ BinaryOpIC::GetName(previous_right),
2278
+ BinaryOpIC::GetName(new_left),
2279
+ BinaryOpIC::GetName(new_right),
2434
2280
  BinaryOpIC::GetName(result_type),
2435
- Token::Name(op));
2281
+ Token::Name(op),
2282
+ static_cast<void*>(*code));
2436
2283
  }
2284
+ #endif
2437
2285
  BinaryOpIC ic(isolate);
2438
2286
  ic.patch(*code);
2439
2287
 
2440
2288
  // Activate inlined smi code.
2441
- if (previous_type == BinaryOpIC::UNINITIALIZED) {
2289
+ if (previous_overall == BinaryOpIC::UNINITIALIZED) {
2442
2290
  PatchInlinedSmiCode(ic.address(), ENABLE_INLINED_SMI_CHECK);
2443
2291
  }
2444
2292
  }
@@ -2501,42 +2349,28 @@ RUNTIME_FUNCTION(MaybeObject*, BinaryOp_Patch) {
2501
2349
 
2502
2350
 
2503
2351
  Code* CompareIC::GetRawUninitialized(Token::Value op) {
2504
- ICCompareStub stub(op, UNINITIALIZED);
2352
+ ICCompareStub stub(op, UNINITIALIZED, UNINITIALIZED, UNINITIALIZED);
2505
2353
  Code* code = NULL;
2506
- CHECK(stub.FindCodeInCache(&code));
2354
+ CHECK(stub.FindCodeInCache(&code, Isolate::Current()));
2507
2355
  return code;
2508
2356
  }
2509
2357
 
2510
2358
 
2511
2359
  Handle<Code> CompareIC::GetUninitialized(Token::Value op) {
2512
- ICCompareStub stub(op, UNINITIALIZED);
2360
+ ICCompareStub stub(op, UNINITIALIZED, UNINITIALIZED, UNINITIALIZED);
2513
2361
  return stub.GetCode();
2514
2362
  }
2515
2363
 
2516
2364
 
2517
- CompareIC::State CompareIC::ComputeState(Code* target) {
2518
- int key = target->major_key();
2519
- if (key == CodeStub::Compare) return GENERIC;
2520
- ASSERT(key == CodeStub::CompareIC);
2521
- return static_cast<State>(target->compare_state());
2522
- }
2523
-
2524
-
2525
- Token::Value CompareIC::ComputeOperation(Code* target) {
2526
- ASSERT(target->major_key() == CodeStub::CompareIC);
2527
- return static_cast<Token::Value>(target->compare_operation());
2528
- }
2529
-
2530
-
2531
2365
  const char* CompareIC::GetStateName(State state) {
2532
2366
  switch (state) {
2533
2367
  case UNINITIALIZED: return "UNINITIALIZED";
2534
- case SMIS: return "SMIS";
2535
- case HEAP_NUMBERS: return "HEAP_NUMBERS";
2536
- case OBJECTS: return "OBJECTS";
2537
- case KNOWN_OBJECTS: return "OBJECTS";
2538
- case SYMBOLS: return "SYMBOLS";
2539
- case STRINGS: return "STRINGS";
2368
+ case SMI: return "SMI";
2369
+ case HEAP_NUMBER: return "HEAP_NUMBER";
2370
+ case OBJECT: return "OBJECTS";
2371
+ case KNOWN_OBJECTS: return "KNOWN_OBJECTS";
2372
+ case SYMBOL: return "SYMBOL";
2373
+ case STRING: return "STRING";
2540
2374
  case GENERIC: return "GENERIC";
2541
2375
  default:
2542
2376
  UNREACHABLE();
@@ -2545,28 +2379,67 @@ const char* CompareIC::GetStateName(State state) {
2545
2379
  }
2546
2380
 
2547
2381
 
2548
- CompareIC::State CompareIC::TargetState(State state,
2382
+ static CompareIC::State InputState(CompareIC::State old_state,
2383
+ Handle<Object> value) {
2384
+ switch (old_state) {
2385
+ case CompareIC::UNINITIALIZED:
2386
+ if (value->IsSmi()) return CompareIC::SMI;
2387
+ if (value->IsHeapNumber()) return CompareIC::HEAP_NUMBER;
2388
+ if (value->IsSymbol()) return CompareIC::SYMBOL;
2389
+ if (value->IsString()) return CompareIC::STRING;
2390
+ if (value->IsJSObject()) return CompareIC::OBJECT;
2391
+ break;
2392
+ case CompareIC::SMI:
2393
+ if (value->IsSmi()) return CompareIC::SMI;
2394
+ if (value->IsHeapNumber()) return CompareIC::HEAP_NUMBER;
2395
+ break;
2396
+ case CompareIC::HEAP_NUMBER:
2397
+ if (value->IsNumber()) return CompareIC::HEAP_NUMBER;
2398
+ break;
2399
+ case CompareIC::SYMBOL:
2400
+ if (value->IsSymbol()) return CompareIC::SYMBOL;
2401
+ if (value->IsString()) return CompareIC::STRING;
2402
+ break;
2403
+ case CompareIC::STRING:
2404
+ if (value->IsSymbol() || value->IsString()) return CompareIC::STRING;
2405
+ break;
2406
+ case CompareIC::OBJECT:
2407
+ if (value->IsJSObject()) return CompareIC::OBJECT;
2408
+ break;
2409
+ case CompareIC::GENERIC:
2410
+ break;
2411
+ case CompareIC::KNOWN_OBJECTS:
2412
+ UNREACHABLE();
2413
+ break;
2414
+ }
2415
+ return CompareIC::GENERIC;
2416
+ }
2417
+
2418
+
2419
+ CompareIC::State CompareIC::TargetState(State old_state,
2420
+ State old_left,
2421
+ State old_right,
2549
2422
  bool has_inlined_smi_code,
2550
2423
  Handle<Object> x,
2551
2424
  Handle<Object> y) {
2552
- switch (state) {
2425
+ switch (old_state) {
2553
2426
  case UNINITIALIZED:
2554
- if (x->IsSmi() && y->IsSmi()) return SMIS;
2555
- if (x->IsNumber() && y->IsNumber()) return HEAP_NUMBERS;
2427
+ if (x->IsSmi() && y->IsSmi()) return SMI;
2428
+ if (x->IsNumber() && y->IsNumber()) return HEAP_NUMBER;
2556
2429
  if (Token::IsOrderedRelationalCompareOp(op_)) {
2557
2430
  // Ordered comparisons treat undefined as NaN, so the
2558
2431
  // HEAP_NUMBER stub will do the right thing.
2559
2432
  if ((x->IsNumber() && y->IsUndefined()) ||
2560
2433
  (y->IsNumber() && x->IsUndefined())) {
2561
- return HEAP_NUMBERS;
2434
+ return HEAP_NUMBER;
2562
2435
  }
2563
2436
  }
2564
2437
  if (x->IsSymbol() && y->IsSymbol()) {
2565
2438
  // We compare symbols as strings if we need to determine
2566
2439
  // the order in a non-equality compare.
2567
- return Token::IsEqualityOp(op_) ? SYMBOLS : STRINGS;
2440
+ return Token::IsEqualityOp(op_) ? SYMBOL : STRING;
2568
2441
  }
2569
- if (x->IsString() && y->IsString()) return STRINGS;
2442
+ if (x->IsString() && y->IsString()) return STRING;
2570
2443
  if (!Token::IsEqualityOp(op_)) return GENERIC;
2571
2444
  if (x->IsJSObject() && y->IsJSObject()) {
2572
2445
  if (Handle<JSObject>::cast(x)->map() ==
@@ -2574,30 +2447,70 @@ CompareIC::State CompareIC::TargetState(State state,
2574
2447
  Token::IsEqualityOp(op_)) {
2575
2448
  return KNOWN_OBJECTS;
2576
2449
  } else {
2577
- return OBJECTS;
2450
+ return OBJECT;
2578
2451
  }
2579
2452
  }
2580
2453
  return GENERIC;
2581
- case SMIS:
2582
- return has_inlined_smi_code && x->IsNumber() && y->IsNumber()
2583
- ? HEAP_NUMBERS
2454
+ case SMI:
2455
+ return x->IsNumber() && y->IsNumber()
2456
+ ? HEAP_NUMBER
2584
2457
  : GENERIC;
2585
- case SYMBOLS:
2458
+ case SYMBOL:
2586
2459
  ASSERT(Token::IsEqualityOp(op_));
2587
- return x->IsString() && y->IsString() ? STRINGS : GENERIC;
2588
- case HEAP_NUMBERS:
2589
- case STRINGS:
2590
- case OBJECTS:
2460
+ return x->IsString() && y->IsString() ? STRING : GENERIC;
2461
+ case HEAP_NUMBER:
2462
+ if (old_left == SMI && x->IsHeapNumber()) return HEAP_NUMBER;
2463
+ if (old_right == SMI && y->IsHeapNumber()) return HEAP_NUMBER;
2464
+ case STRING:
2465
+ case OBJECT:
2591
2466
  case KNOWN_OBJECTS:
2592
2467
  case GENERIC:
2593
2468
  return GENERIC;
2594
2469
  }
2595
2470
  UNREACHABLE();
2596
- return GENERIC;
2471
+ return GENERIC; // Make the compiler happy.
2472
+ }
2473
+
2474
+
2475
+ void CompareIC::UpdateCaches(Handle<Object> x, Handle<Object> y) {
2476
+ HandleScope scope;
2477
+ State previous_left, previous_right, previous_state;
2478
+ ICCompareStub::DecodeMinorKey(target()->stub_info(), &previous_left,
2479
+ &previous_right, &previous_state, NULL);
2480
+ State new_left = InputState(previous_left, x);
2481
+ State new_right = InputState(previous_right, y);
2482
+ State state = TargetState(previous_state, previous_left, previous_right,
2483
+ HasInlinedSmiCode(address()), x, y);
2484
+ ICCompareStub stub(op_, new_left, new_right, state);
2485
+ if (state == KNOWN_OBJECTS) {
2486
+ stub.set_known_map(Handle<Map>(Handle<JSObject>::cast(x)->map()));
2487
+ }
2488
+ set_target(*stub.GetCode());
2489
+
2490
+ #ifdef DEBUG
2491
+ if (FLAG_trace_ic) {
2492
+ PrintF("[CompareIC in ");
2493
+ JavaScriptFrame::PrintTop(stdout, false, true);
2494
+ PrintF(" ((%s+%s=%s)->(%s+%s=%s))#%s @ %p]\n",
2495
+ GetStateName(previous_left),
2496
+ GetStateName(previous_right),
2497
+ GetStateName(previous_state),
2498
+ GetStateName(new_left),
2499
+ GetStateName(new_right),
2500
+ GetStateName(state),
2501
+ Token::Name(op_),
2502
+ static_cast<void*>(*stub.GetCode()));
2503
+ }
2504
+ #endif
2505
+
2506
+ // Activate inlined smi code.
2507
+ if (previous_state == UNINITIALIZED) {
2508
+ PatchInlinedSmiCode(address(), ENABLE_INLINED_SMI_CHECK);
2509
+ }
2597
2510
  }
2598
2511
 
2599
2512
 
2600
- // Used from ic_<arch>.cc.
2513
+ // Used from ICCompareStub::GenerateMiss in code-stubs-<arch>.cc.
2601
2514
  RUNTIME_FUNCTION(Code*, CompareIC_Miss) {
2602
2515
  NoHandleAllocation na;
2603
2516
  ASSERT(args.length() == 3);