libv8-sgonyea 3.3.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (500) hide show
  1. data/.gitignore +8 -0
  2. data/.gitmodules +3 -0
  3. data/Gemfile +4 -0
  4. data/README.md +76 -0
  5. data/Rakefile +113 -0
  6. data/ext/libv8/extconf.rb +28 -0
  7. data/lib/libv8.rb +15 -0
  8. data/lib/libv8/Makefile +30 -0
  9. data/lib/libv8/detect_cpu.rb +27 -0
  10. data/lib/libv8/fpic-on-linux-amd64.patch +13 -0
  11. data/lib/libv8/v8/.gitignore +35 -0
  12. data/lib/libv8/v8/AUTHORS +44 -0
  13. data/lib/libv8/v8/ChangeLog +2839 -0
  14. data/lib/libv8/v8/LICENSE +52 -0
  15. data/lib/libv8/v8/LICENSE.strongtalk +29 -0
  16. data/lib/libv8/v8/LICENSE.v8 +26 -0
  17. data/lib/libv8/v8/LICENSE.valgrind +45 -0
  18. data/lib/libv8/v8/SConstruct +1478 -0
  19. data/lib/libv8/v8/build/README.txt +49 -0
  20. data/lib/libv8/v8/build/all.gyp +18 -0
  21. data/lib/libv8/v8/build/armu.gypi +32 -0
  22. data/lib/libv8/v8/build/common.gypi +144 -0
  23. data/lib/libv8/v8/build/gyp_v8 +145 -0
  24. data/lib/libv8/v8/include/v8-debug.h +395 -0
  25. data/lib/libv8/v8/include/v8-preparser.h +117 -0
  26. data/lib/libv8/v8/include/v8-profiler.h +505 -0
  27. data/lib/libv8/v8/include/v8-testing.h +104 -0
  28. data/lib/libv8/v8/include/v8.h +4124 -0
  29. data/lib/libv8/v8/include/v8stdint.h +53 -0
  30. data/lib/libv8/v8/preparser/SConscript +38 -0
  31. data/lib/libv8/v8/preparser/preparser-process.cc +379 -0
  32. data/lib/libv8/v8/src/SConscript +368 -0
  33. data/lib/libv8/v8/src/accessors.cc +767 -0
  34. data/lib/libv8/v8/src/accessors.h +123 -0
  35. data/lib/libv8/v8/src/allocation-inl.h +49 -0
  36. data/lib/libv8/v8/src/allocation.cc +122 -0
  37. data/lib/libv8/v8/src/allocation.h +143 -0
  38. data/lib/libv8/v8/src/api.cc +5845 -0
  39. data/lib/libv8/v8/src/api.h +574 -0
  40. data/lib/libv8/v8/src/apinatives.js +110 -0
  41. data/lib/libv8/v8/src/apiutils.h +73 -0
  42. data/lib/libv8/v8/src/arguments.h +118 -0
  43. data/lib/libv8/v8/src/arm/assembler-arm-inl.h +353 -0
  44. data/lib/libv8/v8/src/arm/assembler-arm.cc +2661 -0
  45. data/lib/libv8/v8/src/arm/assembler-arm.h +1375 -0
  46. data/lib/libv8/v8/src/arm/builtins-arm.cc +1658 -0
  47. data/lib/libv8/v8/src/arm/code-stubs-arm.cc +6398 -0
  48. data/lib/libv8/v8/src/arm/code-stubs-arm.h +673 -0
  49. data/lib/libv8/v8/src/arm/codegen-arm.cc +52 -0
  50. data/lib/libv8/v8/src/arm/codegen-arm.h +91 -0
  51. data/lib/libv8/v8/src/arm/constants-arm.cc +152 -0
  52. data/lib/libv8/v8/src/arm/constants-arm.h +775 -0
  53. data/lib/libv8/v8/src/arm/cpu-arm.cc +120 -0
  54. data/lib/libv8/v8/src/arm/debug-arm.cc +317 -0
  55. data/lib/libv8/v8/src/arm/deoptimizer-arm.cc +754 -0
  56. data/lib/libv8/v8/src/arm/disasm-arm.cc +1506 -0
  57. data/lib/libv8/v8/src/arm/frames-arm.cc +45 -0
  58. data/lib/libv8/v8/src/arm/frames-arm.h +168 -0
  59. data/lib/libv8/v8/src/arm/full-codegen-arm.cc +4375 -0
  60. data/lib/libv8/v8/src/arm/ic-arm.cc +1562 -0
  61. data/lib/libv8/v8/src/arm/lithium-arm.cc +2206 -0
  62. data/lib/libv8/v8/src/arm/lithium-arm.h +2348 -0
  63. data/lib/libv8/v8/src/arm/lithium-codegen-arm.cc +4526 -0
  64. data/lib/libv8/v8/src/arm/lithium-codegen-arm.h +403 -0
  65. data/lib/libv8/v8/src/arm/lithium-gap-resolver-arm.cc +305 -0
  66. data/lib/libv8/v8/src/arm/lithium-gap-resolver-arm.h +84 -0
  67. data/lib/libv8/v8/src/arm/macro-assembler-arm.cc +3163 -0
  68. data/lib/libv8/v8/src/arm/macro-assembler-arm.h +1126 -0
  69. data/lib/libv8/v8/src/arm/regexp-macro-assembler-arm.cc +1287 -0
  70. data/lib/libv8/v8/src/arm/regexp-macro-assembler-arm.h +253 -0
  71. data/lib/libv8/v8/src/arm/simulator-arm.cc +3424 -0
  72. data/lib/libv8/v8/src/arm/simulator-arm.h +431 -0
  73. data/lib/libv8/v8/src/arm/stub-cache-arm.cc +4243 -0
  74. data/lib/libv8/v8/src/array.js +1366 -0
  75. data/lib/libv8/v8/src/assembler.cc +1207 -0
  76. data/lib/libv8/v8/src/assembler.h +858 -0
  77. data/lib/libv8/v8/src/ast-inl.h +112 -0
  78. data/lib/libv8/v8/src/ast.cc +1146 -0
  79. data/lib/libv8/v8/src/ast.h +2188 -0
  80. data/lib/libv8/v8/src/atomicops.h +167 -0
  81. data/lib/libv8/v8/src/atomicops_internals_arm_gcc.h +145 -0
  82. data/lib/libv8/v8/src/atomicops_internals_mips_gcc.h +169 -0
  83. data/lib/libv8/v8/src/atomicops_internals_x86_gcc.cc +133 -0
  84. data/lib/libv8/v8/src/atomicops_internals_x86_gcc.h +287 -0
  85. data/lib/libv8/v8/src/atomicops_internals_x86_macosx.h +301 -0
  86. data/lib/libv8/v8/src/atomicops_internals_x86_msvc.h +203 -0
  87. data/lib/libv8/v8/src/bignum-dtoa.cc +655 -0
  88. data/lib/libv8/v8/src/bignum-dtoa.h +81 -0
  89. data/lib/libv8/v8/src/bignum.cc +768 -0
  90. data/lib/libv8/v8/src/bignum.h +140 -0
  91. data/lib/libv8/v8/src/bootstrapper.cc +2184 -0
  92. data/lib/libv8/v8/src/bootstrapper.h +188 -0
  93. data/lib/libv8/v8/src/builtins.cc +1707 -0
  94. data/lib/libv8/v8/src/builtins.h +371 -0
  95. data/lib/libv8/v8/src/bytecodes-irregexp.h +105 -0
  96. data/lib/libv8/v8/src/cached-powers.cc +177 -0
  97. data/lib/libv8/v8/src/cached-powers.h +65 -0
  98. data/lib/libv8/v8/src/char-predicates-inl.h +94 -0
  99. data/lib/libv8/v8/src/char-predicates.h +67 -0
  100. data/lib/libv8/v8/src/checks.cc +110 -0
  101. data/lib/libv8/v8/src/checks.h +296 -0
  102. data/lib/libv8/v8/src/circular-queue-inl.h +53 -0
  103. data/lib/libv8/v8/src/circular-queue.cc +122 -0
  104. data/lib/libv8/v8/src/circular-queue.h +103 -0
  105. data/lib/libv8/v8/src/code-stubs.cc +267 -0
  106. data/lib/libv8/v8/src/code-stubs.h +1011 -0
  107. data/lib/libv8/v8/src/code.h +70 -0
  108. data/lib/libv8/v8/src/codegen.cc +231 -0
  109. data/lib/libv8/v8/src/codegen.h +84 -0
  110. data/lib/libv8/v8/src/compilation-cache.cc +540 -0
  111. data/lib/libv8/v8/src/compilation-cache.h +287 -0
  112. data/lib/libv8/v8/src/compiler.cc +786 -0
  113. data/lib/libv8/v8/src/compiler.h +312 -0
  114. data/lib/libv8/v8/src/contexts.cc +347 -0
  115. data/lib/libv8/v8/src/contexts.h +391 -0
  116. data/lib/libv8/v8/src/conversions-inl.h +106 -0
  117. data/lib/libv8/v8/src/conversions.cc +1131 -0
  118. data/lib/libv8/v8/src/conversions.h +135 -0
  119. data/lib/libv8/v8/src/counters.cc +93 -0
  120. data/lib/libv8/v8/src/counters.h +254 -0
  121. data/lib/libv8/v8/src/cpu-profiler-inl.h +101 -0
  122. data/lib/libv8/v8/src/cpu-profiler.cc +609 -0
  123. data/lib/libv8/v8/src/cpu-profiler.h +302 -0
  124. data/lib/libv8/v8/src/cpu.h +69 -0
  125. data/lib/libv8/v8/src/d8-debug.cc +367 -0
  126. data/lib/libv8/v8/src/d8-debug.h +158 -0
  127. data/lib/libv8/v8/src/d8-posix.cc +695 -0
  128. data/lib/libv8/v8/src/d8-readline.cc +130 -0
  129. data/lib/libv8/v8/src/d8-windows.cc +42 -0
  130. data/lib/libv8/v8/src/d8.cc +803 -0
  131. data/lib/libv8/v8/src/d8.gyp +91 -0
  132. data/lib/libv8/v8/src/d8.h +235 -0
  133. data/lib/libv8/v8/src/d8.js +2798 -0
  134. data/lib/libv8/v8/src/data-flow.cc +66 -0
  135. data/lib/libv8/v8/src/data-flow.h +205 -0
  136. data/lib/libv8/v8/src/date.js +1103 -0
  137. data/lib/libv8/v8/src/dateparser-inl.h +127 -0
  138. data/lib/libv8/v8/src/dateparser.cc +178 -0
  139. data/lib/libv8/v8/src/dateparser.h +266 -0
  140. data/lib/libv8/v8/src/debug-agent.cc +447 -0
  141. data/lib/libv8/v8/src/debug-agent.h +129 -0
  142. data/lib/libv8/v8/src/debug-debugger.js +2569 -0
  143. data/lib/libv8/v8/src/debug.cc +3165 -0
  144. data/lib/libv8/v8/src/debug.h +1057 -0
  145. data/lib/libv8/v8/src/deoptimizer.cc +1256 -0
  146. data/lib/libv8/v8/src/deoptimizer.h +602 -0
  147. data/lib/libv8/v8/src/disasm.h +80 -0
  148. data/lib/libv8/v8/src/disassembler.cc +343 -0
  149. data/lib/libv8/v8/src/disassembler.h +58 -0
  150. data/lib/libv8/v8/src/diy-fp.cc +58 -0
  151. data/lib/libv8/v8/src/diy-fp.h +117 -0
  152. data/lib/libv8/v8/src/double.h +238 -0
  153. data/lib/libv8/v8/src/dtoa.cc +103 -0
  154. data/lib/libv8/v8/src/dtoa.h +85 -0
  155. data/lib/libv8/v8/src/execution.cc +849 -0
  156. data/lib/libv8/v8/src/execution.h +297 -0
  157. data/lib/libv8/v8/src/extensions/experimental/break-iterator.cc +250 -0
  158. data/lib/libv8/v8/src/extensions/experimental/break-iterator.h +89 -0
  159. data/lib/libv8/v8/src/extensions/experimental/collator.cc +218 -0
  160. data/lib/libv8/v8/src/extensions/experimental/collator.h +69 -0
  161. data/lib/libv8/v8/src/extensions/experimental/experimental.gyp +94 -0
  162. data/lib/libv8/v8/src/extensions/experimental/i18n-extension.cc +78 -0
  163. data/lib/libv8/v8/src/extensions/experimental/i18n-extension.h +54 -0
  164. data/lib/libv8/v8/src/extensions/experimental/i18n-locale.cc +112 -0
  165. data/lib/libv8/v8/src/extensions/experimental/i18n-locale.h +60 -0
  166. data/lib/libv8/v8/src/extensions/experimental/i18n-utils.cc +43 -0
  167. data/lib/libv8/v8/src/extensions/experimental/i18n-utils.h +49 -0
  168. data/lib/libv8/v8/src/extensions/experimental/i18n.js +180 -0
  169. data/lib/libv8/v8/src/extensions/experimental/language-matcher.cc +251 -0
  170. data/lib/libv8/v8/src/extensions/experimental/language-matcher.h +95 -0
  171. data/lib/libv8/v8/src/extensions/externalize-string-extension.cc +141 -0
  172. data/lib/libv8/v8/src/extensions/externalize-string-extension.h +50 -0
  173. data/lib/libv8/v8/src/extensions/gc-extension.cc +58 -0
  174. data/lib/libv8/v8/src/extensions/gc-extension.h +49 -0
  175. data/lib/libv8/v8/src/factory.cc +1222 -0
  176. data/lib/libv8/v8/src/factory.h +442 -0
  177. data/lib/libv8/v8/src/fast-dtoa.cc +736 -0
  178. data/lib/libv8/v8/src/fast-dtoa.h +83 -0
  179. data/lib/libv8/v8/src/fixed-dtoa.cc +405 -0
  180. data/lib/libv8/v8/src/fixed-dtoa.h +55 -0
  181. data/lib/libv8/v8/src/flag-definitions.h +560 -0
  182. data/lib/libv8/v8/src/flags.cc +551 -0
  183. data/lib/libv8/v8/src/flags.h +79 -0
  184. data/lib/libv8/v8/src/frames-inl.h +247 -0
  185. data/lib/libv8/v8/src/frames.cc +1243 -0
  186. data/lib/libv8/v8/src/frames.h +870 -0
  187. data/lib/libv8/v8/src/full-codegen.cc +1374 -0
  188. data/lib/libv8/v8/src/full-codegen.h +771 -0
  189. data/lib/libv8/v8/src/func-name-inferrer.cc +92 -0
  190. data/lib/libv8/v8/src/func-name-inferrer.h +111 -0
  191. data/lib/libv8/v8/src/gdb-jit.cc +1555 -0
  192. data/lib/libv8/v8/src/gdb-jit.h +143 -0
  193. data/lib/libv8/v8/src/global-handles.cc +665 -0
  194. data/lib/libv8/v8/src/global-handles.h +284 -0
  195. data/lib/libv8/v8/src/globals.h +325 -0
  196. data/lib/libv8/v8/src/handles-inl.h +177 -0
  197. data/lib/libv8/v8/src/handles.cc +987 -0
  198. data/lib/libv8/v8/src/handles.h +382 -0
  199. data/lib/libv8/v8/src/hashmap.cc +230 -0
  200. data/lib/libv8/v8/src/hashmap.h +123 -0
  201. data/lib/libv8/v8/src/heap-inl.h +704 -0
  202. data/lib/libv8/v8/src/heap-profiler.cc +1173 -0
  203. data/lib/libv8/v8/src/heap-profiler.h +397 -0
  204. data/lib/libv8/v8/src/heap.cc +5930 -0
  205. data/lib/libv8/v8/src/heap.h +2268 -0
  206. data/lib/libv8/v8/src/hydrogen-instructions.cc +1769 -0
  207. data/lib/libv8/v8/src/hydrogen-instructions.h +3971 -0
  208. data/lib/libv8/v8/src/hydrogen.cc +6239 -0
  209. data/lib/libv8/v8/src/hydrogen.h +1202 -0
  210. data/lib/libv8/v8/src/ia32/assembler-ia32-inl.h +446 -0
  211. data/lib/libv8/v8/src/ia32/assembler-ia32.cc +2487 -0
  212. data/lib/libv8/v8/src/ia32/assembler-ia32.h +1144 -0
  213. data/lib/libv8/v8/src/ia32/builtins-ia32.cc +1621 -0
  214. data/lib/libv8/v8/src/ia32/code-stubs-ia32.cc +6198 -0
  215. data/lib/libv8/v8/src/ia32/code-stubs-ia32.h +517 -0
  216. data/lib/libv8/v8/src/ia32/codegen-ia32.cc +265 -0
  217. data/lib/libv8/v8/src/ia32/codegen-ia32.h +79 -0
  218. data/lib/libv8/v8/src/ia32/cpu-ia32.cc +88 -0
  219. data/lib/libv8/v8/src/ia32/debug-ia32.cc +312 -0
  220. data/lib/libv8/v8/src/ia32/deoptimizer-ia32.cc +774 -0
  221. data/lib/libv8/v8/src/ia32/disasm-ia32.cc +1628 -0
  222. data/lib/libv8/v8/src/ia32/frames-ia32.cc +45 -0
  223. data/lib/libv8/v8/src/ia32/frames-ia32.h +142 -0
  224. data/lib/libv8/v8/src/ia32/full-codegen-ia32.cc +4338 -0
  225. data/lib/libv8/v8/src/ia32/ic-ia32.cc +1597 -0
  226. data/lib/libv8/v8/src/ia32/lithium-codegen-ia32.cc +4461 -0
  227. data/lib/libv8/v8/src/ia32/lithium-codegen-ia32.h +375 -0
  228. data/lib/libv8/v8/src/ia32/lithium-gap-resolver-ia32.cc +475 -0
  229. data/lib/libv8/v8/src/ia32/lithium-gap-resolver-ia32.h +110 -0
  230. data/lib/libv8/v8/src/ia32/lithium-ia32.cc +2261 -0
  231. data/lib/libv8/v8/src/ia32/lithium-ia32.h +2396 -0
  232. data/lib/libv8/v8/src/ia32/macro-assembler-ia32.cc +2136 -0
  233. data/lib/libv8/v8/src/ia32/macro-assembler-ia32.h +775 -0
  234. data/lib/libv8/v8/src/ia32/regexp-macro-assembler-ia32.cc +1263 -0
  235. data/lib/libv8/v8/src/ia32/regexp-macro-assembler-ia32.h +216 -0
  236. data/lib/libv8/v8/src/ia32/simulator-ia32.cc +30 -0
  237. data/lib/libv8/v8/src/ia32/simulator-ia32.h +74 -0
  238. data/lib/libv8/v8/src/ia32/stub-cache-ia32.cc +3847 -0
  239. data/lib/libv8/v8/src/ic-inl.h +130 -0
  240. data/lib/libv8/v8/src/ic.cc +2577 -0
  241. data/lib/libv8/v8/src/ic.h +736 -0
  242. data/lib/libv8/v8/src/inspector.cc +63 -0
  243. data/lib/libv8/v8/src/inspector.h +62 -0
  244. data/lib/libv8/v8/src/interpreter-irregexp.cc +659 -0
  245. data/lib/libv8/v8/src/interpreter-irregexp.h +49 -0
  246. data/lib/libv8/v8/src/isolate-inl.h +50 -0
  247. data/lib/libv8/v8/src/isolate.cc +1869 -0
  248. data/lib/libv8/v8/src/isolate.h +1382 -0
  249. data/lib/libv8/v8/src/json-parser.cc +504 -0
  250. data/lib/libv8/v8/src/json-parser.h +161 -0
  251. data/lib/libv8/v8/src/json.js +342 -0
  252. data/lib/libv8/v8/src/jsregexp.cc +5385 -0
  253. data/lib/libv8/v8/src/jsregexp.h +1492 -0
  254. data/lib/libv8/v8/src/list-inl.h +212 -0
  255. data/lib/libv8/v8/src/list.h +174 -0
  256. data/lib/libv8/v8/src/lithium-allocator-inl.h +142 -0
  257. data/lib/libv8/v8/src/lithium-allocator.cc +2123 -0
  258. data/lib/libv8/v8/src/lithium-allocator.h +630 -0
  259. data/lib/libv8/v8/src/lithium.cc +190 -0
  260. data/lib/libv8/v8/src/lithium.h +597 -0
  261. data/lib/libv8/v8/src/liveedit-debugger.js +1082 -0
  262. data/lib/libv8/v8/src/liveedit.cc +1691 -0
  263. data/lib/libv8/v8/src/liveedit.h +180 -0
  264. data/lib/libv8/v8/src/liveobjectlist-inl.h +126 -0
  265. data/lib/libv8/v8/src/liveobjectlist.cc +2589 -0
  266. data/lib/libv8/v8/src/liveobjectlist.h +322 -0
  267. data/lib/libv8/v8/src/log-inl.h +59 -0
  268. data/lib/libv8/v8/src/log-utils.cc +428 -0
  269. data/lib/libv8/v8/src/log-utils.h +231 -0
  270. data/lib/libv8/v8/src/log.cc +1993 -0
  271. data/lib/libv8/v8/src/log.h +476 -0
  272. data/lib/libv8/v8/src/macro-assembler.h +120 -0
  273. data/lib/libv8/v8/src/macros.py +178 -0
  274. data/lib/libv8/v8/src/mark-compact.cc +3143 -0
  275. data/lib/libv8/v8/src/mark-compact.h +506 -0
  276. data/lib/libv8/v8/src/math.js +264 -0
  277. data/lib/libv8/v8/src/messages.cc +179 -0
  278. data/lib/libv8/v8/src/messages.h +113 -0
  279. data/lib/libv8/v8/src/messages.js +1096 -0
  280. data/lib/libv8/v8/src/mips/assembler-mips-inl.h +312 -0
  281. data/lib/libv8/v8/src/mips/assembler-mips.cc +1960 -0
  282. data/lib/libv8/v8/src/mips/assembler-mips.h +1138 -0
  283. data/lib/libv8/v8/src/mips/builtins-mips.cc +1628 -0
  284. data/lib/libv8/v8/src/mips/code-stubs-mips.cc +6656 -0
  285. data/lib/libv8/v8/src/mips/code-stubs-mips.h +682 -0
  286. data/lib/libv8/v8/src/mips/codegen-mips.cc +52 -0
  287. data/lib/libv8/v8/src/mips/codegen-mips.h +98 -0
  288. data/lib/libv8/v8/src/mips/constants-mips.cc +352 -0
  289. data/lib/libv8/v8/src/mips/constants-mips.h +739 -0
  290. data/lib/libv8/v8/src/mips/cpu-mips.cc +96 -0
  291. data/lib/libv8/v8/src/mips/debug-mips.cc +308 -0
  292. data/lib/libv8/v8/src/mips/deoptimizer-mips.cc +91 -0
  293. data/lib/libv8/v8/src/mips/disasm-mips.cc +1050 -0
  294. data/lib/libv8/v8/src/mips/frames-mips.cc +47 -0
  295. data/lib/libv8/v8/src/mips/frames-mips.h +219 -0
  296. data/lib/libv8/v8/src/mips/full-codegen-mips.cc +4388 -0
  297. data/lib/libv8/v8/src/mips/ic-mips.cc +1580 -0
  298. data/lib/libv8/v8/src/mips/lithium-codegen-mips.h +65 -0
  299. data/lib/libv8/v8/src/mips/lithium-mips.h +307 -0
  300. data/lib/libv8/v8/src/mips/macro-assembler-mips.cc +4056 -0
  301. data/lib/libv8/v8/src/mips/macro-assembler-mips.h +1214 -0
  302. data/lib/libv8/v8/src/mips/regexp-macro-assembler-mips.cc +1251 -0
  303. data/lib/libv8/v8/src/mips/regexp-macro-assembler-mips.h +252 -0
  304. data/lib/libv8/v8/src/mips/simulator-mips.cc +2621 -0
  305. data/lib/libv8/v8/src/mips/simulator-mips.h +401 -0
  306. data/lib/libv8/v8/src/mips/stub-cache-mips.cc +4285 -0
  307. data/lib/libv8/v8/src/mirror-debugger.js +2382 -0
  308. data/lib/libv8/v8/src/mksnapshot.cc +328 -0
  309. data/lib/libv8/v8/src/natives.h +64 -0
  310. data/lib/libv8/v8/src/objects-debug.cc +738 -0
  311. data/lib/libv8/v8/src/objects-inl.h +4323 -0
  312. data/lib/libv8/v8/src/objects-printer.cc +829 -0
  313. data/lib/libv8/v8/src/objects-visiting.cc +148 -0
  314. data/lib/libv8/v8/src/objects-visiting.h +424 -0
  315. data/lib/libv8/v8/src/objects.cc +10585 -0
  316. data/lib/libv8/v8/src/objects.h +6838 -0
  317. data/lib/libv8/v8/src/parser.cc +4997 -0
  318. data/lib/libv8/v8/src/parser.h +765 -0
  319. data/lib/libv8/v8/src/platform-cygwin.cc +779 -0
  320. data/lib/libv8/v8/src/platform-freebsd.cc +826 -0
  321. data/lib/libv8/v8/src/platform-linux.cc +1149 -0
  322. data/lib/libv8/v8/src/platform-macos.cc +830 -0
  323. data/lib/libv8/v8/src/platform-nullos.cc +479 -0
  324. data/lib/libv8/v8/src/platform-openbsd.cc +640 -0
  325. data/lib/libv8/v8/src/platform-posix.cc +424 -0
  326. data/lib/libv8/v8/src/platform-solaris.cc +762 -0
  327. data/lib/libv8/v8/src/platform-tls-mac.h +62 -0
  328. data/lib/libv8/v8/src/platform-tls-win32.h +62 -0
  329. data/lib/libv8/v8/src/platform-tls.h +50 -0
  330. data/lib/libv8/v8/src/platform-win32.cc +2021 -0
  331. data/lib/libv8/v8/src/platform.h +667 -0
  332. data/lib/libv8/v8/src/preparse-data-format.h +62 -0
  333. data/lib/libv8/v8/src/preparse-data.cc +183 -0
  334. data/lib/libv8/v8/src/preparse-data.h +225 -0
  335. data/lib/libv8/v8/src/preparser-api.cc +220 -0
  336. data/lib/libv8/v8/src/preparser.cc +1450 -0
  337. data/lib/libv8/v8/src/preparser.h +493 -0
  338. data/lib/libv8/v8/src/prettyprinter.cc +1493 -0
  339. data/lib/libv8/v8/src/prettyprinter.h +223 -0
  340. data/lib/libv8/v8/src/profile-generator-inl.h +128 -0
  341. data/lib/libv8/v8/src/profile-generator.cc +3098 -0
  342. data/lib/libv8/v8/src/profile-generator.h +1126 -0
  343. data/lib/libv8/v8/src/property.cc +105 -0
  344. data/lib/libv8/v8/src/property.h +365 -0
  345. data/lib/libv8/v8/src/proxy.js +83 -0
  346. data/lib/libv8/v8/src/regexp-macro-assembler-irregexp-inl.h +78 -0
  347. data/lib/libv8/v8/src/regexp-macro-assembler-irregexp.cc +471 -0
  348. data/lib/libv8/v8/src/regexp-macro-assembler-irregexp.h +142 -0
  349. data/lib/libv8/v8/src/regexp-macro-assembler-tracer.cc +373 -0
  350. data/lib/libv8/v8/src/regexp-macro-assembler-tracer.h +104 -0
  351. data/lib/libv8/v8/src/regexp-macro-assembler.cc +267 -0
  352. data/lib/libv8/v8/src/regexp-macro-assembler.h +243 -0
  353. data/lib/libv8/v8/src/regexp-stack.cc +111 -0
  354. data/lib/libv8/v8/src/regexp-stack.h +147 -0
  355. data/lib/libv8/v8/src/regexp.js +483 -0
  356. data/lib/libv8/v8/src/rewriter.cc +360 -0
  357. data/lib/libv8/v8/src/rewriter.h +50 -0
  358. data/lib/libv8/v8/src/runtime-profiler.cc +489 -0
  359. data/lib/libv8/v8/src/runtime-profiler.h +201 -0
  360. data/lib/libv8/v8/src/runtime.cc +12227 -0
  361. data/lib/libv8/v8/src/runtime.h +652 -0
  362. data/lib/libv8/v8/src/runtime.js +649 -0
  363. data/lib/libv8/v8/src/safepoint-table.cc +256 -0
  364. data/lib/libv8/v8/src/safepoint-table.h +270 -0
  365. data/lib/libv8/v8/src/scanner-base.cc +952 -0
  366. data/lib/libv8/v8/src/scanner-base.h +670 -0
  367. data/lib/libv8/v8/src/scanner.cc +345 -0
  368. data/lib/libv8/v8/src/scanner.h +146 -0
  369. data/lib/libv8/v8/src/scopeinfo.cc +646 -0
  370. data/lib/libv8/v8/src/scopeinfo.h +254 -0
  371. data/lib/libv8/v8/src/scopes.cc +1150 -0
  372. data/lib/libv8/v8/src/scopes.h +507 -0
  373. data/lib/libv8/v8/src/serialize.cc +1574 -0
  374. data/lib/libv8/v8/src/serialize.h +589 -0
  375. data/lib/libv8/v8/src/shell.h +55 -0
  376. data/lib/libv8/v8/src/simulator.h +43 -0
  377. data/lib/libv8/v8/src/small-pointer-list.h +163 -0
  378. data/lib/libv8/v8/src/smart-pointer.h +109 -0
  379. data/lib/libv8/v8/src/snapshot-common.cc +83 -0
  380. data/lib/libv8/v8/src/snapshot-empty.cc +54 -0
  381. data/lib/libv8/v8/src/snapshot.h +91 -0
  382. data/lib/libv8/v8/src/spaces-inl.h +529 -0
  383. data/lib/libv8/v8/src/spaces.cc +3145 -0
  384. data/lib/libv8/v8/src/spaces.h +2369 -0
  385. data/lib/libv8/v8/src/splay-tree-inl.h +310 -0
  386. data/lib/libv8/v8/src/splay-tree.h +205 -0
  387. data/lib/libv8/v8/src/string-search.cc +41 -0
  388. data/lib/libv8/v8/src/string-search.h +568 -0
  389. data/lib/libv8/v8/src/string-stream.cc +592 -0
  390. data/lib/libv8/v8/src/string-stream.h +191 -0
  391. data/lib/libv8/v8/src/string.js +994 -0
  392. data/lib/libv8/v8/src/strtod.cc +440 -0
  393. data/lib/libv8/v8/src/strtod.h +40 -0
  394. data/lib/libv8/v8/src/stub-cache.cc +1965 -0
  395. data/lib/libv8/v8/src/stub-cache.h +924 -0
  396. data/lib/libv8/v8/src/third_party/valgrind/valgrind.h +3925 -0
  397. data/lib/libv8/v8/src/token.cc +63 -0
  398. data/lib/libv8/v8/src/token.h +288 -0
  399. data/lib/libv8/v8/src/type-info.cc +507 -0
  400. data/lib/libv8/v8/src/type-info.h +272 -0
  401. data/lib/libv8/v8/src/unbound-queue-inl.h +95 -0
  402. data/lib/libv8/v8/src/unbound-queue.h +69 -0
  403. data/lib/libv8/v8/src/unicode-inl.h +238 -0
  404. data/lib/libv8/v8/src/unicode.cc +1624 -0
  405. data/lib/libv8/v8/src/unicode.h +280 -0
  406. data/lib/libv8/v8/src/uri.js +408 -0
  407. data/lib/libv8/v8/src/utils-inl.h +48 -0
  408. data/lib/libv8/v8/src/utils.cc +371 -0
  409. data/lib/libv8/v8/src/utils.h +800 -0
  410. data/lib/libv8/v8/src/v8-counters.cc +62 -0
  411. data/lib/libv8/v8/src/v8-counters.h +314 -0
  412. data/lib/libv8/v8/src/v8.cc +213 -0
  413. data/lib/libv8/v8/src/v8.h +131 -0
  414. data/lib/libv8/v8/src/v8checks.h +64 -0
  415. data/lib/libv8/v8/src/v8dll-main.cc +44 -0
  416. data/lib/libv8/v8/src/v8globals.h +512 -0
  417. data/lib/libv8/v8/src/v8memory.h +82 -0
  418. data/lib/libv8/v8/src/v8natives.js +1310 -0
  419. data/lib/libv8/v8/src/v8preparserdll-main.cc +39 -0
  420. data/lib/libv8/v8/src/v8threads.cc +464 -0
  421. data/lib/libv8/v8/src/v8threads.h +165 -0
  422. data/lib/libv8/v8/src/v8utils.h +319 -0
  423. data/lib/libv8/v8/src/variables.cc +114 -0
  424. data/lib/libv8/v8/src/variables.h +167 -0
  425. data/lib/libv8/v8/src/version.cc +116 -0
  426. data/lib/libv8/v8/src/version.h +68 -0
  427. data/lib/libv8/v8/src/vm-state-inl.h +138 -0
  428. data/lib/libv8/v8/src/vm-state.h +71 -0
  429. data/lib/libv8/v8/src/win32-headers.h +96 -0
  430. data/lib/libv8/v8/src/x64/assembler-x64-inl.h +462 -0
  431. data/lib/libv8/v8/src/x64/assembler-x64.cc +3027 -0
  432. data/lib/libv8/v8/src/x64/assembler-x64.h +1633 -0
  433. data/lib/libv8/v8/src/x64/builtins-x64.cc +1520 -0
  434. data/lib/libv8/v8/src/x64/code-stubs-x64.cc +5132 -0
  435. data/lib/libv8/v8/src/x64/code-stubs-x64.h +514 -0
  436. data/lib/libv8/v8/src/x64/codegen-x64.cc +146 -0
  437. data/lib/libv8/v8/src/x64/codegen-x64.h +76 -0
  438. data/lib/libv8/v8/src/x64/cpu-x64.cc +88 -0
  439. data/lib/libv8/v8/src/x64/debug-x64.cc +319 -0
  440. data/lib/libv8/v8/src/x64/deoptimizer-x64.cc +815 -0
  441. data/lib/libv8/v8/src/x64/disasm-x64.cc +1832 -0
  442. data/lib/libv8/v8/src/x64/frames-x64.cc +45 -0
  443. data/lib/libv8/v8/src/x64/frames-x64.h +130 -0
  444. data/lib/libv8/v8/src/x64/full-codegen-x64.cc +4318 -0
  445. data/lib/libv8/v8/src/x64/ic-x64.cc +1608 -0
  446. data/lib/libv8/v8/src/x64/lithium-codegen-x64.cc +4267 -0
  447. data/lib/libv8/v8/src/x64/lithium-codegen-x64.h +367 -0
  448. data/lib/libv8/v8/src/x64/lithium-gap-resolver-x64.cc +320 -0
  449. data/lib/libv8/v8/src/x64/lithium-gap-resolver-x64.h +74 -0
  450. data/lib/libv8/v8/src/x64/lithium-x64.cc +2202 -0
  451. data/lib/libv8/v8/src/x64/lithium-x64.h +2333 -0
  452. data/lib/libv8/v8/src/x64/macro-assembler-x64.cc +3745 -0
  453. data/lib/libv8/v8/src/x64/macro-assembler-x64.h +1290 -0
  454. data/lib/libv8/v8/src/x64/regexp-macro-assembler-x64.cc +1398 -0
  455. data/lib/libv8/v8/src/x64/regexp-macro-assembler-x64.h +282 -0
  456. data/lib/libv8/v8/src/x64/simulator-x64.cc +27 -0
  457. data/lib/libv8/v8/src/x64/simulator-x64.h +72 -0
  458. data/lib/libv8/v8/src/x64/stub-cache-x64.cc +3610 -0
  459. data/lib/libv8/v8/src/zone-inl.h +140 -0
  460. data/lib/libv8/v8/src/zone.cc +196 -0
  461. data/lib/libv8/v8/src/zone.h +240 -0
  462. data/lib/libv8/v8/tools/codemap.js +265 -0
  463. data/lib/libv8/v8/tools/consarray.js +93 -0
  464. data/lib/libv8/v8/tools/csvparser.js +78 -0
  465. data/lib/libv8/v8/tools/disasm.py +92 -0
  466. data/lib/libv8/v8/tools/freebsd-tick-processor +10 -0
  467. data/lib/libv8/v8/tools/gc-nvp-trace-processor.py +342 -0
  468. data/lib/libv8/v8/tools/gcmole/README +62 -0
  469. data/lib/libv8/v8/tools/gcmole/gccause.lua +60 -0
  470. data/lib/libv8/v8/tools/gcmole/gcmole.cc +1261 -0
  471. data/lib/libv8/v8/tools/gcmole/gcmole.lua +378 -0
  472. data/lib/libv8/v8/tools/generate-ten-powers.scm +286 -0
  473. data/lib/libv8/v8/tools/grokdump.py +841 -0
  474. data/lib/libv8/v8/tools/gyp/v8.gyp +995 -0
  475. data/lib/libv8/v8/tools/js2c.py +364 -0
  476. data/lib/libv8/v8/tools/jsmin.py +280 -0
  477. data/lib/libv8/v8/tools/linux-tick-processor +35 -0
  478. data/lib/libv8/v8/tools/ll_prof.py +942 -0
  479. data/lib/libv8/v8/tools/logreader.js +185 -0
  480. data/lib/libv8/v8/tools/mac-nm +18 -0
  481. data/lib/libv8/v8/tools/mac-tick-processor +6 -0
  482. data/lib/libv8/v8/tools/oom_dump/README +31 -0
  483. data/lib/libv8/v8/tools/oom_dump/SConstruct +42 -0
  484. data/lib/libv8/v8/tools/oom_dump/oom_dump.cc +288 -0
  485. data/lib/libv8/v8/tools/presubmit.py +305 -0
  486. data/lib/libv8/v8/tools/process-heap-prof.py +120 -0
  487. data/lib/libv8/v8/tools/profile.js +751 -0
  488. data/lib/libv8/v8/tools/profile_view.js +219 -0
  489. data/lib/libv8/v8/tools/run-valgrind.py +77 -0
  490. data/lib/libv8/v8/tools/splaytree.js +316 -0
  491. data/lib/libv8/v8/tools/stats-viewer.py +468 -0
  492. data/lib/libv8/v8/tools/test.py +1510 -0
  493. data/lib/libv8/v8/tools/tickprocessor-driver.js +59 -0
  494. data/lib/libv8/v8/tools/tickprocessor.js +877 -0
  495. data/lib/libv8/v8/tools/utils.py +96 -0
  496. data/lib/libv8/v8/tools/visual_studio/README.txt +12 -0
  497. data/lib/libv8/v8/tools/windows-tick-processor.bat +30 -0
  498. data/lib/libv8/version.rb +5 -0
  499. data/libv8.gemspec +36 -0
  500. metadata +578 -0
@@ -0,0 +1,1965 @@
1
+ // Copyright 2011 the V8 project authors. All rights reserved.
2
+ // Redistribution and use in source and binary forms, with or without
3
+ // modification, are permitted provided that the following conditions are
4
+ // met:
5
+ //
6
+ // * Redistributions of source code must retain the above copyright
7
+ // notice, this list of conditions and the following disclaimer.
8
+ // * Redistributions in binary form must reproduce the above
9
+ // copyright notice, this list of conditions and the following
10
+ // disclaimer in the documentation and/or other materials provided
11
+ // with the distribution.
12
+ // * Neither the name of Google Inc. nor the names of its
13
+ // contributors may be used to endorse or promote products derived
14
+ // from this software without specific prior written permission.
15
+ //
16
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
+ // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
+ // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
+ // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20
+ // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
+ // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
+ // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
+ // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
+ // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
+ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
+ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
+
28
+ #include "v8.h"
29
+
30
+ #include "api.h"
31
+ #include "arguments.h"
32
+ #include "gdb-jit.h"
33
+ #include "ic-inl.h"
34
+ #include "stub-cache.h"
35
+ #include "vm-state-inl.h"
36
+
37
+ namespace v8 {
38
+ namespace internal {
39
+
40
+ // -----------------------------------------------------------------------
41
+ // StubCache implementation.
42
+
43
+
44
+ StubCache::StubCache(Isolate* isolate) : isolate_(isolate) {
45
+ ASSERT(isolate == Isolate::Current());
46
+ memset(primary_, 0, sizeof(primary_[0]) * StubCache::kPrimaryTableSize);
47
+ memset(secondary_, 0, sizeof(secondary_[0]) * StubCache::kSecondaryTableSize);
48
+ }
49
+
50
+
51
+ void StubCache::Initialize(bool create_heap_objects) {
52
+ ASSERT(IsPowerOf2(kPrimaryTableSize));
53
+ ASSERT(IsPowerOf2(kSecondaryTableSize));
54
+ if (create_heap_objects) {
55
+ HandleScope scope;
56
+ Clear();
57
+ }
58
+ }
59
+
60
+
61
+ Code* StubCache::Set(String* name, Map* map, Code* code) {
62
+ // Get the flags from the code.
63
+ Code::Flags flags = Code::RemoveTypeFromFlags(code->flags());
64
+
65
+ // Validate that the name does not move on scavenge, and that we
66
+ // can use identity checks instead of string equality checks.
67
+ ASSERT(!heap()->InNewSpace(name));
68
+ ASSERT(name->IsSymbol());
69
+
70
+ // The state bits are not important to the hash function because
71
+ // the stub cache only contains monomorphic stubs. Make sure that
72
+ // the bits are the least significant so they will be the ones
73
+ // masked out.
74
+ ASSERT(Code::ExtractICStateFromFlags(flags) == MONOMORPHIC);
75
+ ASSERT(Code::kFlagsICStateShift == 0);
76
+
77
+ // Make sure that the code type is not included in the hash.
78
+ ASSERT(Code::ExtractTypeFromFlags(flags) == 0);
79
+
80
+ // Compute the primary entry.
81
+ int primary_offset = PrimaryOffset(name, flags, map);
82
+ Entry* primary = entry(primary_, primary_offset);
83
+ Code* hit = primary->value;
84
+
85
+ // If the primary entry has useful data in it, we retire it to the
86
+ // secondary cache before overwriting it.
87
+ if (hit != isolate_->builtins()->builtin(Builtins::kIllegal)) {
88
+ Code::Flags primary_flags = Code::RemoveTypeFromFlags(hit->flags());
89
+ int secondary_offset =
90
+ SecondaryOffset(primary->key, primary_flags, primary_offset);
91
+ Entry* secondary = entry(secondary_, secondary_offset);
92
+ *secondary = *primary;
93
+ }
94
+
95
+ // Update primary cache.
96
+ primary->key = name;
97
+ primary->value = code;
98
+ return code;
99
+ }
100
+
101
+
102
+ MaybeObject* StubCache::ComputeLoadNonexistent(String* name,
103
+ JSObject* receiver) {
104
+ ASSERT(receiver->IsGlobalObject() || receiver->HasFastProperties());
105
+ // If no global objects are present in the prototype chain, the load
106
+ // nonexistent IC stub can be shared for all names for a given map
107
+ // and we use the empty string for the map cache in that case. If
108
+ // there are global objects involved, we need to check global
109
+ // property cells in the stub and therefore the stub will be
110
+ // specific to the name.
111
+ String* cache_name = heap()->empty_string();
112
+ if (receiver->IsGlobalObject()) cache_name = name;
113
+ JSObject* last = receiver;
114
+ while (last->GetPrototype() != heap()->null_value()) {
115
+ last = JSObject::cast(last->GetPrototype());
116
+ if (last->IsGlobalObject()) cache_name = name;
117
+ }
118
+ // Compile the stub that is either shared for all names or
119
+ // name specific if there are global objects involved.
120
+ Code::Flags flags =
121
+ Code::ComputeMonomorphicFlags(Code::LOAD_IC, NONEXISTENT);
122
+ Object* code = receiver->map()->FindInCodeCache(cache_name, flags);
123
+ if (code->IsUndefined()) {
124
+ LoadStubCompiler compiler;
125
+ { MaybeObject* maybe_code =
126
+ compiler.CompileLoadNonexistent(cache_name, receiver, last);
127
+ if (!maybe_code->ToObject(&code)) return maybe_code;
128
+ }
129
+ PROFILE(isolate_,
130
+ CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), cache_name));
131
+ GDBJIT(AddCode(GDBJITInterface::LOAD_IC, cache_name, Code::cast(code)));
132
+ Object* result;
133
+ { MaybeObject* maybe_result =
134
+ receiver->UpdateMapCodeCache(cache_name, Code::cast(code));
135
+ if (!maybe_result->ToObject(&result)) return maybe_result;
136
+ }
137
+ }
138
+ return code;
139
+ }
140
+
141
+
142
+ MaybeObject* StubCache::ComputeLoadField(String* name,
143
+ JSObject* receiver,
144
+ JSObject* holder,
145
+ int field_index) {
146
+ ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP);
147
+ Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, FIELD);
148
+ Object* code = receiver->map()->FindInCodeCache(name, flags);
149
+ if (code->IsUndefined()) {
150
+ LoadStubCompiler compiler;
151
+ { MaybeObject* maybe_code =
152
+ compiler.CompileLoadField(receiver, holder, field_index, name);
153
+ if (!maybe_code->ToObject(&code)) return maybe_code;
154
+ }
155
+ PROFILE(isolate_,
156
+ CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name));
157
+ GDBJIT(AddCode(GDBJITInterface::LOAD_IC, name, Code::cast(code)));
158
+ Object* result;
159
+ { MaybeObject* maybe_result =
160
+ receiver->UpdateMapCodeCache(name, Code::cast(code));
161
+ if (!maybe_result->ToObject(&result)) return maybe_result;
162
+ }
163
+ }
164
+ return code;
165
+ }
166
+
167
+
168
+ MaybeObject* StubCache::ComputeLoadCallback(String* name,
169
+ JSObject* receiver,
170
+ JSObject* holder,
171
+ AccessorInfo* callback) {
172
+ ASSERT(v8::ToCData<Address>(callback->getter()) != 0);
173
+ ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP);
174
+ Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, CALLBACKS);
175
+ Object* code = receiver->map()->FindInCodeCache(name, flags);
176
+ if (code->IsUndefined()) {
177
+ LoadStubCompiler compiler;
178
+ { MaybeObject* maybe_code =
179
+ compiler.CompileLoadCallback(name, receiver, holder, callback);
180
+ if (!maybe_code->ToObject(&code)) return maybe_code;
181
+ }
182
+ PROFILE(isolate_,
183
+ CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name));
184
+ GDBJIT(AddCode(GDBJITInterface::LOAD_IC, name, Code::cast(code)));
185
+ Object* result;
186
+ { MaybeObject* maybe_result =
187
+ receiver->UpdateMapCodeCache(name, Code::cast(code));
188
+ if (!maybe_result->ToObject(&result)) return maybe_result;
189
+ }
190
+ }
191
+ return code;
192
+ }
193
+
194
+
195
+ MaybeObject* StubCache::ComputeLoadConstant(String* name,
196
+ JSObject* receiver,
197
+ JSObject* holder,
198
+ Object* value) {
199
+ ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP);
200
+ Code::Flags flags =
201
+ Code::ComputeMonomorphicFlags(Code::LOAD_IC, CONSTANT_FUNCTION);
202
+ Object* code = receiver->map()->FindInCodeCache(name, flags);
203
+ if (code->IsUndefined()) {
204
+ LoadStubCompiler compiler;
205
+ { MaybeObject* maybe_code =
206
+ compiler.CompileLoadConstant(receiver, holder, value, name);
207
+ if (!maybe_code->ToObject(&code)) return maybe_code;
208
+ }
209
+ PROFILE(isolate_,
210
+ CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name));
211
+ GDBJIT(AddCode(GDBJITInterface::LOAD_IC, name, Code::cast(code)));
212
+ Object* result;
213
+ { MaybeObject* maybe_result =
214
+ receiver->UpdateMapCodeCache(name, Code::cast(code));
215
+ if (!maybe_result->ToObject(&result)) return maybe_result;
216
+ }
217
+ }
218
+ return code;
219
+ }
220
+
221
+
222
+ MaybeObject* StubCache::ComputeLoadInterceptor(String* name,
223
+ JSObject* receiver,
224
+ JSObject* holder) {
225
+ ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP);
226
+ Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, INTERCEPTOR);
227
+ Object* code = receiver->map()->FindInCodeCache(name, flags);
228
+ if (code->IsUndefined()) {
229
+ LoadStubCompiler compiler;
230
+ { MaybeObject* maybe_code =
231
+ compiler.CompileLoadInterceptor(receiver, holder, name);
232
+ if (!maybe_code->ToObject(&code)) return maybe_code;
233
+ }
234
+ PROFILE(isolate_,
235
+ CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name));
236
+ GDBJIT(AddCode(GDBJITInterface::LOAD_IC, name, Code::cast(code)));
237
+ Object* result;
238
+ { MaybeObject* maybe_result =
239
+ receiver->UpdateMapCodeCache(name, Code::cast(code));
240
+ if (!maybe_result->ToObject(&result)) return maybe_result;
241
+ }
242
+ }
243
+ return code;
244
+ }
245
+
246
+
247
+ MaybeObject* StubCache::ComputeLoadNormal() {
248
+ return isolate_->builtins()->builtin(Builtins::kLoadIC_Normal);
249
+ }
250
+
251
+
252
+ MaybeObject* StubCache::ComputeLoadGlobal(String* name,
253
+ JSObject* receiver,
254
+ GlobalObject* holder,
255
+ JSGlobalPropertyCell* cell,
256
+ bool is_dont_delete) {
257
+ ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP);
258
+ Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, NORMAL);
259
+ Object* code = receiver->map()->FindInCodeCache(name, flags);
260
+ if (code->IsUndefined()) {
261
+ LoadStubCompiler compiler;
262
+ { MaybeObject* maybe_code = compiler.CompileLoadGlobal(receiver,
263
+ holder,
264
+ cell,
265
+ name,
266
+ is_dont_delete);
267
+ if (!maybe_code->ToObject(&code)) return maybe_code;
268
+ }
269
+ PROFILE(isolate_,
270
+ CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name));
271
+ GDBJIT(AddCode(GDBJITInterface::LOAD_IC, name, Code::cast(code)));
272
+ Object* result;
273
+ { MaybeObject* maybe_result =
274
+ receiver->UpdateMapCodeCache(name, Code::cast(code));
275
+ if (!maybe_result->ToObject(&result)) return maybe_result;
276
+ }
277
+ }
278
+ return code;
279
+ }
280
+
281
+
282
+ MaybeObject* StubCache::ComputeKeyedLoadField(String* name,
283
+ JSObject* receiver,
284
+ JSObject* holder,
285
+ int field_index) {
286
+ ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP);
287
+ Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, FIELD);
288
+ Object* code = receiver->map()->FindInCodeCache(name, flags);
289
+ if (code->IsUndefined()) {
290
+ KeyedLoadStubCompiler compiler;
291
+ { MaybeObject* maybe_code =
292
+ compiler.CompileLoadField(name, receiver, holder, field_index);
293
+ if (!maybe_code->ToObject(&code)) return maybe_code;
294
+ }
295
+ PROFILE(isolate_,
296
+ CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name));
297
+ GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, name, Code::cast(code)));
298
+ Object* result;
299
+ { MaybeObject* maybe_result =
300
+ receiver->UpdateMapCodeCache(name, Code::cast(code));
301
+ if (!maybe_result->ToObject(&result)) return maybe_result;
302
+ }
303
+ }
304
+ return code;
305
+ }
306
+
307
+
308
+ MaybeObject* StubCache::ComputeKeyedLoadConstant(String* name,
309
+ JSObject* receiver,
310
+ JSObject* holder,
311
+ Object* value) {
312
+ ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP);
313
+ Code::Flags flags =
314
+ Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CONSTANT_FUNCTION);
315
+ Object* code = receiver->map()->FindInCodeCache(name, flags);
316
+ if (code->IsUndefined()) {
317
+ KeyedLoadStubCompiler compiler;
318
+ { MaybeObject* maybe_code =
319
+ compiler.CompileLoadConstant(name, receiver, holder, value);
320
+ if (!maybe_code->ToObject(&code)) return maybe_code;
321
+ }
322
+ PROFILE(isolate_,
323
+ CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name));
324
+ GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, name, Code::cast(code)));
325
+ Object* result;
326
+ { MaybeObject* maybe_result =
327
+ receiver->UpdateMapCodeCache(name, Code::cast(code));
328
+ if (!maybe_result->ToObject(&result)) return maybe_result;
329
+ }
330
+ }
331
+ return code;
332
+ }
333
+
334
+
335
+ MaybeObject* StubCache::ComputeKeyedLoadInterceptor(String* name,
336
+ JSObject* receiver,
337
+ JSObject* holder) {
338
+ ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP);
339
+ Code::Flags flags =
340
+ Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, INTERCEPTOR);
341
+ Object* code = receiver->map()->FindInCodeCache(name, flags);
342
+ if (code->IsUndefined()) {
343
+ KeyedLoadStubCompiler compiler;
344
+ { MaybeObject* maybe_code =
345
+ compiler.CompileLoadInterceptor(receiver, holder, name);
346
+ if (!maybe_code->ToObject(&code)) return maybe_code;
347
+ }
348
+ PROFILE(isolate_,
349
+ CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name));
350
+ GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, name, Code::cast(code)));
351
+ Object* result;
352
+ { MaybeObject* maybe_result =
353
+ receiver->UpdateMapCodeCache(name, Code::cast(code));
354
+ if (!maybe_result->ToObject(&result)) return maybe_result;
355
+ }
356
+ }
357
+ return code;
358
+ }
359
+
360
+
361
+ MaybeObject* StubCache::ComputeKeyedLoadCallback(String* name,
362
+ JSObject* receiver,
363
+ JSObject* holder,
364
+ AccessorInfo* callback) {
365
+ ASSERT(IC::GetCodeCacheForObject(receiver, holder) == OWN_MAP);
366
+ Code::Flags flags =
367
+ Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS);
368
+ Object* code = receiver->map()->FindInCodeCache(name, flags);
369
+ if (code->IsUndefined()) {
370
+ KeyedLoadStubCompiler compiler;
371
+ { MaybeObject* maybe_code =
372
+ compiler.CompileLoadCallback(name, receiver, holder, callback);
373
+ if (!maybe_code->ToObject(&code)) return maybe_code;
374
+ }
375
+ PROFILE(isolate_,
376
+ CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name));
377
+ GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, name, Code::cast(code)));
378
+ Object* result;
379
+ { MaybeObject* maybe_result =
380
+ receiver->UpdateMapCodeCache(name, Code::cast(code));
381
+ if (!maybe_result->ToObject(&result)) return maybe_result;
382
+ }
383
+ }
384
+ return code;
385
+ }
386
+
387
+
388
+
389
+ MaybeObject* StubCache::ComputeKeyedLoadArrayLength(String* name,
390
+ JSArray* receiver) {
391
+ Code::Flags flags =
392
+ Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS);
393
+ ASSERT(receiver->IsJSObject());
394
+ Object* code = receiver->map()->FindInCodeCache(name, flags);
395
+ if (code->IsUndefined()) {
396
+ KeyedLoadStubCompiler compiler;
397
+ { MaybeObject* maybe_code = compiler.CompileLoadArrayLength(name);
398
+ if (!maybe_code->ToObject(&code)) return maybe_code;
399
+ }
400
+ PROFILE(isolate_,
401
+ CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name));
402
+ GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, name, Code::cast(code)));
403
+ Object* result;
404
+ { MaybeObject* maybe_result =
405
+ receiver->UpdateMapCodeCache(name, Code::cast(code));
406
+ if (!maybe_result->ToObject(&result)) return maybe_result;
407
+ }
408
+ }
409
+ return code;
410
+ }
411
+
412
+
413
+ MaybeObject* StubCache::ComputeKeyedLoadStringLength(String* name,
414
+ String* receiver) {
415
+ Code::Flags flags =
416
+ Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS);
417
+ Map* map = receiver->map();
418
+ Object* code = map->FindInCodeCache(name, flags);
419
+ if (code->IsUndefined()) {
420
+ KeyedLoadStubCompiler compiler;
421
+ { MaybeObject* maybe_code = compiler.CompileLoadStringLength(name);
422
+ if (!maybe_code->ToObject(&code)) return maybe_code;
423
+ }
424
+ PROFILE(isolate_,
425
+ CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name));
426
+ GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, name, Code::cast(code)));
427
+ Object* result;
428
+ { MaybeObject* maybe_result = map->UpdateCodeCache(name, Code::cast(code));
429
+ if (!maybe_result->ToObject(&result)) return maybe_result;
430
+ }
431
+ }
432
+ return code;
433
+ }
434
+
435
+
436
+ MaybeObject* StubCache::ComputeKeyedLoadFunctionPrototype(
437
+ String* name,
438
+ JSFunction* receiver) {
439
+ Code::Flags flags =
440
+ Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS);
441
+ Object* code = receiver->map()->FindInCodeCache(name, flags);
442
+ if (code->IsUndefined()) {
443
+ KeyedLoadStubCompiler compiler;
444
+ { MaybeObject* maybe_code = compiler.CompileLoadFunctionPrototype(name);
445
+ if (!maybe_code->ToObject(&code)) return maybe_code;
446
+ }
447
+ PROFILE(isolate_,
448
+ CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name));
449
+ GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, name, Code::cast(code)));
450
+ Object* result;
451
+ { MaybeObject* maybe_result =
452
+ receiver->UpdateMapCodeCache(name, Code::cast(code));
453
+ if (!maybe_result->ToObject(&result)) return maybe_result;
454
+ }
455
+ }
456
+ return code;
457
+ }
458
+
459
+
460
+ MaybeObject* StubCache::ComputeStoreField(String* name,
461
+ JSObject* receiver,
462
+ int field_index,
463
+ Map* transition,
464
+ StrictModeFlag strict_mode) {
465
+ PropertyType type = (transition == NULL) ? FIELD : MAP_TRANSITION;
466
+ Code::Flags flags = Code::ComputeMonomorphicFlags(
467
+ Code::STORE_IC, type, strict_mode);
468
+ Object* code = receiver->map()->FindInCodeCache(name, flags);
469
+ if (code->IsUndefined()) {
470
+ StoreStubCompiler compiler(strict_mode);
471
+ { MaybeObject* maybe_code =
472
+ compiler.CompileStoreField(receiver, field_index, transition, name);
473
+ if (!maybe_code->ToObject(&code)) return maybe_code;
474
+ }
475
+ PROFILE(isolate_,
476
+ CodeCreateEvent(Logger::STORE_IC_TAG, Code::cast(code), name));
477
+ GDBJIT(AddCode(GDBJITInterface::STORE_IC, name, Code::cast(code)));
478
+ Object* result;
479
+ { MaybeObject* maybe_result =
480
+ receiver->UpdateMapCodeCache(name, Code::cast(code));
481
+ if (!maybe_result->ToObject(&result)) return maybe_result;
482
+ }
483
+ }
484
+ return code;
485
+ }
486
+
487
+
488
+ namespace {
489
+
490
+ ExternalArrayType ElementsKindToExternalArrayType(JSObject::ElementsKind kind) {
491
+ switch (kind) {
492
+ case JSObject::EXTERNAL_BYTE_ELEMENTS:
493
+ return kExternalByteArray;
494
+ case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
495
+ return kExternalUnsignedByteArray;
496
+ case JSObject::EXTERNAL_SHORT_ELEMENTS:
497
+ return kExternalShortArray;
498
+ case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
499
+ return kExternalUnsignedShortArray;
500
+ case JSObject::EXTERNAL_INT_ELEMENTS:
501
+ return kExternalIntArray;
502
+ case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS:
503
+ return kExternalUnsignedIntArray;
504
+ case JSObject::EXTERNAL_FLOAT_ELEMENTS:
505
+ return kExternalFloatArray;
506
+ case JSObject::EXTERNAL_DOUBLE_ELEMENTS:
507
+ return kExternalDoubleArray;
508
+ case JSObject::EXTERNAL_PIXEL_ELEMENTS:
509
+ return kExternalPixelArray;
510
+ default:
511
+ UNREACHABLE();
512
+ return static_cast<ExternalArrayType>(0);
513
+ }
514
+ }
515
+
516
+ } // anonymous namespace
517
+
518
+
519
+ MaybeObject* StubCache::ComputeKeyedLoadOrStoreExternalArray(
520
+ JSObject* receiver,
521
+ bool is_store,
522
+ StrictModeFlag strict_mode) {
523
+ Code::Flags flags =
524
+ Code::ComputeMonomorphicFlags(
525
+ is_store ? Code::KEYED_STORE_IC :
526
+ Code::KEYED_LOAD_IC,
527
+ NORMAL,
528
+ strict_mode);
529
+ ExternalArrayType array_type =
530
+ ElementsKindToExternalArrayType(receiver->GetElementsKind());
531
+ String* name = is_store
532
+ ? isolate()->heap()->KeyedStoreSpecializedMonomorphic_symbol()
533
+ : isolate()->heap()->KeyedLoadSpecializedMonomorphic_symbol();
534
+ Object* maybe_code = receiver->map()->FindInCodeCache(name, flags);
535
+ if (!maybe_code->IsUndefined()) return Code::cast(maybe_code);
536
+
537
+ MaybeObject* maybe_new_code = NULL;
538
+ if (is_store) {
539
+ ExternalArrayStoreStubCompiler compiler(strict_mode);
540
+ maybe_new_code = compiler.CompileStore(receiver, array_type);
541
+ } else {
542
+ ExternalArrayLoadStubCompiler compiler(strict_mode);
543
+ maybe_new_code = compiler.CompileLoad(receiver, array_type);
544
+ }
545
+ Code* code;
546
+ if (!maybe_new_code->To(&code)) return maybe_new_code;
547
+ code->set_external_array_type(array_type);
548
+ if (is_store) {
549
+ PROFILE(isolate_,
550
+ CodeCreateEvent(Logger::KEYED_EXTERNAL_ARRAY_STORE_IC_TAG,
551
+ Code::cast(code), 0));
552
+ } else {
553
+ PROFILE(isolate_,
554
+ CodeCreateEvent(Logger::KEYED_EXTERNAL_ARRAY_LOAD_IC_TAG,
555
+ Code::cast(code), 0));
556
+ }
557
+ ASSERT(code->IsCode());
558
+ Object* result;
559
+ { MaybeObject* maybe_result =
560
+ receiver->UpdateMapCodeCache(name, Code::cast(code));
561
+ if (!maybe_result->ToObject(&result)) return maybe_result;
562
+ }
563
+ return code;
564
+ }
565
+
566
+
567
+ MaybeObject* StubCache::ComputeKeyedLoadOrStoreFastElement(
568
+ JSObject* receiver,
569
+ bool is_store,
570
+ StrictModeFlag strict_mode) {
571
+ Code::Flags flags =
572
+ Code::ComputeMonomorphicFlags(
573
+ is_store ? Code::KEYED_STORE_IC :
574
+ Code::KEYED_LOAD_IC,
575
+ NORMAL,
576
+ strict_mode);
577
+ String* name = is_store
578
+ ? isolate()->heap()->KeyedStoreSpecializedMonomorphic_symbol()
579
+ : isolate()->heap()->KeyedLoadSpecializedMonomorphic_symbol();
580
+ Object* maybe_code = receiver->map()->FindInCodeCache(name, flags);
581
+ if (!maybe_code->IsUndefined()) return Code::cast(maybe_code);
582
+
583
+ MaybeObject* maybe_new_code = NULL;
584
+ if (is_store) {
585
+ KeyedStoreStubCompiler compiler(strict_mode);
586
+ maybe_new_code = compiler.CompileStoreFastElement(receiver->map());
587
+ } else {
588
+ KeyedLoadStubCompiler compiler;
589
+ maybe_new_code = compiler.CompileLoadFastElement(receiver->map());
590
+ }
591
+ Code* code;
592
+ if (!maybe_new_code->To(&code)) return maybe_new_code;
593
+ if (is_store) {
594
+ PROFILE(isolate_,
595
+ CodeCreateEvent(Logger::KEYED_STORE_IC_TAG,
596
+ Code::cast(code), 0));
597
+ } else {
598
+ PROFILE(isolate_,
599
+ CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG,
600
+ Code::cast(code), 0));
601
+ }
602
+ ASSERT(code->IsCode());
603
+ Object* result;
604
+ { MaybeObject* maybe_result =
605
+ receiver->UpdateMapCodeCache(name, Code::cast(code));
606
+ if (!maybe_result->ToObject(&result)) return maybe_result;
607
+ }
608
+ return code;
609
+ }
610
+
611
+
612
+ MaybeObject* StubCache::ComputeStoreNormal(StrictModeFlag strict_mode) {
613
+ return isolate_->builtins()->builtin((strict_mode == kStrictMode)
614
+ ? Builtins::kStoreIC_Normal_Strict
615
+ : Builtins::kStoreIC_Normal);
616
+ }
617
+
618
+
619
+ MaybeObject* StubCache::ComputeStoreGlobal(String* name,
620
+ GlobalObject* receiver,
621
+ JSGlobalPropertyCell* cell,
622
+ StrictModeFlag strict_mode) {
623
+ Code::Flags flags = Code::ComputeMonomorphicFlags(
624
+ Code::STORE_IC, NORMAL, strict_mode);
625
+ Object* code = receiver->map()->FindInCodeCache(name, flags);
626
+ if (code->IsUndefined()) {
627
+ StoreStubCompiler compiler(strict_mode);
628
+ { MaybeObject* maybe_code =
629
+ compiler.CompileStoreGlobal(receiver, cell, name);
630
+ if (!maybe_code->ToObject(&code)) return maybe_code;
631
+ }
632
+ PROFILE(isolate_,
633
+ CodeCreateEvent(Logger::STORE_IC_TAG, Code::cast(code), name));
634
+ GDBJIT(AddCode(GDBJITInterface::STORE_IC, name, Code::cast(code)));
635
+ Object* result;
636
+ { MaybeObject* maybe_result =
637
+ receiver->UpdateMapCodeCache(name, Code::cast(code));
638
+ if (!maybe_result->ToObject(&result)) return maybe_result;
639
+ }
640
+ }
641
+ return code;
642
+ }
643
+
644
+
645
+ MaybeObject* StubCache::ComputeStoreCallback(
646
+ String* name,
647
+ JSObject* receiver,
648
+ AccessorInfo* callback,
649
+ StrictModeFlag strict_mode) {
650
+ ASSERT(v8::ToCData<Address>(callback->setter()) != 0);
651
+ Code::Flags flags = Code::ComputeMonomorphicFlags(
652
+ Code::STORE_IC, CALLBACKS, strict_mode);
653
+ Object* code = receiver->map()->FindInCodeCache(name, flags);
654
+ if (code->IsUndefined()) {
655
+ StoreStubCompiler compiler(strict_mode);
656
+ { MaybeObject* maybe_code =
657
+ compiler.CompileStoreCallback(receiver, callback, name);
658
+ if (!maybe_code->ToObject(&code)) return maybe_code;
659
+ }
660
+ PROFILE(isolate_,
661
+ CodeCreateEvent(Logger::STORE_IC_TAG, Code::cast(code), name));
662
+ GDBJIT(AddCode(GDBJITInterface::STORE_IC, name, Code::cast(code)));
663
+ Object* result;
664
+ { MaybeObject* maybe_result =
665
+ receiver->UpdateMapCodeCache(name, Code::cast(code));
666
+ if (!maybe_result->ToObject(&result)) return maybe_result;
667
+ }
668
+ }
669
+ return code;
670
+ }
671
+
672
+
673
+ MaybeObject* StubCache::ComputeStoreInterceptor(
674
+ String* name,
675
+ JSObject* receiver,
676
+ StrictModeFlag strict_mode) {
677
+ Code::Flags flags = Code::ComputeMonomorphicFlags(
678
+ Code::STORE_IC, INTERCEPTOR, strict_mode);
679
+ Object* code = receiver->map()->FindInCodeCache(name, flags);
680
+ if (code->IsUndefined()) {
681
+ StoreStubCompiler compiler(strict_mode);
682
+ { MaybeObject* maybe_code =
683
+ compiler.CompileStoreInterceptor(receiver, name);
684
+ if (!maybe_code->ToObject(&code)) return maybe_code;
685
+ }
686
+ PROFILE(isolate_,
687
+ CodeCreateEvent(Logger::STORE_IC_TAG, Code::cast(code), name));
688
+ GDBJIT(AddCode(GDBJITInterface::STORE_IC, name, Code::cast(code)));
689
+ Object* result;
690
+ { MaybeObject* maybe_result =
691
+ receiver->UpdateMapCodeCache(name, Code::cast(code));
692
+ if (!maybe_result->ToObject(&result)) return maybe_result;
693
+ }
694
+ }
695
+ return code;
696
+ }
697
+
698
+
699
+ MaybeObject* StubCache::ComputeKeyedStoreField(String* name,
700
+ JSObject* receiver,
701
+ int field_index,
702
+ Map* transition,
703
+ StrictModeFlag strict_mode) {
704
+ PropertyType type = (transition == NULL) ? FIELD : MAP_TRANSITION;
705
+ Code::Flags flags = Code::ComputeMonomorphicFlags(
706
+ Code::KEYED_STORE_IC, type, strict_mode);
707
+ Object* code = receiver->map()->FindInCodeCache(name, flags);
708
+ if (code->IsUndefined()) {
709
+ KeyedStoreStubCompiler compiler(strict_mode);
710
+ { MaybeObject* maybe_code =
711
+ compiler.CompileStoreField(receiver, field_index, transition, name);
712
+ if (!maybe_code->ToObject(&code)) return maybe_code;
713
+ }
714
+ PROFILE(isolate(),
715
+ CodeCreateEvent(Logger::KEYED_STORE_IC_TAG,
716
+ Code::cast(code), name));
717
+ GDBJIT(AddCode(GDBJITInterface::KEYED_STORE_IC, name, Code::cast(code)));
718
+ Object* result;
719
+ { MaybeObject* maybe_result =
720
+ receiver->UpdateMapCodeCache(name, Code::cast(code));
721
+ if (!maybe_result->ToObject(&result)) return maybe_result;
722
+ }
723
+ }
724
+ return code;
725
+ }
726
+
727
+ #define CALL_LOGGER_TAG(kind, type) \
728
+ (kind == Code::CALL_IC ? Logger::type : Logger::KEYED_##type)
729
+
730
+ MaybeObject* StubCache::ComputeCallConstant(int argc,
731
+ InLoopFlag in_loop,
732
+ Code::Kind kind,
733
+ Code::ExtraICState extra_ic_state,
734
+ String* name,
735
+ Object* object,
736
+ JSObject* holder,
737
+ JSFunction* function) {
738
+ // Compute the check type and the map.
739
+ InlineCacheHolderFlag cache_holder =
740
+ IC::GetCodeCacheForObject(object, holder);
741
+ JSObject* map_holder = IC::GetCodeCacheHolder(object, cache_holder);
742
+
743
+ // Compute check type based on receiver/holder.
744
+ CheckType check = RECEIVER_MAP_CHECK;
745
+ if (object->IsString()) {
746
+ check = STRING_CHECK;
747
+ } else if (object->IsNumber()) {
748
+ check = NUMBER_CHECK;
749
+ } else if (object->IsBoolean()) {
750
+ check = BOOLEAN_CHECK;
751
+ }
752
+
753
+ Code::Flags flags = Code::ComputeMonomorphicFlags(kind,
754
+ CONSTANT_FUNCTION,
755
+ extra_ic_state,
756
+ cache_holder,
757
+ in_loop,
758
+ argc);
759
+ Object* code = map_holder->map()->FindInCodeCache(name, flags);
760
+ if (code->IsUndefined()) {
761
+ // If the function hasn't been compiled yet, we cannot do it now
762
+ // because it may cause GC. To avoid this issue, we return an
763
+ // internal error which will make sure we do not update any
764
+ // caches.
765
+ if (!function->is_compiled()) return Failure::InternalError();
766
+ // Compile the stub - only create stubs for fully compiled functions.
767
+ CallStubCompiler compiler(
768
+ argc, in_loop, kind, extra_ic_state, cache_holder);
769
+ { MaybeObject* maybe_code =
770
+ compiler.CompileCallConstant(object, holder, function, name, check);
771
+ if (!maybe_code->ToObject(&code)) return maybe_code;
772
+ }
773
+ Code::cast(code)->set_check_type(check);
774
+ ASSERT_EQ(flags, Code::cast(code)->flags());
775
+ PROFILE(isolate_,
776
+ CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG),
777
+ Code::cast(code), name));
778
+ GDBJIT(AddCode(GDBJITInterface::CALL_IC, name, Code::cast(code)));
779
+ Object* result;
780
+ { MaybeObject* maybe_result =
781
+ map_holder->UpdateMapCodeCache(name, Code::cast(code));
782
+ if (!maybe_result->ToObject(&result)) return maybe_result;
783
+ }
784
+ }
785
+ return code;
786
+ }
787
+
788
+
789
+ MaybeObject* StubCache::ComputeCallField(int argc,
790
+ InLoopFlag in_loop,
791
+ Code::Kind kind,
792
+ Code::ExtraICState extra_ic_state,
793
+ String* name,
794
+ Object* object,
795
+ JSObject* holder,
796
+ int index) {
797
+ // Compute the check type and the map.
798
+ InlineCacheHolderFlag cache_holder =
799
+ IC::GetCodeCacheForObject(object, holder);
800
+ JSObject* map_holder = IC::GetCodeCacheHolder(object, cache_holder);
801
+
802
+ // TODO(1233596): We cannot do receiver map check for non-JS objects
803
+ // because they may be represented as immediates without a
804
+ // map. Instead, we check against the map in the holder.
805
+ if (object->IsNumber() || object->IsBoolean() || object->IsString()) {
806
+ object = holder;
807
+ }
808
+
809
+ Code::Flags flags = Code::ComputeMonomorphicFlags(kind,
810
+ FIELD,
811
+ extra_ic_state,
812
+ cache_holder,
813
+ in_loop,
814
+ argc);
815
+ Object* code = map_holder->map()->FindInCodeCache(name, flags);
816
+ if (code->IsUndefined()) {
817
+ CallStubCompiler compiler(
818
+ argc, in_loop, kind, extra_ic_state, cache_holder);
819
+ { MaybeObject* maybe_code =
820
+ compiler.CompileCallField(JSObject::cast(object),
821
+ holder,
822
+ index,
823
+ name);
824
+ if (!maybe_code->ToObject(&code)) return maybe_code;
825
+ }
826
+ ASSERT_EQ(flags, Code::cast(code)->flags());
827
+ PROFILE(isolate_,
828
+ CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG),
829
+ Code::cast(code), name));
830
+ GDBJIT(AddCode(GDBJITInterface::CALL_IC, name, Code::cast(code)));
831
+ Object* result;
832
+ { MaybeObject* maybe_result =
833
+ map_holder->UpdateMapCodeCache(name, Code::cast(code));
834
+ if (!maybe_result->ToObject(&result)) return maybe_result;
835
+ }
836
+ }
837
+ return code;
838
+ }
839
+
840
+
841
+ MaybeObject* StubCache::ComputeCallInterceptor(
842
+ int argc,
843
+ Code::Kind kind,
844
+ Code::ExtraICState extra_ic_state,
845
+ String* name,
846
+ Object* object,
847
+ JSObject* holder) {
848
+ // Compute the check type and the map.
849
+ InlineCacheHolderFlag cache_holder =
850
+ IC::GetCodeCacheForObject(object, holder);
851
+ JSObject* map_holder = IC::GetCodeCacheHolder(object, cache_holder);
852
+
853
+ // TODO(1233596): We cannot do receiver map check for non-JS objects
854
+ // because they may be represented as immediates without a
855
+ // map. Instead, we check against the map in the holder.
856
+ if (object->IsNumber() || object->IsBoolean() || object->IsString()) {
857
+ object = holder;
858
+ }
859
+
860
+ Code::Flags flags = Code::ComputeMonomorphicFlags(kind,
861
+ INTERCEPTOR,
862
+ extra_ic_state,
863
+ cache_holder,
864
+ NOT_IN_LOOP,
865
+ argc);
866
+ Object* code = map_holder->map()->FindInCodeCache(name, flags);
867
+ if (code->IsUndefined()) {
868
+ CallStubCompiler compiler(
869
+ argc, NOT_IN_LOOP, kind, extra_ic_state, cache_holder);
870
+ { MaybeObject* maybe_code =
871
+ compiler.CompileCallInterceptor(JSObject::cast(object), holder, name);
872
+ if (!maybe_code->ToObject(&code)) return maybe_code;
873
+ }
874
+ ASSERT_EQ(flags, Code::cast(code)->flags());
875
+ PROFILE(isolate(),
876
+ CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG),
877
+ Code::cast(code), name));
878
+ GDBJIT(AddCode(GDBJITInterface::CALL_IC, name, Code::cast(code)));
879
+ Object* result;
880
+ { MaybeObject* maybe_result =
881
+ map_holder->UpdateMapCodeCache(name, Code::cast(code));
882
+ if (!maybe_result->ToObject(&result)) return maybe_result;
883
+ }
884
+ }
885
+ return code;
886
+ }
887
+
888
+
889
+ MaybeObject* StubCache::ComputeCallNormal(int argc,
890
+ InLoopFlag in_loop,
891
+ Code::Kind kind,
892
+ Code::ExtraICState extra_ic_state,
893
+ String* name,
894
+ JSObject* receiver) {
895
+ Object* code;
896
+ { MaybeObject* maybe_code =
897
+ ComputeCallNormal(argc, in_loop, kind, extra_ic_state);
898
+ if (!maybe_code->ToObject(&code)) return maybe_code;
899
+ }
900
+ return code;
901
+ }
902
+
903
+
904
+ MaybeObject* StubCache::ComputeCallGlobal(int argc,
905
+ InLoopFlag in_loop,
906
+ Code::Kind kind,
907
+ Code::ExtraICState extra_ic_state,
908
+ String* name,
909
+ JSObject* receiver,
910
+ GlobalObject* holder,
911
+ JSGlobalPropertyCell* cell,
912
+ JSFunction* function) {
913
+ InlineCacheHolderFlag cache_holder =
914
+ IC::GetCodeCacheForObject(receiver, holder);
915
+ JSObject* map_holder = IC::GetCodeCacheHolder(receiver, cache_holder);
916
+ Code::Flags flags = Code::ComputeMonomorphicFlags(kind,
917
+ NORMAL,
918
+ extra_ic_state,
919
+ cache_holder,
920
+ in_loop,
921
+ argc);
922
+ Object* code = map_holder->map()->FindInCodeCache(name, flags);
923
+ if (code->IsUndefined()) {
924
+ // If the function hasn't been compiled yet, we cannot do it now
925
+ // because it may cause GC. To avoid this issue, we return an
926
+ // internal error which will make sure we do not update any
927
+ // caches.
928
+ if (!function->is_compiled()) return Failure::InternalError();
929
+ CallStubCompiler compiler(
930
+ argc, in_loop, kind, extra_ic_state, cache_holder);
931
+ { MaybeObject* maybe_code =
932
+ compiler.CompileCallGlobal(receiver,
933
+ holder,
934
+ cell,
935
+ function,
936
+ name,
937
+ extra_ic_state);
938
+ if (!maybe_code->ToObject(&code)) return maybe_code;
939
+ }
940
+ ASSERT_EQ(flags, Code::cast(code)->flags());
941
+ PROFILE(isolate(),
942
+ CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG),
943
+ Code::cast(code), name));
944
+ GDBJIT(AddCode(GDBJITInterface::CALL_IC, name, Code::cast(code)));
945
+ Object* result;
946
+ { MaybeObject* maybe_result =
947
+ map_holder->UpdateMapCodeCache(name, Code::cast(code));
948
+ if (!maybe_result->ToObject(&result)) return maybe_result;
949
+ }
950
+ }
951
+ return code;
952
+ }
953
+
954
+
955
+ static Object* GetProbeValue(Isolate* isolate, Code::Flags flags) {
956
+ // Use raw_unchecked... so we don't get assert failures during GC.
957
+ NumberDictionary* dictionary =
958
+ isolate->heap()->raw_unchecked_non_monomorphic_cache();
959
+ int entry = dictionary->FindEntry(isolate, flags);
960
+ if (entry != -1) return dictionary->ValueAt(entry);
961
+ return isolate->heap()->raw_unchecked_undefined_value();
962
+ }
963
+
964
+
965
+ MUST_USE_RESULT static MaybeObject* ProbeCache(Isolate* isolate,
966
+ Code::Flags flags) {
967
+ Heap* heap = isolate->heap();
968
+ Object* probe = GetProbeValue(isolate, flags);
969
+ if (probe != heap->undefined_value()) return probe;
970
+ // Seed the cache with an undefined value to make sure that any
971
+ // generated code object can always be inserted into the cache
972
+ // without causing allocation failures.
973
+ Object* result;
974
+ { MaybeObject* maybe_result =
975
+ heap->non_monomorphic_cache()->AtNumberPut(flags,
976
+ heap->undefined_value());
977
+ if (!maybe_result->ToObject(&result)) return maybe_result;
978
+ }
979
+ heap->public_set_non_monomorphic_cache(NumberDictionary::cast(result));
980
+ return probe;
981
+ }
982
+
983
+
984
+ static MaybeObject* FillCache(Isolate* isolate, MaybeObject* maybe_code) {
985
+ Object* code;
986
+ if (maybe_code->ToObject(&code)) {
987
+ if (code->IsCode()) {
988
+ Heap* heap = isolate->heap();
989
+ int entry = heap->non_monomorphic_cache()->FindEntry(
990
+ Code::cast(code)->flags());
991
+ // The entry must be present see comment in ProbeCache.
992
+ ASSERT(entry != -1);
993
+ ASSERT(heap->non_monomorphic_cache()->ValueAt(entry) ==
994
+ heap->undefined_value());
995
+ heap->non_monomorphic_cache()->ValueAtPut(entry, code);
996
+ CHECK(GetProbeValue(isolate, Code::cast(code)->flags()) == code);
997
+ }
998
+ }
999
+ return maybe_code;
1000
+ }
1001
+
1002
+
1003
+ Code* StubCache::FindCallInitialize(int argc,
1004
+ InLoopFlag in_loop,
1005
+ RelocInfo::Mode mode,
1006
+ Code::Kind kind) {
1007
+ Code::ExtraICState extra_state =
1008
+ CallICBase::StringStubState::encode(DEFAULT_STRING_STUB) |
1009
+ CallICBase::Contextual::encode(mode == RelocInfo::CODE_TARGET_CONTEXT);
1010
+ Code::Flags flags = Code::ComputeFlags(kind,
1011
+ in_loop,
1012
+ UNINITIALIZED,
1013
+ extra_state,
1014
+ NORMAL,
1015
+ argc);
1016
+ Object* result = ProbeCache(isolate(), flags)->ToObjectUnchecked();
1017
+ ASSERT(result != heap()->undefined_value());
1018
+ // This might be called during the marking phase of the collector
1019
+ // hence the unchecked cast.
1020
+ return reinterpret_cast<Code*>(result);
1021
+ }
1022
+
1023
+
1024
+ MaybeObject* StubCache::ComputeCallInitialize(int argc,
1025
+ InLoopFlag in_loop,
1026
+ RelocInfo::Mode mode,
1027
+ Code::Kind kind) {
1028
+ Code::ExtraICState extra_state =
1029
+ CallICBase::StringStubState::encode(DEFAULT_STRING_STUB) |
1030
+ CallICBase::Contextual::encode(mode == RelocInfo::CODE_TARGET_CONTEXT);
1031
+ Code::Flags flags = Code::ComputeFlags(kind,
1032
+ in_loop,
1033
+ UNINITIALIZED,
1034
+ extra_state,
1035
+ NORMAL,
1036
+ argc);
1037
+ Object* probe;
1038
+ { MaybeObject* maybe_probe = ProbeCache(isolate_, flags);
1039
+ if (!maybe_probe->ToObject(&probe)) return maybe_probe;
1040
+ }
1041
+ if (!probe->IsUndefined()) return probe;
1042
+ StubCompiler compiler;
1043
+ return FillCache(isolate_, compiler.CompileCallInitialize(flags));
1044
+ }
1045
+
1046
+
1047
+ Handle<Code> StubCache::ComputeCallInitialize(int argc,
1048
+ InLoopFlag in_loop,
1049
+ RelocInfo::Mode mode) {
1050
+ if (in_loop == IN_LOOP) {
1051
+ // Force the creation of the corresponding stub outside loops,
1052
+ // because it may be used when clearing the ICs later - it is
1053
+ // possible for a series of IC transitions to lose the in-loop
1054
+ // information, and the IC clearing code can't generate a stub
1055
+ // that it needs so we need to ensure it is generated already.
1056
+ ComputeCallInitialize(argc, NOT_IN_LOOP, mode);
1057
+ }
1058
+ CALL_HEAP_FUNCTION(isolate_,
1059
+ ComputeCallInitialize(argc, in_loop, mode, Code::CALL_IC),
1060
+ Code);
1061
+ }
1062
+
1063
+
1064
+ Handle<Code> StubCache::ComputeKeyedCallInitialize(int argc,
1065
+ InLoopFlag in_loop) {
1066
+ if (in_loop == IN_LOOP) {
1067
+ // Force the creation of the corresponding stub outside loops,
1068
+ // because it may be used when clearing the ICs later - it is
1069
+ // possible for a series of IC transitions to lose the in-loop
1070
+ // information, and the IC clearing code can't generate a stub
1071
+ // that it needs so we need to ensure it is generated already.
1072
+ ComputeKeyedCallInitialize(argc, NOT_IN_LOOP);
1073
+ }
1074
+ CALL_HEAP_FUNCTION(
1075
+ isolate_,
1076
+ ComputeCallInitialize(argc,
1077
+ in_loop,
1078
+ RelocInfo::CODE_TARGET,
1079
+ Code::KEYED_CALL_IC),
1080
+ Code);
1081
+ }
1082
+
1083
+
1084
+ MaybeObject* StubCache::ComputeCallPreMonomorphic(
1085
+ int argc,
1086
+ InLoopFlag in_loop,
1087
+ Code::Kind kind,
1088
+ Code::ExtraICState extra_ic_state) {
1089
+ Code::Flags flags = Code::ComputeFlags(kind,
1090
+ in_loop,
1091
+ PREMONOMORPHIC,
1092
+ extra_ic_state,
1093
+ NORMAL,
1094
+ argc);
1095
+ Object* probe;
1096
+ { MaybeObject* maybe_probe = ProbeCache(isolate_, flags);
1097
+ if (!maybe_probe->ToObject(&probe)) return maybe_probe;
1098
+ }
1099
+ if (!probe->IsUndefined()) return probe;
1100
+ StubCompiler compiler;
1101
+ return FillCache(isolate_, compiler.CompileCallPreMonomorphic(flags));
1102
+ }
1103
+
1104
+
1105
+ MaybeObject* StubCache::ComputeCallNormal(int argc,
1106
+ InLoopFlag in_loop,
1107
+ Code::Kind kind,
1108
+ Code::ExtraICState extra_ic_state) {
1109
+ Code::Flags flags = Code::ComputeFlags(kind,
1110
+ in_loop,
1111
+ MONOMORPHIC,
1112
+ extra_ic_state,
1113
+ NORMAL,
1114
+ argc);
1115
+ Object* probe;
1116
+ { MaybeObject* maybe_probe = ProbeCache(isolate_, flags);
1117
+ if (!maybe_probe->ToObject(&probe)) return maybe_probe;
1118
+ }
1119
+ if (!probe->IsUndefined()) return probe;
1120
+ StubCompiler compiler;
1121
+ return FillCache(isolate_, compiler.CompileCallNormal(flags));
1122
+ }
1123
+
1124
+
1125
+ MaybeObject* StubCache::ComputeCallMegamorphic(
1126
+ int argc,
1127
+ InLoopFlag in_loop,
1128
+ Code::Kind kind,
1129
+ Code::ExtraICState extra_ic_state) {
1130
+ Code::Flags flags = Code::ComputeFlags(kind,
1131
+ in_loop,
1132
+ MEGAMORPHIC,
1133
+ extra_ic_state,
1134
+ NORMAL,
1135
+ argc);
1136
+ Object* probe;
1137
+ { MaybeObject* maybe_probe = ProbeCache(isolate_, flags);
1138
+ if (!maybe_probe->ToObject(&probe)) return maybe_probe;
1139
+ }
1140
+ if (!probe->IsUndefined()) return probe;
1141
+ StubCompiler compiler;
1142
+ return FillCache(isolate_, compiler.CompileCallMegamorphic(flags));
1143
+ }
1144
+
1145
+
1146
+ MaybeObject* StubCache::ComputeCallMiss(int argc,
1147
+ Code::Kind kind,
1148
+ Code::ExtraICState extra_ic_state) {
1149
+ // MONOMORPHIC_PROTOTYPE_FAILURE state is used to make sure that miss stubs
1150
+ // and monomorphic stubs are not mixed up together in the stub cache.
1151
+ Code::Flags flags = Code::ComputeFlags(kind,
1152
+ NOT_IN_LOOP,
1153
+ MONOMORPHIC_PROTOTYPE_FAILURE,
1154
+ extra_ic_state,
1155
+ NORMAL,
1156
+ argc,
1157
+ OWN_MAP);
1158
+ Object* probe;
1159
+ { MaybeObject* maybe_probe = ProbeCache(isolate_, flags);
1160
+ if (!maybe_probe->ToObject(&probe)) return maybe_probe;
1161
+ }
1162
+ if (!probe->IsUndefined()) return probe;
1163
+ StubCompiler compiler;
1164
+ return FillCache(isolate_, compiler.CompileCallMiss(flags));
1165
+ }
1166
+
1167
+
1168
+ #ifdef ENABLE_DEBUGGER_SUPPORT
1169
+ MaybeObject* StubCache::ComputeCallDebugBreak(
1170
+ int argc,
1171
+ Code::Kind kind) {
1172
+ // Extra IC state is irrelevant for debug break ICs. They jump to
1173
+ // the actual call ic to carry out the work.
1174
+ Code::Flags flags = Code::ComputeFlags(kind,
1175
+ NOT_IN_LOOP,
1176
+ DEBUG_BREAK,
1177
+ Code::kNoExtraICState,
1178
+ NORMAL,
1179
+ argc);
1180
+ Object* probe;
1181
+ { MaybeObject* maybe_probe = ProbeCache(isolate_, flags);
1182
+ if (!maybe_probe->ToObject(&probe)) return maybe_probe;
1183
+ }
1184
+ if (!probe->IsUndefined()) return probe;
1185
+ StubCompiler compiler;
1186
+ return FillCache(isolate_, compiler.CompileCallDebugBreak(flags));
1187
+ }
1188
+
1189
+
1190
+ MaybeObject* StubCache::ComputeCallDebugPrepareStepIn(
1191
+ int argc,
1192
+ Code::Kind kind) {
1193
+ // Extra IC state is irrelevant for debug break ICs. They jump to
1194
+ // the actual call ic to carry out the work.
1195
+ Code::Flags flags = Code::ComputeFlags(kind,
1196
+ NOT_IN_LOOP,
1197
+ DEBUG_PREPARE_STEP_IN,
1198
+ Code::kNoExtraICState,
1199
+ NORMAL,
1200
+ argc);
1201
+ Object* probe;
1202
+ { MaybeObject* maybe_probe = ProbeCache(isolate_, flags);
1203
+ if (!maybe_probe->ToObject(&probe)) return maybe_probe;
1204
+ }
1205
+ if (!probe->IsUndefined()) return probe;
1206
+ StubCompiler compiler;
1207
+ return FillCache(isolate_, compiler.CompileCallDebugPrepareStepIn(flags));
1208
+ }
1209
+ #endif
1210
+
1211
+
1212
+ void StubCache::Clear() {
1213
+ for (int i = 0; i < kPrimaryTableSize; i++) {
1214
+ primary_[i].key = heap()->empty_string();
1215
+ primary_[i].value = isolate_->builtins()->builtin(
1216
+ Builtins::kIllegal);
1217
+ }
1218
+ for (int j = 0; j < kSecondaryTableSize; j++) {
1219
+ secondary_[j].key = heap()->empty_string();
1220
+ secondary_[j].value = isolate_->builtins()->builtin(
1221
+ Builtins::kIllegal);
1222
+ }
1223
+ }
1224
+
1225
+
1226
+ void StubCache::CollectMatchingMaps(ZoneMapList* types,
1227
+ String* name,
1228
+ Code::Flags flags) {
1229
+ for (int i = 0; i < kPrimaryTableSize; i++) {
1230
+ if (primary_[i].key == name) {
1231
+ Map* map = primary_[i].value->FindFirstMap();
1232
+ // Map can be NULL, if the stub is constant function call
1233
+ // with a primitive receiver.
1234
+ if (map == NULL) continue;
1235
+
1236
+ int offset = PrimaryOffset(name, flags, map);
1237
+ if (entry(primary_, offset) == &primary_[i]) {
1238
+ types->Add(Handle<Map>(map));
1239
+ }
1240
+ }
1241
+ }
1242
+
1243
+ for (int i = 0; i < kSecondaryTableSize; i++) {
1244
+ if (secondary_[i].key == name) {
1245
+ Map* map = secondary_[i].value->FindFirstMap();
1246
+ // Map can be NULL, if the stub is constant function call
1247
+ // with a primitive receiver.
1248
+ if (map == NULL) continue;
1249
+
1250
+ // Lookup in primary table and skip duplicates.
1251
+ int primary_offset = PrimaryOffset(name, flags, map);
1252
+ Entry* primary_entry = entry(primary_, primary_offset);
1253
+ if (primary_entry->key == name) {
1254
+ Map* primary_map = primary_entry->value->FindFirstMap();
1255
+ if (map == primary_map) continue;
1256
+ }
1257
+
1258
+ // Lookup in secondary table and add matches.
1259
+ int offset = SecondaryOffset(name, flags, primary_offset);
1260
+ if (entry(secondary_, offset) == &secondary_[i]) {
1261
+ types->Add(Handle<Map>(map));
1262
+ }
1263
+ }
1264
+ }
1265
+ }
1266
+
1267
+
1268
+ // ------------------------------------------------------------------------
1269
+ // StubCompiler implementation.
1270
+
1271
+
1272
+ RUNTIME_FUNCTION(MaybeObject*, LoadCallbackProperty) {
1273
+ ASSERT(args[0]->IsJSObject());
1274
+ ASSERT(args[1]->IsJSObject());
1275
+ AccessorInfo* callback = AccessorInfo::cast(args[3]);
1276
+ Address getter_address = v8::ToCData<Address>(callback->getter());
1277
+ v8::AccessorGetter fun = FUNCTION_CAST<v8::AccessorGetter>(getter_address);
1278
+ ASSERT(fun != NULL);
1279
+ v8::AccessorInfo info(&args[0]);
1280
+ HandleScope scope(isolate);
1281
+ v8::Handle<v8::Value> result;
1282
+ {
1283
+ // Leaving JavaScript.
1284
+ VMState state(isolate, EXTERNAL);
1285
+ ExternalCallbackScope call_scope(isolate, getter_address);
1286
+ result = fun(v8::Utils::ToLocal(args.at<String>(4)), info);
1287
+ }
1288
+ RETURN_IF_SCHEDULED_EXCEPTION(isolate);
1289
+ if (result.IsEmpty()) return HEAP->undefined_value();
1290
+ return *v8::Utils::OpenHandle(*result);
1291
+ }
1292
+
1293
+
1294
+ RUNTIME_FUNCTION(MaybeObject*, StoreCallbackProperty) {
1295
+ JSObject* recv = JSObject::cast(args[0]);
1296
+ AccessorInfo* callback = AccessorInfo::cast(args[1]);
1297
+ Address setter_address = v8::ToCData<Address>(callback->setter());
1298
+ v8::AccessorSetter fun = FUNCTION_CAST<v8::AccessorSetter>(setter_address);
1299
+ ASSERT(fun != NULL);
1300
+ Handle<String> name = args.at<String>(2);
1301
+ Handle<Object> value = args.at<Object>(3);
1302
+ HandleScope scope(isolate);
1303
+ LOG(isolate, ApiNamedPropertyAccess("store", recv, *name));
1304
+ CustomArguments custom_args(isolate, callback->data(), recv, recv);
1305
+ v8::AccessorInfo info(custom_args.end());
1306
+ {
1307
+ // Leaving JavaScript.
1308
+ VMState state(isolate, EXTERNAL);
1309
+ ExternalCallbackScope call_scope(isolate, setter_address);
1310
+ fun(v8::Utils::ToLocal(name), v8::Utils::ToLocal(value), info);
1311
+ }
1312
+ RETURN_IF_SCHEDULED_EXCEPTION(isolate);
1313
+ return *value;
1314
+ }
1315
+
1316
+
1317
+ static const int kAccessorInfoOffsetInInterceptorArgs = 2;
1318
+
1319
+
1320
+ /**
1321
+ * Attempts to load a property with an interceptor (which must be present),
1322
+ * but doesn't search the prototype chain.
1323
+ *
1324
+ * Returns |Heap::no_interceptor_result_sentinel()| if interceptor doesn't
1325
+ * provide any value for the given name.
1326
+ */
1327
+ RUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorOnly) {
1328
+ Handle<String> name_handle = args.at<String>(0);
1329
+ Handle<InterceptorInfo> interceptor_info = args.at<InterceptorInfo>(1);
1330
+ ASSERT(kAccessorInfoOffsetInInterceptorArgs == 2);
1331
+ ASSERT(args[2]->IsJSObject()); // Receiver.
1332
+ ASSERT(args[3]->IsJSObject()); // Holder.
1333
+ ASSERT(args.length() == 5); // Last arg is data object.
1334
+
1335
+ Address getter_address = v8::ToCData<Address>(interceptor_info->getter());
1336
+ v8::NamedPropertyGetter getter =
1337
+ FUNCTION_CAST<v8::NamedPropertyGetter>(getter_address);
1338
+ ASSERT(getter != NULL);
1339
+
1340
+ {
1341
+ // Use the interceptor getter.
1342
+ v8::AccessorInfo info(args.arguments() -
1343
+ kAccessorInfoOffsetInInterceptorArgs);
1344
+ HandleScope scope(isolate);
1345
+ v8::Handle<v8::Value> r;
1346
+ {
1347
+ // Leaving JavaScript.
1348
+ VMState state(isolate, EXTERNAL);
1349
+ r = getter(v8::Utils::ToLocal(name_handle), info);
1350
+ }
1351
+ RETURN_IF_SCHEDULED_EXCEPTION(isolate);
1352
+ if (!r.IsEmpty()) {
1353
+ return *v8::Utils::OpenHandle(*r);
1354
+ }
1355
+ }
1356
+
1357
+ return isolate->heap()->no_interceptor_result_sentinel();
1358
+ }
1359
+
1360
+
1361
+ static MaybeObject* ThrowReferenceError(String* name) {
1362
+ // If the load is non-contextual, just return the undefined result.
1363
+ // Note that both keyed and non-keyed loads may end up here, so we
1364
+ // can't use either LoadIC or KeyedLoadIC constructors.
1365
+ IC ic(IC::NO_EXTRA_FRAME, Isolate::Current());
1366
+ ASSERT(ic.target()->is_load_stub() || ic.target()->is_keyed_load_stub());
1367
+ if (!ic.SlowIsContextual()) return HEAP->undefined_value();
1368
+
1369
+ // Throw a reference error.
1370
+ HandleScope scope;
1371
+ Handle<String> name_handle(name);
1372
+ Handle<Object> error =
1373
+ FACTORY->NewReferenceError("not_defined",
1374
+ HandleVector(&name_handle, 1));
1375
+ return Isolate::Current()->Throw(*error);
1376
+ }
1377
+
1378
+
1379
+ static MaybeObject* LoadWithInterceptor(Arguments* args,
1380
+ PropertyAttributes* attrs) {
1381
+ Handle<String> name_handle = args->at<String>(0);
1382
+ Handle<InterceptorInfo> interceptor_info = args->at<InterceptorInfo>(1);
1383
+ ASSERT(kAccessorInfoOffsetInInterceptorArgs == 2);
1384
+ Handle<JSObject> receiver_handle = args->at<JSObject>(2);
1385
+ Handle<JSObject> holder_handle = args->at<JSObject>(3);
1386
+ ASSERT(args->length() == 5); // Last arg is data object.
1387
+
1388
+ Isolate* isolate = receiver_handle->GetIsolate();
1389
+
1390
+ Address getter_address = v8::ToCData<Address>(interceptor_info->getter());
1391
+ v8::NamedPropertyGetter getter =
1392
+ FUNCTION_CAST<v8::NamedPropertyGetter>(getter_address);
1393
+ ASSERT(getter != NULL);
1394
+
1395
+ {
1396
+ // Use the interceptor getter.
1397
+ v8::AccessorInfo info(args->arguments() -
1398
+ kAccessorInfoOffsetInInterceptorArgs);
1399
+ HandleScope scope(isolate);
1400
+ v8::Handle<v8::Value> r;
1401
+ {
1402
+ // Leaving JavaScript.
1403
+ VMState state(isolate, EXTERNAL);
1404
+ r = getter(v8::Utils::ToLocal(name_handle), info);
1405
+ }
1406
+ RETURN_IF_SCHEDULED_EXCEPTION(isolate);
1407
+ if (!r.IsEmpty()) {
1408
+ *attrs = NONE;
1409
+ return *v8::Utils::OpenHandle(*r);
1410
+ }
1411
+ }
1412
+
1413
+ MaybeObject* result = holder_handle->GetPropertyPostInterceptor(
1414
+ *receiver_handle,
1415
+ *name_handle,
1416
+ attrs);
1417
+ RETURN_IF_SCHEDULED_EXCEPTION(isolate);
1418
+ return result;
1419
+ }
1420
+
1421
+
1422
+ /**
1423
+ * Loads a property with an interceptor performing post interceptor
1424
+ * lookup if interceptor failed.
1425
+ */
1426
+ RUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorForLoad) {
1427
+ PropertyAttributes attr = NONE;
1428
+ Object* result;
1429
+ { MaybeObject* maybe_result = LoadWithInterceptor(&args, &attr);
1430
+ if (!maybe_result->ToObject(&result)) return maybe_result;
1431
+ }
1432
+
1433
+ // If the property is present, return it.
1434
+ if (attr != ABSENT) return result;
1435
+ return ThrowReferenceError(String::cast(args[0]));
1436
+ }
1437
+
1438
+
1439
+ RUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorForCall) {
1440
+ PropertyAttributes attr;
1441
+ MaybeObject* result = LoadWithInterceptor(&args, &attr);
1442
+ RETURN_IF_SCHEDULED_EXCEPTION(isolate);
1443
+ // This is call IC. In this case, we simply return the undefined result which
1444
+ // will lead to an exception when trying to invoke the result as a
1445
+ // function.
1446
+ return result;
1447
+ }
1448
+
1449
+
1450
+ RUNTIME_FUNCTION(MaybeObject*, StoreInterceptorProperty) {
1451
+ ASSERT(args.length() == 4);
1452
+ JSObject* recv = JSObject::cast(args[0]);
1453
+ String* name = String::cast(args[1]);
1454
+ Object* value = args[2];
1455
+ StrictModeFlag strict_mode =
1456
+ static_cast<StrictModeFlag>(Smi::cast(args[3])->value());
1457
+ ASSERT(strict_mode == kStrictMode || strict_mode == kNonStrictMode);
1458
+ ASSERT(recv->HasNamedInterceptor());
1459
+ PropertyAttributes attr = NONE;
1460
+ MaybeObject* result = recv->SetPropertyWithInterceptor(
1461
+ name, value, attr, strict_mode);
1462
+ return result;
1463
+ }
1464
+
1465
+
1466
+ RUNTIME_FUNCTION(MaybeObject*, KeyedLoadPropertyWithInterceptor) {
1467
+ JSObject* receiver = JSObject::cast(args[0]);
1468
+ ASSERT(Smi::cast(args[1])->value() >= 0);
1469
+ uint32_t index = Smi::cast(args[1])->value();
1470
+ return receiver->GetElementWithInterceptor(receiver, index);
1471
+ }
1472
+
1473
+
1474
+ MaybeObject* StubCompiler::CompileCallInitialize(Code::Flags flags) {
1475
+ HandleScope scope(isolate());
1476
+ int argc = Code::ExtractArgumentsCountFromFlags(flags);
1477
+ Code::Kind kind = Code::ExtractKindFromFlags(flags);
1478
+ Code::ExtraICState extra_ic_state = Code::ExtractExtraICStateFromFlags(flags);
1479
+ if (kind == Code::CALL_IC) {
1480
+ CallIC::GenerateInitialize(masm(), argc, extra_ic_state);
1481
+ } else {
1482
+ KeyedCallIC::GenerateInitialize(masm(), argc);
1483
+ }
1484
+ Object* result;
1485
+ { MaybeObject* maybe_result =
1486
+ GetCodeWithFlags(flags, "CompileCallInitialize");
1487
+ if (!maybe_result->ToObject(&result)) return maybe_result;
1488
+ }
1489
+ isolate()->counters()->call_initialize_stubs()->Increment();
1490
+ Code* code = Code::cast(result);
1491
+ USE(code);
1492
+ PROFILE(isolate(),
1493
+ CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_INITIALIZE_TAG),
1494
+ code, code->arguments_count()));
1495
+ GDBJIT(AddCode(GDBJITInterface::CALL_INITIALIZE, Code::cast(code)));
1496
+ return result;
1497
+ }
1498
+
1499
+
1500
+ MaybeObject* StubCompiler::CompileCallPreMonomorphic(Code::Flags flags) {
1501
+ HandleScope scope(isolate());
1502
+ int argc = Code::ExtractArgumentsCountFromFlags(flags);
1503
+ // The code of the PreMonomorphic stub is the same as the code
1504
+ // of the Initialized stub. They just differ on the code object flags.
1505
+ Code::Kind kind = Code::ExtractKindFromFlags(flags);
1506
+ Code::ExtraICState extra_ic_state = Code::ExtractExtraICStateFromFlags(flags);
1507
+ if (kind == Code::CALL_IC) {
1508
+ CallIC::GenerateInitialize(masm(), argc, extra_ic_state);
1509
+ } else {
1510
+ KeyedCallIC::GenerateInitialize(masm(), argc);
1511
+ }
1512
+ Object* result;
1513
+ { MaybeObject* maybe_result =
1514
+ GetCodeWithFlags(flags, "CompileCallPreMonomorphic");
1515
+ if (!maybe_result->ToObject(&result)) return maybe_result;
1516
+ }
1517
+ isolate()->counters()->call_premonomorphic_stubs()->Increment();
1518
+ Code* code = Code::cast(result);
1519
+ USE(code);
1520
+ PROFILE(isolate(),
1521
+ CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_PRE_MONOMORPHIC_TAG),
1522
+ code, code->arguments_count()));
1523
+ GDBJIT(AddCode(GDBJITInterface::CALL_PRE_MONOMORPHIC, Code::cast(code)));
1524
+ return result;
1525
+ }
1526
+
1527
+
1528
+ MaybeObject* StubCompiler::CompileCallNormal(Code::Flags flags) {
1529
+ HandleScope scope(isolate());
1530
+ int argc = Code::ExtractArgumentsCountFromFlags(flags);
1531
+ Code::Kind kind = Code::ExtractKindFromFlags(flags);
1532
+ if (kind == Code::CALL_IC) {
1533
+ // Call normal is always with a explict receiver.
1534
+ ASSERT(!CallIC::Contextual::decode(
1535
+ Code::ExtractExtraICStateFromFlags(flags)));
1536
+ CallIC::GenerateNormal(masm(), argc);
1537
+ } else {
1538
+ KeyedCallIC::GenerateNormal(masm(), argc);
1539
+ }
1540
+ Object* result;
1541
+ { MaybeObject* maybe_result = GetCodeWithFlags(flags, "CompileCallNormal");
1542
+ if (!maybe_result->ToObject(&result)) return maybe_result;
1543
+ }
1544
+ isolate()->counters()->call_normal_stubs()->Increment();
1545
+ Code* code = Code::cast(result);
1546
+ USE(code);
1547
+ PROFILE(isolate(),
1548
+ CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_NORMAL_TAG),
1549
+ code, code->arguments_count()));
1550
+ GDBJIT(AddCode(GDBJITInterface::CALL_NORMAL, Code::cast(code)));
1551
+ return result;
1552
+ }
1553
+
1554
+
1555
+ MaybeObject* StubCompiler::CompileCallMegamorphic(Code::Flags flags) {
1556
+ HandleScope scope(isolate());
1557
+ int argc = Code::ExtractArgumentsCountFromFlags(flags);
1558
+ Code::Kind kind = Code::ExtractKindFromFlags(flags);
1559
+ Code::ExtraICState extra_ic_state = Code::ExtractExtraICStateFromFlags(flags);
1560
+ if (kind == Code::CALL_IC) {
1561
+ CallIC::GenerateMegamorphic(masm(), argc, extra_ic_state);
1562
+ } else {
1563
+ KeyedCallIC::GenerateMegamorphic(masm(), argc);
1564
+ }
1565
+ Object* result;
1566
+ { MaybeObject* maybe_result =
1567
+ GetCodeWithFlags(flags, "CompileCallMegamorphic");
1568
+ if (!maybe_result->ToObject(&result)) return maybe_result;
1569
+ }
1570
+ isolate()->counters()->call_megamorphic_stubs()->Increment();
1571
+ Code* code = Code::cast(result);
1572
+ USE(code);
1573
+ PROFILE(isolate(),
1574
+ CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_MEGAMORPHIC_TAG),
1575
+ code, code->arguments_count()));
1576
+ GDBJIT(AddCode(GDBJITInterface::CALL_MEGAMORPHIC, Code::cast(code)));
1577
+ return result;
1578
+ }
1579
+
1580
+
1581
+ MaybeObject* StubCompiler::CompileCallMiss(Code::Flags flags) {
1582
+ HandleScope scope(isolate());
1583
+ int argc = Code::ExtractArgumentsCountFromFlags(flags);
1584
+ Code::Kind kind = Code::ExtractKindFromFlags(flags);
1585
+ Code::ExtraICState extra_ic_state = Code::ExtractExtraICStateFromFlags(flags);
1586
+ if (kind == Code::CALL_IC) {
1587
+ CallIC::GenerateMiss(masm(), argc, extra_ic_state);
1588
+ } else {
1589
+ KeyedCallIC::GenerateMiss(masm(), argc);
1590
+ }
1591
+ Object* result;
1592
+ { MaybeObject* maybe_result = GetCodeWithFlags(flags, "CompileCallMiss");
1593
+ if (!maybe_result->ToObject(&result)) return maybe_result;
1594
+ }
1595
+ isolate()->counters()->call_megamorphic_stubs()->Increment();
1596
+ Code* code = Code::cast(result);
1597
+ USE(code);
1598
+ PROFILE(isolate(),
1599
+ CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_MISS_TAG),
1600
+ code, code->arguments_count()));
1601
+ GDBJIT(AddCode(GDBJITInterface::CALL_MISS, Code::cast(code)));
1602
+ return result;
1603
+ }
1604
+
1605
+
1606
+ #ifdef ENABLE_DEBUGGER_SUPPORT
1607
+ MaybeObject* StubCompiler::CompileCallDebugBreak(Code::Flags flags) {
1608
+ HandleScope scope(isolate());
1609
+ Debug::GenerateCallICDebugBreak(masm());
1610
+ Object* result;
1611
+ { MaybeObject* maybe_result =
1612
+ GetCodeWithFlags(flags, "CompileCallDebugBreak");
1613
+ if (!maybe_result->ToObject(&result)) return maybe_result;
1614
+ }
1615
+ Code* code = Code::cast(result);
1616
+ USE(code);
1617
+ Code::Kind kind = Code::ExtractKindFromFlags(flags);
1618
+ USE(kind);
1619
+ PROFILE(isolate(),
1620
+ CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_DEBUG_BREAK_TAG),
1621
+ code, code->arguments_count()));
1622
+ return result;
1623
+ }
1624
+
1625
+
1626
+ MaybeObject* StubCompiler::CompileCallDebugPrepareStepIn(Code::Flags flags) {
1627
+ HandleScope scope(isolate());
1628
+ // Use the same code for the the step in preparations as we do for
1629
+ // the miss case.
1630
+ int argc = Code::ExtractArgumentsCountFromFlags(flags);
1631
+ Code::Kind kind = Code::ExtractKindFromFlags(flags);
1632
+ if (kind == Code::CALL_IC) {
1633
+ // For the debugger extra ic state is irrelevant.
1634
+ CallIC::GenerateMiss(masm(), argc, Code::kNoExtraICState);
1635
+ } else {
1636
+ KeyedCallIC::GenerateMiss(masm(), argc);
1637
+ }
1638
+ Object* result;
1639
+ { MaybeObject* maybe_result =
1640
+ GetCodeWithFlags(flags, "CompileCallDebugPrepareStepIn");
1641
+ if (!maybe_result->ToObject(&result)) return maybe_result;
1642
+ }
1643
+ Code* code = Code::cast(result);
1644
+ USE(code);
1645
+ PROFILE(isolate(),
1646
+ CodeCreateEvent(
1647
+ CALL_LOGGER_TAG(kind, CALL_DEBUG_PREPARE_STEP_IN_TAG),
1648
+ code,
1649
+ code->arguments_count()));
1650
+ return result;
1651
+ }
1652
+ #endif
1653
+
1654
+ #undef CALL_LOGGER_TAG
1655
+
1656
+ MaybeObject* StubCompiler::GetCodeWithFlags(Code::Flags flags,
1657
+ const char* name) {
1658
+ // Check for allocation failures during stub compilation.
1659
+ if (failure_->IsFailure()) return failure_;
1660
+
1661
+ // Create code object in the heap.
1662
+ CodeDesc desc;
1663
+ masm_.GetCode(&desc);
1664
+ MaybeObject* result = heap()->CreateCode(desc, flags, masm_.CodeObject());
1665
+ #ifdef ENABLE_DISASSEMBLER
1666
+ if (FLAG_print_code_stubs && !result->IsFailure()) {
1667
+ Code::cast(result->ToObjectUnchecked())->Disassemble(name);
1668
+ }
1669
+ #endif
1670
+ return result;
1671
+ }
1672
+
1673
+
1674
+ MaybeObject* StubCompiler::GetCodeWithFlags(Code::Flags flags, String* name) {
1675
+ if (FLAG_print_code_stubs && (name != NULL)) {
1676
+ return GetCodeWithFlags(flags, *name->ToCString());
1677
+ }
1678
+ return GetCodeWithFlags(flags, reinterpret_cast<char*>(NULL));
1679
+ }
1680
+
1681
+
1682
+ void StubCompiler::LookupPostInterceptor(JSObject* holder,
1683
+ String* name,
1684
+ LookupResult* lookup) {
1685
+ holder->LocalLookupRealNamedProperty(name, lookup);
1686
+ if (!lookup->IsProperty()) {
1687
+ lookup->NotFound();
1688
+ Object* proto = holder->GetPrototype();
1689
+ if (!proto->IsNull()) {
1690
+ proto->Lookup(name, lookup);
1691
+ }
1692
+ }
1693
+ }
1694
+
1695
+
1696
+
1697
+ MaybeObject* LoadStubCompiler::GetCode(PropertyType type, String* name) {
1698
+ Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, type);
1699
+ MaybeObject* result = GetCodeWithFlags(flags, name);
1700
+ if (!result->IsFailure()) {
1701
+ PROFILE(isolate(),
1702
+ CodeCreateEvent(Logger::LOAD_IC_TAG,
1703
+ Code::cast(result->ToObjectUnchecked()),
1704
+ name));
1705
+ GDBJIT(AddCode(GDBJITInterface::LOAD_IC,
1706
+ name,
1707
+ Code::cast(result->ToObjectUnchecked())));
1708
+ }
1709
+ return result;
1710
+ }
1711
+
1712
+
1713
+ MaybeObject* KeyedLoadStubCompiler::GetCode(PropertyType type,
1714
+ String* name,
1715
+ InlineCacheState state) {
1716
+ Code::Flags flags = Code::ComputeFlags(
1717
+ Code::KEYED_LOAD_IC, NOT_IN_LOOP, state, Code::kNoExtraICState, type);
1718
+ MaybeObject* result = GetCodeWithFlags(flags, name);
1719
+ if (!result->IsFailure()) {
1720
+ PROFILE(isolate(),
1721
+ CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG,
1722
+ Code::cast(result->ToObjectUnchecked()),
1723
+ name));
1724
+ GDBJIT(AddCode(GDBJITInterface::LOAD_IC,
1725
+ name,
1726
+ Code::cast(result->ToObjectUnchecked())));
1727
+ }
1728
+ return result;
1729
+ }
1730
+
1731
+
1732
+ MaybeObject* StoreStubCompiler::GetCode(PropertyType type, String* name) {
1733
+ Code::Flags flags = Code::ComputeMonomorphicFlags(
1734
+ Code::STORE_IC, type, strict_mode_);
1735
+ MaybeObject* result = GetCodeWithFlags(flags, name);
1736
+ if (!result->IsFailure()) {
1737
+ PROFILE(isolate(),
1738
+ CodeCreateEvent(Logger::STORE_IC_TAG,
1739
+ Code::cast(result->ToObjectUnchecked()),
1740
+ name));
1741
+ GDBJIT(AddCode(GDBJITInterface::STORE_IC,
1742
+ name,
1743
+ Code::cast(result->ToObjectUnchecked())));
1744
+ }
1745
+ return result;
1746
+ }
1747
+
1748
+
1749
+ MaybeObject* KeyedStoreStubCompiler::GetCode(PropertyType type,
1750
+ String* name,
1751
+ InlineCacheState state) {
1752
+ Code::Flags flags = Code::ComputeFlags(
1753
+ Code::KEYED_STORE_IC, NOT_IN_LOOP, state, strict_mode_, type);
1754
+ MaybeObject* result = GetCodeWithFlags(flags, name);
1755
+ if (!result->IsFailure()) {
1756
+ PROFILE(isolate(),
1757
+ CodeCreateEvent(Logger::KEYED_STORE_IC_TAG,
1758
+ Code::cast(result->ToObjectUnchecked()),
1759
+ name));
1760
+ GDBJIT(AddCode(GDBJITInterface::KEYED_STORE_IC,
1761
+ name,
1762
+ Code::cast(result->ToObjectUnchecked())));
1763
+ }
1764
+ return result;
1765
+ }
1766
+
1767
+
1768
+ CallStubCompiler::CallStubCompiler(int argc,
1769
+ InLoopFlag in_loop,
1770
+ Code::Kind kind,
1771
+ Code::ExtraICState extra_ic_state,
1772
+ InlineCacheHolderFlag cache_holder)
1773
+ : arguments_(argc),
1774
+ in_loop_(in_loop),
1775
+ kind_(kind),
1776
+ extra_ic_state_(extra_ic_state),
1777
+ cache_holder_(cache_holder) {
1778
+ }
1779
+
1780
+
1781
+ bool CallStubCompiler::HasCustomCallGenerator(JSFunction* function) {
1782
+ SharedFunctionInfo* info = function->shared();
1783
+ if (info->HasBuiltinFunctionId()) {
1784
+ BuiltinFunctionId id = info->builtin_function_id();
1785
+ #define CALL_GENERATOR_CASE(name) if (id == k##name) return true;
1786
+ CUSTOM_CALL_IC_GENERATORS(CALL_GENERATOR_CASE)
1787
+ #undef CALL_GENERATOR_CASE
1788
+ }
1789
+ CallOptimization optimization(function);
1790
+ if (optimization.is_simple_api_call()) {
1791
+ return true;
1792
+ }
1793
+ return false;
1794
+ }
1795
+
1796
+
1797
+ MaybeObject* CallStubCompiler::CompileCustomCall(Object* object,
1798
+ JSObject* holder,
1799
+ JSGlobalPropertyCell* cell,
1800
+ JSFunction* function,
1801
+ String* fname) {
1802
+ ASSERT(HasCustomCallGenerator(function));
1803
+
1804
+ SharedFunctionInfo* info = function->shared();
1805
+ if (info->HasBuiltinFunctionId()) {
1806
+ BuiltinFunctionId id = info->builtin_function_id();
1807
+ #define CALL_GENERATOR_CASE(name) \
1808
+ if (id == k##name) { \
1809
+ return CallStubCompiler::Compile##name##Call(object, \
1810
+ holder, \
1811
+ cell, \
1812
+ function, \
1813
+ fname); \
1814
+ }
1815
+ CUSTOM_CALL_IC_GENERATORS(CALL_GENERATOR_CASE)
1816
+ #undef CALL_GENERATOR_CASE
1817
+ }
1818
+ CallOptimization optimization(function);
1819
+ ASSERT(optimization.is_simple_api_call());
1820
+ return CompileFastApiCall(optimization,
1821
+ object,
1822
+ holder,
1823
+ cell,
1824
+ function,
1825
+ fname);
1826
+ }
1827
+
1828
+
1829
+ MaybeObject* CallStubCompiler::GetCode(PropertyType type, String* name) {
1830
+ int argc = arguments_.immediate();
1831
+ Code::Flags flags = Code::ComputeMonomorphicFlags(kind_,
1832
+ type,
1833
+ extra_ic_state_,
1834
+ cache_holder_,
1835
+ in_loop_,
1836
+ argc);
1837
+ return GetCodeWithFlags(flags, name);
1838
+ }
1839
+
1840
+
1841
+ MaybeObject* CallStubCompiler::GetCode(JSFunction* function) {
1842
+ String* function_name = NULL;
1843
+ if (function->shared()->name()->IsString()) {
1844
+ function_name = String::cast(function->shared()->name());
1845
+ }
1846
+ return GetCode(CONSTANT_FUNCTION, function_name);
1847
+ }
1848
+
1849
+
1850
+ MaybeObject* ConstructStubCompiler::GetCode() {
1851
+ Code::Flags flags = Code::ComputeFlags(Code::STUB);
1852
+ Object* result;
1853
+ { MaybeObject* maybe_result = GetCodeWithFlags(flags, "ConstructStub");
1854
+ if (!maybe_result->ToObject(&result)) return maybe_result;
1855
+ }
1856
+ Code* code = Code::cast(result);
1857
+ USE(code);
1858
+ PROFILE(isolate(), CodeCreateEvent(Logger::STUB_TAG, code, "ConstructStub"));
1859
+ GDBJIT(AddCode(GDBJITInterface::STUB, "ConstructStub", Code::cast(code)));
1860
+ return result;
1861
+ }
1862
+
1863
+
1864
+ CallOptimization::CallOptimization(LookupResult* lookup) {
1865
+ if (!lookup->IsProperty() || !lookup->IsCacheable() ||
1866
+ lookup->type() != CONSTANT_FUNCTION) {
1867
+ Initialize(NULL);
1868
+ } else {
1869
+ // We only optimize constant function calls.
1870
+ Initialize(lookup->GetConstantFunction());
1871
+ }
1872
+ }
1873
+
1874
+ CallOptimization::CallOptimization(JSFunction* function) {
1875
+ Initialize(function);
1876
+ }
1877
+
1878
+
1879
+ int CallOptimization::GetPrototypeDepthOfExpectedType(JSObject* object,
1880
+ JSObject* holder) const {
1881
+ ASSERT(is_simple_api_call_);
1882
+ if (expected_receiver_type_ == NULL) return 0;
1883
+ int depth = 0;
1884
+ while (object != holder) {
1885
+ if (object->IsInstanceOf(expected_receiver_type_)) return depth;
1886
+ object = JSObject::cast(object->GetPrototype());
1887
+ ++depth;
1888
+ }
1889
+ if (holder->IsInstanceOf(expected_receiver_type_)) return depth;
1890
+ return kInvalidProtoDepth;
1891
+ }
1892
+
1893
+
1894
+ void CallOptimization::Initialize(JSFunction* function) {
1895
+ constant_function_ = NULL;
1896
+ is_simple_api_call_ = false;
1897
+ expected_receiver_type_ = NULL;
1898
+ api_call_info_ = NULL;
1899
+
1900
+ if (function == NULL || !function->is_compiled()) return;
1901
+
1902
+ constant_function_ = function;
1903
+ AnalyzePossibleApiFunction(function);
1904
+ }
1905
+
1906
+
1907
+ void CallOptimization::AnalyzePossibleApiFunction(JSFunction* function) {
1908
+ SharedFunctionInfo* sfi = function->shared();
1909
+ if (!sfi->IsApiFunction()) return;
1910
+ FunctionTemplateInfo* info = sfi->get_api_func_data();
1911
+
1912
+ // Require a C++ callback.
1913
+ if (info->call_code()->IsUndefined()) return;
1914
+ api_call_info_ = CallHandlerInfo::cast(info->call_code());
1915
+
1916
+ // Accept signatures that either have no restrictions at all or
1917
+ // only have restrictions on the receiver.
1918
+ if (!info->signature()->IsUndefined()) {
1919
+ SignatureInfo* signature = SignatureInfo::cast(info->signature());
1920
+ if (!signature->args()->IsUndefined()) return;
1921
+ if (!signature->receiver()->IsUndefined()) {
1922
+ expected_receiver_type_ =
1923
+ FunctionTemplateInfo::cast(signature->receiver());
1924
+ }
1925
+ }
1926
+
1927
+ is_simple_api_call_ = true;
1928
+ }
1929
+
1930
+
1931
+ MaybeObject* ExternalArrayLoadStubCompiler::GetCode() {
1932
+ Object* result;
1933
+ Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC,
1934
+ NORMAL,
1935
+ strict_mode_);
1936
+ { MaybeObject* maybe_result = GetCodeWithFlags(flags,
1937
+ "ExternalArrayLoadStub");
1938
+ if (!maybe_result->ToObject(&result)) return maybe_result;
1939
+ }
1940
+ Code* code = Code::cast(result);
1941
+ USE(code);
1942
+ PROFILE(isolate(),
1943
+ CodeCreateEvent(Logger::STUB_TAG, code, "ExternalArrayLoadStub"));
1944
+ return result;
1945
+ }
1946
+
1947
+
1948
+ MaybeObject* ExternalArrayStoreStubCompiler::GetCode() {
1949
+ Object* result;
1950
+ Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_STORE_IC,
1951
+ NORMAL,
1952
+ strict_mode_);
1953
+ { MaybeObject* maybe_result = GetCodeWithFlags(flags,
1954
+ "ExternalArrayStoreStub");
1955
+ if (!maybe_result->ToObject(&result)) return maybe_result;
1956
+ }
1957
+ Code* code = Code::cast(result);
1958
+ USE(code);
1959
+ PROFILE(isolate(),
1960
+ CodeCreateEvent(Logger::STUB_TAG, code, "ExternalArrayStoreStub"));
1961
+ return result;
1962
+ }
1963
+
1964
+
1965
+ } } // namespace v8::internal