libv8 3.3.10.4 → 3.5.10.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (538) hide show
  1. data/lib/libv8/scons/CHANGES.txt +24 -231
  2. data/lib/libv8/scons/LICENSE.txt +1 -1
  3. data/lib/libv8/scons/MANIFEST +0 -1
  4. data/lib/libv8/scons/PKG-INFO +1 -1
  5. data/lib/libv8/scons/README.txt +9 -9
  6. data/lib/libv8/scons/RELEASE.txt +75 -77
  7. data/lib/libv8/scons/engine/SCons/Action.py +6 -22
  8. data/lib/libv8/scons/engine/SCons/Builder.py +2 -2
  9. data/lib/libv8/scons/engine/SCons/CacheDir.py +2 -2
  10. data/lib/libv8/scons/engine/SCons/Debug.py +2 -2
  11. data/lib/libv8/scons/engine/SCons/Defaults.py +10 -24
  12. data/lib/libv8/scons/engine/SCons/Environment.py +19 -118
  13. data/lib/libv8/scons/engine/SCons/Errors.py +2 -2
  14. data/lib/libv8/scons/engine/SCons/Executor.py +2 -2
  15. data/lib/libv8/scons/engine/SCons/Job.py +2 -2
  16. data/lib/libv8/scons/engine/SCons/Memoize.py +2 -2
  17. data/lib/libv8/scons/engine/SCons/Node/Alias.py +2 -2
  18. data/lib/libv8/scons/engine/SCons/Node/FS.py +121 -281
  19. data/lib/libv8/scons/engine/SCons/Node/Python.py +2 -2
  20. data/lib/libv8/scons/engine/SCons/Node/__init__.py +5 -6
  21. data/lib/libv8/scons/engine/SCons/Options/BoolOption.py +2 -2
  22. data/lib/libv8/scons/engine/SCons/Options/EnumOption.py +2 -2
  23. data/lib/libv8/scons/engine/SCons/Options/ListOption.py +2 -2
  24. data/lib/libv8/scons/engine/SCons/Options/PackageOption.py +2 -2
  25. data/lib/libv8/scons/engine/SCons/Options/PathOption.py +2 -2
  26. data/lib/libv8/scons/engine/SCons/Options/__init__.py +2 -2
  27. data/lib/libv8/scons/engine/SCons/PathList.py +2 -2
  28. data/lib/libv8/scons/engine/SCons/Platform/__init__.py +2 -2
  29. data/lib/libv8/scons/engine/SCons/Platform/aix.py +2 -2
  30. data/lib/libv8/scons/engine/SCons/Platform/cygwin.py +2 -2
  31. data/lib/libv8/scons/engine/SCons/Platform/darwin.py +3 -27
  32. data/lib/libv8/scons/engine/SCons/Platform/hpux.py +2 -2
  33. data/lib/libv8/scons/engine/SCons/Platform/irix.py +2 -2
  34. data/lib/libv8/scons/engine/SCons/Platform/os2.py +2 -2
  35. data/lib/libv8/scons/engine/SCons/Platform/posix.py +2 -2
  36. data/lib/libv8/scons/engine/SCons/Platform/sunos.py +2 -2
  37. data/lib/libv8/scons/engine/SCons/Platform/win32.py +2 -2
  38. data/lib/libv8/scons/engine/SCons/SConf.py +2 -2
  39. data/lib/libv8/scons/engine/SCons/SConsign.py +3 -9
  40. data/lib/libv8/scons/engine/SCons/Scanner/C.py +2 -2
  41. data/lib/libv8/scons/engine/SCons/Scanner/D.py +2 -2
  42. data/lib/libv8/scons/engine/SCons/Scanner/Dir.py +2 -2
  43. data/lib/libv8/scons/engine/SCons/Scanner/Fortran.py +2 -2
  44. data/lib/libv8/scons/engine/SCons/Scanner/IDL.py +2 -2
  45. data/lib/libv8/scons/engine/SCons/Scanner/LaTeX.py +2 -5
  46. data/lib/libv8/scons/engine/SCons/Scanner/Prog.py +2 -2
  47. data/lib/libv8/scons/engine/SCons/Scanner/RC.py +3 -3
  48. data/lib/libv8/scons/engine/SCons/Scanner/__init__.py +2 -2
  49. data/lib/libv8/scons/engine/SCons/Script/Interactive.py +2 -2
  50. data/lib/libv8/scons/engine/SCons/Script/Main.py +11 -82
  51. data/lib/libv8/scons/engine/SCons/Script/SConsOptions.py +5 -5
  52. data/lib/libv8/scons/engine/SCons/Script/SConscript.py +2 -2
  53. data/lib/libv8/scons/engine/SCons/Script/__init__.py +2 -2
  54. data/lib/libv8/scons/engine/SCons/Sig.py +2 -2
  55. data/lib/libv8/scons/engine/SCons/Subst.py +2 -2
  56. data/lib/libv8/scons/engine/SCons/Taskmaster.py +2 -10
  57. data/lib/libv8/scons/engine/SCons/Tool/386asm.py +2 -2
  58. data/lib/libv8/scons/engine/SCons/Tool/BitKeeper.py +2 -2
  59. data/lib/libv8/scons/engine/SCons/Tool/CVS.py +2 -2
  60. data/lib/libv8/scons/engine/SCons/Tool/FortranCommon.py +2 -19
  61. data/lib/libv8/scons/engine/SCons/Tool/JavaCommon.py +2 -2
  62. data/lib/libv8/scons/engine/SCons/Tool/MSCommon/__init__.py +2 -2
  63. data/lib/libv8/scons/engine/SCons/Tool/MSCommon/arch.py +2 -2
  64. data/lib/libv8/scons/engine/SCons/Tool/MSCommon/common.py +2 -2
  65. data/lib/libv8/scons/engine/SCons/Tool/MSCommon/netframework.py +2 -2
  66. data/lib/libv8/scons/engine/SCons/Tool/MSCommon/sdk.py +2 -2
  67. data/lib/libv8/scons/engine/SCons/Tool/MSCommon/vc.py +6 -9
  68. data/lib/libv8/scons/engine/SCons/Tool/MSCommon/vs.py +2 -29
  69. data/lib/libv8/scons/engine/SCons/Tool/Perforce.py +2 -2
  70. data/lib/libv8/scons/engine/SCons/Tool/PharLapCommon.py +2 -2
  71. data/lib/libv8/scons/engine/SCons/Tool/RCS.py +2 -2
  72. data/lib/libv8/scons/engine/SCons/Tool/SCCS.py +2 -2
  73. data/lib/libv8/scons/engine/SCons/Tool/Subversion.py +2 -2
  74. data/lib/libv8/scons/engine/SCons/Tool/__init__.py +3 -3
  75. data/lib/libv8/scons/engine/SCons/Tool/aixc++.py +2 -2
  76. data/lib/libv8/scons/engine/SCons/Tool/aixcc.py +2 -2
  77. data/lib/libv8/scons/engine/SCons/Tool/aixf77.py +2 -2
  78. data/lib/libv8/scons/engine/SCons/Tool/aixlink.py +2 -2
  79. data/lib/libv8/scons/engine/SCons/Tool/applelink.py +2 -2
  80. data/lib/libv8/scons/engine/SCons/Tool/ar.py +2 -2
  81. data/lib/libv8/scons/engine/SCons/Tool/as.py +2 -2
  82. data/lib/libv8/scons/engine/SCons/Tool/bcc32.py +2 -2
  83. data/lib/libv8/scons/engine/SCons/Tool/c++.py +2 -2
  84. data/lib/libv8/scons/engine/SCons/Tool/cc.py +2 -2
  85. data/lib/libv8/scons/engine/SCons/Tool/cvf.py +2 -2
  86. data/lib/libv8/scons/engine/SCons/Tool/default.py +2 -2
  87. data/lib/libv8/scons/engine/SCons/Tool/dmd.py +7 -24
  88. data/lib/libv8/scons/engine/SCons/Tool/dvi.py +2 -2
  89. data/lib/libv8/scons/engine/SCons/Tool/dvipdf.py +2 -3
  90. data/lib/libv8/scons/engine/SCons/Tool/dvips.py +2 -3
  91. data/lib/libv8/scons/engine/SCons/Tool/f77.py +2 -2
  92. data/lib/libv8/scons/engine/SCons/Tool/f90.py +2 -2
  93. data/lib/libv8/scons/engine/SCons/Tool/f95.py +2 -2
  94. data/lib/libv8/scons/engine/SCons/Tool/filesystem.py +2 -2
  95. data/lib/libv8/scons/engine/SCons/Tool/fortran.py +2 -2
  96. data/lib/libv8/scons/engine/SCons/Tool/g++.py +2 -2
  97. data/lib/libv8/scons/engine/SCons/Tool/g77.py +2 -2
  98. data/lib/libv8/scons/engine/SCons/Tool/gas.py +2 -2
  99. data/lib/libv8/scons/engine/SCons/Tool/gcc.py +2 -2
  100. data/lib/libv8/scons/engine/SCons/Tool/gfortran.py +3 -3
  101. data/lib/libv8/scons/engine/SCons/Tool/gnulink.py +3 -2
  102. data/lib/libv8/scons/engine/SCons/Tool/gs.py +2 -2
  103. data/lib/libv8/scons/engine/SCons/Tool/hpc++.py +2 -2
  104. data/lib/libv8/scons/engine/SCons/Tool/hpcc.py +2 -2
  105. data/lib/libv8/scons/engine/SCons/Tool/hplink.py +2 -2
  106. data/lib/libv8/scons/engine/SCons/Tool/icc.py +2 -2
  107. data/lib/libv8/scons/engine/SCons/Tool/icl.py +2 -2
  108. data/lib/libv8/scons/engine/SCons/Tool/ifl.py +2 -2
  109. data/lib/libv8/scons/engine/SCons/Tool/ifort.py +2 -2
  110. data/lib/libv8/scons/engine/SCons/Tool/ilink.py +2 -2
  111. data/lib/libv8/scons/engine/SCons/Tool/ilink32.py +2 -2
  112. data/lib/libv8/scons/engine/SCons/Tool/install.py +3 -57
  113. data/lib/libv8/scons/engine/SCons/Tool/intelc.py +25 -65
  114. data/lib/libv8/scons/engine/SCons/Tool/ipkg.py +2 -2
  115. data/lib/libv8/scons/engine/SCons/Tool/jar.py +3 -9
  116. data/lib/libv8/scons/engine/SCons/Tool/javac.py +2 -2
  117. data/lib/libv8/scons/engine/SCons/Tool/javah.py +2 -2
  118. data/lib/libv8/scons/engine/SCons/Tool/latex.py +2 -3
  119. data/lib/libv8/scons/engine/SCons/Tool/lex.py +2 -2
  120. data/lib/libv8/scons/engine/SCons/Tool/link.py +5 -6
  121. data/lib/libv8/scons/engine/SCons/Tool/linkloc.py +2 -2
  122. data/lib/libv8/scons/engine/SCons/Tool/m4.py +2 -2
  123. data/lib/libv8/scons/engine/SCons/Tool/masm.py +2 -2
  124. data/lib/libv8/scons/engine/SCons/Tool/midl.py +2 -2
  125. data/lib/libv8/scons/engine/SCons/Tool/mingw.py +10 -31
  126. data/lib/libv8/scons/engine/SCons/Tool/mslib.py +2 -2
  127. data/lib/libv8/scons/engine/SCons/Tool/mslink.py +9 -61
  128. data/lib/libv8/scons/engine/SCons/Tool/mssdk.py +2 -2
  129. data/lib/libv8/scons/engine/SCons/Tool/msvc.py +11 -21
  130. data/lib/libv8/scons/engine/SCons/Tool/msvs.py +59 -477
  131. data/lib/libv8/scons/engine/SCons/Tool/mwcc.py +2 -2
  132. data/lib/libv8/scons/engine/SCons/Tool/mwld.py +2 -2
  133. data/lib/libv8/scons/engine/SCons/Tool/nasm.py +2 -2
  134. data/lib/libv8/scons/engine/SCons/Tool/packaging/__init__.py +2 -2
  135. data/lib/libv8/scons/engine/SCons/Tool/packaging/ipk.py +2 -2
  136. data/lib/libv8/scons/engine/SCons/Tool/packaging/msi.py +2 -2
  137. data/lib/libv8/scons/engine/SCons/Tool/packaging/rpm.py +2 -2
  138. data/lib/libv8/scons/engine/SCons/Tool/packaging/src_tarbz2.py +2 -2
  139. data/lib/libv8/scons/engine/SCons/Tool/packaging/src_targz.py +2 -2
  140. data/lib/libv8/scons/engine/SCons/Tool/packaging/src_zip.py +2 -2
  141. data/lib/libv8/scons/engine/SCons/Tool/packaging/tarbz2.py +2 -2
  142. data/lib/libv8/scons/engine/SCons/Tool/packaging/targz.py +2 -2
  143. data/lib/libv8/scons/engine/SCons/Tool/packaging/zip.py +2 -2
  144. data/lib/libv8/scons/engine/SCons/Tool/pdf.py +2 -2
  145. data/lib/libv8/scons/engine/SCons/Tool/pdflatex.py +2 -3
  146. data/lib/libv8/scons/engine/SCons/Tool/pdftex.py +2 -3
  147. data/lib/libv8/scons/engine/SCons/Tool/qt.py +2 -2
  148. data/lib/libv8/scons/engine/SCons/Tool/rmic.py +3 -9
  149. data/lib/libv8/scons/engine/SCons/Tool/rpcgen.py +2 -2
  150. data/lib/libv8/scons/engine/SCons/Tool/rpm.py +2 -2
  151. data/lib/libv8/scons/engine/SCons/Tool/sgiar.py +2 -2
  152. data/lib/libv8/scons/engine/SCons/Tool/sgic++.py +2 -2
  153. data/lib/libv8/scons/engine/SCons/Tool/sgicc.py +2 -2
  154. data/lib/libv8/scons/engine/SCons/Tool/sgilink.py +3 -2
  155. data/lib/libv8/scons/engine/SCons/Tool/sunar.py +2 -2
  156. data/lib/libv8/scons/engine/SCons/Tool/sunc++.py +2 -2
  157. data/lib/libv8/scons/engine/SCons/Tool/suncc.py +2 -2
  158. data/lib/libv8/scons/engine/SCons/Tool/sunf77.py +2 -2
  159. data/lib/libv8/scons/engine/SCons/Tool/sunf90.py +2 -2
  160. data/lib/libv8/scons/engine/SCons/Tool/sunf95.py +2 -2
  161. data/lib/libv8/scons/engine/SCons/Tool/sunlink.py +3 -2
  162. data/lib/libv8/scons/engine/SCons/Tool/swig.py +5 -6
  163. data/lib/libv8/scons/engine/SCons/Tool/tar.py +2 -2
  164. data/lib/libv8/scons/engine/SCons/Tool/tex.py +43 -96
  165. data/lib/libv8/scons/engine/SCons/Tool/textfile.py +2 -2
  166. data/lib/libv8/scons/engine/SCons/Tool/tlib.py +2 -2
  167. data/lib/libv8/scons/engine/SCons/Tool/wix.py +2 -2
  168. data/lib/libv8/scons/engine/SCons/Tool/yacc.py +2 -12
  169. data/lib/libv8/scons/engine/SCons/Tool/zip.py +2 -2
  170. data/lib/libv8/scons/engine/SCons/Util.py +3 -3
  171. data/lib/libv8/scons/engine/SCons/Variables/BoolVariable.py +2 -2
  172. data/lib/libv8/scons/engine/SCons/Variables/EnumVariable.py +3 -3
  173. data/lib/libv8/scons/engine/SCons/Variables/ListVariable.py +2 -2
  174. data/lib/libv8/scons/engine/SCons/Variables/PackageVariable.py +2 -2
  175. data/lib/libv8/scons/engine/SCons/Variables/PathVariable.py +2 -2
  176. data/lib/libv8/scons/engine/SCons/Variables/__init__.py +2 -2
  177. data/lib/libv8/scons/engine/SCons/Warnings.py +2 -2
  178. data/lib/libv8/scons/engine/SCons/__init__.py +6 -6
  179. data/lib/libv8/scons/engine/SCons/compat/__init__.py +2 -2
  180. data/lib/libv8/scons/engine/SCons/compat/_scons_builtins.py +2 -2
  181. data/lib/libv8/scons/engine/SCons/compat/_scons_collections.py +2 -2
  182. data/lib/libv8/scons/engine/SCons/compat/_scons_dbm.py +2 -2
  183. data/lib/libv8/scons/engine/SCons/compat/_scons_hashlib.py +2 -2
  184. data/lib/libv8/scons/engine/SCons/compat/_scons_io.py +2 -2
  185. data/lib/libv8/scons/engine/SCons/cpp.py +2 -2
  186. data/lib/libv8/scons/engine/SCons/dblite.py +1 -4
  187. data/lib/libv8/scons/engine/SCons/exitfuncs.py +2 -2
  188. data/lib/libv8/scons/scons-time.1 +3 -3
  189. data/lib/libv8/scons/scons.1 +1164 -1170
  190. data/lib/libv8/scons/sconsign.1 +3 -3
  191. data/lib/libv8/scons/script/scons +22 -22
  192. data/lib/libv8/scons/script/scons-time +2 -2
  193. data/lib/libv8/scons/script/scons.bat +4 -7
  194. data/lib/libv8/scons/script/sconsign +20 -21
  195. data/lib/libv8/scons/setup.cfg +1 -0
  196. data/lib/libv8/scons/setup.py +40 -38
  197. data/lib/libv8/v8/.gitignore +1 -1
  198. data/lib/libv8/v8/AUTHORS +2 -0
  199. data/lib/libv8/v8/ChangeLog +387 -0
  200. data/lib/libv8/v8/Makefile +171 -0
  201. data/lib/libv8/v8/SConstruct +124 -51
  202. data/lib/libv8/v8/build/README.txt +31 -14
  203. data/lib/libv8/v8/build/all.gyp +11 -4
  204. data/lib/libv8/v8/build/armu.gypi +6 -2
  205. data/lib/libv8/v8/build/common.gypi +240 -94
  206. data/lib/libv8/v8/build/gyp_v8 +32 -4
  207. data/lib/libv8/v8/build/standalone.gypi +200 -0
  208. data/lib/libv8/v8/include/v8-debug.h +0 -0
  209. data/lib/libv8/v8/include/v8-profiler.h +8 -11
  210. data/lib/libv8/v8/include/v8.h +191 -108
  211. data/lib/libv8/v8/preparser/SConscript +2 -2
  212. data/lib/libv8/v8/preparser/preparser-process.cc +3 -3
  213. data/lib/libv8/v8/preparser/preparser.gyp +42 -0
  214. data/lib/libv8/v8/src/SConscript +33 -8
  215. data/lib/libv8/v8/src/accessors.cc +77 -43
  216. data/lib/libv8/v8/src/api.cc +393 -191
  217. data/lib/libv8/v8/src/api.h +4 -8
  218. data/lib/libv8/v8/src/apinatives.js +15 -3
  219. data/lib/libv8/v8/src/arguments.h +8 -0
  220. data/lib/libv8/v8/src/arm/assembler-arm.cc +120 -120
  221. data/lib/libv8/v8/src/arm/assembler-arm.h +92 -43
  222. data/lib/libv8/v8/src/arm/builtins-arm.cc +32 -39
  223. data/lib/libv8/v8/src/arm/code-stubs-arm.cc +572 -351
  224. data/lib/libv8/v8/src/arm/code-stubs-arm.h +8 -77
  225. data/lib/libv8/v8/src/arm/codegen-arm.h +0 -2
  226. data/lib/libv8/v8/src/arm/deoptimizer-arm.cc +50 -30
  227. data/lib/libv8/v8/src/arm/disasm-arm.cc +1 -1
  228. data/lib/libv8/v8/src/arm/frames-arm.h +9 -5
  229. data/lib/libv8/v8/src/arm/full-codegen-arm.cc +331 -432
  230. data/lib/libv8/v8/src/arm/ic-arm.cc +192 -124
  231. data/lib/libv8/v8/src/arm/lithium-arm.cc +216 -232
  232. data/lib/libv8/v8/src/arm/lithium-arm.h +106 -259
  233. data/lib/libv8/v8/src/arm/lithium-codegen-arm.cc +633 -642
  234. data/lib/libv8/v8/src/arm/lithium-codegen-arm.h +4 -4
  235. data/lib/libv8/v8/src/arm/lithium-gap-resolver-arm.cc +1 -3
  236. data/lib/libv8/v8/src/arm/macro-assembler-arm.cc +260 -185
  237. data/lib/libv8/v8/src/arm/macro-assembler-arm.h +45 -25
  238. data/lib/libv8/v8/src/arm/regexp-macro-assembler-arm.cc +25 -13
  239. data/lib/libv8/v8/src/arm/regexp-macro-assembler-arm.h +3 -0
  240. data/lib/libv8/v8/src/arm/stub-cache-arm.cc +413 -226
  241. data/lib/libv8/v8/src/array.js +38 -18
  242. data/lib/libv8/v8/src/assembler.cc +12 -5
  243. data/lib/libv8/v8/src/assembler.h +15 -9
  244. data/lib/libv8/v8/src/ast-inl.h +34 -25
  245. data/lib/libv8/v8/src/ast.cc +141 -72
  246. data/lib/libv8/v8/src/ast.h +255 -181
  247. data/lib/libv8/v8/src/bignum.cc +3 -4
  248. data/lib/libv8/v8/src/bootstrapper.cc +55 -11
  249. data/lib/libv8/v8/src/bootstrapper.h +3 -2
  250. data/lib/libv8/v8/src/builtins.cc +8 -2
  251. data/lib/libv8/v8/src/builtins.h +4 -0
  252. data/lib/libv8/v8/src/cached-powers.cc +8 -4
  253. data/lib/libv8/v8/src/checks.h +3 -3
  254. data/lib/libv8/v8/src/code-stubs.cc +173 -28
  255. data/lib/libv8/v8/src/code-stubs.h +104 -148
  256. data/lib/libv8/v8/src/codegen.cc +8 -8
  257. data/lib/libv8/v8/src/compilation-cache.cc +2 -47
  258. data/lib/libv8/v8/src/compilation-cache.h +0 -10
  259. data/lib/libv8/v8/src/compiler.cc +27 -16
  260. data/lib/libv8/v8/src/compiler.h +13 -18
  261. data/lib/libv8/v8/src/contexts.cc +107 -72
  262. data/lib/libv8/v8/src/contexts.h +70 -34
  263. data/lib/libv8/v8/src/conversions-inl.h +572 -14
  264. data/lib/libv8/v8/src/conversions.cc +9 -707
  265. data/lib/libv8/v8/src/conversions.h +23 -12
  266. data/lib/libv8/v8/src/cpu-profiler-inl.h +2 -19
  267. data/lib/libv8/v8/src/cpu-profiler.cc +4 -21
  268. data/lib/libv8/v8/src/cpu-profiler.h +8 -17
  269. data/lib/libv8/v8/src/d8-debug.cc +5 -3
  270. data/lib/libv8/v8/src/d8-debug.h +6 -7
  271. data/lib/libv8/v8/src/d8-posix.cc +1 -10
  272. data/lib/libv8/v8/src/d8.cc +721 -219
  273. data/lib/libv8/v8/src/d8.gyp +37 -12
  274. data/lib/libv8/v8/src/d8.h +141 -19
  275. data/lib/libv8/v8/src/d8.js +17 -8
  276. data/lib/libv8/v8/src/date.js +16 -5
  277. data/lib/libv8/v8/src/dateparser-inl.h +242 -39
  278. data/lib/libv8/v8/src/dateparser.cc +38 -4
  279. data/lib/libv8/v8/src/dateparser.h +170 -28
  280. data/lib/libv8/v8/src/debug-agent.cc +5 -3
  281. data/lib/libv8/v8/src/debug-agent.h +11 -7
  282. data/lib/libv8/v8/src/debug-debugger.js +65 -34
  283. data/lib/libv8/v8/src/debug.cc +30 -60
  284. data/lib/libv8/v8/src/debug.h +5 -3
  285. data/lib/libv8/v8/src/deoptimizer.cc +227 -10
  286. data/lib/libv8/v8/src/deoptimizer.h +133 -9
  287. data/lib/libv8/v8/src/disassembler.cc +22 -14
  288. data/lib/libv8/v8/src/diy-fp.cc +4 -3
  289. data/lib/libv8/v8/src/diy-fp.h +3 -3
  290. data/lib/libv8/v8/src/elements.cc +634 -0
  291. data/lib/libv8/v8/src/elements.h +95 -0
  292. data/lib/libv8/v8/src/execution.cc +5 -21
  293. data/lib/libv8/v8/src/extensions/experimental/break-iterator.cc +3 -1
  294. data/lib/libv8/v8/src/extensions/experimental/break-iterator.h +1 -1
  295. data/lib/libv8/v8/src/extensions/experimental/collator.cc +6 -2
  296. data/lib/libv8/v8/src/extensions/experimental/collator.h +1 -2
  297. data/lib/libv8/v8/src/extensions/experimental/datetime-format.cc +384 -0
  298. data/lib/libv8/v8/src/extensions/experimental/datetime-format.h +83 -0
  299. data/lib/libv8/v8/src/extensions/experimental/experimental.gyp +18 -7
  300. data/lib/libv8/v8/src/extensions/experimental/i18n-extension.cc +12 -16
  301. data/lib/libv8/v8/src/extensions/experimental/i18n-extension.h +1 -1
  302. data/lib/libv8/v8/src/extensions/experimental/i18n-js2c.py +126 -0
  303. data/lib/libv8/v8/src/extensions/experimental/i18n-locale.cc +3 -4
  304. data/lib/libv8/v8/src/extensions/experimental/i18n-locale.h +1 -1
  305. data/lib/libv8/v8/src/{shell.h → extensions/experimental/i18n-natives.h} +8 -20
  306. data/lib/libv8/v8/src/extensions/experimental/i18n-utils.cc +45 -1
  307. data/lib/libv8/v8/src/extensions/experimental/i18n-utils.h +21 -1
  308. data/lib/libv8/v8/src/extensions/experimental/i18n.js +211 -11
  309. data/lib/libv8/v8/src/extensions/experimental/language-matcher.cc +4 -3
  310. data/lib/libv8/v8/src/extensions/experimental/language-matcher.h +1 -1
  311. data/lib/libv8/v8/src/extensions/experimental/number-format.cc +374 -0
  312. data/lib/libv8/v8/src/extensions/experimental/number-format.h +71 -0
  313. data/lib/libv8/v8/src/factory.cc +89 -18
  314. data/lib/libv8/v8/src/factory.h +36 -8
  315. data/lib/libv8/v8/src/flag-definitions.h +11 -44
  316. data/lib/libv8/v8/src/frames-inl.h +8 -1
  317. data/lib/libv8/v8/src/frames.cc +39 -3
  318. data/lib/libv8/v8/src/frames.h +10 -3
  319. data/lib/libv8/v8/src/full-codegen.cc +311 -293
  320. data/lib/libv8/v8/src/full-codegen.h +183 -143
  321. data/lib/libv8/v8/src/func-name-inferrer.cc +29 -15
  322. data/lib/libv8/v8/src/func-name-inferrer.h +19 -9
  323. data/lib/libv8/v8/src/gdb-jit.cc +658 -55
  324. data/lib/libv8/v8/src/gdb-jit.h +6 -2
  325. data/lib/libv8/v8/src/global-handles.cc +368 -312
  326. data/lib/libv8/v8/src/global-handles.h +29 -36
  327. data/lib/libv8/v8/src/globals.h +3 -1
  328. data/lib/libv8/v8/src/handles.cc +43 -69
  329. data/lib/libv8/v8/src/handles.h +21 -16
  330. data/lib/libv8/v8/src/heap-inl.h +11 -13
  331. data/lib/libv8/v8/src/heap-profiler.cc +0 -999
  332. data/lib/libv8/v8/src/heap-profiler.h +0 -303
  333. data/lib/libv8/v8/src/heap.cc +366 -141
  334. data/lib/libv8/v8/src/heap.h +87 -26
  335. data/lib/libv8/v8/src/hydrogen-instructions.cc +192 -81
  336. data/lib/libv8/v8/src/hydrogen-instructions.h +711 -482
  337. data/lib/libv8/v8/src/hydrogen.cc +1146 -629
  338. data/lib/libv8/v8/src/hydrogen.h +100 -64
  339. data/lib/libv8/v8/src/ia32/assembler-ia32.cc +19 -0
  340. data/lib/libv8/v8/src/ia32/assembler-ia32.h +15 -2
  341. data/lib/libv8/v8/src/ia32/builtins-ia32.cc +34 -39
  342. data/lib/libv8/v8/src/ia32/code-stubs-ia32.cc +675 -377
  343. data/lib/libv8/v8/src/ia32/code-stubs-ia32.h +8 -69
  344. data/lib/libv8/v8/src/ia32/codegen-ia32.cc +1 -0
  345. data/lib/libv8/v8/src/ia32/codegen-ia32.h +0 -2
  346. data/lib/libv8/v8/src/ia32/cpu-ia32.cc +3 -2
  347. data/lib/libv8/v8/src/ia32/deoptimizer-ia32.cc +28 -3
  348. data/lib/libv8/v8/src/ia32/disasm-ia32.cc +21 -10
  349. data/lib/libv8/v8/src/ia32/frames-ia32.h +6 -5
  350. data/lib/libv8/v8/src/ia32/full-codegen-ia32.cc +459 -465
  351. data/lib/libv8/v8/src/ia32/ic-ia32.cc +196 -147
  352. data/lib/libv8/v8/src/ia32/lithium-codegen-ia32.cc +575 -650
  353. data/lib/libv8/v8/src/ia32/lithium-codegen-ia32.h +19 -21
  354. data/lib/libv8/v8/src/ia32/lithium-gap-resolver-ia32.cc +7 -2
  355. data/lib/libv8/v8/src/ia32/lithium-ia32.cc +261 -256
  356. data/lib/libv8/v8/src/ia32/lithium-ia32.h +234 -335
  357. data/lib/libv8/v8/src/ia32/macro-assembler-ia32.cc +224 -67
  358. data/lib/libv8/v8/src/ia32/macro-assembler-ia32.h +63 -19
  359. data/lib/libv8/v8/src/ia32/regexp-macro-assembler-ia32.cc +22 -8
  360. data/lib/libv8/v8/src/ia32/regexp-macro-assembler-ia32.h +3 -0
  361. data/lib/libv8/v8/src/ia32/stub-cache-ia32.cc +380 -239
  362. data/lib/libv8/v8/src/ic.cc +198 -234
  363. data/lib/libv8/v8/src/ic.h +32 -30
  364. data/lib/libv8/v8/src/interpreter-irregexp.cc +6 -4
  365. data/lib/libv8/v8/src/isolate.cc +112 -95
  366. data/lib/libv8/v8/src/isolate.h +55 -71
  367. data/lib/libv8/v8/src/json-parser.h +486 -48
  368. data/lib/libv8/v8/src/json.js +28 -23
  369. data/lib/libv8/v8/src/jsregexp.cc +163 -208
  370. data/lib/libv8/v8/src/jsregexp.h +0 -1
  371. data/lib/libv8/v8/src/lithium-allocator-inl.h +29 -27
  372. data/lib/libv8/v8/src/lithium-allocator.cc +22 -17
  373. data/lib/libv8/v8/src/lithium-allocator.h +8 -8
  374. data/lib/libv8/v8/src/lithium.cc +16 -11
  375. data/lib/libv8/v8/src/lithium.h +31 -34
  376. data/lib/libv8/v8/src/liveedit.cc +111 -15
  377. data/lib/libv8/v8/src/liveedit.h +3 -4
  378. data/lib/libv8/v8/src/liveobjectlist.cc +116 -80
  379. data/lib/libv8/v8/src/liveobjectlist.h +2 -2
  380. data/lib/libv8/v8/src/log-inl.h +0 -4
  381. data/lib/libv8/v8/src/log-utils.cc +25 -143
  382. data/lib/libv8/v8/src/log-utils.h +13 -92
  383. data/lib/libv8/v8/src/log.cc +26 -249
  384. data/lib/libv8/v8/src/log.h +6 -17
  385. data/lib/libv8/v8/src/macros.py +9 -6
  386. data/lib/libv8/v8/src/mark-compact.cc +276 -56
  387. data/lib/libv8/v8/src/mark-compact.h +20 -0
  388. data/lib/libv8/v8/src/messages.js +93 -39
  389. data/lib/libv8/v8/src/mips/assembler-mips-inl.h +9 -3
  390. data/lib/libv8/v8/src/mips/assembler-mips.cc +297 -189
  391. data/lib/libv8/v8/src/mips/assembler-mips.h +121 -54
  392. data/lib/libv8/v8/src/mips/builtins-mips.cc +23 -24
  393. data/lib/libv8/v8/src/mips/code-stubs-mips.cc +484 -263
  394. data/lib/libv8/v8/src/mips/code-stubs-mips.h +8 -83
  395. data/lib/libv8/v8/src/mips/codegen-mips.h +0 -2
  396. data/lib/libv8/v8/src/mips/constants-mips.h +37 -11
  397. data/lib/libv8/v8/src/mips/deoptimizer-mips.cc +6 -1
  398. data/lib/libv8/v8/src/mips/frames-mips.h +8 -7
  399. data/lib/libv8/v8/src/mips/full-codegen-mips.cc +258 -419
  400. data/lib/libv8/v8/src/mips/ic-mips.cc +181 -121
  401. data/lib/libv8/v8/src/mips/macro-assembler-mips.cc +640 -382
  402. data/lib/libv8/v8/src/mips/macro-assembler-mips.h +94 -89
  403. data/lib/libv8/v8/src/mips/regexp-macro-assembler-mips.cc +23 -10
  404. data/lib/libv8/v8/src/mips/regexp-macro-assembler-mips.h +6 -1
  405. data/lib/libv8/v8/src/mips/simulator-mips.cc +249 -49
  406. data/lib/libv8/v8/src/mips/simulator-mips.h +25 -1
  407. data/lib/libv8/v8/src/mips/stub-cache-mips.cc +373 -161
  408. data/lib/libv8/v8/src/mirror-debugger.js +55 -8
  409. data/lib/libv8/v8/src/misc-intrinsics.h +89 -0
  410. data/lib/libv8/v8/src/mksnapshot.cc +36 -4
  411. data/lib/libv8/v8/src/natives.h +5 -2
  412. data/lib/libv8/v8/src/objects-debug.cc +73 -6
  413. data/lib/libv8/v8/src/objects-inl.h +529 -164
  414. data/lib/libv8/v8/src/objects-printer.cc +67 -12
  415. data/lib/libv8/v8/src/objects-visiting.cc +13 -2
  416. data/lib/libv8/v8/src/objects-visiting.h +41 -1
  417. data/lib/libv8/v8/src/objects.cc +2200 -1177
  418. data/lib/libv8/v8/src/objects.h +912 -283
  419. data/lib/libv8/v8/src/parser.cc +566 -371
  420. data/lib/libv8/v8/src/parser.h +35 -33
  421. data/lib/libv8/v8/src/platform-cygwin.cc +10 -25
  422. data/lib/libv8/v8/src/platform-freebsd.cc +4 -29
  423. data/lib/libv8/v8/src/platform-linux.cc +60 -57
  424. data/lib/libv8/v8/src/platform-macos.cc +4 -27
  425. data/lib/libv8/v8/src/platform-nullos.cc +3 -16
  426. data/lib/libv8/v8/src/platform-openbsd.cc +247 -85
  427. data/lib/libv8/v8/src/platform-posix.cc +43 -1
  428. data/lib/libv8/v8/src/platform-solaris.cc +151 -112
  429. data/lib/libv8/v8/src/platform-tls.h +1 -1
  430. data/lib/libv8/v8/src/platform-win32.cc +65 -39
  431. data/lib/libv8/v8/src/platform.h +17 -14
  432. data/lib/libv8/v8/src/preparse-data-format.h +2 -2
  433. data/lib/libv8/v8/src/preparse-data.h +8 -2
  434. data/lib/libv8/v8/src/preparser-api.cc +2 -18
  435. data/lib/libv8/v8/src/preparser.cc +106 -65
  436. data/lib/libv8/v8/src/preparser.h +26 -5
  437. data/lib/libv8/v8/src/prettyprinter.cc +25 -43
  438. data/lib/libv8/v8/src/profile-generator-inl.h +0 -4
  439. data/lib/libv8/v8/src/profile-generator.cc +213 -34
  440. data/lib/libv8/v8/src/profile-generator.h +9 -9
  441. data/lib/libv8/v8/src/property.h +1 -0
  442. data/lib/libv8/v8/src/proxy.js +74 -4
  443. data/lib/libv8/v8/src/regexp-macro-assembler.cc +10 -6
  444. data/lib/libv8/v8/src/regexp.js +16 -11
  445. data/lib/libv8/v8/src/rewriter.cc +24 -133
  446. data/lib/libv8/v8/src/runtime-profiler.cc +27 -151
  447. data/lib/libv8/v8/src/runtime-profiler.h +5 -31
  448. data/lib/libv8/v8/src/runtime.cc +1450 -681
  449. data/lib/libv8/v8/src/runtime.h +47 -31
  450. data/lib/libv8/v8/src/runtime.js +2 -1
  451. data/lib/libv8/v8/src/scanner-base.cc +358 -220
  452. data/lib/libv8/v8/src/scanner-base.h +30 -138
  453. data/lib/libv8/v8/src/scanner.cc +0 -18
  454. data/lib/libv8/v8/src/scanner.h +0 -15
  455. data/lib/libv8/v8/src/scopeinfo.cc +3 -1
  456. data/lib/libv8/v8/src/scopeinfo.h +1 -6
  457. data/lib/libv8/v8/src/scopes.cc +243 -253
  458. data/lib/libv8/v8/src/scopes.h +58 -109
  459. data/lib/libv8/v8/src/serialize.cc +12 -54
  460. data/lib/libv8/v8/src/serialize.h +47 -0
  461. data/lib/libv8/v8/src/small-pointer-list.h +25 -0
  462. data/lib/libv8/v8/src/spaces-inl.h +4 -50
  463. data/lib/libv8/v8/src/spaces.cc +64 -131
  464. data/lib/libv8/v8/src/spaces.h +19 -70
  465. data/lib/libv8/v8/src/string-stream.cc +3 -1
  466. data/lib/libv8/v8/src/string.js +10 -6
  467. data/lib/libv8/v8/src/strtod.cc +7 -3
  468. data/lib/libv8/v8/src/stub-cache.cc +59 -129
  469. data/lib/libv8/v8/src/stub-cache.h +42 -54
  470. data/lib/libv8/v8/src/third_party/valgrind/valgrind.h +1447 -1339
  471. data/lib/libv8/v8/src/token.cc +4 -4
  472. data/lib/libv8/v8/src/token.h +6 -5
  473. data/lib/libv8/v8/src/type-info.cc +173 -129
  474. data/lib/libv8/v8/src/type-info.h +40 -22
  475. data/lib/libv8/v8/src/utils.cc +25 -304
  476. data/lib/libv8/v8/src/utils.h +118 -3
  477. data/lib/libv8/v8/src/v8-counters.h +3 -6
  478. data/lib/libv8/v8/src/v8.cc +34 -27
  479. data/lib/libv8/v8/src/v8.h +7 -7
  480. data/lib/libv8/v8/src/v8conversions.cc +129 -0
  481. data/lib/libv8/v8/src/v8conversions.h +60 -0
  482. data/lib/libv8/v8/src/v8globals.h +15 -6
  483. data/lib/libv8/v8/src/v8natives.js +300 -78
  484. data/lib/libv8/v8/src/v8threads.cc +14 -6
  485. data/lib/libv8/v8/src/v8threads.h +4 -1
  486. data/lib/libv8/v8/src/v8utils.cc +360 -0
  487. data/lib/libv8/v8/src/v8utils.h +17 -66
  488. data/lib/libv8/v8/src/variables.cc +7 -12
  489. data/lib/libv8/v8/src/variables.h +12 -10
  490. data/lib/libv8/v8/src/version.cc +2 -2
  491. data/lib/libv8/v8/src/vm-state-inl.h +0 -41
  492. data/lib/libv8/v8/src/vm-state.h +0 -11
  493. data/lib/libv8/v8/src/weakmap.js +103 -0
  494. data/lib/libv8/v8/src/x64/assembler-x64.h +6 -3
  495. data/lib/libv8/v8/src/x64/builtins-x64.cc +25 -22
  496. data/lib/libv8/v8/src/x64/code-stubs-x64.cc +523 -250
  497. data/lib/libv8/v8/src/x64/code-stubs-x64.h +8 -71
  498. data/lib/libv8/v8/src/x64/codegen-x64.cc +1 -0
  499. data/lib/libv8/v8/src/x64/codegen-x64.h +0 -2
  500. data/lib/libv8/v8/src/x64/cpu-x64.cc +2 -1
  501. data/lib/libv8/v8/src/x64/deoptimizer-x64.cc +40 -8
  502. data/lib/libv8/v8/src/x64/disasm-x64.cc +12 -10
  503. data/lib/libv8/v8/src/x64/frames-x64.h +7 -6
  504. data/lib/libv8/v8/src/x64/full-codegen-x64.cc +310 -415
  505. data/lib/libv8/v8/src/x64/ic-x64.cc +180 -117
  506. data/lib/libv8/v8/src/x64/lithium-codegen-x64.cc +411 -523
  507. data/lib/libv8/v8/src/x64/lithium-codegen-x64.h +11 -6
  508. data/lib/libv8/v8/src/x64/lithium-x64.cc +191 -216
  509. data/lib/libv8/v8/src/x64/lithium-x64.h +112 -263
  510. data/lib/libv8/v8/src/x64/macro-assembler-x64.cc +177 -61
  511. data/lib/libv8/v8/src/x64/macro-assembler-x64.h +23 -7
  512. data/lib/libv8/v8/src/x64/regexp-macro-assembler-x64.cc +21 -9
  513. data/lib/libv8/v8/src/x64/regexp-macro-assembler-x64.h +6 -0
  514. data/lib/libv8/v8/src/x64/stub-cache-x64.cc +273 -107
  515. data/lib/libv8/v8/src/zone.cc +31 -22
  516. data/lib/libv8/v8/src/zone.h +12 -6
  517. data/lib/libv8/v8/tools/codemap.js +8 -0
  518. data/lib/libv8/v8/tools/gcmole/Makefile +43 -0
  519. data/lib/libv8/v8/tools/gcmole/gcmole.lua +0 -2
  520. data/lib/libv8/v8/tools/gdb-v8-support.py +154 -0
  521. data/lib/libv8/v8/tools/grokdump.py +44 -35
  522. data/lib/libv8/v8/tools/gyp/v8.gyp +94 -248
  523. data/lib/libv8/v8/tools/js2c.py +83 -52
  524. data/lib/libv8/v8/tools/linux-tick-processor +4 -6
  525. data/lib/libv8/v8/tools/ll_prof.py +3 -3
  526. data/lib/libv8/v8/tools/oom_dump/README +3 -1
  527. data/lib/libv8/v8/tools/presubmit.py +11 -4
  528. data/lib/libv8/v8/tools/profile.js +46 -2
  529. data/lib/libv8/v8/tools/splaytree.js +11 -0
  530. data/lib/libv8/v8/tools/stats-viewer.py +15 -11
  531. data/lib/libv8/v8/tools/test-wrapper-gypbuild.py +227 -0
  532. data/lib/libv8/v8/tools/test.py +28 -8
  533. data/lib/libv8/v8/tools/tickprocessor.js +0 -16
  534. data/lib/libv8/version.rb +1 -1
  535. data/libv8.gemspec +2 -2
  536. metadata +31 -19
  537. data/lib/libv8/scons/engine/SCons/Tool/f03.py +0 -63
  538. data/lib/libv8/v8/src/json-parser.cc +0 -504
@@ -43,32 +43,6 @@ namespace v8 {
43
43
  namespace internal {
44
44
 
45
45
 
46
- class PendingListNode : public Malloced {
47
- public:
48
- explicit PendingListNode(JSFunction* function);
49
- ~PendingListNode() { Destroy(); }
50
-
51
- PendingListNode* next() const { return next_; }
52
- void set_next(PendingListNode* node) { next_ = node; }
53
- Handle<JSFunction> function() { return Handle<JSFunction>::cast(function_); }
54
-
55
- // If the function is garbage collected before we've had the chance
56
- // to optimize it the weak handle will be null.
57
- bool IsValid() { return !function_.is_null(); }
58
-
59
- // Returns the number of microseconds this node has been pending.
60
- int Delay() const { return static_cast<int>(OS::Ticks() - start_); }
61
-
62
- private:
63
- void Destroy();
64
- static void WeakCallback(v8::Persistent<v8::Value> object, void* data);
65
-
66
- PendingListNode* next_;
67
- Handle<Object> function_; // Weak handle.
68
- int64_t start_;
69
- };
70
-
71
-
72
46
  // Optimization sampler constants.
73
47
  static const int kSamplerFrameCount = 2;
74
48
  static const int kSamplerFrameWeight[kSamplerFrameCount] = { 2, 1 };
@@ -80,39 +54,14 @@ static const int kSamplerThresholdMin = 1;
80
54
  static const int kSamplerThresholdDelta = 1;
81
55
 
82
56
  static const int kSamplerThresholdSizeFactorInit = 3;
83
- static const int kSamplerThresholdSizeFactorMin = 1;
84
- static const int kSamplerThresholdSizeFactorDelta = 1;
85
57
 
86
58
  static const int kSizeLimit = 1500;
87
59
 
88
60
 
89
- PendingListNode::PendingListNode(JSFunction* function) : next_(NULL) {
90
- GlobalHandles* global_handles = Isolate::Current()->global_handles();
91
- function_ = global_handles->Create(function);
92
- start_ = OS::Ticks();
93
- global_handles->MakeWeak(function_.location(), this, &WeakCallback);
94
- }
95
-
96
-
97
- void PendingListNode::Destroy() {
98
- if (!IsValid()) return;
99
- GlobalHandles* global_handles = Isolate::Current()->global_handles();
100
- global_handles->Destroy(function_.location());
101
- function_= Handle<Object>::null();
102
- }
103
-
104
-
105
- void PendingListNode::WeakCallback(v8::Persistent<v8::Value>, void* data) {
106
- reinterpret_cast<PendingListNode*>(data)->Destroy();
107
- }
108
-
109
-
110
61
  Atomic32 RuntimeProfiler::state_ = 0;
111
62
  // TODO(isolates): Create the semaphore lazily and clean it up when no
112
63
  // longer required.
113
- #ifdef ENABLE_LOGGING_AND_PROFILING
114
64
  Semaphore* RuntimeProfiler::semaphore_ = OS::CreateSemaphore(0);
115
- #endif
116
65
 
117
66
  #ifdef DEBUG
118
67
  bool RuntimeProfiler::has_been_globally_setup_ = false;
@@ -125,16 +74,8 @@ RuntimeProfiler::RuntimeProfiler(Isolate* isolate)
125
74
  sampler_threshold_(kSamplerThresholdInit),
126
75
  sampler_threshold_size_factor_(kSamplerThresholdSizeFactorInit),
127
76
  sampler_ticks_until_threshold_adjustment_(
128
- kSamplerTicksBetweenThresholdAdjustment),
129
- js_ratio_(0),
130
- sampler_window_position_(0),
131
- optimize_soon_list_(NULL),
132
- state_window_position_(0),
133
- state_window_ticks_(0) {
134
- state_counts_[IN_NON_JS_STATE] = kStateWindowSize;
135
- state_counts_[IN_JS_STATE] = 0;
136
- STATIC_ASSERT(IN_NON_JS_STATE == 0);
137
- memset(state_window_, 0, sizeof(state_window_));
77
+ kSamplerTicksBetweenThresholdAdjustment),
78
+ sampler_window_position_(0) {
138
79
  ClearSampleBuffer();
139
80
  }
140
81
 
@@ -148,16 +89,13 @@ void RuntimeProfiler::GlobalSetup() {
148
89
  }
149
90
 
150
91
 
151
- void RuntimeProfiler::Optimize(JSFunction* function, bool eager, int delay) {
92
+ void RuntimeProfiler::Optimize(JSFunction* function) {
152
93
  ASSERT(function->IsOptimizable());
153
94
  if (FLAG_trace_opt) {
154
- PrintF("[marking (%s) ", eager ? "eagerly" : "lazily");
95
+ PrintF("[marking ");
155
96
  function->PrintName();
156
97
  PrintF(" 0x%" V8PRIxPTR, reinterpret_cast<intptr_t>(function->address()));
157
98
  PrintF(" for recompilation");
158
- if (delay > 0) {
159
- PrintF(" (delayed %0.3f ms)", static_cast<double>(delay) / 1000);
160
- }
161
99
  PrintF("]\n");
162
100
  }
163
101
 
@@ -185,7 +123,7 @@ void RuntimeProfiler::AttemptOnStackReplacement(JSFunction* function) {
185
123
  // We are not prepared to do OSR for a function that already has an
186
124
  // allocated arguments object. The optimized code would bypass it for
187
125
  // arguments accesses, which is unsound. Don't try OSR.
188
- if (shared->scope_info()->HasArgumentsShadow()) return;
126
+ if (shared->uses_arguments()) return;
189
127
 
190
128
  // We're using on-stack replacement: patch the unoptimized code so that
191
129
  // any back edge in any unoptimized frame will trigger on-stack
@@ -243,20 +181,6 @@ void RuntimeProfiler::AddSample(JSFunction* function, int weight) {
243
181
 
244
182
  void RuntimeProfiler::OptimizeNow() {
245
183
  HandleScope scope(isolate_);
246
- PendingListNode* current = optimize_soon_list_;
247
- while (current != NULL) {
248
- PendingListNode* next = current->next();
249
- if (current->IsValid()) {
250
- Handle<JSFunction> function = current->function();
251
- int delay = current->Delay();
252
- if (function->IsOptimizable()) {
253
- Optimize(*function, true, delay);
254
- }
255
- }
256
- delete current;
257
- current = next;
258
- }
259
- optimize_soon_list_ = NULL;
260
184
 
261
185
  // Run through the JavaScript frames and collect them. If we already
262
186
  // have a sample of the function, we mark it for optimizations
@@ -303,24 +227,9 @@ void RuntimeProfiler::OptimizeNow() {
303
227
  : 1;
304
228
 
305
229
  int threshold = sampler_threshold_ * threshold_size_factor;
306
- int current_js_ratio = NoBarrier_Load(&js_ratio_);
307
-
308
- // Adjust threshold depending on the ratio of time spent
309
- // in JS code.
310
- if (current_js_ratio < 20) {
311
- // If we spend less than 20% of the time in JS code,
312
- // do not optimize.
313
- continue;
314
- } else if (current_js_ratio < 75) {
315
- // Below 75% of time spent in JS code, only optimize very
316
- // frequently used functions.
317
- threshold *= 3;
318
- }
319
230
 
320
231
  if (LookupSample(function) >= threshold) {
321
- Optimize(function, false, 0);
322
- isolate_->compilation_cache()->MarkForEagerOptimizing(
323
- Handle<JSFunction>(function));
232
+ Optimize(function);
324
233
  }
325
234
  }
326
235
 
@@ -333,42 +242,8 @@ void RuntimeProfiler::OptimizeNow() {
333
242
  }
334
243
 
335
244
 
336
- void RuntimeProfiler::OptimizeSoon(JSFunction* function) {
337
- if (!function->IsOptimizable()) return;
338
- PendingListNode* node = new PendingListNode(function);
339
- node->set_next(optimize_soon_list_);
340
- optimize_soon_list_ = node;
341
- }
342
-
343
-
344
- #ifdef ENABLE_LOGGING_AND_PROFILING
345
- void RuntimeProfiler::UpdateStateRatio(SamplerState current_state) {
346
- SamplerState old_state = state_window_[state_window_position_];
347
- state_counts_[old_state]--;
348
- state_window_[state_window_position_] = current_state;
349
- state_counts_[current_state]++;
350
- ASSERT(IsPowerOf2(kStateWindowSize));
351
- state_window_position_ = (state_window_position_ + 1) &
352
- (kStateWindowSize - 1);
353
- // Note: to calculate correct ratio we have to track how many valid
354
- // ticks are actually in the state window, because on profiler
355
- // startup this number can be less than the window size.
356
- state_window_ticks_ = Min(kStateWindowSize, state_window_ticks_ + 1);
357
- NoBarrier_Store(&js_ratio_, state_counts_[IN_JS_STATE] * 100 /
358
- state_window_ticks_);
359
- }
360
- #endif
361
-
362
-
363
245
  void RuntimeProfiler::NotifyTick() {
364
- #ifdef ENABLE_LOGGING_AND_PROFILING
365
- // Record state sample.
366
- SamplerState state = IsSomeIsolateInJS()
367
- ? IN_JS_STATE
368
- : IN_NON_JS_STATE;
369
- UpdateStateRatio(state);
370
246
  isolate_->stack_guard()->RequestRuntimeProfilerTick();
371
- #endif
372
247
  }
373
248
 
374
249
 
@@ -416,7 +291,6 @@ void RuntimeProfiler::UpdateSamplesAfterScavenge() {
416
291
 
417
292
 
418
293
  void RuntimeProfiler::HandleWakeUp(Isolate* isolate) {
419
- #ifdef ENABLE_LOGGING_AND_PROFILING
420
294
  // The profiler thread must still be waiting.
421
295
  ASSERT(NoBarrier_Load(&state_) >= 0);
422
296
  // In IsolateEnteredJS we have already incremented the counter and
@@ -424,8 +298,6 @@ void RuntimeProfiler::HandleWakeUp(Isolate* isolate) {
424
298
  // to get the right count of active isolates.
425
299
  NoBarrier_AtomicIncrement(&state_, 1);
426
300
  semaphore_->Signal();
427
- isolate->ResetEagerOptimizingData();
428
- #endif
429
301
  }
430
302
 
431
303
 
@@ -435,20 +307,33 @@ bool RuntimeProfiler::IsSomeIsolateInJS() {
435
307
 
436
308
 
437
309
  bool RuntimeProfiler::WaitForSomeIsolateToEnterJS() {
438
- #ifdef ENABLE_LOGGING_AND_PROFILING
439
310
  Atomic32 old_state = NoBarrier_CompareAndSwap(&state_, 0, -1);
440
311
  ASSERT(old_state >= -1);
441
312
  if (old_state != 0) return false;
442
313
  semaphore_->Wait();
443
- #endif
444
314
  return true;
445
315
  }
446
316
 
447
317
 
448
- void RuntimeProfiler::WakeUpRuntimeProfilerThreadBeforeShutdown() {
449
- #ifdef ENABLE_LOGGING_AND_PROFILING
450
- semaphore_->Signal();
451
- #endif
318
+ void RuntimeProfiler::StopRuntimeProfilerThreadBeforeShutdown(Thread* thread) {
319
+ // Do a fake increment. If the profiler is waiting on the semaphore,
320
+ // the returned state is 0, which can be left as an initial state in
321
+ // case profiling is restarted later. If the profiler is not
322
+ // waiting, the increment will prevent it from waiting, but has to
323
+ // be undone after the profiler is stopped.
324
+ Atomic32 new_state = NoBarrier_AtomicIncrement(&state_, 1);
325
+ ASSERT(new_state >= 0);
326
+ if (new_state == 0) {
327
+ // The profiler thread is waiting. Wake it up. It must check for
328
+ // stop conditions before attempting to wait again.
329
+ semaphore_->Signal();
330
+ }
331
+ thread->Join();
332
+ // The profiler thread is now stopped. Undo the increment in case it
333
+ // was not waiting.
334
+ if (new_state != 0) {
335
+ NoBarrier_AtomicIncrement(&state_, -1);
336
+ }
452
337
  }
453
338
 
454
339
 
@@ -470,18 +355,9 @@ void RuntimeProfiler::UpdateSamplesAfterCompact(ObjectVisitor* visitor) {
470
355
 
471
356
 
472
357
  bool RuntimeProfilerRateLimiter::SuspendIfNecessary() {
473
- #ifdef ENABLE_LOGGING_AND_PROFILING
474
- static const int kNonJSTicksThreshold = 100;
475
- if (RuntimeProfiler::IsSomeIsolateInJS()) {
476
- non_js_ticks_ = 0;
477
- } else {
478
- if (non_js_ticks_ < kNonJSTicksThreshold) {
479
- ++non_js_ticks_;
480
- } else {
481
- return RuntimeProfiler::WaitForSomeIsolateToEnterJS();
482
- }
358
+ if (!RuntimeProfiler::IsSomeIsolateInJS()) {
359
+ return RuntimeProfiler::WaitForSomeIsolateToEnterJS();
483
360
  }
484
- #endif
485
361
  return false;
486
362
  }
487
363
 
@@ -37,7 +37,6 @@ namespace internal {
37
37
  class Isolate;
38
38
  class JSFunction;
39
39
  class Object;
40
- class PendingListNode;
41
40
  class Semaphore;
42
41
 
43
42
  class RuntimeProfiler {
@@ -52,7 +51,6 @@ class RuntimeProfiler {
52
51
  }
53
52
 
54
53
  void OptimizeNow();
55
- void OptimizeSoon(JSFunction* function);
56
54
 
57
55
  void NotifyTick();
58
56
 
@@ -86,10 +84,9 @@ class RuntimeProfiler {
86
84
  static bool IsSomeIsolateInJS();
87
85
  static bool WaitForSomeIsolateToEnterJS();
88
86
 
89
- // When shutting down we join the profiler thread. Doing so while
90
- // it's waiting on a semaphore will cause a deadlock, so we have to
91
- // wake it up first.
92
- static void WakeUpRuntimeProfilerThreadBeforeShutdown();
87
+ // Stops the runtime profiler thread when profiling support is being
88
+ // turned off.
89
+ static void StopRuntimeProfilerThreadBeforeShutdown(Thread* thread);
93
90
 
94
91
  void UpdateSamplesAfterScavenge();
95
92
  void RemoveDeadSamples();
@@ -97,16 +94,10 @@ class RuntimeProfiler {
97
94
 
98
95
  private:
99
96
  static const int kSamplerWindowSize = 16;
100
- static const int kStateWindowSize = 128;
101
-
102
- enum SamplerState {
103
- IN_NON_JS_STATE = 0,
104
- IN_JS_STATE = 1
105
- };
106
97
 
107
98
  static void HandleWakeUp(Isolate* isolate);
108
99
 
109
- void Optimize(JSFunction* function, bool eager, int delay);
100
+ void Optimize(JSFunction* function);
110
101
 
111
102
  void AttemptOnStackReplacement(JSFunction* function);
112
103
 
@@ -118,31 +109,16 @@ class RuntimeProfiler {
118
109
 
119
110
  void AddSample(JSFunction* function, int weight);
120
111
 
121
- #ifdef ENABLE_LOGGING_AND_PROFILING
122
- void UpdateStateRatio(SamplerState current_state);
123
- #endif
124
-
125
112
  Isolate* isolate_;
126
113
 
127
114
  int sampler_threshold_;
128
115
  int sampler_threshold_size_factor_;
129
116
  int sampler_ticks_until_threshold_adjustment_;
130
117
 
131
- // The ratio of ticks spent in JS code in percent.
132
- Atomic32 js_ratio_;
133
-
134
118
  Object* sampler_window_[kSamplerWindowSize];
135
119
  int sampler_window_position_;
136
120
  int sampler_window_weight_[kSamplerWindowSize];
137
121
 
138
- // Support for pending 'optimize soon' requests.
139
- PendingListNode* optimize_soon_list_;
140
-
141
- SamplerState state_window_[kStateWindowSize];
142
- int state_window_position_;
143
- int state_window_ticks_;
144
- int state_counts_[2];
145
-
146
122
  // Possible state values:
147
123
  // -1 => the profiler thread is waiting on the semaphore
148
124
  // 0 or positive => the number of isolates running JavaScript code.
@@ -159,7 +135,7 @@ class RuntimeProfiler {
159
135
  // Rate limiter intended to be used in the profiler thread.
160
136
  class RuntimeProfilerRateLimiter BASE_EMBEDDED {
161
137
  public:
162
- RuntimeProfilerRateLimiter() : non_js_ticks_(0) { }
138
+ RuntimeProfilerRateLimiter() {}
163
139
 
164
140
  // Suspends the current thread (which must be the profiler thread)
165
141
  // when not executing JavaScript to minimize CPU usage. Returns
@@ -170,8 +146,6 @@ class RuntimeProfilerRateLimiter BASE_EMBEDDED {
170
146
  bool SuspendIfNecessary();
171
147
 
172
148
  private:
173
- int non_js_ticks_;
174
-
175
149
  DISALLOW_COPY_AND_ASSIGN(RuntimeProfilerRateLimiter);
176
150
  };
177
151
 
@@ -45,6 +45,7 @@
45
45
  #include "json-parser.h"
46
46
  #include "liveedit.h"
47
47
  #include "liveobjectlist-inl.h"
48
+ #include "misc-intrinsics.h"
48
49
  #include "parser.h"
49
50
  #include "platform.h"
50
51
  #include "runtime-profiler.h"
@@ -81,19 +82,19 @@ namespace internal {
81
82
  RUNTIME_ASSERT(obj->IsBoolean()); \
82
83
  bool name = (obj)->IsTrue();
83
84
 
84
- // Cast the given object to a Smi and store its value in an int variable
85
- // with the given name. If the object is not a Smi call IllegalOperation
85
+ // Cast the given argument to a Smi and store its value in an int variable
86
+ // with the given name. If the argument is not a Smi call IllegalOperation
86
87
  // and return.
87
- #define CONVERT_SMI_CHECKED(name, obj) \
88
- RUNTIME_ASSERT(obj->IsSmi()); \
89
- int name = Smi::cast(obj)->value();
88
+ #define CONVERT_SMI_ARG_CHECKED(name, index) \
89
+ RUNTIME_ASSERT(args[index]->IsSmi()); \
90
+ int name = args.smi_at(index);
90
91
 
91
- // Cast the given object to a double and store it in a variable with
92
- // the given name. If the object is not a number (as opposed to
92
+ // Cast the given argument to a double and store it in a variable with
93
+ // the given name. If the argument is not a number (as opposed to
93
94
  // the number not-a-number) call IllegalOperation and return.
94
- #define CONVERT_DOUBLE_CHECKED(name, obj) \
95
- RUNTIME_ASSERT(obj->IsNumber()); \
96
- double name = (obj)->Number();
95
+ #define CONVERT_DOUBLE_ARG_CHECKED(name, index) \
96
+ RUNTIME_ASSERT(args[index]->IsNumber()); \
97
+ double name = args.number_at(index);
97
98
 
98
99
  // Call the specified converter on the object *comand store the result in
99
100
  // a variable of the specified type with the given name. If the
@@ -218,8 +219,20 @@ MUST_USE_RESULT static MaybeObject* DeepCopyBoilerplate(Isolate* isolate,
218
219
  }
219
220
  break;
220
221
  }
221
- default:
222
- UNREACHABLE();
222
+ case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS:
223
+ UNIMPLEMENTED();
224
+ break;
225
+ case JSObject::EXTERNAL_PIXEL_ELEMENTS:
226
+ case JSObject::EXTERNAL_BYTE_ELEMENTS:
227
+ case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
228
+ case JSObject::EXTERNAL_SHORT_ELEMENTS:
229
+ case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
230
+ case JSObject::EXTERNAL_INT_ELEMENTS:
231
+ case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS:
232
+ case JSObject::EXTERNAL_FLOAT_ELEMENTS:
233
+ case JSObject::EXTERNAL_DOUBLE_ELEMENTS:
234
+ case JSObject::FAST_DOUBLE_ELEMENTS:
235
+ // No contained objects, nothing to do.
223
236
  break;
224
237
  }
225
238
  return copy;
@@ -482,7 +495,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateArrayLiteralBoilerplate) {
482
495
  HandleScope scope(isolate);
483
496
  ASSERT(args.length() == 3);
484
497
  CONVERT_ARG_CHECKED(FixedArray, literals, 0);
485
- CONVERT_SMI_CHECKED(literals_index, args[1]);
498
+ CONVERT_SMI_ARG_CHECKED(literals_index, 1);
486
499
  CONVERT_ARG_CHECKED(FixedArray, elements, 2);
487
500
 
488
501
  Handle<Object> object =
@@ -499,9 +512,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateObjectLiteral) {
499
512
  HandleScope scope(isolate);
500
513
  ASSERT(args.length() == 4);
501
514
  CONVERT_ARG_CHECKED(FixedArray, literals, 0);
502
- CONVERT_SMI_CHECKED(literals_index, args[1]);
515
+ CONVERT_SMI_ARG_CHECKED(literals_index, 1);
503
516
  CONVERT_ARG_CHECKED(FixedArray, constant_properties, 2);
504
- CONVERT_SMI_CHECKED(flags, args[3]);
517
+ CONVERT_SMI_ARG_CHECKED(flags, 3);
505
518
  bool should_have_fast_elements = (flags & ObjectLiteral::kFastElements) != 0;
506
519
  bool has_function_literal = (flags & ObjectLiteral::kHasFunction) != 0;
507
520
 
@@ -525,9 +538,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateObjectLiteralShallow) {
525
538
  HandleScope scope(isolate);
526
539
  ASSERT(args.length() == 4);
527
540
  CONVERT_ARG_CHECKED(FixedArray, literals, 0);
528
- CONVERT_SMI_CHECKED(literals_index, args[1]);
541
+ CONVERT_SMI_ARG_CHECKED(literals_index, 1);
529
542
  CONVERT_ARG_CHECKED(FixedArray, constant_properties, 2);
530
- CONVERT_SMI_CHECKED(flags, args[3]);
543
+ CONVERT_SMI_ARG_CHECKED(flags, 3);
531
544
  bool should_have_fast_elements = (flags & ObjectLiteral::kFastElements) != 0;
532
545
  bool has_function_literal = (flags & ObjectLiteral::kHasFunction) != 0;
533
546
 
@@ -551,7 +564,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateArrayLiteral) {
551
564
  HandleScope scope(isolate);
552
565
  ASSERT(args.length() == 3);
553
566
  CONVERT_ARG_CHECKED(FixedArray, literals, 0);
554
- CONVERT_SMI_CHECKED(literals_index, args[1]);
567
+ CONVERT_SMI_ARG_CHECKED(literals_index, 1);
555
568
  CONVERT_ARG_CHECKED(FixedArray, elements, 2);
556
569
 
557
570
  // Check if boilerplate exists. If not, create it first.
@@ -570,7 +583,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateArrayLiteralShallow) {
570
583
  HandleScope scope(isolate);
571
584
  ASSERT(args.length() == 3);
572
585
  CONVERT_ARG_CHECKED(FixedArray, literals, 0);
573
- CONVERT_SMI_CHECKED(literals_index, args[1]);
586
+ CONVERT_SMI_ARG_CHECKED(literals_index, 1);
574
587
  CONVERT_ARG_CHECKED(FixedArray, elements, 2);
575
588
 
576
589
  // Check if boilerplate exists. If not, create it first.
@@ -594,34 +607,67 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateJSProxy) {
594
607
  Object* handler = args[0];
595
608
  Object* prototype = args[1];
596
609
  Object* used_prototype =
597
- (prototype->IsJSObject() || prototype->IsJSProxy()) ? prototype
598
- : isolate->heap()->null_value();
610
+ prototype->IsJSReceiver() ? prototype : isolate->heap()->null_value();
599
611
  return isolate->heap()->AllocateJSProxy(handler, used_prototype);
600
612
  }
601
613
 
602
614
 
603
- RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateCatchExtensionObject) {
615
+ RUNTIME_FUNCTION(MaybeObject*, Runtime_IsJSProxy) {
616
+ ASSERT(args.length() == 1);
617
+ Object* obj = args[0];
618
+ return isolate->heap()->ToBoolean(obj->IsJSProxy());
619
+ }
620
+
621
+
622
+ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetHandler) {
623
+ ASSERT(args.length() == 1);
624
+ CONVERT_CHECKED(JSProxy, proxy, args[0]);
625
+ return proxy->handler();
626
+ }
627
+
628
+
629
+ RUNTIME_FUNCTION(MaybeObject*, Runtime_Fix) {
630
+ ASSERT(args.length() == 1);
631
+ CONVERT_CHECKED(JSProxy, proxy, args[0]);
632
+ proxy->Fix();
633
+ return isolate->heap()->undefined_value();
634
+ }
635
+
636
+
637
+ RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakMapInitialize) {
638
+ HandleScope scope(isolate);
639
+ ASSERT(args.length() == 1);
640
+ CONVERT_ARG_CHECKED(JSWeakMap, weakmap, 0);
641
+ ASSERT(weakmap->map()->inobject_properties() == 0);
642
+ Handle<ObjectHashTable> table = isolate->factory()->NewObjectHashTable(0);
643
+ weakmap->set_table(*table);
644
+ weakmap->set_next(Smi::FromInt(0));
645
+ return *weakmap;
646
+ }
647
+
648
+
649
+ RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakMapGet) {
650
+ NoHandleAllocation ha;
604
651
  ASSERT(args.length() == 2);
605
- CONVERT_CHECKED(String, key, args[0]);
606
- Object* value = args[1];
607
- ASSERT(!value->IsFailure());
608
- // Create a catch context extension object.
609
- JSFunction* constructor =
610
- isolate->context()->global_context()->
611
- context_extension_function();
612
- Object* object;
613
- { MaybeObject* maybe_object = isolate->heap()->AllocateJSObject(constructor);
614
- if (!maybe_object->ToObject(&object)) return maybe_object;
615
- }
616
- // Assign the exception value to the catch variable and make sure
617
- // that the catch variable is DontDelete.
618
- { MaybeObject* maybe_value =
619
- // Passing non-strict per ECMA-262 5th Ed. 12.14. Catch, bullet #4.
620
- JSObject::cast(object)->SetProperty(
621
- key, value, DONT_DELETE, kNonStrictMode);
622
- if (!maybe_value->ToObject(&value)) return maybe_value;
623
- }
624
- return object;
652
+ CONVERT_ARG_CHECKED(JSWeakMap, weakmap, 0);
653
+ // TODO(mstarzinger): Currently we cannot use JSProxy objects as keys
654
+ // because they cannot be cast to JSObject to get an identity hash code.
655
+ CONVERT_ARG_CHECKED(JSObject, key, 1);
656
+ return weakmap->table()->Lookup(*key);
657
+ }
658
+
659
+
660
+ RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakMapSet) {
661
+ HandleScope scope(isolate);
662
+ ASSERT(args.length() == 3);
663
+ CONVERT_ARG_CHECKED(JSWeakMap, weakmap, 0);
664
+ // TODO(mstarzinger): See Runtime_WeakMapGet above.
665
+ CONVERT_ARG_CHECKED(JSObject, key, 1);
666
+ Handle<Object> value(args[2]);
667
+ Handle<ObjectHashTable> table(weakmap->table());
668
+ Handle<ObjectHashTable> new_table = PutIntoObjectHashTable(table, key, value);
669
+ weakmap->set_table(*new_table);
670
+ return *value;
625
671
  }
626
672
 
627
673
 
@@ -634,6 +680,28 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_ClassOf) {
634
680
  }
635
681
 
636
682
 
683
+ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPrototype) {
684
+ NoHandleAllocation ha;
685
+ ASSERT(args.length() == 1);
686
+ CONVERT_CHECKED(JSReceiver, input_obj, args[0]);
687
+ Object* obj = input_obj;
688
+ // We don't expect access checks to be needed on JSProxy objects.
689
+ ASSERT(!obj->IsAccessCheckNeeded() || obj->IsJSObject());
690
+ do {
691
+ if (obj->IsAccessCheckNeeded() &&
692
+ !isolate->MayNamedAccess(JSObject::cast(obj),
693
+ isolate->heap()->Proto_symbol(),
694
+ v8::ACCESS_GET)) {
695
+ isolate->ReportFailedAccessCheck(JSObject::cast(obj), v8::ACCESS_GET);
696
+ return isolate->heap()->undefined_value();
697
+ }
698
+ obj = obj->GetPrototype();
699
+ } while (obj->IsJSObject() &&
700
+ JSObject::cast(obj)->map()->is_hidden_prototype());
701
+ return obj;
702
+ }
703
+
704
+
637
705
  RUNTIME_FUNCTION(MaybeObject*, Runtime_IsInPrototypeChain) {
638
706
  NoHandleAllocation ha;
639
707
  ASSERT(args.length() == 2);
@@ -874,7 +942,13 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOwnProperty) {
874
942
  ASSERT(proto->IsJSGlobalObject());
875
943
  holder = Handle<JSObject>(JSObject::cast(proto));
876
944
  }
877
- NumberDictionary* dictionary = holder->element_dictionary();
945
+ FixedArray* elements = FixedArray::cast(holder->elements());
946
+ NumberDictionary* dictionary = NULL;
947
+ if (elements->map() == heap->non_strict_arguments_elements_map()) {
948
+ dictionary = NumberDictionary::cast(elements->get(1));
949
+ } else {
950
+ dictionary = NumberDictionary::cast(elements);
951
+ }
878
952
  int entry = dictionary->FindEntry(index);
879
953
  ASSERT(entry != NumberDictionary::kNotFound);
880
954
  PropertyDetails details = dictionary->DetailsAt(entry);
@@ -973,8 +1047,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_IsExtensible) {
973
1047
  ASSERT(proto->IsJSGlobalObject());
974
1048
  obj = JSObject::cast(proto);
975
1049
  }
976
- return obj->map()->is_extensible() ? isolate->heap()->true_value()
977
- : isolate->heap()->false_value();
1050
+ return isolate->heap()->ToBoolean(obj->map()->is_extensible());
978
1051
  }
979
1052
 
980
1053
 
@@ -1040,8 +1113,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DisableAccessChecks) {
1040
1113
  Map::cast(new_map)->set_is_access_check_needed(false);
1041
1114
  object->set_map(Map::cast(new_map));
1042
1115
  }
1043
- return needs_access_checks ? isolate->heap()->true_value()
1044
- : isolate->heap()->false_value();
1116
+ return isolate->heap()->ToBoolean(needs_access_checks);
1045
1117
  }
1046
1118
 
1047
1119
 
@@ -1084,9 +1156,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareGlobals) {
1084
1156
 
1085
1157
  Handle<Context> context = args.at<Context>(0);
1086
1158
  CONVERT_ARG_CHECKED(FixedArray, pairs, 1);
1087
- bool is_eval = Smi::cast(args[2])->value() == 1;
1088
- StrictModeFlag strict_mode =
1089
- static_cast<StrictModeFlag>(Smi::cast(args[3])->value());
1159
+ bool is_eval = args.smi_at(2) == 1;
1160
+ StrictModeFlag strict_mode = static_cast<StrictModeFlag>(args.smi_at(3));
1090
1161
  ASSERT(strict_mode == kStrictMode || strict_mode == kNonStrictMode);
1091
1162
 
1092
1163
  // Compute the property attributes. According to ECMA-262, section
@@ -1225,19 +1296,19 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareContextSlot) {
1225
1296
 
1226
1297
  CONVERT_ARG_CHECKED(Context, context, 0);
1227
1298
  Handle<String> name(String::cast(args[1]));
1228
- PropertyAttributes mode =
1229
- static_cast<PropertyAttributes>(Smi::cast(args[2])->value());
1299
+ PropertyAttributes mode = static_cast<PropertyAttributes>(args.smi_at(2));
1230
1300
  RUNTIME_ASSERT(mode == READ_ONLY || mode == NONE);
1231
1301
  Handle<Object> initial_value(args[3], isolate);
1232
1302
 
1233
- // Declarations are always done in the function context.
1234
- context = Handle<Context>(context->fcontext());
1303
+ // Declarations are always done in a function or global context.
1304
+ context = Handle<Context>(context->declaration_context());
1235
1305
 
1236
1306
  int index;
1237
1307
  PropertyAttributes attributes;
1238
1308
  ContextLookupFlags flags = DONT_FOLLOW_CHAINS;
1309
+ BindingFlags binding_flags;
1239
1310
  Handle<Object> holder =
1240
- context->Lookup(name, flags, &index, &attributes);
1311
+ context->Lookup(name, flags, &index, &attributes, &binding_flags);
1241
1312
 
1242
1313
  if (attributes != ABSENT) {
1243
1314
  // The name was declared before; check for conflicting
@@ -1285,7 +1356,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareContextSlot) {
1285
1356
  Handle<JSObject> context_ext;
1286
1357
  if (context->has_extension()) {
1287
1358
  // The function context's extension context exists - use it.
1288
- context_ext = Handle<JSObject>(context->extension());
1359
+ context_ext = Handle<JSObject>(JSObject::cast(context->extension()));
1289
1360
  } else {
1290
1361
  // The function context's extension context does not exists - allocate
1291
1362
  // it.
@@ -1339,8 +1410,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) {
1339
1410
  CONVERT_ARG_CHECKED(String, name, 0);
1340
1411
  GlobalObject* global = isolate->context()->global();
1341
1412
  RUNTIME_ASSERT(args[1]->IsSmi());
1342
- StrictModeFlag strict_mode =
1343
- static_cast<StrictModeFlag>(Smi::cast(args[1])->value());
1413
+ StrictModeFlag strict_mode = static_cast<StrictModeFlag>(args.smi_at(1));
1344
1414
  ASSERT(strict_mode == kStrictMode || strict_mode == kNonStrictMode);
1345
1415
 
1346
1416
  // According to ECMA-262, section 12.2, page 62, the property must
@@ -1519,14 +1589,15 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstContextSlot) {
1519
1589
  CONVERT_ARG_CHECKED(Context, context, 1);
1520
1590
  Handle<String> name(String::cast(args[2]));
1521
1591
 
1522
- // Initializations are always done in the function context.
1523
- context = Handle<Context>(context->fcontext());
1592
+ // Initializations are always done in a function or global context.
1593
+ context = Handle<Context>(context->declaration_context());
1524
1594
 
1525
1595
  int index;
1526
1596
  PropertyAttributes attributes;
1527
1597
  ContextLookupFlags flags = FOLLOW_CHAINS;
1598
+ BindingFlags binding_flags;
1528
1599
  Handle<Object> holder =
1529
- context->Lookup(name, flags, &index, &attributes);
1600
+ context->Lookup(name, flags, &index, &attributes, &binding_flags);
1530
1601
 
1531
1602
  // In most situations, the property introduced by the const
1532
1603
  // declaration should be present in the context extension object.
@@ -1541,14 +1612,12 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstContextSlot) {
1541
1612
  // In that case, the initialization behaves like a normal assignment
1542
1613
  // to property 'x'.
1543
1614
  if (index >= 0) {
1544
- // Property was found in a context.
1545
1615
  if (holder->IsContext()) {
1546
- // The holder cannot be the function context. If it is, there
1547
- // should have been a const redeclaration error when declaring
1548
- // the const property.
1549
- ASSERT(!holder.is_identical_to(context));
1550
- if ((attributes & READ_ONLY) == 0) {
1551
- Handle<Context>::cast(holder)->set(index, *value);
1616
+ // Property was found in a context. Perform the assignment if we
1617
+ // found some non-constant or an uninitialized constant.
1618
+ Handle<Context> context = Handle<Context>::cast(holder);
1619
+ if ((attributes & READ_ONLY) == 0 || context->get(index)->IsTheHole()) {
1620
+ context->set(index, *value);
1552
1621
  }
1553
1622
  } else {
1554
1623
  // The holder is an arguments object.
@@ -1622,7 +1691,7 @@ RUNTIME_FUNCTION(MaybeObject*,
1622
1691
  HandleScope scope(isolate);
1623
1692
  ASSERT(args.length() == 2);
1624
1693
  CONVERT_ARG_CHECKED(JSObject, object, 0);
1625
- CONVERT_SMI_CHECKED(properties, args[1]);
1694
+ CONVERT_SMI_ARG_CHECKED(properties, 1);
1626
1695
  if (object->HasFastProperties()) {
1627
1696
  NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, properties);
1628
1697
  }
@@ -1637,7 +1706,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpExec) {
1637
1706
  CONVERT_ARG_CHECKED(String, subject, 1);
1638
1707
  // Due to the way the JS calls are constructed this must be less than the
1639
1708
  // length of a string, i.e. it is always a Smi. We check anyway for security.
1640
- CONVERT_SMI_CHECKED(index, args[2]);
1709
+ CONVERT_SMI_ARG_CHECKED(index, 2);
1641
1710
  CONVERT_ARG_CHECKED(JSArray, last_match_info, 3);
1642
1711
  RUNTIME_ASSERT(last_match_info->HasFastElements());
1643
1712
  RUNTIME_ASSERT(index >= 0);
@@ -1654,8 +1723,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpExec) {
1654
1723
 
1655
1724
  RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpConstructResult) {
1656
1725
  ASSERT(args.length() == 3);
1657
- CONVERT_SMI_CHECKED(elements_count, args[0]);
1658
- if (elements_count > JSArray::kMaxFastElementsLength) {
1726
+ CONVERT_SMI_ARG_CHECKED(elements_count, 0);
1727
+ if (elements_count < 0 ||
1728
+ elements_count > FixedArray::kMaxLength ||
1729
+ !Smi::IsValid(elements_count)) {
1659
1730
  return isolate->ThrowIllegalOperation();
1660
1731
  }
1661
1732
  Object* new_object;
@@ -1797,10 +1868,19 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SpecialArrayFunctions) {
1797
1868
  }
1798
1869
 
1799
1870
 
1800
- RUNTIME_FUNCTION(MaybeObject*, Runtime_GetGlobalReceiver) {
1801
- // Returns a real global receiver, not one of builtins object.
1871
+ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetDefaultReceiver) {
1872
+ NoHandleAllocation handle_free;
1873
+ ASSERT(args.length() == 1);
1874
+ CONVERT_CHECKED(JSFunction, function, args[0]);
1875
+ SharedFunctionInfo* shared = function->shared();
1876
+ if (shared->native() || shared->strict_mode()) {
1877
+ return isolate->heap()->undefined_value();
1878
+ }
1879
+ // Returns undefined for strict or native functions, or
1880
+ // the associated global receiver for "normal" functions.
1881
+
1802
1882
  Context* global_context =
1803
- isolate->context()->global()->global_context();
1883
+ function->context()->global()->global_context();
1804
1884
  return global_context->global()->global_receiver();
1805
1885
  }
1806
1886
 
@@ -1809,7 +1889,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_MaterializeRegExpLiteral) {
1809
1889
  HandleScope scope(isolate);
1810
1890
  ASSERT(args.length() == 4);
1811
1891
  CONVERT_ARG_CHECKED(FixedArray, literals, 0);
1812
- int index = Smi::cast(args[1])->value();
1892
+ int index = args.smi_at(1);
1813
1893
  Handle<String> pattern = args.at<String>(2);
1814
1894
  Handle<String> flags = args.at<String>(3);
1815
1895
 
@@ -1855,6 +1935,33 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetName) {
1855
1935
  }
1856
1936
 
1857
1937
 
1938
+ RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionNameShouldPrintAsAnonymous) {
1939
+ NoHandleAllocation ha;
1940
+ ASSERT(args.length() == 1);
1941
+ CONVERT_CHECKED(JSFunction, f, args[0]);
1942
+ return isolate->heap()->ToBoolean(
1943
+ f->shared()->name_should_print_as_anonymous());
1944
+ }
1945
+
1946
+
1947
+ RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionMarkNameShouldPrintAsAnonymous) {
1948
+ NoHandleAllocation ha;
1949
+ ASSERT(args.length() == 1);
1950
+ CONVERT_CHECKED(JSFunction, f, args[0]);
1951
+ f->shared()->set_name_should_print_as_anonymous(true);
1952
+ return isolate->heap()->undefined_value();
1953
+ }
1954
+
1955
+
1956
+ RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetBound) {
1957
+ HandleScope scope(isolate);
1958
+ ASSERT(args.length() == 1);
1959
+
1960
+ CONVERT_CHECKED(JSFunction, fun, args[0]);
1961
+ fun->shared()->set_bound(true);
1962
+ return isolate->heap()->undefined_value();
1963
+ }
1964
+
1858
1965
  RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionRemovePrototype) {
1859
1966
  NoHandleAllocation ha;
1860
1967
  ASSERT(args.length() == 1);
@@ -1933,6 +2040,24 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetLength) {
1933
2040
  }
1934
2041
 
1935
2042
 
2043
+ // Creates a local, readonly, property called length with the correct
2044
+ // length (when read by the user). This effectively overwrites the
2045
+ // interceptor used to normally provide the length.
2046
+ RUNTIME_FUNCTION(MaybeObject*, Runtime_BoundFunctionSetLength) {
2047
+ NoHandleAllocation ha;
2048
+ ASSERT(args.length() == 2);
2049
+ CONVERT_CHECKED(JSFunction, fun, args[0]);
2050
+ CONVERT_CHECKED(Smi, length, args[1]);
2051
+ MaybeObject* maybe_name =
2052
+ isolate->heap()->AllocateStringFromAscii(CStrVector("length"));
2053
+ String* name;
2054
+ if (!maybe_name->To(&name)) return maybe_name;
2055
+ PropertyAttributes attr =
2056
+ static_cast<PropertyAttributes>(DONT_DELETE | DONT_ENUM | READ_ONLY);
2057
+ return fun->AddProperty(name, length, attr, kNonStrictMode);
2058
+ }
2059
+
2060
+
1936
2061
  RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetPrototype) {
1937
2062
  NoHandleAllocation ha;
1938
2063
  ASSERT(args.length() == 2);
@@ -1948,13 +2073,67 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetPrototype) {
1948
2073
  }
1949
2074
 
1950
2075
 
2076
+ RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetReadOnlyPrototype) {
2077
+ NoHandleAllocation ha;
2078
+ RUNTIME_ASSERT(args.length() == 1);
2079
+ CONVERT_CHECKED(JSFunction, function, args[0]);
2080
+
2081
+ MaybeObject* maybe_name =
2082
+ isolate->heap()->AllocateStringFromAscii(CStrVector("prototype"));
2083
+ String* name;
2084
+ if (!maybe_name->To(&name)) return maybe_name;
2085
+
2086
+ if (function->HasFastProperties()) {
2087
+ // Construct a new field descriptor with updated attributes.
2088
+ DescriptorArray* instance_desc = function->map()->instance_descriptors();
2089
+ int index = instance_desc->Search(name);
2090
+ ASSERT(index != DescriptorArray::kNotFound);
2091
+ PropertyDetails details(instance_desc->GetDetails(index));
2092
+ CallbacksDescriptor new_desc(name,
2093
+ instance_desc->GetValue(index),
2094
+ static_cast<PropertyAttributes>(details.attributes() | READ_ONLY),
2095
+ details.index());
2096
+ // Construct a new field descriptors array containing the new descriptor.
2097
+ Object* descriptors_unchecked;
2098
+ { MaybeObject* maybe_descriptors_unchecked =
2099
+ instance_desc->CopyInsert(&new_desc, REMOVE_TRANSITIONS);
2100
+ if (!maybe_descriptors_unchecked->ToObject(&descriptors_unchecked)) {
2101
+ return maybe_descriptors_unchecked;
2102
+ }
2103
+ }
2104
+ DescriptorArray* new_descriptors =
2105
+ DescriptorArray::cast(descriptors_unchecked);
2106
+ // Create a new map featuring the new field descriptors array.
2107
+ Object* map_unchecked;
2108
+ { MaybeObject* maybe_map_unchecked = function->map()->CopyDropDescriptors();
2109
+ if (!maybe_map_unchecked->ToObject(&map_unchecked)) {
2110
+ return maybe_map_unchecked;
2111
+ }
2112
+ }
2113
+ Map* new_map = Map::cast(map_unchecked);
2114
+ new_map->set_instance_descriptors(new_descriptors);
2115
+ function->set_map(new_map);
2116
+ } else { // Dictionary properties.
2117
+ // Directly manipulate the property details.
2118
+ int entry = function->property_dictionary()->FindEntry(name);
2119
+ ASSERT(entry != StringDictionary::kNotFound);
2120
+ PropertyDetails details = function->property_dictionary()->DetailsAt(entry);
2121
+ PropertyDetails new_details(
2122
+ static_cast<PropertyAttributes>(details.attributes() | READ_ONLY),
2123
+ details.type(),
2124
+ details.index());
2125
+ function->property_dictionary()->DetailsAtPut(entry, new_details);
2126
+ }
2127
+ return function;
2128
+ }
2129
+
2130
+
1951
2131
  RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionIsAPIFunction) {
1952
2132
  NoHandleAllocation ha;
1953
2133
  ASSERT(args.length() == 1);
1954
2134
 
1955
2135
  CONVERT_CHECKED(JSFunction, f, args[0]);
1956
- return f->shared()->IsApiFunction() ? isolate->heap()->true_value()
1957
- : isolate->heap()->false_value();
2136
+ return isolate->heap()->ToBoolean(f->shared()->IsApiFunction());
1958
2137
  }
1959
2138
 
1960
2139
 
@@ -1963,8 +2142,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionIsBuiltin) {
1963
2142
  ASSERT(args.length() == 1);
1964
2143
 
1965
2144
  CONVERT_CHECKED(JSFunction, f, args[0]);
1966
- return f->IsBuiltin() ? isolate->heap()->true_value() :
1967
- isolate->heap()->false_value();
2145
+ return isolate->heap()->ToBoolean(f->IsBuiltin());
1968
2146
  }
1969
2147
 
1970
2148
 
@@ -2035,7 +2213,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetExpectedNumberOfProperties) {
2035
2213
  HandleScope scope(isolate);
2036
2214
  ASSERT(args.length() == 2);
2037
2215
  CONVERT_ARG_CHECKED(JSFunction, function, 0);
2038
- CONVERT_SMI_CHECKED(num, args[1]);
2216
+ CONVERT_SMI_ARG_CHECKED(num, 1);
2039
2217
  RUNTIME_ASSERT(num >= 0);
2040
2218
  SetExpectedNofProperties(function, num);
2041
2219
  return isolate->heap()->undefined_value();
@@ -2259,24 +2437,24 @@ class ReplacementStringBuilder {
2259
2437
 
2260
2438
  Handle<String> joined_string;
2261
2439
  if (is_ascii_) {
2262
- joined_string = NewRawAsciiString(character_count_);
2440
+ Handle<SeqAsciiString> seq = NewRawAsciiString(character_count_);
2263
2441
  AssertNoAllocation no_alloc;
2264
- SeqAsciiString* seq = SeqAsciiString::cast(*joined_string);
2265
2442
  char* char_buffer = seq->GetChars();
2266
2443
  StringBuilderConcatHelper(*subject_,
2267
2444
  char_buffer,
2268
2445
  *array_builder_.array(),
2269
2446
  array_builder_.length());
2447
+ joined_string = Handle<String>::cast(seq);
2270
2448
  } else {
2271
2449
  // Non-ASCII.
2272
- joined_string = NewRawTwoByteString(character_count_);
2450
+ Handle<SeqTwoByteString> seq = NewRawTwoByteString(character_count_);
2273
2451
  AssertNoAllocation no_alloc;
2274
- SeqTwoByteString* seq = SeqTwoByteString::cast(*joined_string);
2275
2452
  uc16* char_buffer = seq->GetChars();
2276
2453
  StringBuilderConcatHelper(*subject_,
2277
2454
  char_buffer,
2278
2455
  *array_builder_.array(),
2279
2456
  array_builder_.length());
2457
+ joined_string = Handle<String>::cast(seq);
2280
2458
  }
2281
2459
  return joined_string;
2282
2460
  }
@@ -2294,15 +2472,13 @@ class ReplacementStringBuilder {
2294
2472
  }
2295
2473
 
2296
2474
  private:
2297
- Handle<String> NewRawAsciiString(int size) {
2298
- CALL_HEAP_FUNCTION(heap_->isolate(),
2299
- heap_->AllocateRawAsciiString(size), String);
2475
+ Handle<SeqAsciiString> NewRawAsciiString(int length) {
2476
+ return heap_->isolate()->factory()->NewRawAsciiString(length);
2300
2477
  }
2301
2478
 
2302
2479
 
2303
- Handle<String> NewRawTwoByteString(int size) {
2304
- CALL_HEAP_FUNCTION(heap_->isolate(),
2305
- heap_->AllocateRawTwoByteString(size), String);
2480
+ Handle<SeqTwoByteString> NewRawTwoByteString(int length) {
2481
+ return heap_->isolate()->factory()->NewRawTwoByteString(length);
2306
2482
  }
2307
2483
 
2308
2484
 
@@ -2338,6 +2514,7 @@ class CompiledReplacement {
2338
2514
  int parts() {
2339
2515
  return parts_.length();
2340
2516
  }
2517
+
2341
2518
  private:
2342
2519
  enum PartType {
2343
2520
  SUBJECT_PREFIX = 1,
@@ -2507,21 +2684,22 @@ class CompiledReplacement {
2507
2684
  void CompiledReplacement::Compile(Handle<String> replacement,
2508
2685
  int capture_count,
2509
2686
  int subject_length) {
2510
- ASSERT(replacement->IsFlat());
2511
- if (replacement->IsAsciiRepresentation()) {
2512
- AssertNoAllocation no_alloc;
2513
- ParseReplacementPattern(&parts_,
2514
- replacement->ToAsciiVector(),
2515
- capture_count,
2516
- subject_length);
2517
- } else {
2518
- ASSERT(replacement->IsTwoByteRepresentation());
2687
+ {
2519
2688
  AssertNoAllocation no_alloc;
2520
-
2521
- ParseReplacementPattern(&parts_,
2522
- replacement->ToUC16Vector(),
2523
- capture_count,
2524
- subject_length);
2689
+ String::FlatContent content = replacement->GetFlatContent();
2690
+ ASSERT(content.IsFlat());
2691
+ if (content.IsAscii()) {
2692
+ ParseReplacementPattern(&parts_,
2693
+ content.ToAsciiVector(),
2694
+ capture_count,
2695
+ subject_length);
2696
+ } else {
2697
+ ASSERT(content.IsTwoByte());
2698
+ ParseReplacementPattern(&parts_,
2699
+ content.ToUC16Vector(),
2700
+ capture_count,
2701
+ subject_length);
2702
+ }
2525
2703
  }
2526
2704
  Isolate* isolate = replacement->GetIsolate();
2527
2705
  // Find substrings of replacement string and create them as String objects.
@@ -2614,7 +2792,7 @@ MUST_USE_RESULT static MaybeObject* StringReplaceRegExpWithString(
2614
2792
  int capture_count = regexp_handle->CaptureCount();
2615
2793
 
2616
2794
  // CompiledReplacement uses zone allocation.
2617
- CompilationZoneScope zone(isolate, DELETE_ON_EXIT);
2795
+ ZoneScope zone(isolate, DELETE_ON_EXIT);
2618
2796
  CompiledReplacement compiled_replacement;
2619
2797
  compiled_replacement.Compile(replacement_handle,
2620
2798
  capture_count,
@@ -2893,34 +3071,32 @@ int Runtime::StringMatch(Isolate* isolate,
2893
3071
 
2894
3072
  AssertNoAllocation no_heap_allocation; // ensure vectors stay valid
2895
3073
  // Extract flattened substrings of cons strings before determining asciiness.
2896
- String* seq_sub = *sub;
2897
- if (seq_sub->IsConsString()) seq_sub = ConsString::cast(seq_sub)->first();
2898
- String* seq_pat = *pat;
2899
- if (seq_pat->IsConsString()) seq_pat = ConsString::cast(seq_pat)->first();
3074
+ String::FlatContent seq_sub = sub->GetFlatContent();
3075
+ String::FlatContent seq_pat = pat->GetFlatContent();
2900
3076
 
2901
3077
  // dispatch on type of strings
2902
- if (seq_pat->IsAsciiRepresentation()) {
2903
- Vector<const char> pat_vector = seq_pat->ToAsciiVector();
2904
- if (seq_sub->IsAsciiRepresentation()) {
3078
+ if (seq_pat.IsAscii()) {
3079
+ Vector<const char> pat_vector = seq_pat.ToAsciiVector();
3080
+ if (seq_sub.IsAscii()) {
2905
3081
  return SearchString(isolate,
2906
- seq_sub->ToAsciiVector(),
3082
+ seq_sub.ToAsciiVector(),
2907
3083
  pat_vector,
2908
3084
  start_index);
2909
3085
  }
2910
3086
  return SearchString(isolate,
2911
- seq_sub->ToUC16Vector(),
3087
+ seq_sub.ToUC16Vector(),
2912
3088
  pat_vector,
2913
3089
  start_index);
2914
3090
  }
2915
- Vector<const uc16> pat_vector = seq_pat->ToUC16Vector();
2916
- if (seq_sub->IsAsciiRepresentation()) {
3091
+ Vector<const uc16> pat_vector = seq_pat.ToUC16Vector();
3092
+ if (seq_sub.IsAscii()) {
2917
3093
  return SearchString(isolate,
2918
- seq_sub->ToAsciiVector(),
3094
+ seq_sub.ToAsciiVector(),
2919
3095
  pat_vector,
2920
3096
  start_index);
2921
3097
  }
2922
3098
  return SearchString(isolate,
2923
- seq_sub->ToUC16Vector(),
3099
+ seq_sub.ToUC16Vector(),
2924
3100
  pat_vector,
2925
3101
  start_index);
2926
3102
  }
@@ -3003,29 +3179,31 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringLastIndexOf) {
3003
3179
  if (!sub->IsFlat()) FlattenString(sub);
3004
3180
  if (!pat->IsFlat()) FlattenString(pat);
3005
3181
 
3182
+ int position = -1;
3006
3183
  AssertNoAllocation no_heap_allocation; // ensure vectors stay valid
3007
3184
 
3008
- int position = -1;
3185
+ String::FlatContent sub_content = sub->GetFlatContent();
3186
+ String::FlatContent pat_content = pat->GetFlatContent();
3009
3187
 
3010
- if (pat->IsAsciiRepresentation()) {
3011
- Vector<const char> pat_vector = pat->ToAsciiVector();
3012
- if (sub->IsAsciiRepresentation()) {
3013
- position = StringMatchBackwards(sub->ToAsciiVector(),
3188
+ if (pat_content.IsAscii()) {
3189
+ Vector<const char> pat_vector = pat_content.ToAsciiVector();
3190
+ if (sub_content.IsAscii()) {
3191
+ position = StringMatchBackwards(sub_content.ToAsciiVector(),
3014
3192
  pat_vector,
3015
3193
  start_index);
3016
3194
  } else {
3017
- position = StringMatchBackwards(sub->ToUC16Vector(),
3195
+ position = StringMatchBackwards(sub_content.ToUC16Vector(),
3018
3196
  pat_vector,
3019
3197
  start_index);
3020
3198
  }
3021
3199
  } else {
3022
- Vector<const uc16> pat_vector = pat->ToUC16Vector();
3023
- if (sub->IsAsciiRepresentation()) {
3024
- position = StringMatchBackwards(sub->ToAsciiVector(),
3200
+ Vector<const uc16> pat_vector = pat_content.ToUC16Vector();
3201
+ if (sub_content.IsAscii()) {
3202
+ position = StringMatchBackwards(sub_content.ToAsciiVector(),
3025
3203
  pat_vector,
3026
3204
  start_index);
3027
3205
  } else {
3028
- position = StringMatchBackwards(sub->ToUC16Vector(),
3206
+ position = StringMatchBackwards(sub_content.ToUC16Vector(),
3029
3207
  pat_vector,
3030
3208
  start_index);
3031
3209
  }
@@ -3088,17 +3266,17 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SubString) {
3088
3266
  ASSERT(args.length() == 3);
3089
3267
 
3090
3268
  CONVERT_CHECKED(String, value, args[0]);
3091
- Object* from = args[1];
3092
- Object* to = args[2];
3093
3269
  int start, end;
3094
3270
  // We have a fast integer-only case here to avoid a conversion to double in
3095
3271
  // the common case where from and to are Smis.
3096
- if (from->IsSmi() && to->IsSmi()) {
3097
- start = Smi::cast(from)->value();
3098
- end = Smi::cast(to)->value();
3272
+ if (args[1]->IsSmi() && args[2]->IsSmi()) {
3273
+ CONVERT_SMI_ARG_CHECKED(from_number, 1);
3274
+ CONVERT_SMI_ARG_CHECKED(to_number, 2);
3275
+ start = from_number;
3276
+ end = to_number;
3099
3277
  } else {
3100
- CONVERT_DOUBLE_CHECKED(from_number, from);
3101
- CONVERT_DOUBLE_CHECKED(to_number, to);
3278
+ CONVERT_DOUBLE_ARG_CHECKED(from_number, 1);
3279
+ CONVERT_DOUBLE_ARG_CHECKED(to_number, 2);
3102
3280
  start = FastD2I(from_number);
3103
3281
  end = FastD2I(to_number);
3104
3282
  }
@@ -3128,11 +3306,11 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringMatch) {
3128
3306
  }
3129
3307
  int length = subject->length();
3130
3308
 
3131
- CompilationZoneScope zone_space(isolate, DELETE_ON_EXIT);
3309
+ ZoneScope zone_space(isolate, DELETE_ON_EXIT);
3132
3310
  ZoneList<int> offsets(8);
3311
+ int start;
3312
+ int end;
3133
3313
  do {
3134
- int start;
3135
- int end;
3136
3314
  {
3137
3315
  AssertNoAllocation no_alloc;
3138
3316
  FixedArray* elements = FixedArray::cast(regexp_info->elements());
@@ -3141,20 +3319,23 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringMatch) {
3141
3319
  }
3142
3320
  offsets.Add(start);
3143
3321
  offsets.Add(end);
3144
- int index = start < end ? end : end + 1;
3145
- if (index > length) break;
3146
- match = RegExpImpl::Exec(regexp, subject, index, regexp_info);
3322
+ if (start == end) if (++end > length) break;
3323
+ match = RegExpImpl::Exec(regexp, subject, end, regexp_info);
3147
3324
  if (match.is_null()) {
3148
3325
  return Failure::Exception();
3149
3326
  }
3150
3327
  } while (!match->IsNull());
3151
3328
  int matches = offsets.length() / 2;
3152
3329
  Handle<FixedArray> elements = isolate->factory()->NewFixedArray(matches);
3153
- for (int i = 0; i < matches ; i++) {
3330
+ Handle<String> substring = isolate->factory()->
3331
+ NewSubString(subject, offsets.at(0), offsets.at(1));
3332
+ elements->set(0, *substring);
3333
+ for (int i = 1; i < matches ; i++) {
3154
3334
  int from = offsets.at(i * 2);
3155
3335
  int to = offsets.at(i * 2 + 1);
3156
- Handle<String> match = isolate->factory()->NewSubString(subject, from, to);
3157
- elements->set(i, *match);
3336
+ Handle<String> substring = isolate->factory()->
3337
+ NewProperSubString(subject, from, to);
3338
+ elements->set(i, *substring);
3158
3339
  }
3159
3340
  Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(elements);
3160
3341
  result->set_length(Smi::FromInt(matches));
@@ -3240,36 +3421,38 @@ static bool SearchStringMultiple(Isolate* isolate,
3240
3421
  for (;;) { // Break when search complete.
3241
3422
  builder->EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch);
3242
3423
  AssertNoAllocation no_gc;
3243
- if (subject->IsAsciiRepresentation()) {
3244
- Vector<const char> subject_vector = subject->ToAsciiVector();
3245
- if (pattern->IsAsciiRepresentation()) {
3424
+ String::FlatContent subject_content = subject->GetFlatContent();
3425
+ String::FlatContent pattern_content = pattern->GetFlatContent();
3426
+ if (subject_content.IsAscii()) {
3427
+ Vector<const char> subject_vector = subject_content.ToAsciiVector();
3428
+ if (pattern_content.IsAscii()) {
3246
3429
  if (SearchStringMultiple(isolate,
3247
3430
  subject_vector,
3248
- pattern->ToAsciiVector(),
3431
+ pattern_content.ToAsciiVector(),
3249
3432
  *pattern,
3250
3433
  builder,
3251
3434
  &match_pos)) break;
3252
3435
  } else {
3253
3436
  if (SearchStringMultiple(isolate,
3254
3437
  subject_vector,
3255
- pattern->ToUC16Vector(),
3438
+ pattern_content.ToUC16Vector(),
3256
3439
  *pattern,
3257
3440
  builder,
3258
3441
  &match_pos)) break;
3259
3442
  }
3260
3443
  } else {
3261
- Vector<const uc16> subject_vector = subject->ToUC16Vector();
3262
- if (pattern->IsAsciiRepresentation()) {
3444
+ Vector<const uc16> subject_vector = subject_content.ToUC16Vector();
3445
+ if (pattern_content.IsAscii()) {
3263
3446
  if (SearchStringMultiple(isolate,
3264
3447
  subject_vector,
3265
- pattern->ToAsciiVector(),
3448
+ pattern_content.ToAsciiVector(),
3266
3449
  *pattern,
3267
3450
  builder,
3268
3451
  &match_pos)) break;
3269
3452
  } else {
3270
3453
  if (SearchStringMultiple(isolate,
3271
3454
  subject_vector,
3272
- pattern->ToUC16Vector(),
3455
+ pattern_content.ToUC16Vector(),
3273
3456
  *pattern,
3274
3457
  builder,
3275
3458
  &match_pos)) break;
@@ -3304,6 +3487,7 @@ static RegExpImpl::IrregexpResult SearchRegExpNoCaptureMultiple(
3304
3487
  OffsetsVector registers(required_registers);
3305
3488
  Vector<int32_t> register_vector(registers.vector(), registers.length());
3306
3489
  int subject_length = subject->length();
3490
+ bool first = true;
3307
3491
 
3308
3492
  for (;;) { // Break on failure, return on exception.
3309
3493
  RegExpImpl::IrregexpResult result =
@@ -3321,9 +3505,15 @@ static RegExpImpl::IrregexpResult SearchRegExpNoCaptureMultiple(
3321
3505
  }
3322
3506
  match_end = register_vector[1];
3323
3507
  HandleScope loop_scope(isolate);
3324
- builder->Add(*isolate->factory()->NewSubString(subject,
3325
- match_start,
3326
- match_end));
3508
+ if (!first) {
3509
+ builder->Add(*isolate->factory()->NewProperSubString(subject,
3510
+ match_start,
3511
+ match_end));
3512
+ } else {
3513
+ builder->Add(*isolate->factory()->NewSubString(subject,
3514
+ match_start,
3515
+ match_end));
3516
+ }
3327
3517
  if (match_start != match_end) {
3328
3518
  pos = match_end;
3329
3519
  } else {
@@ -3336,6 +3526,7 @@ static RegExpImpl::IrregexpResult SearchRegExpNoCaptureMultiple(
3336
3526
  ASSERT_EQ(result, RegExpImpl::RE_EXCEPTION);
3337
3527
  return result;
3338
3528
  }
3529
+ first = false;
3339
3530
  }
3340
3531
 
3341
3532
  if (match_start >= 0) {
@@ -3387,7 +3578,7 @@ static RegExpImpl::IrregexpResult SearchRegExpMultiple(
3387
3578
  // at the end, so we have two vectors that we swap between.
3388
3579
  OffsetsVector registers2(required_registers);
3389
3580
  Vector<int> prev_register_vector(registers2.vector(), registers2.length());
3390
-
3581
+ bool first = true;
3391
3582
  do {
3392
3583
  int match_start = register_vector[0];
3393
3584
  builder->EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch);
@@ -3405,18 +3596,30 @@ static RegExpImpl::IrregexpResult SearchRegExpMultiple(
3405
3596
  // subject, i.e., 3 + capture count in total.
3406
3597
  Handle<FixedArray> elements =
3407
3598
  isolate->factory()->NewFixedArray(3 + capture_count);
3408
- Handle<String> match = isolate->factory()->NewSubString(subject,
3409
- match_start,
3410
- match_end);
3599
+ Handle<String> match;
3600
+ if (!first) {
3601
+ match = isolate->factory()->NewProperSubString(subject,
3602
+ match_start,
3603
+ match_end);
3604
+ } else {
3605
+ match = isolate->factory()->NewSubString(subject,
3606
+ match_start,
3607
+ match_end);
3608
+ }
3411
3609
  elements->set(0, *match);
3412
3610
  for (int i = 1; i <= capture_count; i++) {
3413
3611
  int start = register_vector[i * 2];
3414
3612
  if (start >= 0) {
3415
3613
  int end = register_vector[i * 2 + 1];
3416
3614
  ASSERT(start <= end);
3417
- Handle<String> substring = isolate->factory()->NewSubString(subject,
3418
- start,
3419
- end);
3615
+ Handle<String> substring;
3616
+ if (!first) {
3617
+ substring = isolate->factory()->NewProperSubString(subject,
3618
+ start,
3619
+ end);
3620
+ } else {
3621
+ substring = isolate->factory()->NewSubString(subject, start, end);
3622
+ }
3420
3623
  elements->set(i, *substring);
3421
3624
  } else {
3422
3625
  ASSERT(register_vector[i * 2 + 1] < 0);
@@ -3446,6 +3649,7 @@ static RegExpImpl::IrregexpResult SearchRegExpMultiple(
3446
3649
  subject,
3447
3650
  pos,
3448
3651
  register_vector);
3652
+ first = false;
3449
3653
  } while (result == RegExpImpl::RE_SUCCESS);
3450
3654
 
3451
3655
  if (result != RegExpImpl::RE_EXCEPTION) {
@@ -3481,7 +3685,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpExecMultiple) {
3481
3685
  HandleScope handles(isolate);
3482
3686
 
3483
3687
  CONVERT_ARG_CHECKED(String, subject, 1);
3484
- if (!subject->IsFlat()) { FlattenString(subject); }
3688
+ if (!subject->IsFlat()) FlattenString(subject);
3485
3689
  CONVERT_ARG_CHECKED(JSRegExp, regexp, 0);
3486
3690
  CONVERT_ARG_CHECKED(JSArray, last_match_info, 2);
3487
3691
  CONVERT_ARG_CHECKED(JSArray, result_array, 3);
@@ -3492,7 +3696,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpExecMultiple) {
3492
3696
  if (result_array->HasFastElements()) {
3493
3697
  result_elements =
3494
3698
  Handle<FixedArray>(FixedArray::cast(result_array->elements()));
3495
- } else {
3699
+ }
3700
+ if (result_elements.is_null() || result_elements->length() < 16) {
3496
3701
  result_elements = isolate->factory()->NewFixedArrayWithHoles(16);
3497
3702
  }
3498
3703
  FixedArrayBuilder builder(result_elements);
@@ -3534,13 +3739,13 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpExecMultiple) {
3534
3739
  RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToRadixString) {
3535
3740
  NoHandleAllocation ha;
3536
3741
  ASSERT(args.length() == 2);
3742
+ CONVERT_SMI_ARG_CHECKED(radix, 1);
3743
+ RUNTIME_ASSERT(2 <= radix && radix <= 36);
3537
3744
 
3538
3745
  // Fast case where the result is a one character string.
3539
- if (args[0]->IsSmi() && args[1]->IsSmi()) {
3540
- int value = Smi::cast(args[0])->value();
3541
- int radix = Smi::cast(args[1])->value();
3746
+ if (args[0]->IsSmi()) {
3747
+ int value = args.smi_at(0);
3542
3748
  if (value >= 0 && value < radix) {
3543
- RUNTIME_ASSERT(radix <= 36);
3544
3749
  // Character array used for conversion.
3545
3750
  static const char kCharTable[] = "0123456789abcdefghijklmnopqrstuvwxyz";
3546
3751
  return isolate->heap()->
@@ -3549,7 +3754,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToRadixString) {
3549
3754
  }
3550
3755
 
3551
3756
  // Slow case.
3552
- CONVERT_DOUBLE_CHECKED(value, args[0]);
3757
+ CONVERT_DOUBLE_ARG_CHECKED(value, 0);
3553
3758
  if (isnan(value)) {
3554
3759
  return isolate->heap()->AllocateStringFromAscii(CStrVector("NaN"));
3555
3760
  }
@@ -3559,9 +3764,6 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToRadixString) {
3559
3764
  }
3560
3765
  return isolate->heap()->AllocateStringFromAscii(CStrVector("Infinity"));
3561
3766
  }
3562
- CONVERT_DOUBLE_CHECKED(radix_number, args[1]);
3563
- int radix = FastD2I(radix_number);
3564
- RUNTIME_ASSERT(2 <= radix && radix <= 36);
3565
3767
  char* str = DoubleToRadixCString(value, radix);
3566
3768
  MaybeObject* result =
3567
3769
  isolate->heap()->AllocateStringFromAscii(CStrVector(str));
@@ -3574,7 +3776,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToFixed) {
3574
3776
  NoHandleAllocation ha;
3575
3777
  ASSERT(args.length() == 2);
3576
3778
 
3577
- CONVERT_DOUBLE_CHECKED(value, args[0]);
3779
+ CONVERT_DOUBLE_ARG_CHECKED(value, 0);
3578
3780
  if (isnan(value)) {
3579
3781
  return isolate->heap()->AllocateStringFromAscii(CStrVector("NaN"));
3580
3782
  }
@@ -3584,7 +3786,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToFixed) {
3584
3786
  }
3585
3787
  return isolate->heap()->AllocateStringFromAscii(CStrVector("Infinity"));
3586
3788
  }
3587
- CONVERT_DOUBLE_CHECKED(f_number, args[1]);
3789
+ CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
3588
3790
  int f = FastD2I(f_number);
3589
3791
  RUNTIME_ASSERT(f >= 0);
3590
3792
  char* str = DoubleToFixedCString(value, f);
@@ -3599,7 +3801,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToExponential) {
3599
3801
  NoHandleAllocation ha;
3600
3802
  ASSERT(args.length() == 2);
3601
3803
 
3602
- CONVERT_DOUBLE_CHECKED(value, args[0]);
3804
+ CONVERT_DOUBLE_ARG_CHECKED(value, 0);
3603
3805
  if (isnan(value)) {
3604
3806
  return isolate->heap()->AllocateStringFromAscii(CStrVector("NaN"));
3605
3807
  }
@@ -3609,7 +3811,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToExponential) {
3609
3811
  }
3610
3812
  return isolate->heap()->AllocateStringFromAscii(CStrVector("Infinity"));
3611
3813
  }
3612
- CONVERT_DOUBLE_CHECKED(f_number, args[1]);
3814
+ CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
3613
3815
  int f = FastD2I(f_number);
3614
3816
  RUNTIME_ASSERT(f >= -1 && f <= 20);
3615
3817
  char* str = DoubleToExponentialCString(value, f);
@@ -3624,7 +3826,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToPrecision) {
3624
3826
  NoHandleAllocation ha;
3625
3827
  ASSERT(args.length() == 2);
3626
3828
 
3627
- CONVERT_DOUBLE_CHECKED(value, args[0]);
3829
+ CONVERT_DOUBLE_ARG_CHECKED(value, 0);
3628
3830
  if (isnan(value)) {
3629
3831
  return isolate->heap()->AllocateStringFromAscii(CStrVector("NaN"));
3630
3832
  }
@@ -3634,7 +3836,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToPrecision) {
3634
3836
  }
3635
3837
  return isolate->heap()->AllocateStringFromAscii(CStrVector("Infinity"));
3636
3838
  }
3637
- CONVERT_DOUBLE_CHECKED(f_number, args[1]);
3839
+ CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
3638
3840
  int f = FastD2I(f_number);
3639
3841
  RUNTIME_ASSERT(f >= 1 && f <= 21);
3640
3842
  char* str = DoubleToPrecisionCString(value, f);
@@ -3724,8 +3926,7 @@ MaybeObject* Runtime::GetObjectProperty(Isolate* isolate,
3724
3926
  if (name->AsArrayIndex(&index)) {
3725
3927
  return GetElementOrCharAt(isolate, object, index);
3726
3928
  } else {
3727
- PropertyAttributes attr;
3728
- return object->GetProperty(*name, &attr);
3929
+ return object->GetProperty(*name);
3729
3930
  }
3730
3931
  }
3731
3932
 
@@ -3797,7 +3998,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_KeyedGetProperty) {
3797
3998
  // Fast case for string indexing using [] with a smi index.
3798
3999
  HandleScope scope(isolate);
3799
4000
  Handle<String> str = args.at<String>(0);
3800
- int index = Smi::cast(args[1])->value();
4001
+ int index = args.smi_at(1);
3801
4002
  if (index >= 0 && index < str->length()) {
3802
4003
  Handle<Object> result = GetCharAt(str, index);
3803
4004
  return *result;
@@ -3840,7 +4041,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineAccessorProperty) {
3840
4041
  || result.type() == CONSTANT_FUNCTION)) {
3841
4042
  Object* ok;
3842
4043
  { MaybeObject* maybe_ok =
3843
- obj->DeleteProperty(name, JSObject::NORMAL_DELETION);
4044
+ obj->DeleteProperty(name, JSReceiver::NORMAL_DELETION);
3844
4045
  if (!maybe_ok->ToObject(&ok)) return maybe_ok;
3845
4046
  }
3846
4047
  }
@@ -3885,17 +4086,25 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineDataProperty) {
3885
4086
  if (proto->IsNull()) return *obj_value;
3886
4087
  js_object = Handle<JSObject>::cast(proto);
3887
4088
  }
3888
- NormalizeElements(js_object);
3889
- Handle<NumberDictionary> dictionary(js_object->element_dictionary());
4089
+ Handle<NumberDictionary> dictionary = NormalizeElements(js_object);
3890
4090
  // Make sure that we never go back to fast case.
3891
4091
  dictionary->set_requires_slow_elements();
3892
4092
  PropertyDetails details = PropertyDetails(attr, NORMAL);
3893
- NumberDictionarySet(dictionary, index, obj_value, details);
4093
+ Handle<NumberDictionary> extended_dictionary =
4094
+ NumberDictionarySet(dictionary, index, obj_value, details);
4095
+ if (*extended_dictionary != *dictionary) {
4096
+ if (js_object->GetElementsKind() ==
4097
+ JSObject::NON_STRICT_ARGUMENTS_ELEMENTS) {
4098
+ FixedArray::cast(js_object->elements())->set(1, *extended_dictionary);
4099
+ } else {
4100
+ js_object->set_elements(*extended_dictionary);
4101
+ }
4102
+ }
3894
4103
  return *obj_value;
3895
4104
  }
3896
4105
 
3897
4106
  LookupResult result;
3898
- js_object->LookupRealNamedProperty(*name, &result);
4107
+ js_object->LocalLookupRealNamedProperty(*name, &result);
3899
4108
 
3900
4109
  // To be compatible with safari we do not change the value on API objects
3901
4110
  // in defineProperty. Firefox disagrees here, and actually changes the value.
@@ -3935,6 +4144,28 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineDataProperty) {
3935
4144
  }
3936
4145
 
3937
4146
 
4147
+ // Special case for elements if any of the flags are true.
4148
+ // If elements are in fast case we always implicitly assume that:
4149
+ // DONT_DELETE: false, DONT_ENUM: false, READ_ONLY: false.
4150
+ static MaybeObject* NormalizeObjectSetElement(Isolate* isolate,
4151
+ Handle<JSObject> js_object,
4152
+ uint32_t index,
4153
+ Handle<Object> value,
4154
+ PropertyAttributes attr) {
4155
+ // Normalize the elements to enable attributes on the property.
4156
+ Handle<NumberDictionary> dictionary = NormalizeElements(js_object);
4157
+ // Make sure that we never go back to fast case.
4158
+ dictionary->set_requires_slow_elements();
4159
+ PropertyDetails details = PropertyDetails(attr, NORMAL);
4160
+ Handle<NumberDictionary> extended_dictionary =
4161
+ NumberDictionarySet(dictionary, index, value, details);
4162
+ if (*extended_dictionary != *dictionary) {
4163
+ js_object->set_elements(*extended_dictionary);
4164
+ }
4165
+ return *value;
4166
+ }
4167
+
4168
+
3938
4169
  MaybeObject* Runtime::SetObjectProperty(Isolate* isolate,
3939
4170
  Handle<Object> object,
3940
4171
  Handle<Object> key,
@@ -3970,6 +4201,10 @@ MaybeObject* Runtime::SetObjectProperty(Isolate* isolate,
3970
4201
  return *value;
3971
4202
  }
3972
4203
 
4204
+ if (((attr & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0)) {
4205
+ return NormalizeObjectSetElement(isolate, js_object, index, value, attr);
4206
+ }
4207
+
3973
4208
  Handle<Object> result = SetElement(js_object, index, value, strict_mode);
3974
4209
  if (result.is_null()) return Failure::Exception();
3975
4210
  return *value;
@@ -3978,6 +4213,13 @@ MaybeObject* Runtime::SetObjectProperty(Isolate* isolate,
3978
4213
  if (key->IsString()) {
3979
4214
  Handle<Object> result;
3980
4215
  if (Handle<String>::cast(key)->AsArrayIndex(&index)) {
4216
+ if (((attr & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0)) {
4217
+ return NormalizeObjectSetElement(isolate,
4218
+ js_object,
4219
+ index,
4220
+ value,
4221
+ attr);
4222
+ }
3981
4223
  result = SetElement(js_object, index, value, strict_mode);
3982
4224
  } else {
3983
4225
  Handle<String> key_string = Handle<String>::cast(key);
@@ -3995,7 +4237,7 @@ MaybeObject* Runtime::SetObjectProperty(Isolate* isolate,
3995
4237
  Handle<String> name = Handle<String>::cast(converted);
3996
4238
 
3997
4239
  if (name->AsArrayIndex(&index)) {
3998
- return js_object->SetElement(index, *value, strict_mode);
4240
+ return js_object->SetElement(index, *value, strict_mode, true);
3999
4241
  } else {
4000
4242
  return js_object->SetProperty(*name, *value, attr, strict_mode);
4001
4243
  }
@@ -4023,12 +4265,12 @@ MaybeObject* Runtime::ForceSetObjectProperty(Isolate* isolate,
4023
4265
  return *value;
4024
4266
  }
4025
4267
 
4026
- return js_object->SetElement(index, *value, kNonStrictMode);
4268
+ return js_object->SetElement(index, *value, kNonStrictMode, true);
4027
4269
  }
4028
4270
 
4029
4271
  if (key->IsString()) {
4030
4272
  if (Handle<String>::cast(key)->AsArrayIndex(&index)) {
4031
- return js_object->SetElement(index, *value, kNonStrictMode);
4273
+ return js_object->SetElement(index, *value, kNonStrictMode, true);
4032
4274
  } else {
4033
4275
  Handle<String> key_string = Handle<String>::cast(key);
4034
4276
  key_string->TryFlatten();
@@ -4045,7 +4287,7 @@ MaybeObject* Runtime::ForceSetObjectProperty(Isolate* isolate,
4045
4287
  Handle<String> name = Handle<String>::cast(converted);
4046
4288
 
4047
4289
  if (name->AsArrayIndex(&index)) {
4048
- return js_object->SetElement(index, *value, kNonStrictMode);
4290
+ return js_object->SetElement(index, *value, kNonStrictMode, true);
4049
4291
  } else {
4050
4292
  return js_object->SetLocalPropertyIgnoreAttributes(*name, *value, attr);
4051
4293
  }
@@ -4053,24 +4295,25 @@ MaybeObject* Runtime::ForceSetObjectProperty(Isolate* isolate,
4053
4295
 
4054
4296
 
4055
4297
  MaybeObject* Runtime::ForceDeleteObjectProperty(Isolate* isolate,
4056
- Handle<JSObject> js_object,
4298
+ Handle<JSReceiver> receiver,
4057
4299
  Handle<Object> key) {
4058
4300
  HandleScope scope(isolate);
4059
4301
 
4060
4302
  // Check if the given key is an array index.
4061
4303
  uint32_t index;
4062
- if (key->ToArrayIndex(&index)) {
4304
+ if (receiver->IsJSObject() && key->ToArrayIndex(&index)) {
4063
4305
  // In Firefox/SpiderMonkey, Safari and Opera you can access the
4064
4306
  // characters of a string using [] notation. In the case of a
4065
4307
  // String object we just need to redirect the deletion to the
4066
4308
  // underlying string if the index is in range. Since the
4067
4309
  // underlying string does nothing with the deletion, we can ignore
4068
4310
  // such deletions.
4069
- if (js_object->IsStringObjectWithCharacterAt(index)) {
4311
+ if (receiver->IsStringObjectWithCharacterAt(index)) {
4070
4312
  return isolate->heap()->true_value();
4071
4313
  }
4072
4314
 
4073
- return js_object->DeleteElement(index, JSObject::FORCE_DELETION);
4315
+ return JSObject::cast(*receiver)->DeleteElement(
4316
+ index, JSReceiver::FORCE_DELETION);
4074
4317
  }
4075
4318
 
4076
4319
  Handle<String> key_string;
@@ -4085,7 +4328,7 @@ MaybeObject* Runtime::ForceDeleteObjectProperty(Isolate* isolate,
4085
4328
  }
4086
4329
 
4087
4330
  key_string->TryFlatten();
4088
- return js_object->DeleteProperty(*key_string, JSObject::FORCE_DELETION);
4331
+ return receiver->DeleteProperty(*key_string, JSReceiver::FORCE_DELETION);
4089
4332
  }
4090
4333
 
4091
4334
 
@@ -4096,7 +4339,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetProperty) {
4096
4339
  Handle<Object> object = args.at<Object>(0);
4097
4340
  Handle<Object> key = args.at<Object>(1);
4098
4341
  Handle<Object> value = args.at<Object>(2);
4099
- CONVERT_SMI_CHECKED(unchecked_attributes, args[3]);
4342
+ CONVERT_SMI_ARG_CHECKED(unchecked_attributes, 3);
4100
4343
  RUNTIME_ASSERT(
4101
4344
  (unchecked_attributes & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
4102
4345
  // Compute attributes.
@@ -4105,7 +4348,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetProperty) {
4105
4348
 
4106
4349
  StrictModeFlag strict_mode = kNonStrictMode;
4107
4350
  if (args.length() == 5) {
4108
- CONVERT_SMI_CHECKED(strict_unchecked, args[4]);
4351
+ CONVERT_SMI_ARG_CHECKED(strict_unchecked, 4);
4109
4352
  RUNTIME_ASSERT(strict_unchecked == kStrictMode ||
4110
4353
  strict_unchecked == kNonStrictMode);
4111
4354
  strict_mode = static_cast<StrictModeFlag>(strict_unchecked);
@@ -4120,10 +4363,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetProperty) {
4120
4363
  }
4121
4364
 
4122
4365
 
4123
- // Set the ES5 native flag on the function.
4366
+ // Set the native flag on the function.
4124
4367
  // This is used to decide if we should transform null and undefined
4125
4368
  // into the global object when doing call and apply.
4126
- RUNTIME_FUNCTION(MaybeObject*, Runtime_SetES5Flag) {
4369
+ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetNativeFlag) {
4127
4370
  NoHandleAllocation ha;
4128
4371
  RUNTIME_ASSERT(args.length() == 1);
4129
4372
 
@@ -4131,7 +4374,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetES5Flag) {
4131
4374
 
4132
4375
  if (object->IsJSFunction()) {
4133
4376
  JSFunction* func = JSFunction::cast(*object);
4134
- func->shared()->set_es5_native(true);
4377
+ func->shared()->set_native(true);
4135
4378
  }
4136
4379
  return isolate->heap()->undefined_value();
4137
4380
  }
@@ -4164,12 +4407,12 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeleteProperty) {
4164
4407
  NoHandleAllocation ha;
4165
4408
  ASSERT(args.length() == 3);
4166
4409
 
4167
- CONVERT_CHECKED(JSObject, object, args[0]);
4410
+ CONVERT_CHECKED(JSReceiver, object, args[0]);
4168
4411
  CONVERT_CHECKED(String, key, args[1]);
4169
- CONVERT_SMI_CHECKED(strict, args[2]);
4412
+ CONVERT_SMI_ARG_CHECKED(strict, 2);
4170
4413
  return object->DeleteProperty(key, (strict == kStrictMode)
4171
- ? JSObject::STRICT_DELETION
4172
- : JSObject::NORMAL_DELETION);
4414
+ ? JSReceiver::STRICT_DELETION
4415
+ : JSReceiver::NORMAL_DELETION);
4173
4416
  }
4174
4417
 
4175
4418
 
@@ -4233,11 +4476,11 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_HasProperty) {
4233
4476
  NoHandleAllocation na;
4234
4477
  ASSERT(args.length() == 2);
4235
4478
 
4236
- // Only JS objects can have properties.
4237
- if (args[0]->IsJSObject()) {
4238
- JSObject* object = JSObject::cast(args[0]);
4479
+ // Only JS receivers can have properties.
4480
+ if (args[0]->IsJSReceiver()) {
4481
+ JSReceiver* receiver = JSReceiver::cast(args[0]);
4239
4482
  CONVERT_CHECKED(String, key, args[1]);
4240
- if (object->HasProperty(key)) return isolate->heap()->true_value();
4483
+ if (receiver->HasProperty(key)) return isolate->heap()->true_value();
4241
4484
  }
4242
4485
  return isolate->heap()->false_value();
4243
4486
  }
@@ -4378,10 +4621,11 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLocalPropertyNames) {
4378
4621
  // Get the property names.
4379
4622
  jsproto = obj;
4380
4623
  int proto_with_hidden_properties = 0;
4624
+ int next_copy_index = 0;
4381
4625
  for (int i = 0; i < length; i++) {
4382
- jsproto->GetLocalPropertyNames(*names,
4383
- i == 0 ? 0 : local_property_count[i - 1]);
4384
- if (!GetHiddenProperties(jsproto, false)->IsUndefined()) {
4626
+ jsproto->GetLocalPropertyNames(*names, next_copy_index);
4627
+ next_copy_index += local_property_count[i];
4628
+ if (jsproto->HasHiddenProperties()) {
4385
4629
  proto_with_hidden_properties++;
4386
4630
  }
4387
4631
  if (i < length - 1) {
@@ -4633,11 +4877,13 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_Typeof) {
4633
4877
  return isolate->heap()->boolean_symbol();
4634
4878
  }
4635
4879
  if (heap_obj->IsNull()) {
4636
- return isolate->heap()->object_symbol();
4880
+ return FLAG_harmony_typeof
4881
+ ? isolate->heap()->null_symbol()
4882
+ : isolate->heap()->object_symbol();
4637
4883
  }
4638
4884
  ASSERT(heap_obj->IsUndefined());
4639
4885
  return isolate->heap()->undefined_symbol();
4640
- case JS_FUNCTION_TYPE: case JS_REGEXP_TYPE:
4886
+ case JS_FUNCTION_TYPE:
4641
4887
  return isolate->heap()->function_symbol();
4642
4888
  default:
4643
4889
  // For any kind of object not handled above, the spec rule for
@@ -5011,6 +5257,8 @@ static const int kMaxGuaranteedNewSpaceString = 32 * 1024;
5011
5257
  // Doing JSON quoting cannot make the string more than this many times larger.
5012
5258
  static const int kJsonQuoteWorstCaseBlowup = 6;
5013
5259
 
5260
+ static const int kSpaceForQuotesAndComma = 3;
5261
+ static const int kSpaceForBrackets = 2;
5014
5262
 
5015
5263
  // Covers the entire ASCII range (all other characters are unchanged by JSON
5016
5264
  // quoting).
@@ -5098,13 +5346,51 @@ static MaybeObject* SlowQuoteJsonString(Isolate* isolate,
5098
5346
  }
5099
5347
 
5100
5348
 
5349
+ template <typename SinkChar, typename SourceChar>
5350
+ static inline SinkChar* WriteQuoteJsonString(
5351
+ Isolate* isolate,
5352
+ SinkChar* write_cursor,
5353
+ Vector<const SourceChar> characters) {
5354
+ // SinkChar is only char if SourceChar is guaranteed to be char.
5355
+ ASSERT(sizeof(SinkChar) >= sizeof(SourceChar));
5356
+ const SourceChar* read_cursor = characters.start();
5357
+ const SourceChar* end = read_cursor + characters.length();
5358
+ *(write_cursor++) = '"';
5359
+ while (read_cursor < end) {
5360
+ SourceChar c = *(read_cursor++);
5361
+ if (sizeof(SourceChar) > 1u &&
5362
+ static_cast<unsigned>(c) >= kQuoteTableLength) {
5363
+ *(write_cursor++) = static_cast<SinkChar>(c);
5364
+ } else {
5365
+ int len = JsonQuoteLengths[static_cast<unsigned>(c)];
5366
+ const char* replacement = JsonQuotes +
5367
+ static_cast<unsigned>(c) * kJsonQuotesCharactersPerEntry;
5368
+ write_cursor[0] = replacement[0];
5369
+ if (len > 1) {
5370
+ write_cursor[1] = replacement[1];
5371
+ if (len > 2) {
5372
+ ASSERT(len == 6);
5373
+ write_cursor[2] = replacement[2];
5374
+ write_cursor[3] = replacement[3];
5375
+ write_cursor[4] = replacement[4];
5376
+ write_cursor[5] = replacement[5];
5377
+ }
5378
+ }
5379
+ write_cursor += len;
5380
+ }
5381
+ }
5382
+ *(write_cursor++) = '"';
5383
+ return write_cursor;
5384
+ }
5385
+
5386
+
5101
5387
  template <typename Char, typename StringType, bool comma>
5102
5388
  static MaybeObject* QuoteJsonString(Isolate* isolate,
5103
5389
  Vector<const Char> characters) {
5104
5390
  int length = characters.length();
5105
5391
  isolate->counters()->quote_json_char_count()->Increment(length);
5106
- const int kSpaceForQuotes = 2 + (comma ? 1 :0);
5107
- int worst_case_length = length * kJsonQuoteWorstCaseBlowup + kSpaceForQuotes;
5392
+ int worst_case_length =
5393
+ length * kJsonQuoteWorstCaseBlowup + kSpaceForQuotesAndComma;
5108
5394
  if (worst_case_length > kMaxGuaranteedNewSpaceString) {
5109
5395
  return SlowQuoteJsonString<Char, StringType, comma>(isolate, characters);
5110
5396
  }
@@ -5129,34 +5415,9 @@ static MaybeObject* QuoteJsonString(Isolate* isolate,
5129
5415
  Char* write_cursor = reinterpret_cast<Char*>(
5130
5416
  new_string->address() + SeqAsciiString::kHeaderSize);
5131
5417
  if (comma) *(write_cursor++) = ',';
5132
- *(write_cursor++) = '"';
5133
-
5134
- const Char* read_cursor = characters.start();
5135
- const Char* end = read_cursor + length;
5136
- while (read_cursor < end) {
5137
- Char c = *(read_cursor++);
5138
- if (sizeof(Char) > 1u && static_cast<unsigned>(c) >= kQuoteTableLength) {
5139
- *(write_cursor++) = c;
5140
- } else {
5141
- int len = JsonQuoteLengths[static_cast<unsigned>(c)];
5142
- const char* replacement = JsonQuotes +
5143
- static_cast<unsigned>(c) * kJsonQuotesCharactersPerEntry;
5144
- write_cursor[0] = replacement[0];
5145
- if (len > 1) {
5146
- write_cursor[1] = replacement[1];
5147
- if (len > 2) {
5148
- ASSERT(len == 6);
5149
- write_cursor[2] = replacement[2];
5150
- write_cursor[3] = replacement[3];
5151
- write_cursor[4] = replacement[4];
5152
- write_cursor[5] = replacement[5];
5153
- }
5154
- }
5155
- write_cursor += len;
5156
- }
5157
- }
5158
- *(write_cursor++) = '"';
5159
-
5418
+ write_cursor = WriteQuoteJsonString<Char, Char>(isolate,
5419
+ write_cursor,
5420
+ characters);
5160
5421
  int final_length = static_cast<int>(
5161
5422
  write_cursor - reinterpret_cast<Char*>(
5162
5423
  new_string->address() + SeqAsciiString::kHeaderSize));
@@ -5179,12 +5440,14 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_QuoteJSONString) {
5179
5440
  str = String::cast(flat);
5180
5441
  ASSERT(str->IsFlat());
5181
5442
  }
5182
- if (str->IsTwoByteRepresentation()) {
5443
+ String::FlatContent flat = str->GetFlatContent();
5444
+ ASSERT(flat.IsFlat());
5445
+ if (flat.IsTwoByte()) {
5183
5446
  return QuoteJsonString<uc16, SeqTwoByteString, false>(isolate,
5184
- str->ToUC16Vector());
5447
+ flat.ToUC16Vector());
5185
5448
  } else {
5186
5449
  return QuoteJsonString<char, SeqAsciiString, false>(isolate,
5187
- str->ToAsciiVector());
5450
+ flat.ToAsciiVector());
5188
5451
  }
5189
5452
  }
5190
5453
 
@@ -5201,20 +5464,118 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_QuoteJSONStringComma) {
5201
5464
  str = String::cast(flat);
5202
5465
  ASSERT(str->IsFlat());
5203
5466
  }
5204
- if (str->IsTwoByteRepresentation()) {
5467
+ String::FlatContent flat = str->GetFlatContent();
5468
+ if (flat.IsTwoByte()) {
5205
5469
  return QuoteJsonString<uc16, SeqTwoByteString, true>(isolate,
5206
- str->ToUC16Vector());
5470
+ flat.ToUC16Vector());
5207
5471
  } else {
5208
5472
  return QuoteJsonString<char, SeqAsciiString, true>(isolate,
5209
- str->ToAsciiVector());
5473
+ flat.ToAsciiVector());
5474
+ }
5475
+ }
5476
+
5477
+
5478
+ template <typename Char, typename StringType>
5479
+ static MaybeObject* QuoteJsonStringArray(Isolate* isolate,
5480
+ FixedArray* array,
5481
+ int worst_case_length) {
5482
+ int length = array->length();
5483
+
5484
+ MaybeObject* new_alloc = AllocateRawString<StringType>(isolate,
5485
+ worst_case_length);
5486
+ Object* new_object;
5487
+ if (!new_alloc->ToObject(&new_object)) {
5488
+ return new_alloc;
5489
+ }
5490
+ if (!isolate->heap()->new_space()->Contains(new_object)) {
5491
+ // Even if our string is small enough to fit in new space we still have to
5492
+ // handle it being allocated in old space as may happen in the third
5493
+ // attempt. See CALL_AND_RETRY in heap-inl.h and similar code in
5494
+ // CEntryStub::GenerateCore.
5495
+ return isolate->heap()->undefined_value();
5496
+ }
5497
+ AssertNoAllocation no_gc;
5498
+ StringType* new_string = StringType::cast(new_object);
5499
+ ASSERT(isolate->heap()->new_space()->Contains(new_string));
5500
+
5501
+ STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqAsciiString::kHeaderSize);
5502
+ Char* write_cursor = reinterpret_cast<Char*>(
5503
+ new_string->address() + SeqAsciiString::kHeaderSize);
5504
+ *(write_cursor++) = '[';
5505
+ for (int i = 0; i < length; i++) {
5506
+ if (i != 0) *(write_cursor++) = ',';
5507
+ String* str = String::cast(array->get(i));
5508
+ String::FlatContent content = str->GetFlatContent();
5509
+ ASSERT(content.IsFlat());
5510
+ if (content.IsTwoByte()) {
5511
+ write_cursor = WriteQuoteJsonString<Char, uc16>(isolate,
5512
+ write_cursor,
5513
+ content.ToUC16Vector());
5514
+ } else {
5515
+ write_cursor = WriteQuoteJsonString<Char, char>(isolate,
5516
+ write_cursor,
5517
+ content.ToAsciiVector());
5518
+ }
5519
+ }
5520
+ *(write_cursor++) = ']';
5521
+
5522
+ int final_length = static_cast<int>(
5523
+ write_cursor - reinterpret_cast<Char*>(
5524
+ new_string->address() + SeqAsciiString::kHeaderSize));
5525
+ isolate->heap()->new_space()->
5526
+ template ShrinkStringAtAllocationBoundary<StringType>(
5527
+ new_string, final_length);
5528
+ return new_string;
5529
+ }
5530
+
5531
+
5532
+ RUNTIME_FUNCTION(MaybeObject*, Runtime_QuoteJSONStringArray) {
5533
+ NoHandleAllocation ha;
5534
+ ASSERT(args.length() == 1);
5535
+ CONVERT_CHECKED(JSArray, array, args[0]);
5536
+
5537
+ if (!array->HasFastElements()) return isolate->heap()->undefined_value();
5538
+ FixedArray* elements = FixedArray::cast(array->elements());
5539
+ int n = elements->length();
5540
+ bool ascii = true;
5541
+ int total_length = 0;
5542
+
5543
+ for (int i = 0; i < n; i++) {
5544
+ Object* elt = elements->get(i);
5545
+ if (!elt->IsString()) return isolate->heap()->undefined_value();
5546
+ String* element = String::cast(elt);
5547
+ if (!element->IsFlat()) return isolate->heap()->undefined_value();
5548
+ total_length += element->length();
5549
+ if (ascii && element->IsTwoByteRepresentation()) {
5550
+ ascii = false;
5551
+ }
5552
+ }
5553
+
5554
+ int worst_case_length =
5555
+ kSpaceForBrackets + n * kSpaceForQuotesAndComma
5556
+ + total_length * kJsonQuoteWorstCaseBlowup;
5557
+
5558
+ if (worst_case_length > kMaxGuaranteedNewSpaceString) {
5559
+ return isolate->heap()->undefined_value();
5560
+ }
5561
+
5562
+ if (ascii) {
5563
+ return QuoteJsonStringArray<char, SeqAsciiString>(isolate,
5564
+ elements,
5565
+ worst_case_length);
5566
+ } else {
5567
+ return QuoteJsonStringArray<uc16, SeqTwoByteString>(isolate,
5568
+ elements,
5569
+ worst_case_length);
5210
5570
  }
5211
5571
  }
5212
5572
 
5573
+
5213
5574
  RUNTIME_FUNCTION(MaybeObject*, Runtime_StringParseInt) {
5214
5575
  NoHandleAllocation ha;
5215
5576
 
5216
5577
  CONVERT_CHECKED(String, s, args[0]);
5217
- CONVERT_SMI_CHECKED(radix, args[1]);
5578
+ CONVERT_SMI_ARG_CHECKED(radix, 1);
5218
5579
 
5219
5580
  s->TryFlatten();
5220
5581
 
@@ -5561,6 +5922,27 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringTrim) {
5561
5922
  }
5562
5923
 
5563
5924
 
5925
+ void FindAsciiStringIndices(Vector<const char> subject,
5926
+ char pattern,
5927
+ ZoneList<int>* indices,
5928
+ unsigned int limit) {
5929
+ ASSERT(limit > 0);
5930
+ // Collect indices of pattern in subject using memchr.
5931
+ // Stop after finding at most limit values.
5932
+ const char* subject_start = reinterpret_cast<const char*>(subject.start());
5933
+ const char* subject_end = subject_start + subject.length();
5934
+ const char* pos = subject_start;
5935
+ while (limit > 0) {
5936
+ pos = reinterpret_cast<const char*>(
5937
+ memchr(pos, pattern, subject_end - pos));
5938
+ if (pos == NULL) return;
5939
+ indices->Add(static_cast<int>(pos - subject_start));
5940
+ pos++;
5941
+ limit--;
5942
+ }
5943
+ }
5944
+
5945
+
5564
5946
  template <typename SubjectChar, typename PatternChar>
5565
5947
  void FindStringIndices(Isolate* isolate,
5566
5948
  Vector<const SubjectChar> subject,
@@ -5568,11 +5950,11 @@ void FindStringIndices(Isolate* isolate,
5568
5950
  ZoneList<int>* indices,
5569
5951
  unsigned int limit) {
5570
5952
  ASSERT(limit > 0);
5571
- // Collect indices of pattern in subject, and the end-of-string index.
5953
+ // Collect indices of pattern in subject.
5572
5954
  // Stop after finding at most limit values.
5573
- StringSearch<PatternChar, SubjectChar> search(isolate, pattern);
5574
5955
  int pattern_length = pattern.length();
5575
5956
  int index = 0;
5957
+ StringSearch<PatternChar, SubjectChar> search(isolate, pattern);
5576
5958
  while (limit > 0) {
5577
5959
  index = search.Search(subject, index);
5578
5960
  if (index < 0) return;
@@ -5611,34 +5993,46 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringSplit) {
5611
5993
 
5612
5994
  // No allocation block.
5613
5995
  {
5614
- AssertNoAllocation nogc;
5615
- if (subject->IsAsciiRepresentation()) {
5616
- Vector<const char> subject_vector = subject->ToAsciiVector();
5617
- if (pattern->IsAsciiRepresentation()) {
5618
- FindStringIndices(isolate,
5619
- subject_vector,
5620
- pattern->ToAsciiVector(),
5621
- &indices,
5622
- limit);
5996
+ AssertNoAllocation no_gc;
5997
+ String::FlatContent subject_content = subject->GetFlatContent();
5998
+ String::FlatContent pattern_content = pattern->GetFlatContent();
5999
+ ASSERT(subject_content.IsFlat());
6000
+ ASSERT(pattern_content.IsFlat());
6001
+ if (subject_content.IsAscii()) {
6002
+ Vector<const char> subject_vector = subject_content.ToAsciiVector();
6003
+ if (pattern_content.IsAscii()) {
6004
+ Vector<const char> pattern_vector = pattern_content.ToAsciiVector();
6005
+ if (pattern_vector.length() == 1) {
6006
+ FindAsciiStringIndices(subject_vector,
6007
+ pattern_vector[0],
6008
+ &indices,
6009
+ limit);
6010
+ } else {
6011
+ FindStringIndices(isolate,
6012
+ subject_vector,
6013
+ pattern_vector,
6014
+ &indices,
6015
+ limit);
6016
+ }
5623
6017
  } else {
5624
6018
  FindStringIndices(isolate,
5625
6019
  subject_vector,
5626
- pattern->ToUC16Vector(),
6020
+ pattern_content.ToUC16Vector(),
5627
6021
  &indices,
5628
6022
  limit);
5629
6023
  }
5630
6024
  } else {
5631
- Vector<const uc16> subject_vector = subject->ToUC16Vector();
6025
+ Vector<const uc16> subject_vector = subject_content.ToUC16Vector();
5632
6026
  if (pattern->IsAsciiRepresentation()) {
5633
6027
  FindStringIndices(isolate,
5634
6028
  subject_vector,
5635
- pattern->ToAsciiVector(),
6029
+ pattern_content.ToAsciiVector(),
5636
6030
  &indices,
5637
6031
  limit);
5638
6032
  } else {
5639
6033
  FindStringIndices(isolate,
5640
6034
  subject_vector,
5641
- pattern->ToUC16Vector(),
6035
+ pattern_content.ToUC16Vector(),
5642
6036
  &indices,
5643
6037
  limit);
5644
6038
  }
@@ -5670,7 +6064,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringSplit) {
5670
6064
  HandleScope local_loop_handle;
5671
6065
  int part_end = indices.at(i);
5672
6066
  Handle<String> substring =
5673
- isolate->factory()->NewSubString(subject, part_start, part_end);
6067
+ isolate->factory()->NewProperSubString(subject, part_start, part_end);
5674
6068
  elements->set(i, *substring);
5675
6069
  part_start = part_end + pattern_length;
5676
6070
  }
@@ -5687,7 +6081,7 @@ static int CopyCachedAsciiCharsToArray(Heap* heap,
5687
6081
  const char* chars,
5688
6082
  FixedArray* elements,
5689
6083
  int length) {
5690
- AssertNoAllocation nogc;
6084
+ AssertNoAllocation no_gc;
5691
6085
  FixedArray* ascii_cache = heap->single_character_string_cache();
5692
6086
  Object* undefined = heap->undefined_value();
5693
6087
  int i;
@@ -5720,36 +6114,39 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringToArray) {
5720
6114
  CONVERT_ARG_CHECKED(String, s, 0);
5721
6115
  CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]);
5722
6116
 
5723
- s->TryFlatten();
6117
+ s = FlattenGetString(s);
5724
6118
  const int length = static_cast<int>(Min<uint32_t>(s->length(), limit));
5725
6119
 
5726
6120
  Handle<FixedArray> elements;
6121
+ int position = 0;
5727
6122
  if (s->IsFlat() && s->IsAsciiRepresentation()) {
6123
+ // Try using cached chars where possible.
5728
6124
  Object* obj;
5729
6125
  { MaybeObject* maybe_obj =
5730
6126
  isolate->heap()->AllocateUninitializedFixedArray(length);
5731
6127
  if (!maybe_obj->ToObject(&obj)) return maybe_obj;
5732
6128
  }
5733
6129
  elements = Handle<FixedArray>(FixedArray::cast(obj), isolate);
5734
-
5735
- Vector<const char> chars = s->ToAsciiVector();
5736
- // Note, this will initialize all elements (not only the prefix)
5737
- // to prevent GC from seeing partially initialized array.
5738
- int num_copied_from_cache = CopyCachedAsciiCharsToArray(isolate->heap(),
5739
- chars.start(),
5740
- *elements,
5741
- length);
5742
-
5743
- for (int i = num_copied_from_cache; i < length; ++i) {
5744
- Handle<Object> str = LookupSingleCharacterStringFromCode(chars[i]);
5745
- elements->set(i, *str);
6130
+ String::FlatContent content = s->GetFlatContent();
6131
+ if (content.IsAscii()) {
6132
+ Vector<const char> chars = content.ToAsciiVector();
6133
+ // Note, this will initialize all elements (not only the prefix)
6134
+ // to prevent GC from seeing partially initialized array.
6135
+ position = CopyCachedAsciiCharsToArray(isolate->heap(),
6136
+ chars.start(),
6137
+ *elements,
6138
+ length);
6139
+ } else {
6140
+ MemsetPointer(elements->data_start(),
6141
+ isolate->heap()->undefined_value(),
6142
+ length);
5746
6143
  }
5747
6144
  } else {
5748
6145
  elements = isolate->factory()->NewFixedArray(length);
5749
- for (int i = 0; i < length; ++i) {
5750
- Handle<Object> str = LookupSingleCharacterStringFromCode(s->Get(i));
5751
- elements->set(i, *str);
5752
- }
6146
+ }
6147
+ for (int i = position; i < length; ++i) {
6148
+ Handle<Object> str = LookupSingleCharacterStringFromCode(s->Get(i));
6149
+ elements->set(i, *str);
5753
6150
  }
5754
6151
 
5755
6152
  #ifdef DEBUG
@@ -5803,7 +6200,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToInteger) {
5803
6200
  NoHandleAllocation ha;
5804
6201
  ASSERT(args.length() == 1);
5805
6202
 
5806
- CONVERT_DOUBLE_CHECKED(number, args[0]);
6203
+ CONVERT_DOUBLE_ARG_CHECKED(number, 0);
5807
6204
 
5808
6205
  // We do not include 0 so that we don't have to treat +0 / -0 cases.
5809
6206
  if (number > 0 && number <= Smi::kMaxValue) {
@@ -5817,7 +6214,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToIntegerMapMinusZero) {
5817
6214
  NoHandleAllocation ha;
5818
6215
  ASSERT(args.length() == 1);
5819
6216
 
5820
- CONVERT_DOUBLE_CHECKED(number, args[0]);
6217
+ CONVERT_DOUBLE_ARG_CHECKED(number, 0);
5821
6218
 
5822
6219
  // We do not include 0 so that we don't have to treat +0 / -0 cases.
5823
6220
  if (number > 0 && number <= Smi::kMaxValue) {
@@ -5845,7 +6242,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToJSInt32) {
5845
6242
  NoHandleAllocation ha;
5846
6243
  ASSERT(args.length() == 1);
5847
6244
 
5848
- CONVERT_DOUBLE_CHECKED(number, args[0]);
6245
+ CONVERT_DOUBLE_ARG_CHECKED(number, 0);
5849
6246
 
5850
6247
  // We do not include 0 so that we don't have to treat +0 / -0 cases.
5851
6248
  if (number > 0 && number <= Smi::kMaxValue) {
@@ -5887,8 +6284,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberAdd) {
5887
6284
  NoHandleAllocation ha;
5888
6285
  ASSERT(args.length() == 2);
5889
6286
 
5890
- CONVERT_DOUBLE_CHECKED(x, args[0]);
5891
- CONVERT_DOUBLE_CHECKED(y, args[1]);
6287
+ CONVERT_DOUBLE_ARG_CHECKED(x, 0);
6288
+ CONVERT_DOUBLE_ARG_CHECKED(y, 1);
5892
6289
  return isolate->heap()->NumberFromDouble(x + y);
5893
6290
  }
5894
6291
 
@@ -5897,8 +6294,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberSub) {
5897
6294
  NoHandleAllocation ha;
5898
6295
  ASSERT(args.length() == 2);
5899
6296
 
5900
- CONVERT_DOUBLE_CHECKED(x, args[0]);
5901
- CONVERT_DOUBLE_CHECKED(y, args[1]);
6297
+ CONVERT_DOUBLE_ARG_CHECKED(x, 0);
6298
+ CONVERT_DOUBLE_ARG_CHECKED(y, 1);
5902
6299
  return isolate->heap()->NumberFromDouble(x - y);
5903
6300
  }
5904
6301
 
@@ -5907,8 +6304,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberMul) {
5907
6304
  NoHandleAllocation ha;
5908
6305
  ASSERT(args.length() == 2);
5909
6306
 
5910
- CONVERT_DOUBLE_CHECKED(x, args[0]);
5911
- CONVERT_DOUBLE_CHECKED(y, args[1]);
6307
+ CONVERT_DOUBLE_ARG_CHECKED(x, 0);
6308
+ CONVERT_DOUBLE_ARG_CHECKED(y, 1);
5912
6309
  return isolate->heap()->NumberFromDouble(x * y);
5913
6310
  }
5914
6311
 
@@ -5917,7 +6314,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberUnaryMinus) {
5917
6314
  NoHandleAllocation ha;
5918
6315
  ASSERT(args.length() == 1);
5919
6316
 
5920
- CONVERT_DOUBLE_CHECKED(x, args[0]);
6317
+ CONVERT_DOUBLE_ARG_CHECKED(x, 0);
5921
6318
  return isolate->heap()->NumberFromDouble(-x);
5922
6319
  }
5923
6320
 
@@ -5934,8 +6331,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberDiv) {
5934
6331
  NoHandleAllocation ha;
5935
6332
  ASSERT(args.length() == 2);
5936
6333
 
5937
- CONVERT_DOUBLE_CHECKED(x, args[0]);
5938
- CONVERT_DOUBLE_CHECKED(y, args[1]);
6334
+ CONVERT_DOUBLE_ARG_CHECKED(x, 0);
6335
+ CONVERT_DOUBLE_ARG_CHECKED(y, 1);
5939
6336
  return isolate->heap()->NumberFromDouble(x / y);
5940
6337
  }
5941
6338
 
@@ -5944,8 +6341,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberMod) {
5944
6341
  NoHandleAllocation ha;
5945
6342
  ASSERT(args.length() == 2);
5946
6343
 
5947
- CONVERT_DOUBLE_CHECKED(x, args[0]);
5948
- CONVERT_DOUBLE_CHECKED(y, args[1]);
6344
+ CONVERT_DOUBLE_ARG_CHECKED(x, 0);
6345
+ CONVERT_DOUBLE_ARG_CHECKED(y, 1);
5949
6346
 
5950
6347
  x = modulo(x, y);
5951
6348
  // NumberFromDouble may return a Smi instead of a Number object
@@ -6010,7 +6407,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringBuilderConcat) {
6010
6407
  isolate->context()->mark_out_of_memory();
6011
6408
  return Failure::OutOfMemoryException();
6012
6409
  }
6013
- int array_length = Smi::cast(args[1])->value();
6410
+ int array_length = args.smi_at(1);
6014
6411
  CONVERT_CHECKED(String, special, args[2]);
6015
6412
 
6016
6413
  // This assumption is used by the slice encoding in one or two smis.
@@ -6123,7 +6520,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringBuilderJoin) {
6123
6520
  isolate->context()->mark_out_of_memory();
6124
6521
  return Failure::OutOfMemoryException();
6125
6522
  }
6126
- int array_length = Smi::cast(args[1])->value();
6523
+ int array_length = args.smi_at(1);
6127
6524
  CONVERT_CHECKED(String, separator, args[2]);
6128
6525
 
6129
6526
  if (!array->HasFastElements()) {
@@ -6401,8 +6798,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberEquals) {
6401
6798
  NoHandleAllocation ha;
6402
6799
  ASSERT(args.length() == 2);
6403
6800
 
6404
- CONVERT_DOUBLE_CHECKED(x, args[0]);
6405
- CONVERT_DOUBLE_CHECKED(y, args[1]);
6801
+ CONVERT_DOUBLE_ARG_CHECKED(x, 0);
6802
+ CONVERT_DOUBLE_ARG_CHECKED(y, 1);
6406
6803
  if (isnan(x)) return Smi::FromInt(NOT_EQUAL);
6407
6804
  if (isnan(y)) return Smi::FromInt(NOT_EQUAL);
6408
6805
  if (x == y) return Smi::FromInt(EQUAL);
@@ -6438,8 +6835,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberCompare) {
6438
6835
  NoHandleAllocation ha;
6439
6836
  ASSERT(args.length() == 3);
6440
6837
 
6441
- CONVERT_DOUBLE_CHECKED(x, args[0]);
6442
- CONVERT_DOUBLE_CHECKED(y, args[1]);
6838
+ CONVERT_DOUBLE_ARG_CHECKED(x, 0);
6839
+ CONVERT_DOUBLE_ARG_CHECKED(y, 1);
6443
6840
  if (isnan(x) || isnan(y)) return args[2];
6444
6841
  if (x == y) return Smi::FromInt(EQUAL);
6445
6842
  if (isless(x, y)) return Smi::FromInt(LESS);
@@ -6462,50 +6859,69 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SmiLexicographicCompare) {
6462
6859
  // If the integers are equal so are the string representations.
6463
6860
  if (x_value == y_value) return Smi::FromInt(EQUAL);
6464
6861
 
6465
- // If one of the integers are zero the normal integer order is the
6862
+ // If one of the integers is zero the normal integer order is the
6466
6863
  // same as the lexicographic order of the string representations.
6467
- if (x_value == 0 || y_value == 0) return Smi::FromInt(x_value - y_value);
6864
+ if (x_value == 0 || y_value == 0)
6865
+ return Smi::FromInt(x_value < y_value ? LESS : GREATER);
6468
6866
 
6469
6867
  // If only one of the integers is negative the negative number is
6470
6868
  // smallest because the char code of '-' is less than the char code
6471
6869
  // of any digit. Otherwise, we make both values positive.
6870
+
6871
+ // Use unsigned values otherwise the logic is incorrect for -MIN_INT on
6872
+ // architectures using 32-bit Smis.
6873
+ uint32_t x_scaled = x_value;
6874
+ uint32_t y_scaled = y_value;
6472
6875
  if (x_value < 0 || y_value < 0) {
6473
6876
  if (y_value >= 0) return Smi::FromInt(LESS);
6474
6877
  if (x_value >= 0) return Smi::FromInt(GREATER);
6475
- x_value = -x_value;
6476
- y_value = -y_value;
6878
+ x_scaled = -x_value;
6879
+ y_scaled = -y_value;
6477
6880
  }
6478
6881
 
6479
- // Arrays for the individual characters of the two Smis. Smis are
6480
- // 31 bit integers and 10 decimal digits are therefore enough.
6481
- // TODO(isolates): maybe we should simply allocate 20 bytes on the stack.
6482
- int* x_elms = isolate->runtime_state()->smi_lexicographic_compare_x_elms();
6483
- int* y_elms = isolate->runtime_state()->smi_lexicographic_compare_y_elms();
6882
+ static const uint32_t kPowersOf10[] = {
6883
+ 1, 10, 100, 1000, 10*1000, 100*1000,
6884
+ 1000*1000, 10*1000*1000, 100*1000*1000,
6885
+ 1000*1000*1000
6886
+ };
6484
6887
 
6888
+ // If the integers have the same number of decimal digits they can be
6889
+ // compared directly as the numeric order is the same as the
6890
+ // lexicographic order. If one integer has fewer digits, it is scaled
6891
+ // by some power of 10 to have the same number of digits as the longer
6892
+ // integer. If the scaled integers are equal it means the shorter
6893
+ // integer comes first in the lexicographic order.
6485
6894
 
6486
- // Convert the integers to arrays of their decimal digits.
6487
- int x_index = 0;
6488
- int y_index = 0;
6489
- while (x_value > 0) {
6490
- x_elms[x_index++] = x_value % 10;
6491
- x_value /= 10;
6492
- }
6493
- while (y_value > 0) {
6494
- y_elms[y_index++] = y_value % 10;
6495
- y_value /= 10;
6496
- }
6895
+ // From http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
6896
+ int x_log2 = IntegerLog2(x_scaled);
6897
+ int x_log10 = ((x_log2 + 1) * 1233) >> 12;
6898
+ x_log10 -= x_scaled < kPowersOf10[x_log10];
6497
6899
 
6498
- // Loop through the arrays of decimal digits finding the first place
6499
- // where they differ.
6500
- while (--x_index >= 0 && --y_index >= 0) {
6501
- int diff = x_elms[x_index] - y_elms[y_index];
6502
- if (diff != 0) return Smi::FromInt(diff);
6900
+ int y_log2 = IntegerLog2(y_scaled);
6901
+ int y_log10 = ((y_log2 + 1) * 1233) >> 12;
6902
+ y_log10 -= y_scaled < kPowersOf10[y_log10];
6903
+
6904
+ int tie = EQUAL;
6905
+
6906
+ if (x_log10 < y_log10) {
6907
+ // X has fewer digits. We would like to simply scale up X but that
6908
+ // might overflow, e.g when comparing 9 with 1_000_000_000, 9 would
6909
+ // be scaled up to 9_000_000_000. So we scale up by the next
6910
+ // smallest power and scale down Y to drop one digit. It is OK to
6911
+ // drop one digit from the longer integer since the final digit is
6912
+ // past the length of the shorter integer.
6913
+ x_scaled *= kPowersOf10[y_log10 - x_log10 - 1];
6914
+ y_scaled /= 10;
6915
+ tie = LESS;
6916
+ } else if (y_log10 < x_log10) {
6917
+ y_scaled *= kPowersOf10[x_log10 - y_log10 - 1];
6918
+ x_scaled /= 10;
6919
+ tie = GREATER;
6503
6920
  }
6504
6921
 
6505
- // If one array is a suffix of the other array, the longest array is
6506
- // the representation of the largest of the Smis in the
6507
- // lexicographic ordering.
6508
- return Smi::FromInt(x_index - y_index);
6922
+ if (x_scaled < y_scaled) return Smi::FromInt(LESS);
6923
+ if (x_scaled > y_scaled) return Smi::FromInt(GREATER);
6924
+ return Smi::FromInt(tie);
6509
6925
  }
6510
6926
 
6511
6927
 
@@ -6541,22 +6957,24 @@ static Object* FlatStringCompare(String* x, String* y) {
6541
6957
  equal_prefix_result = Smi::FromInt(LESS);
6542
6958
  }
6543
6959
  int r;
6544
- if (x->IsAsciiRepresentation()) {
6545
- Vector<const char> x_chars = x->ToAsciiVector();
6546
- if (y->IsAsciiRepresentation()) {
6547
- Vector<const char> y_chars = y->ToAsciiVector();
6960
+ String::FlatContent x_content = x->GetFlatContent();
6961
+ String::FlatContent y_content = y->GetFlatContent();
6962
+ if (x_content.IsAscii()) {
6963
+ Vector<const char> x_chars = x_content.ToAsciiVector();
6964
+ if (y_content.IsAscii()) {
6965
+ Vector<const char> y_chars = y_content.ToAsciiVector();
6548
6966
  r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
6549
6967
  } else {
6550
- Vector<const uc16> y_chars = y->ToUC16Vector();
6968
+ Vector<const uc16> y_chars = y_content.ToUC16Vector();
6551
6969
  r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
6552
6970
  }
6553
6971
  } else {
6554
- Vector<const uc16> x_chars = x->ToUC16Vector();
6555
- if (y->IsAsciiRepresentation()) {
6556
- Vector<const char> y_chars = y->ToAsciiVector();
6972
+ Vector<const uc16> x_chars = x_content.ToUC16Vector();
6973
+ if (y_content.IsAscii()) {
6974
+ Vector<const char> y_chars = y_content.ToAsciiVector();
6557
6975
  r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
6558
6976
  } else {
6559
- Vector<const uc16> y_chars = y->ToUC16Vector();
6977
+ Vector<const uc16> y_chars = y_content.ToUC16Vector();
6560
6978
  r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
6561
6979
  }
6562
6980
  }
@@ -6612,7 +7030,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_acos) {
6612
7030
  ASSERT(args.length() == 1);
6613
7031
  isolate->counters()->math_acos()->Increment();
6614
7032
 
6615
- CONVERT_DOUBLE_CHECKED(x, args[0]);
7033
+ CONVERT_DOUBLE_ARG_CHECKED(x, 0);
6616
7034
  return isolate->transcendental_cache()->Get(TranscendentalCache::ACOS, x);
6617
7035
  }
6618
7036
 
@@ -6622,7 +7040,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_asin) {
6622
7040
  ASSERT(args.length() == 1);
6623
7041
  isolate->counters()->math_asin()->Increment();
6624
7042
 
6625
- CONVERT_DOUBLE_CHECKED(x, args[0]);
7043
+ CONVERT_DOUBLE_ARG_CHECKED(x, 0);
6626
7044
  return isolate->transcendental_cache()->Get(TranscendentalCache::ASIN, x);
6627
7045
  }
6628
7046
 
@@ -6632,7 +7050,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_atan) {
6632
7050
  ASSERT(args.length() == 1);
6633
7051
  isolate->counters()->math_atan()->Increment();
6634
7052
 
6635
- CONVERT_DOUBLE_CHECKED(x, args[0]);
7053
+ CONVERT_DOUBLE_ARG_CHECKED(x, 0);
6636
7054
  return isolate->transcendental_cache()->Get(TranscendentalCache::ATAN, x);
6637
7055
  }
6638
7056
 
@@ -6645,8 +7063,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_atan2) {
6645
7063
  ASSERT(args.length() == 2);
6646
7064
  isolate->counters()->math_atan2()->Increment();
6647
7065
 
6648
- CONVERT_DOUBLE_CHECKED(x, args[0]);
6649
- CONVERT_DOUBLE_CHECKED(y, args[1]);
7066
+ CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7067
+ CONVERT_DOUBLE_ARG_CHECKED(y, 1);
6650
7068
  double result;
6651
7069
  if (isinf(x) && isinf(y)) {
6652
7070
  // Make sure that the result in case of two infinite arguments
@@ -6668,7 +7086,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_ceil) {
6668
7086
  ASSERT(args.length() == 1);
6669
7087
  isolate->counters()->math_ceil()->Increment();
6670
7088
 
6671
- CONVERT_DOUBLE_CHECKED(x, args[0]);
7089
+ CONVERT_DOUBLE_ARG_CHECKED(x, 0);
6672
7090
  return isolate->heap()->NumberFromDouble(ceiling(x));
6673
7091
  }
6674
7092
 
@@ -6678,7 +7096,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_cos) {
6678
7096
  ASSERT(args.length() == 1);
6679
7097
  isolate->counters()->math_cos()->Increment();
6680
7098
 
6681
- CONVERT_DOUBLE_CHECKED(x, args[0]);
7099
+ CONVERT_DOUBLE_ARG_CHECKED(x, 0);
6682
7100
  return isolate->transcendental_cache()->Get(TranscendentalCache::COS, x);
6683
7101
  }
6684
7102
 
@@ -6688,7 +7106,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_exp) {
6688
7106
  ASSERT(args.length() == 1);
6689
7107
  isolate->counters()->math_exp()->Increment();
6690
7108
 
6691
- CONVERT_DOUBLE_CHECKED(x, args[0]);
7109
+ CONVERT_DOUBLE_ARG_CHECKED(x, 0);
6692
7110
  return isolate->transcendental_cache()->Get(TranscendentalCache::EXP, x);
6693
7111
  }
6694
7112
 
@@ -6698,7 +7116,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_floor) {
6698
7116
  ASSERT(args.length() == 1);
6699
7117
  isolate->counters()->math_floor()->Increment();
6700
7118
 
6701
- CONVERT_DOUBLE_CHECKED(x, args[0]);
7119
+ CONVERT_DOUBLE_ARG_CHECKED(x, 0);
6702
7120
  return isolate->heap()->NumberFromDouble(floor(x));
6703
7121
  }
6704
7122
 
@@ -6708,7 +7126,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_log) {
6708
7126
  ASSERT(args.length() == 1);
6709
7127
  isolate->counters()->math_log()->Increment();
6710
7128
 
6711
- CONVERT_DOUBLE_CHECKED(x, args[0]);
7129
+ CONVERT_DOUBLE_ARG_CHECKED(x, 0);
6712
7130
  return isolate->transcendental_cache()->Get(TranscendentalCache::LOG, x);
6713
7131
  }
6714
7132
 
@@ -6718,16 +7136,16 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_pow) {
6718
7136
  ASSERT(args.length() == 2);
6719
7137
  isolate->counters()->math_pow()->Increment();
6720
7138
 
6721
- CONVERT_DOUBLE_CHECKED(x, args[0]);
7139
+ CONVERT_DOUBLE_ARG_CHECKED(x, 0);
6722
7140
 
6723
7141
  // If the second argument is a smi, it is much faster to call the
6724
7142
  // custom powi() function than the generic pow().
6725
7143
  if (args[1]->IsSmi()) {
6726
- int y = Smi::cast(args[1])->value();
7144
+ int y = args.smi_at(1);
6727
7145
  return isolate->heap()->NumberFromDouble(power_double_int(x, y));
6728
7146
  }
6729
7147
 
6730
- CONVERT_DOUBLE_CHECKED(y, args[1]);
7148
+ CONVERT_DOUBLE_ARG_CHECKED(y, 1);
6731
7149
  return isolate->heap()->AllocateHeapNumber(power_double_double(x, y));
6732
7150
  }
6733
7151
 
@@ -6736,8 +7154,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_pow) {
6736
7154
  RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_pow_cfunction) {
6737
7155
  NoHandleAllocation ha;
6738
7156
  ASSERT(args.length() == 2);
6739
- CONVERT_DOUBLE_CHECKED(x, args[0]);
6740
- CONVERT_DOUBLE_CHECKED(y, args[1]);
7157
+ CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7158
+ CONVERT_DOUBLE_ARG_CHECKED(y, 1);
6741
7159
  if (y == 0) {
6742
7160
  return Smi::FromInt(1);
6743
7161
  } else if (isnan(y) || ((x == 1 || x == -1) && isinf(y))) {
@@ -6796,7 +7214,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_sin) {
6796
7214
  ASSERT(args.length() == 1);
6797
7215
  isolate->counters()->math_sin()->Increment();
6798
7216
 
6799
- CONVERT_DOUBLE_CHECKED(x, args[0]);
7217
+ CONVERT_DOUBLE_ARG_CHECKED(x, 0);
6800
7218
  return isolate->transcendental_cache()->Get(TranscendentalCache::SIN, x);
6801
7219
  }
6802
7220
 
@@ -6806,7 +7224,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_sqrt) {
6806
7224
  ASSERT(args.length() == 1);
6807
7225
  isolate->counters()->math_sqrt()->Increment();
6808
7226
 
6809
- CONVERT_DOUBLE_CHECKED(x, args[0]);
7227
+ CONVERT_DOUBLE_ARG_CHECKED(x, 0);
6810
7228
  return isolate->heap()->AllocateHeapNumber(sqrt(x));
6811
7229
  }
6812
7230
 
@@ -6816,7 +7234,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_tan) {
6816
7234
  ASSERT(args.length() == 1);
6817
7235
  isolate->counters()->math_tan()->Increment();
6818
7236
 
6819
- CONVERT_DOUBLE_CHECKED(x, args[0]);
7237
+ CONVERT_DOUBLE_ARG_CHECKED(x, 0);
6820
7238
  return isolate->transcendental_cache()->Get(TranscendentalCache::TAN, x);
6821
7239
  }
6822
7240
 
@@ -6870,9 +7288,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DateMakeDay) {
6870
7288
  NoHandleAllocation ha;
6871
7289
  ASSERT(args.length() == 3);
6872
7290
 
6873
- CONVERT_SMI_CHECKED(year, args[0]);
6874
- CONVERT_SMI_CHECKED(month, args[1]);
6875
- CONVERT_SMI_CHECKED(date, args[2]);
7291
+ CONVERT_SMI_ARG_CHECKED(year, 0);
7292
+ CONVERT_SMI_ARG_CHECKED(month, 1);
7293
+ CONVERT_SMI_ARG_CHECKED(date, 2);
6876
7294
 
6877
7295
  return Smi::FromInt(MakeDay(year, month, date));
6878
7296
  }
@@ -7169,7 +7587,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DateYMDFromTime) {
7169
7587
  NoHandleAllocation ha;
7170
7588
  ASSERT(args.length() == 2);
7171
7589
 
7172
- CONVERT_DOUBLE_CHECKED(t, args[0]);
7590
+ CONVERT_DOUBLE_ARG_CHECKED(t, 0);
7173
7591
  CONVERT_CHECKED(JSArray, res_array, args[1]);
7174
7592
 
7175
7593
  int year, month, day;
@@ -7189,12 +7607,109 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DateYMDFromTime) {
7189
7607
 
7190
7608
 
7191
7609
  RUNTIME_FUNCTION(MaybeObject*, Runtime_NewArgumentsFast) {
7610
+ HandleScope scope(isolate);
7611
+ ASSERT(args.length() == 3);
7612
+
7613
+ Handle<JSFunction> callee = args.at<JSFunction>(0);
7614
+ Object** parameters = reinterpret_cast<Object**>(args[1]);
7615
+ const int argument_count = Smi::cast(args[2])->value();
7616
+
7617
+ Handle<JSObject> result =
7618
+ isolate->factory()->NewArgumentsObject(callee, argument_count);
7619
+ // Allocate the elements if needed.
7620
+ int parameter_count = callee->shared()->formal_parameter_count();
7621
+ if (argument_count > 0) {
7622
+ if (parameter_count > 0) {
7623
+ int mapped_count = Min(argument_count, parameter_count);
7624
+ Handle<FixedArray> parameter_map =
7625
+ isolate->factory()->NewFixedArray(mapped_count + 2, NOT_TENURED);
7626
+ parameter_map->set_map(
7627
+ isolate->heap()->non_strict_arguments_elements_map());
7628
+
7629
+ Handle<Map> old_map(result->map());
7630
+ Handle<Map> new_map =
7631
+ isolate->factory()->CopyMapDropTransitions(old_map);
7632
+ new_map->set_elements_kind(JSObject::NON_STRICT_ARGUMENTS_ELEMENTS);
7633
+
7634
+ result->set_map(*new_map);
7635
+ result->set_elements(*parameter_map);
7636
+
7637
+ // Store the context and the arguments array at the beginning of the
7638
+ // parameter map.
7639
+ Handle<Context> context(isolate->context());
7640
+ Handle<FixedArray> arguments =
7641
+ isolate->factory()->NewFixedArray(argument_count, NOT_TENURED);
7642
+ parameter_map->set(0, *context);
7643
+ parameter_map->set(1, *arguments);
7644
+
7645
+ // Loop over the actual parameters backwards.
7646
+ int index = argument_count - 1;
7647
+ while (index >= mapped_count) {
7648
+ // These go directly in the arguments array and have no
7649
+ // corresponding slot in the parameter map.
7650
+ arguments->set(index, *(parameters - index - 1));
7651
+ --index;
7652
+ }
7653
+
7654
+ ScopeInfo<> scope_info(callee->shared()->scope_info());
7655
+ while (index >= 0) {
7656
+ // Detect duplicate names to the right in the parameter list.
7657
+ Handle<String> name = scope_info.parameter_name(index);
7658
+ int context_slot_count = scope_info.number_of_context_slots();
7659
+ bool duplicate = false;
7660
+ for (int j = index + 1; j < parameter_count; ++j) {
7661
+ if (scope_info.parameter_name(j).is_identical_to(name)) {
7662
+ duplicate = true;
7663
+ break;
7664
+ }
7665
+ }
7666
+
7667
+ if (duplicate) {
7668
+ // This goes directly in the arguments array with a hole in the
7669
+ // parameter map.
7670
+ arguments->set(index, *(parameters - index - 1));
7671
+ parameter_map->set_the_hole(index + 2);
7672
+ } else {
7673
+ // The context index goes in the parameter map with a hole in the
7674
+ // arguments array.
7675
+ int context_index = -1;
7676
+ for (int j = Context::MIN_CONTEXT_SLOTS;
7677
+ j < context_slot_count;
7678
+ ++j) {
7679
+ if (scope_info.context_slot_name(j).is_identical_to(name)) {
7680
+ context_index = j;
7681
+ break;
7682
+ }
7683
+ }
7684
+ ASSERT(context_index >= 0);
7685
+ arguments->set_the_hole(index);
7686
+ parameter_map->set(index + 2, Smi::FromInt(context_index));
7687
+ }
7688
+
7689
+ --index;
7690
+ }
7691
+ } else {
7692
+ // If there is no aliasing, the arguments object elements are not
7693
+ // special in any way.
7694
+ Handle<FixedArray> elements =
7695
+ isolate->factory()->NewFixedArray(argument_count, NOT_TENURED);
7696
+ result->set_elements(*elements);
7697
+ for (int i = 0; i < argument_count; ++i) {
7698
+ elements->set(i, *(parameters - i - 1));
7699
+ }
7700
+ }
7701
+ }
7702
+ return *result;
7703
+ }
7704
+
7705
+
7706
+ RUNTIME_FUNCTION(MaybeObject*, Runtime_NewStrictArgumentsFast) {
7192
7707
  NoHandleAllocation ha;
7193
7708
  ASSERT(args.length() == 3);
7194
7709
 
7195
7710
  JSFunction* callee = JSFunction::cast(args[0]);
7196
7711
  Object** parameters = reinterpret_cast<Object**>(args[1]);
7197
- const int length = Smi::cast(args[2])->value();
7712
+ const int length = args.smi_at(2);
7198
7713
 
7199
7714
  Object* result;
7200
7715
  { MaybeObject* maybe_result =
@@ -7231,10 +7746,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NewClosure) {
7231
7746
  CONVERT_ARG_CHECKED(SharedFunctionInfo, shared, 1);
7232
7747
  CONVERT_BOOLEAN_CHECKED(pretenure, args[2]);
7233
7748
 
7234
- // Allocate global closures in old space and allocate local closures
7235
- // in new space. Additionally pretenure closures that are assigned
7749
+ // The caller ensures that we pretenure closures that are assigned
7236
7750
  // directly to properties.
7237
- pretenure = pretenure || (context->global_context() == *context);
7238
7751
  PretenureFlag pretenure_flag = pretenure ? TENURED : NOT_TENURED;
7239
7752
  Handle<JSFunction> result =
7240
7753
  isolate->factory()->NewFunctionFromSharedFunctionInfo(shared,
@@ -7354,7 +7867,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NewObject) {
7354
7867
 
7355
7868
  // If function should not have prototype, construction is not allowed. In this
7356
7869
  // case generated code bailouts here, since function has no initial_map.
7357
- if (!function->should_have_prototype()) {
7870
+ if (!function->should_have_prototype() && !function->shared()->bound()) {
7358
7871
  Vector< Handle<Object> > arguments = HandleVector(&constructor, 1);
7359
7872
  Handle<Object> type_error =
7360
7873
  isolate->factory()->NewTypeError("not_constructor", arguments);
@@ -7495,7 +8008,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyDeoptimized) {
7495
8008
  ASSERT(args.length() == 1);
7496
8009
  RUNTIME_ASSERT(args[0]->IsSmi());
7497
8010
  Deoptimizer::BailoutType type =
7498
- static_cast<Deoptimizer::BailoutType>(Smi::cast(args[0])->value());
8011
+ static_cast<Deoptimizer::BailoutType>(args.smi_at(0));
7499
8012
  Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate);
7500
8013
  ASSERT(isolate->heap()->IsAllocationAllowed());
7501
8014
  int frames = deoptimizer->output_count();
@@ -7526,7 +8039,6 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NotifyDeoptimized) {
7526
8039
  }
7527
8040
  }
7528
8041
 
7529
- isolate->compilation_cache()->MarkForLazyOptimizing(function);
7530
8042
  if (type == Deoptimizer::EAGER) {
7531
8043
  RUNTIME_ASSERT(function->IsOptimized());
7532
8044
  } else {
@@ -7582,6 +8094,15 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeoptimizeFunction) {
7582
8094
  }
7583
8095
 
7584
8096
 
8097
+ RUNTIME_FUNCTION(MaybeObject*, Runtime_RunningInSimulator) {
8098
+ #if defined(USE_SIMULATOR)
8099
+ return isolate->heap()->true_value();
8100
+ #else
8101
+ return isolate->heap()->false_value();
8102
+ #endif
8103
+ }
8104
+
8105
+
7585
8106
  RUNTIME_FUNCTION(MaybeObject*, Runtime_OptimizeFunctionOnNextCall) {
7586
8107
  HandleScope scope(isolate);
7587
8108
  ASSERT(args.length() == 1);
@@ -7621,7 +8142,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CompileForOnStackReplacement) {
7621
8142
  CONVERT_ARG_CHECKED(JSFunction, function, 0);
7622
8143
 
7623
8144
  // We're not prepared to handle a function with arguments object.
7624
- ASSERT(!function->shared()->scope_info()->HasArgumentsShadow());
8145
+ ASSERT(!function->shared()->uses_arguments());
7625
8146
 
7626
8147
  // We have hit a back edge in an unoptimized frame for a function that was
7627
8148
  // selected for on-stack replacement. Find the unoptimized code object.
@@ -7745,7 +8266,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetConstructorDelegate) {
7745
8266
  }
7746
8267
 
7747
8268
 
7748
- RUNTIME_FUNCTION(MaybeObject*, Runtime_NewContext) {
8269
+ RUNTIME_FUNCTION(MaybeObject*, Runtime_NewFunctionContext) {
7749
8270
  NoHandleAllocation ha;
7750
8271
  ASSERT(args.length() == 1);
7751
8272
 
@@ -7763,50 +8284,97 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NewContext) {
7763
8284
  }
7764
8285
 
7765
8286
 
7766
- MUST_USE_RESULT static MaybeObject* PushContextHelper(Isolate* isolate,
7767
- Object* object,
7768
- bool is_catch_context) {
7769
- // Convert the object to a proper JavaScript object.
7770
- Object* js_object = object;
7771
- if (!js_object->IsJSObject()) {
7772
- MaybeObject* maybe_js_object = js_object->ToObject();
7773
- if (!maybe_js_object->ToObject(&js_object)) {
7774
- if (!Failure::cast(maybe_js_object)->IsInternalError()) {
8287
+ RUNTIME_FUNCTION(MaybeObject*, Runtime_PushWithContext) {
8288
+ NoHandleAllocation ha;
8289
+ ASSERT(args.length() == 2);
8290
+ JSObject* extension_object;
8291
+ if (args[0]->IsJSObject()) {
8292
+ extension_object = JSObject::cast(args[0]);
8293
+ } else {
8294
+ // Convert the object to a proper JavaScript object.
8295
+ MaybeObject* maybe_js_object = args[0]->ToObject();
8296
+ if (!maybe_js_object->To(&extension_object)) {
8297
+ if (Failure::cast(maybe_js_object)->IsInternalError()) {
8298
+ HandleScope scope(isolate);
8299
+ Handle<Object> handle = args.at<Object>(0);
8300
+ Handle<Object> result =
8301
+ isolate->factory()->NewTypeError("with_expression",
8302
+ HandleVector(&handle, 1));
8303
+ return isolate->Throw(*result);
8304
+ } else {
7775
8305
  return maybe_js_object;
7776
8306
  }
7777
- HandleScope scope(isolate);
7778
- Handle<Object> handle(object, isolate);
7779
- Handle<Object> result =
7780
- isolate->factory()->NewTypeError("with_expression",
7781
- HandleVector(&handle, 1));
7782
- return isolate->Throw(*result);
7783
8307
  }
7784
8308
  }
7785
8309
 
7786
- Object* result;
7787
- { MaybeObject* maybe_result = isolate->heap()->AllocateWithContext(
7788
- isolate->context(), JSObject::cast(js_object), is_catch_context);
7789
- if (!maybe_result->ToObject(&result)) return maybe_result;
8310
+ JSFunction* function;
8311
+ if (args[1]->IsSmi()) {
8312
+ // A smi sentinel indicates a context nested inside global code rather
8313
+ // than some function. There is a canonical empty function that can be
8314
+ // gotten from the global context.
8315
+ function = isolate->context()->global_context()->closure();
8316
+ } else {
8317
+ function = JSFunction::cast(args[1]);
7790
8318
  }
7791
8319
 
7792
- Context* context = Context::cast(result);
8320
+ Context* context;
8321
+ MaybeObject* maybe_context =
8322
+ isolate->heap()->AllocateWithContext(function,
8323
+ isolate->context(),
8324
+ extension_object);
8325
+ if (!maybe_context->To(&context)) return maybe_context;
7793
8326
  isolate->set_context(context);
7794
-
7795
- return result;
8327
+ return context;
7796
8328
  }
7797
8329
 
7798
8330
 
7799
- RUNTIME_FUNCTION(MaybeObject*, Runtime_PushContext) {
8331
+ RUNTIME_FUNCTION(MaybeObject*, Runtime_PushCatchContext) {
7800
8332
  NoHandleAllocation ha;
7801
- ASSERT(args.length() == 1);
7802
- return PushContextHelper(isolate, args[0], false);
8333
+ ASSERT(args.length() == 3);
8334
+ String* name = String::cast(args[0]);
8335
+ Object* thrown_object = args[1];
8336
+ JSFunction* function;
8337
+ if (args[2]->IsSmi()) {
8338
+ // A smi sentinel indicates a context nested inside global code rather
8339
+ // than some function. There is a canonical empty function that can be
8340
+ // gotten from the global context.
8341
+ function = isolate->context()->global_context()->closure();
8342
+ } else {
8343
+ function = JSFunction::cast(args[2]);
8344
+ }
8345
+ Context* context;
8346
+ MaybeObject* maybe_context =
8347
+ isolate->heap()->AllocateCatchContext(function,
8348
+ isolate->context(),
8349
+ name,
8350
+ thrown_object);
8351
+ if (!maybe_context->To(&context)) return maybe_context;
8352
+ isolate->set_context(context);
8353
+ return context;
7803
8354
  }
7804
8355
 
7805
8356
 
7806
- RUNTIME_FUNCTION(MaybeObject*, Runtime_PushCatchContext) {
8357
+ RUNTIME_FUNCTION(MaybeObject*, Runtime_PushBlockContext) {
7807
8358
  NoHandleAllocation ha;
7808
- ASSERT(args.length() == 1);
7809
- return PushContextHelper(isolate, args[0], true);
8359
+ ASSERT(args.length() == 2);
8360
+ SerializedScopeInfo* scope_info = SerializedScopeInfo::cast(args[0]);
8361
+ JSFunction* function;
8362
+ if (args[1]->IsSmi()) {
8363
+ // A smi sentinel indicates a context nested inside global code rather
8364
+ // than some function. There is a canonical empty function that can be
8365
+ // gotten from the global context.
8366
+ function = isolate->context()->global_context()->closure();
8367
+ } else {
8368
+ function = JSFunction::cast(args[1]);
8369
+ }
8370
+ Context* context;
8371
+ MaybeObject* maybe_context =
8372
+ isolate->heap()->AllocateBlockContext(function,
8373
+ isolate->context(),
8374
+ scope_info);
8375
+ if (!maybe_context->To(&context)) return maybe_context;
8376
+ isolate->set_context(context);
8377
+ return context;
7810
8378
  }
7811
8379
 
7812
8380
 
@@ -7820,7 +8388,12 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeleteContextSlot) {
7820
8388
  int index;
7821
8389
  PropertyAttributes attributes;
7822
8390
  ContextLookupFlags flags = FOLLOW_CHAINS;
7823
- Handle<Object> holder = context->Lookup(name, flags, &index, &attributes);
8391
+ BindingFlags binding_flags;
8392
+ Handle<Object> holder = context->Lookup(name,
8393
+ flags,
8394
+ &index,
8395
+ &attributes,
8396
+ &binding_flags);
7824
8397
 
7825
8398
  // If the slot was not found the result is true.
7826
8399
  if (holder.is_null()) {
@@ -7841,9 +8414,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeleteContextSlot) {
7841
8414
  // index is non-negative.
7842
8415
  Handle<JSObject> object = Handle<JSObject>::cast(holder);
7843
8416
  if (index >= 0) {
7844
- return object->DeleteElement(index, JSObject::NORMAL_DELETION);
8417
+ return object->DeleteElement(index, JSReceiver::NORMAL_DELETION);
7845
8418
  } else {
7846
- return object->DeleteProperty(*name, JSObject::NORMAL_DELETION);
8419
+ return object->DeleteProperty(*name, JSReceiver::NORMAL_DELETION);
7847
8420
  }
7848
8421
  }
7849
8422
 
@@ -7922,7 +8495,12 @@ static ObjectPair LoadContextSlotHelper(Arguments args,
7922
8495
  int index;
7923
8496
  PropertyAttributes attributes;
7924
8497
  ContextLookupFlags flags = FOLLOW_CHAINS;
7925
- Handle<Object> holder = context->Lookup(name, flags, &index, &attributes);
8498
+ BindingFlags binding_flags;
8499
+ Handle<Object> holder = context->Lookup(name,
8500
+ flags,
8501
+ &index,
8502
+ &attributes,
8503
+ &binding_flags);
7926
8504
 
7927
8505
  // If the index is non-negative, the slot has been found in a local
7928
8506
  // variable or a parameter. Read it from the context object or the
@@ -7938,7 +8516,17 @@ static ObjectPair LoadContextSlotHelper(Arguments args,
7938
8516
  MaybeObject* value = (holder->IsContext())
7939
8517
  ? Context::cast(*holder)->get(index)
7940
8518
  : JSObject::cast(*holder)->GetElement(index);
7941
- return MakePair(Unhole(isolate->heap(), value, attributes), *receiver);
8519
+ // Check for uninitialized bindings.
8520
+ if (holder->IsContext() &&
8521
+ binding_flags == MUTABLE_CHECK_INITIALIZED &&
8522
+ value->IsTheHole()) {
8523
+ Handle<Object> reference_error =
8524
+ isolate->factory()->NewReferenceError("not_defined",
8525
+ HandleVector(&name, 1));
8526
+ return MakePair(isolate->Throw(*reference_error), NULL);
8527
+ } else {
8528
+ return MakePair(Unhole(isolate->heap(), value, attributes), *receiver);
8529
+ }
7942
8530
  }
7943
8531
 
7944
8532
  // If the holder is found, we read the property from it.
@@ -7996,7 +8584,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StoreContextSlot) {
7996
8584
  Handle<Object> value(args[0], isolate);
7997
8585
  CONVERT_ARG_CHECKED(Context, context, 1);
7998
8586
  CONVERT_ARG_CHECKED(String, name, 2);
7999
- CONVERT_SMI_CHECKED(strict_unchecked, args[3]);
8587
+ CONVERT_SMI_ARG_CHECKED(strict_unchecked, 3);
8000
8588
  RUNTIME_ASSERT(strict_unchecked == kStrictMode ||
8001
8589
  strict_unchecked == kNonStrictMode);
8002
8590
  StrictModeFlag strict_mode = static_cast<StrictModeFlag>(strict_unchecked);
@@ -8004,14 +8592,27 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StoreContextSlot) {
8004
8592
  int index;
8005
8593
  PropertyAttributes attributes;
8006
8594
  ContextLookupFlags flags = FOLLOW_CHAINS;
8007
- Handle<Object> holder = context->Lookup(name, flags, &index, &attributes);
8595
+ BindingFlags binding_flags;
8596
+ Handle<Object> holder = context->Lookup(name,
8597
+ flags,
8598
+ &index,
8599
+ &attributes,
8600
+ &binding_flags);
8008
8601
 
8009
8602
  if (index >= 0) {
8010
8603
  if (holder->IsContext()) {
8604
+ Handle<Context> context = Handle<Context>::cast(holder);
8605
+ if (binding_flags == MUTABLE_CHECK_INITIALIZED &&
8606
+ context->get(index)->IsTheHole()) {
8607
+ Handle<Object> error =
8608
+ isolate->factory()->NewReferenceError("not_defined",
8609
+ HandleVector(&name, 1));
8610
+ return isolate->Throw(*error);
8611
+ }
8011
8612
  // Ignore if read_only variable.
8012
8613
  if ((attributes & READ_ONLY) == 0) {
8013
8614
  // Context is a fixed array and set cannot fail.
8014
- Context::cast(*holder)->set(index, *value);
8615
+ context->set(index, *value);
8015
8616
  } else if (strict_mode == kStrictMode) {
8016
8617
  // Setting read only property in strict mode.
8017
8618
  Handle<Object> error =
@@ -8287,13 +8888,14 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DateParseString) {
8287
8888
  FixedArray* output_array = FixedArray::cast(output->elements());
8288
8889
  RUNTIME_ASSERT(output_array->length() >= DateParser::OUTPUT_SIZE);
8289
8890
  bool result;
8290
- if (str->IsAsciiRepresentation()) {
8291
- result = DateParser::Parse(str->ToAsciiVector(),
8891
+ String::FlatContent str_content = str->GetFlatContent();
8892
+ if (str_content.IsAscii()) {
8893
+ result = DateParser::Parse(str_content.ToAsciiVector(),
8292
8894
  output_array,
8293
8895
  isolate->unicode_cache());
8294
8896
  } else {
8295
- ASSERT(str->IsTwoByteRepresentation());
8296
- result = DateParser::Parse(str->ToUC16Vector(),
8897
+ ASSERT(str_content.IsTwoByte());
8898
+ result = DateParser::Parse(str_content.ToUC16Vector(),
8297
8899
  output_array,
8298
8900
  isolate->unicode_cache());
8299
8901
  }
@@ -8310,7 +8912,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DateLocalTimezone) {
8310
8912
  NoHandleAllocation ha;
8311
8913
  ASSERT(args.length() == 1);
8312
8914
 
8313
- CONVERT_DOUBLE_CHECKED(x, args[0]);
8915
+ CONVERT_DOUBLE_ARG_CHECKED(x, 0);
8314
8916
  const char* zone = OS::LocalTimezone(x);
8315
8917
  return isolate->heap()->AllocateStringFromUtf8(CStrVector(zone));
8316
8918
  }
@@ -8328,7 +8930,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DateDaylightSavingsOffset) {
8328
8930
  NoHandleAllocation ha;
8329
8931
  ASSERT(args.length() == 1);
8330
8932
 
8331
- CONVERT_DOUBLE_CHECKED(x, args[0]);
8933
+ CONVERT_DOUBLE_ARG_CHECKED(x, 0);
8332
8934
  return isolate->heap()->NumberFromDouble(OS::DaylightSavingsOffset(x));
8333
8935
  }
8334
8936
 
@@ -8346,7 +8948,14 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_ParseJson) {
8346
8948
  ASSERT_EQ(1, args.length());
8347
8949
  CONVERT_ARG_CHECKED(String, source, 0);
8348
8950
 
8349
- Handle<Object> result = JsonParser::Parse(source);
8951
+ source = Handle<String>(source->TryFlattenGetString());
8952
+ // Optimized fast case where we only have ascii characters.
8953
+ Handle<Object> result;
8954
+ if (source->IsSeqAsciiString()) {
8955
+ result = JsonParser<true>::Parse(source);
8956
+ } else {
8957
+ result = JsonParser<false>::Parse(source);
8958
+ }
8350
8959
  if (result.is_null()) {
8351
8960
  // Syntax error or stack overflow in scanner.
8352
8961
  ASSERT(isolate->has_pending_exception());
@@ -8455,19 +9064,17 @@ RUNTIME_FUNCTION(ObjectPair, Runtime_ResolvePossiblyDirectEval) {
8455
9064
  // it is bound in the global context.
8456
9065
  int index = -1;
8457
9066
  PropertyAttributes attributes = ABSENT;
9067
+ BindingFlags binding_flags;
8458
9068
  while (true) {
8459
9069
  receiver = context->Lookup(isolate->factory()->eval_symbol(),
8460
9070
  FOLLOW_PROTOTYPE_CHAIN,
8461
- &index, &attributes);
9071
+ &index,
9072
+ &attributes,
9073
+ &binding_flags);
8462
9074
  // Stop search when eval is found or when the global context is
8463
9075
  // reached.
8464
9076
  if (attributes != ABSENT || context->IsGlobalContext()) break;
8465
- if (context->is_function_context()) {
8466
- context = Handle<Context>(Context::cast(context->closure()->context()),
8467
- isolate);
8468
- } else {
8469
- context = Handle<Context>(context->previous(), isolate);
8470
- }
9077
+ context = Handle<Context>(context->previous(), isolate);
8471
9078
  }
8472
9079
 
8473
9080
  // If eval could not be resolved, it has been deleted and we need to
@@ -8500,8 +9107,7 @@ RUNTIME_FUNCTION(ObjectPair, Runtime_ResolvePossiblyDirectEval) {
8500
9107
  return CompileGlobalEval(isolate,
8501
9108
  args.at<String>(1),
8502
9109
  args.at<Object>(2),
8503
- static_cast<StrictModeFlag>(
8504
- Smi::cast(args[3])->value()));
9110
+ static_cast<StrictModeFlag>(args.smi_at(3)));
8505
9111
  }
8506
9112
 
8507
9113
 
@@ -8522,8 +9128,7 @@ RUNTIME_FUNCTION(ObjectPair, Runtime_ResolvePossiblyDirectEvalNoLookup) {
8522
9128
  return CompileGlobalEval(isolate,
8523
9129
  args.at<String>(1),
8524
9130
  args.at<Object>(2),
8525
- static_cast<StrictModeFlag>(
8526
- Smi::cast(args[3])->value()));
9131
+ static_cast<StrictModeFlag>(args.smi_at(3)));
8527
9132
  }
8528
9133
 
8529
9134
 
@@ -8584,8 +9189,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_PushIfAbsent) {
8584
9189
  }
8585
9190
  Object* obj;
8586
9191
  // Strict not needed. Used for cycle detection in Array join implementation.
8587
- { MaybeObject* maybe_obj = array->SetFastElement(length, element,
8588
- kNonStrictMode);
9192
+ { MaybeObject* maybe_obj =
9193
+ array->SetFastElement(length, element, kNonStrictMode, true);
8589
9194
  if (!maybe_obj->ToObject(&obj)) return maybe_obj;
8590
9195
  }
8591
9196
  return isolate->heap()->true_value();
@@ -8765,13 +9370,13 @@ static void IterateExternalArrayElements(Isolate* isolate,
8765
9370
  if (elements_are_guaranteed_smis) {
8766
9371
  for (uint32_t j = 0; j < len; j++) {
8767
9372
  HandleScope loop_scope;
8768
- Handle<Smi> e(Smi::FromInt(static_cast<int>(array->get(j))));
9373
+ Handle<Smi> e(Smi::FromInt(static_cast<int>(array->get_scalar(j))));
8769
9374
  visitor->visit(j, e);
8770
9375
  }
8771
9376
  } else {
8772
9377
  for (uint32_t j = 0; j < len; j++) {
8773
9378
  HandleScope loop_scope;
8774
- int64_t val = static_cast<int64_t>(array->get(j));
9379
+ int64_t val = static_cast<int64_t>(array->get_scalar(j));
8775
9380
  if (Smi::IsValid(static_cast<intptr_t>(val))) {
8776
9381
  Handle<Smi> e(Smi::FromInt(static_cast<int>(val)));
8777
9382
  visitor->visit(j, e);
@@ -8785,7 +9390,7 @@ static void IterateExternalArrayElements(Isolate* isolate,
8785
9390
  } else {
8786
9391
  for (uint32_t j = 0; j < len; j++) {
8787
9392
  HandleScope loop_scope(isolate);
8788
- Handle<Object> e = isolate->factory()->NewNumber(array->get(j));
9393
+ Handle<Object> e = isolate->factory()->NewNumber(array->get_scalar(j));
8789
9394
  visitor->visit(j, e);
8790
9395
  }
8791
9396
  }
@@ -8971,7 +9576,7 @@ static bool IterateElements(Isolate* isolate,
8971
9576
  Handle<ExternalPixelArray> pixels(ExternalPixelArray::cast(
8972
9577
  receiver->elements()));
8973
9578
  for (uint32_t j = 0; j < length; j++) {
8974
- Handle<Smi> e(Smi::FromInt(pixels->get(j)));
9579
+ Handle<Smi> e(Smi::FromInt(pixels->get_scalar(j)));
8975
9580
  visitor->visit(j, e);
8976
9581
  }
8977
9582
  break;
@@ -9150,11 +9755,14 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_MoveArrayContents) {
9150
9755
  ASSERT(args.length() == 2);
9151
9756
  CONVERT_CHECKED(JSArray, from, args[0]);
9152
9757
  CONVERT_CHECKED(JSArray, to, args[1]);
9153
- HeapObject* new_elements = from->elements();
9758
+ FixedArrayBase* new_elements = from->elements();
9154
9759
  MaybeObject* maybe_new_map;
9155
9760
  if (new_elements->map() == isolate->heap()->fixed_array_map() ||
9156
9761
  new_elements->map() == isolate->heap()->fixed_cow_array_map()) {
9157
9762
  maybe_new_map = to->map()->GetFastElementsMap();
9763
+ } else if (new_elements->map() ==
9764
+ isolate->heap()->fixed_double_array_map()) {
9765
+ maybe_new_map = to->map()->GetFastDoubleElementsMap();
9158
9766
  } else {
9159
9767
  maybe_new_map = to->map()->GetSlowElementsMap();
9160
9768
  }
@@ -9242,12 +9850,13 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetArrayKeys) {
9242
9850
  }
9243
9851
  return *isolate->factory()->NewJSArrayWithElements(keys);
9244
9852
  } else {
9245
- ASSERT(array->HasFastElements());
9853
+ ASSERT(array->HasFastElements() || array->HasFastDoubleElements());
9246
9854
  Handle<FixedArray> single_interval = isolate->factory()->NewFixedArray(2);
9247
9855
  // -1 means start of array.
9248
9856
  single_interval->set(0, Smi::FromInt(-1));
9857
+ FixedArrayBase* elements = FixedArrayBase::cast(array->elements());
9249
9858
  uint32_t actual_length =
9250
- static_cast<uint32_t>(FixedArray::cast(array->elements())->length());
9859
+ static_cast<uint32_t>(elements->length());
9251
9860
  uint32_t min_length = actual_length < length ? actual_length : length;
9252
9861
  Handle<Object> length_object =
9253
9862
  isolate->factory()->NewNumber(static_cast<double>(min_length));
@@ -9485,9 +10094,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetPropertyDetails) {
9485
10094
  details->set(0, *value);
9486
10095
  details->set(1, property_details);
9487
10096
  if (hasJavaScriptAccessors) {
9488
- details->set(2,
9489
- caught_exception ? isolate->heap()->true_value()
9490
- : isolate->heap()->false_value());
10097
+ details->set(2, isolate->heap()->ToBoolean(caught_exception));
9491
10098
  details->set(3, FixedArray::cast(*result_callback_obj)->get(0));
9492
10099
  details->set(4, FixedArray::cast(*result_callback_obj)->get(1));
9493
10100
  }
@@ -9611,11 +10218,79 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameCount) {
9611
10218
  // If there is no JavaScript stack frame count is 0.
9612
10219
  return Smi::FromInt(0);
9613
10220
  }
9614
- for (JavaScriptFrameIterator it(isolate, id); !it.done(); it.Advance()) n++;
10221
+
10222
+ for (JavaScriptFrameIterator it(isolate, id); !it.done(); it.Advance()) {
10223
+ n += it.frame()->GetInlineCount();
10224
+ }
9615
10225
  return Smi::FromInt(n);
9616
10226
  }
9617
10227
 
9618
10228
 
10229
+ class FrameInspector {
10230
+ public:
10231
+ FrameInspector(JavaScriptFrame* frame,
10232
+ int inlined_frame_index,
10233
+ Isolate* isolate)
10234
+ : frame_(frame), deoptimized_frame_(NULL), isolate_(isolate) {
10235
+ // Calculate the deoptimized frame.
10236
+ if (frame->is_optimized()) {
10237
+ deoptimized_frame_ = Deoptimizer::DebuggerInspectableFrame(
10238
+ frame, inlined_frame_index, isolate);
10239
+ }
10240
+ has_adapted_arguments_ = frame_->has_adapted_arguments();
10241
+ is_optimized_ = frame_->is_optimized();
10242
+ }
10243
+
10244
+ ~FrameInspector() {
10245
+ // Get rid of the calculated deoptimized frame if any.
10246
+ if (deoptimized_frame_ != NULL) {
10247
+ Deoptimizer::DeleteDebuggerInspectableFrame(deoptimized_frame_,
10248
+ isolate_);
10249
+ }
10250
+ }
10251
+
10252
+ int GetParametersCount() {
10253
+ return is_optimized_
10254
+ ? deoptimized_frame_->parameters_count()
10255
+ : frame_->ComputeParametersCount();
10256
+ }
10257
+ int expression_count() { return deoptimized_frame_->expression_count(); }
10258
+ Object* GetFunction() {
10259
+ return is_optimized_
10260
+ ? deoptimized_frame_->GetFunction()
10261
+ : frame_->function();
10262
+ }
10263
+ Object* GetParameter(int index) {
10264
+ return is_optimized_
10265
+ ? deoptimized_frame_->GetParameter(index)
10266
+ : frame_->GetParameter(index);
10267
+ }
10268
+ Object* GetExpression(int index) {
10269
+ return is_optimized_
10270
+ ? deoptimized_frame_->GetExpression(index)
10271
+ : frame_->GetExpression(index);
10272
+ }
10273
+
10274
+ // To inspect all the provided arguments the frame might need to be
10275
+ // replaced with the arguments frame.
10276
+ void SetArgumentsFrame(JavaScriptFrame* frame) {
10277
+ ASSERT(has_adapted_arguments_);
10278
+ frame_ = frame;
10279
+ is_optimized_ = frame_->is_optimized();
10280
+ ASSERT(!is_optimized_);
10281
+ }
10282
+
10283
+ private:
10284
+ JavaScriptFrame* frame_;
10285
+ DeoptimizedFrameInfo* deoptimized_frame_;
10286
+ Isolate* isolate_;
10287
+ bool is_optimized_;
10288
+ bool has_adapted_arguments_;
10289
+
10290
+ DISALLOW_COPY_AND_ASSIGN(FrameInspector);
10291
+ };
10292
+
10293
+
9619
10294
  static const int kFrameDetailsFrameIdIndex = 0;
9620
10295
  static const int kFrameDetailsReceiverIndex = 1;
9621
10296
  static const int kFrameDetailsFunctionIndex = 2;
@@ -9624,7 +10299,7 @@ static const int kFrameDetailsLocalCountIndex = 4;
9624
10299
  static const int kFrameDetailsSourcePositionIndex = 5;
9625
10300
  static const int kFrameDetailsConstructCallIndex = 6;
9626
10301
  static const int kFrameDetailsAtReturnIndex = 7;
9627
- static const int kFrameDetailsDebuggerFrameIndex = 8;
10302
+ static const int kFrameDetailsFlagsIndex = 8;
9628
10303
  static const int kFrameDetailsFirstDynamicIndex = 9;
9629
10304
 
9630
10305
  // Return an array with frame details
@@ -9640,7 +10315,7 @@ static const int kFrameDetailsFirstDynamicIndex = 9;
9640
10315
  // 5: Source position
9641
10316
  // 6: Constructor call
9642
10317
  // 7: Is at return
9643
- // 8: Debugger frame
10318
+ // 8: Flags
9644
10319
  // Arguments name, value
9645
10320
  // Locals name, value
9646
10321
  // Return value if any
@@ -9663,16 +10338,22 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) {
9663
10338
  // If there are no JavaScript stack frames return undefined.
9664
10339
  return heap->undefined_value();
9665
10340
  }
10341
+
10342
+ int inlined_frame_index = 0; // Inlined frame index in optimized frame.
10343
+
9666
10344
  int count = 0;
9667
10345
  JavaScriptFrameIterator it(isolate, id);
9668
10346
  for (; !it.done(); it.Advance()) {
9669
- if (count == index) break;
9670
- count++;
10347
+ if (index < count + it.frame()->GetInlineCount()) break;
10348
+ count += it.frame()->GetInlineCount();
9671
10349
  }
9672
10350
  if (it.done()) return heap->undefined_value();
9673
10351
 
9674
- bool is_optimized_frame =
9675
- it.frame()->LookupCode()->kind() == Code::OPTIMIZED_FUNCTION;
10352
+ if (it.frame()->is_optimized()) {
10353
+ inlined_frame_index =
10354
+ it.frame()->GetInlineCount() - (index - count) - 1;
10355
+ }
10356
+ FrameInspector frame_inspector(it.frame(), inlined_frame_index, isolate);
9676
10357
 
9677
10358
  // Traverse the saved contexts chain to find the active context for the
9678
10359
  // selected frame.
@@ -9689,17 +10370,18 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) {
9689
10370
  int position =
9690
10371
  it.frame()->LookupCode()->SourcePosition(it.frame()->pc());
9691
10372
 
9692
- // Check for constructor frame.
9693
- bool constructor = it.frame()->IsConstructor();
10373
+ // Check for constructor frame. Inlined frames cannot be construct calls.
10374
+ bool inlined_frame =
10375
+ it.frame()->is_optimized() && inlined_frame_index != 0;
10376
+ bool constructor = !inlined_frame && it.frame()->IsConstructor();
9694
10377
 
9695
10378
  // Get scope info and read from it for local variable information.
9696
10379
  Handle<JSFunction> function(JSFunction::cast(it.frame()->function()));
9697
- Handle<SerializedScopeInfo> scope_info(function->shared()->scope_info());
10380
+ Handle<SharedFunctionInfo> shared(function->shared());
10381
+ Handle<SerializedScopeInfo> scope_info(shared->scope_info());
10382
+ ASSERT(*scope_info != SerializedScopeInfo::Empty());
9698
10383
  ScopeInfo<> info(*scope_info);
9699
10384
 
9700
- // Get the context.
9701
- Handle<Context> context(Context::cast(it.frame()->context()));
9702
-
9703
10385
  // Get the locals names and values into a temporary array.
9704
10386
  //
9705
10387
  // TODO(1240907): Hide compiler-introduced stack variables
@@ -9708,31 +10390,20 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) {
9708
10390
  Handle<FixedArray> locals =
9709
10391
  isolate->factory()->NewFixedArray(info.NumberOfLocals() * 2);
9710
10392
 
9711
- // Fill in the names of the locals.
9712
- for (int i = 0; i < info.NumberOfLocals(); i++) {
10393
+ // Fill in the values of the locals.
10394
+ int i = 0;
10395
+ for (; i < info.number_of_stack_slots(); ++i) {
10396
+ // Use the value from the stack.
9713
10397
  locals->set(i * 2, *info.LocalName(i));
10398
+ locals->set(i * 2 + 1, frame_inspector.GetExpression(i));
9714
10399
  }
9715
-
9716
- // Fill in the values of the locals.
9717
- for (int i = 0; i < info.NumberOfLocals(); i++) {
9718
- if (is_optimized_frame) {
9719
- // If we are inspecting an optimized frame use undefined as the
9720
- // value for all locals.
9721
- //
9722
- // TODO(1140): We should be able to get the correct values
9723
- // for locals in optimized frames.
9724
- locals->set(i * 2 + 1, isolate->heap()->undefined_value());
9725
- } else if (i < info.number_of_stack_slots()) {
9726
- // Get the value from the stack.
9727
- locals->set(i * 2 + 1, it.frame()->GetExpression(i));
9728
- } else {
9729
- // Traverse the context chain to the function context as all local
9730
- // variables stored in the context will be on the function context.
10400
+ if (i < info.NumberOfLocals()) {
10401
+ // Get the context containing declarations.
10402
+ Handle<Context> context(
10403
+ Context::cast(it.frame()->context())->declaration_context());
10404
+ for (; i < info.NumberOfLocals(); ++i) {
9731
10405
  Handle<String> name = info.LocalName(i);
9732
- while (!context->is_function_context()) {
9733
- context = Handle<Context>(context->previous());
9734
- }
9735
- ASSERT(context->is_function_context());
10406
+ locals->set(i * 2, *name);
9736
10407
  locals->set(i * 2 + 1,
9737
10408
  context->get(scope_info->ContextSlotIndex(*name, NULL)));
9738
10409
  }
@@ -9741,7 +10412,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) {
9741
10412
  // Check whether this frame is positioned at return. If not top
9742
10413
  // frame or if the frame is optimized it cannot be at a return.
9743
10414
  bool at_return = false;
9744
- if (!is_optimized_frame && index == 0) {
10415
+ if (!it.frame()->is_optimized() && index == 0) {
9745
10416
  at_return = isolate->debug()->IsBreakAtReturn(it.frame());
9746
10417
  }
9747
10418
 
@@ -9781,14 +10452,22 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) {
9781
10452
  // the provided parameters whereas the function frame always have the number
9782
10453
  // of arguments matching the functions parameters. The rest of the
9783
10454
  // information (except for what is collected above) is the same.
9784
- it.AdvanceToArgumentsFrame();
10455
+ if (it.frame()->has_adapted_arguments()) {
10456
+ it.AdvanceToArgumentsFrame();
10457
+ frame_inspector.SetArgumentsFrame(it.frame());
10458
+ }
9785
10459
 
9786
10460
  // Find the number of arguments to fill. At least fill the number of
9787
10461
  // parameters for the function and fill more if more parameters are provided.
9788
10462
  int argument_count = info.number_of_parameters();
9789
- if (argument_count < it.frame()->ComputeParametersCount()) {
9790
- argument_count = it.frame()->ComputeParametersCount();
10463
+ if (argument_count < frame_inspector.GetParametersCount()) {
10464
+ argument_count = frame_inspector.GetParametersCount();
10465
+ }
10466
+ #ifdef DEBUG
10467
+ if (it.frame()->is_optimized()) {
10468
+ ASSERT_EQ(argument_count, frame_inspector.GetParametersCount());
9791
10469
  }
10470
+ #endif
9792
10471
 
9793
10472
  // Calculate the size of the result.
9794
10473
  int details_size = kFrameDetailsFirstDynamicIndex +
@@ -9800,7 +10479,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) {
9800
10479
  details->set(kFrameDetailsFrameIdIndex, *frame_id);
9801
10480
 
9802
10481
  // Add the function (same as in function frame).
9803
- details->set(kFrameDetailsFunctionIndex, it.frame()->function());
10482
+ details->set(kFrameDetailsFunctionIndex, frame_inspector.GetFunction());
9804
10483
 
9805
10484
  // Add the arguments count.
9806
10485
  details->set(kFrameDetailsArgumentCountIndex, Smi::FromInt(argument_count));
@@ -9822,10 +10501,19 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) {
9822
10501
  // Add the at return information.
9823
10502
  details->set(kFrameDetailsAtReturnIndex, heap->ToBoolean(at_return));
9824
10503
 
9825
- // Add information on whether this frame is invoked in the debugger context.
9826
- details->set(kFrameDetailsDebuggerFrameIndex,
9827
- heap->ToBoolean(*save->context() ==
9828
- *isolate->debug()->debug_context()));
10504
+ // Add flags to indicate information on whether this frame is
10505
+ // bit 0: invoked in the debugger context.
10506
+ // bit 1: optimized frame.
10507
+ // bit 2: inlined in optimized frame
10508
+ int flags = 0;
10509
+ if (*save->context() == *isolate->debug()->debug_context()) {
10510
+ flags |= 1 << 0;
10511
+ }
10512
+ if (it.frame()->is_optimized()) {
10513
+ flags |= 1 << 1;
10514
+ flags |= inlined_frame_index << 2;
10515
+ }
10516
+ details->set(kFrameDetailsFlagsIndex, Smi::FromInt(flags));
9829
10517
 
9830
10518
  // Fill the dynamic part.
9831
10519
  int details_index = kFrameDetailsFirstDynamicIndex;
@@ -9839,14 +10527,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) {
9839
10527
  details->set(details_index++, heap->undefined_value());
9840
10528
  }
9841
10529
 
9842
- // Parameter value. If we are inspecting an optimized frame, use
9843
- // undefined as the value.
9844
- //
9845
- // TODO(3141533): We should be able to get the actual parameter
9846
- // value for optimized frames.
9847
- if (!is_optimized_frame &&
9848
- (i < it.frame()->ComputeParametersCount())) {
9849
- details->set(details_index++, it.frame()->GetParameter(i));
10530
+ // Parameter value.
10531
+ if (i < it.frame()->ComputeParametersCount()) {
10532
+ // Get the value from the stack.
10533
+ details->set(details_index++, frame_inspector.GetParameter(i));
9850
10534
  } else {
9851
10535
  details->set(details_index++, heap->undefined_value());
9852
10536
  }
@@ -9866,10 +10550,11 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFrameDetails) {
9866
10550
  // THIS MUST BE DONE LAST SINCE WE MIGHT ADVANCE
9867
10551
  // THE FRAME ITERATOR TO WRAP THE RECEIVER.
9868
10552
  Handle<Object> receiver(it.frame()->receiver(), isolate);
9869
- if (!receiver->IsJSObject()) {
9870
- // If the receiver is NOT a JSObject we have hit an optimization
9871
- // where a value object is not converted into a wrapped JS objects.
9872
- // To hide this optimization from the debugger, we wrap the receiver
10553
+ if (!receiver->IsJSObject() && !shared->strict_mode() && !shared->native()) {
10554
+ // If the receiver is not a JSObject and the function is not a
10555
+ // builtin or strict-mode we have hit an optimization where a
10556
+ // value object is not converted into a wrapped JS objects. To
10557
+ // hide this optimization from the debugger, we wrap the receiver
9873
10558
  // by creating correct wrapper object based on the calling frame's
9874
10559
  // global context.
9875
10560
  it.Advance();
@@ -9899,18 +10584,14 @@ static bool CopyContextLocalsToScopeObject(
9899
10584
  int context_index = serialized_scope_info->ContextSlotIndex(
9900
10585
  *scope_info.context_slot_name(i), NULL);
9901
10586
 
9902
- // Don't include the arguments shadow (.arguments) context variable.
9903
- if (*scope_info.context_slot_name(i) !=
9904
- isolate->heap()->arguments_shadow_symbol()) {
9905
- RETURN_IF_EMPTY_HANDLE_VALUE(
9906
- isolate,
9907
- SetProperty(scope_object,
9908
- scope_info.context_slot_name(i),
9909
- Handle<Object>(context->get(context_index), isolate),
9910
- NONE,
9911
- kNonStrictMode),
9912
- false);
9913
- }
10587
+ RETURN_IF_EMPTY_HANDLE_VALUE(
10588
+ isolate,
10589
+ SetProperty(scope_object,
10590
+ scope_info.context_slot_name(i),
10591
+ Handle<Object>(context->get(context_index), isolate),
10592
+ NONE,
10593
+ kNonStrictMode),
10594
+ false);
9914
10595
  }
9915
10596
 
9916
10597
  return true;
@@ -9919,12 +10600,15 @@ static bool CopyContextLocalsToScopeObject(
9919
10600
 
9920
10601
  // Create a plain JSObject which materializes the local scope for the specified
9921
10602
  // frame.
9922
- static Handle<JSObject> MaterializeLocalScope(Isolate* isolate,
9923
- JavaScriptFrame* frame) {
10603
+ static Handle<JSObject> MaterializeLocalScope(
10604
+ Isolate* isolate,
10605
+ JavaScriptFrame* frame,
10606
+ int inlined_frame_index) {
9924
10607
  Handle<JSFunction> function(JSFunction::cast(frame->function()));
9925
10608
  Handle<SharedFunctionInfo> shared(function->shared());
9926
10609
  Handle<SerializedScopeInfo> serialized_scope_info(shared->scope_info());
9927
10610
  ScopeInfo<> scope_info(*serialized_scope_info);
10611
+ FrameInspector frame_inspector(frame, inlined_frame_index, isolate);
9928
10612
 
9929
10613
  // Allocate and initialize a JSObject with all the arguments, stack locals
9930
10614
  // heap locals and extension properties of the debugged function.
@@ -9937,55 +10621,58 @@ static Handle<JSObject> MaterializeLocalScope(Isolate* isolate,
9937
10621
  isolate,
9938
10622
  SetProperty(local_scope,
9939
10623
  scope_info.parameter_name(i),
9940
- Handle<Object>(frame->GetParameter(i), isolate),
10624
+ Handle<Object>(frame_inspector.GetParameter(i)),
9941
10625
  NONE,
9942
10626
  kNonStrictMode),
9943
10627
  Handle<JSObject>());
9944
10628
  }
9945
10629
 
9946
10630
  // Second fill all stack locals.
9947
- for (int i = 0; i < scope_info.number_of_stack_slots(); i++) {
10631
+ for (int i = 0; i < scope_info.number_of_stack_slots(); ++i) {
9948
10632
  RETURN_IF_EMPTY_HANDLE_VALUE(
9949
10633
  isolate,
9950
10634
  SetProperty(local_scope,
9951
10635
  scope_info.stack_slot_name(i),
9952
- Handle<Object>(frame->GetExpression(i), isolate),
10636
+ Handle<Object>(frame_inspector.GetExpression(i)),
9953
10637
  NONE,
9954
10638
  kNonStrictMode),
9955
10639
  Handle<JSObject>());
9956
10640
  }
9957
10641
 
9958
- // Third fill all context locals.
9959
- Handle<Context> frame_context(Context::cast(frame->context()));
9960
- Handle<Context> function_context(frame_context->fcontext());
9961
- if (!CopyContextLocalsToScopeObject(isolate,
9962
- serialized_scope_info, scope_info,
9963
- function_context, local_scope)) {
9964
- return Handle<JSObject>();
9965
- }
9966
-
9967
- // Finally copy any properties from the function context extension. This will
9968
- // be variables introduced by eval.
9969
- if (function_context->closure() == *function) {
9970
- if (function_context->has_extension() &&
9971
- !function_context->IsGlobalContext()) {
9972
- Handle<JSObject> ext(JSObject::cast(function_context->extension()));
9973
- Handle<FixedArray> keys = GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS);
9974
- for (int i = 0; i < keys->length(); i++) {
9975
- // Names of variables introduced by eval are strings.
9976
- ASSERT(keys->get(i)->IsString());
9977
- Handle<String> key(String::cast(keys->get(i)));
9978
- RETURN_IF_EMPTY_HANDLE_VALUE(
9979
- isolate,
9980
- SetProperty(local_scope,
9981
- key,
9982
- GetProperty(ext, key),
9983
- NONE,
9984
- kNonStrictMode),
9985
- Handle<JSObject>());
10642
+ if (scope_info.number_of_context_slots() > Context::MIN_CONTEXT_SLOTS) {
10643
+ // Third fill all context locals.
10644
+ Handle<Context> frame_context(Context::cast(frame->context()));
10645
+ Handle<Context> function_context(frame_context->declaration_context());
10646
+ if (!CopyContextLocalsToScopeObject(isolate,
10647
+ serialized_scope_info, scope_info,
10648
+ function_context, local_scope)) {
10649
+ return Handle<JSObject>();
10650
+ }
10651
+
10652
+ // Finally copy any properties from the function context extension.
10653
+ // These will be variables introduced by eval.
10654
+ if (function_context->closure() == *function) {
10655
+ if (function_context->has_extension() &&
10656
+ !function_context->IsGlobalContext()) {
10657
+ Handle<JSObject> ext(JSObject::cast(function_context->extension()));
10658
+ Handle<FixedArray> keys = GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS);
10659
+ for (int i = 0; i < keys->length(); i++) {
10660
+ // Names of variables introduced by eval are strings.
10661
+ ASSERT(keys->get(i)->IsString());
10662
+ Handle<String> key(String::cast(keys->get(i)));
10663
+ RETURN_IF_EMPTY_HANDLE_VALUE(
10664
+ isolate,
10665
+ SetProperty(local_scope,
10666
+ key,
10667
+ GetProperty(ext, key),
10668
+ NONE,
10669
+ kNonStrictMode),
10670
+ Handle<JSObject>());
10671
+ }
9986
10672
  }
9987
10673
  }
9988
10674
  }
10675
+
9989
10676
  return local_scope;
9990
10677
  }
9991
10678
 
@@ -9994,7 +10681,7 @@ static Handle<JSObject> MaterializeLocalScope(Isolate* isolate,
9994
10681
  // context.
9995
10682
  static Handle<JSObject> MaterializeClosure(Isolate* isolate,
9996
10683
  Handle<Context> context) {
9997
- ASSERT(context->is_function_context());
10684
+ ASSERT(context->IsFunctionContext());
9998
10685
 
9999
10686
  Handle<SharedFunctionInfo> shared(context->closure()->shared());
10000
10687
  Handle<SerializedScopeInfo> serialized_scope_info(shared->scope_info());
@@ -10005,29 +10692,6 @@ static Handle<JSObject> MaterializeClosure(Isolate* isolate,
10005
10692
  Handle<JSObject> closure_scope =
10006
10693
  isolate->factory()->NewJSObject(isolate->object_function());
10007
10694
 
10008
- // Check whether the arguments shadow object exists.
10009
- int arguments_shadow_index =
10010
- shared->scope_info()->ContextSlotIndex(
10011
- isolate->heap()->arguments_shadow_symbol(), NULL);
10012
- if (arguments_shadow_index >= 0) {
10013
- // In this case all the arguments are available in the arguments shadow
10014
- // object.
10015
- Handle<JSObject> arguments_shadow(
10016
- JSObject::cast(context->get(arguments_shadow_index)));
10017
- for (int i = 0; i < scope_info.number_of_parameters(); ++i) {
10018
- // We don't expect exception-throwing getters on the arguments shadow.
10019
- Object* element = arguments_shadow->GetElement(i)->ToObjectUnchecked();
10020
- RETURN_IF_EMPTY_HANDLE_VALUE(
10021
- isolate,
10022
- SetProperty(closure_scope,
10023
- scope_info.parameter_name(i),
10024
- Handle<Object>(element, isolate),
10025
- NONE,
10026
- kNonStrictMode),
10027
- Handle<JSObject>());
10028
- }
10029
- }
10030
-
10031
10695
  // Fill all context locals to the context extension.
10032
10696
  if (!CopyContextLocalsToScopeObject(isolate,
10033
10697
  serialized_scope_info, scope_info,
@@ -10059,6 +10723,51 @@ static Handle<JSObject> MaterializeClosure(Isolate* isolate,
10059
10723
  }
10060
10724
 
10061
10725
 
10726
+ // Create a plain JSObject which materializes the scope for the specified
10727
+ // catch context.
10728
+ static Handle<JSObject> MaterializeCatchScope(Isolate* isolate,
10729
+ Handle<Context> context) {
10730
+ ASSERT(context->IsCatchContext());
10731
+ Handle<String> name(String::cast(context->extension()));
10732
+ Handle<Object> thrown_object(context->get(Context::THROWN_OBJECT_INDEX));
10733
+ Handle<JSObject> catch_scope =
10734
+ isolate->factory()->NewJSObject(isolate->object_function());
10735
+ RETURN_IF_EMPTY_HANDLE_VALUE(
10736
+ isolate,
10737
+ SetProperty(catch_scope, name, thrown_object, NONE, kNonStrictMode),
10738
+ Handle<JSObject>());
10739
+ return catch_scope;
10740
+ }
10741
+
10742
+
10743
+ // Create a plain JSObject which materializes the block scope for the specified
10744
+ // block context.
10745
+ static Handle<JSObject> MaterializeBlockScope(
10746
+ Isolate* isolate,
10747
+ Handle<Context> context) {
10748
+ ASSERT(context->IsBlockContext());
10749
+ Handle<SerializedScopeInfo> serialized_scope_info(
10750
+ SerializedScopeInfo::cast(context->extension()));
10751
+ ScopeInfo<> scope_info(*serialized_scope_info);
10752
+
10753
+ // Allocate and initialize a JSObject with all the arguments, stack locals
10754
+ // heap locals and extension properties of the debugged function.
10755
+ Handle<JSObject> block_scope =
10756
+ isolate->factory()->NewJSObject(isolate->object_function());
10757
+
10758
+ // Fill all context locals.
10759
+ if (scope_info.number_of_context_slots() > Context::MIN_CONTEXT_SLOTS) {
10760
+ if (!CopyContextLocalsToScopeObject(isolate,
10761
+ serialized_scope_info, scope_info,
10762
+ context, block_scope)) {
10763
+ return Handle<JSObject>();
10764
+ }
10765
+ }
10766
+
10767
+ return block_scope;
10768
+ }
10769
+
10770
+
10062
10771
  // Iterate over the actual scopes visible from a stack frame. All scopes are
10063
10772
  // backed by an actual context except the local scope, which is inserted
10064
10773
  // "artifically" in the context chain.
@@ -10069,16 +10778,16 @@ class ScopeIterator {
10069
10778
  ScopeTypeLocal,
10070
10779
  ScopeTypeWith,
10071
10780
  ScopeTypeClosure,
10072
- // Every catch block contains an implicit with block (its parameter is
10073
- // a JSContextExtensionObject) that extends current scope with a variable
10074
- // holding exception object. Such with blocks are treated as scopes of their
10075
- // own type.
10076
- ScopeTypeCatch
10781
+ ScopeTypeCatch,
10782
+ ScopeTypeBlock
10077
10783
  };
10078
10784
 
10079
- ScopeIterator(Isolate* isolate, JavaScriptFrame* frame)
10785
+ ScopeIterator(Isolate* isolate,
10786
+ JavaScriptFrame* frame,
10787
+ int inlined_frame_index)
10080
10788
  : isolate_(isolate),
10081
10789
  frame_(frame),
10790
+ inlined_frame_index_(inlined_frame_index),
10082
10791
  function_(JSFunction::cast(frame->function())),
10083
10792
  context_(Context::cast(frame->context())),
10084
10793
  local_done_(false),
@@ -10093,11 +10802,13 @@ class ScopeIterator {
10093
10802
  int index = function_->shared()->scope_info()->
10094
10803
  StackSlotIndex(isolate_->heap()->result_symbol());
10095
10804
  at_local_ = index < 0;
10096
- } else if (context_->is_function_context()) {
10805
+ } else if (context_->IsFunctionContext()) {
10097
10806
  at_local_ = true;
10098
10807
  } else if (context_->closure() != *function_) {
10099
- // The context_ is a with block from the outer function.
10100
- ASSERT(context_->has_extension());
10808
+ // The context_ is a block or with or catch block from the outer function.
10809
+ ASSERT(context_->IsWithContext() ||
10810
+ context_->IsCatchContext() ||
10811
+ context_->IsBlockContext());
10101
10812
  at_local_ = true;
10102
10813
  }
10103
10814
  }
@@ -10127,16 +10838,12 @@ class ScopeIterator {
10127
10838
  }
10128
10839
 
10129
10840
  // Move to the next context.
10130
- if (context_->is_function_context()) {
10131
- context_ = Handle<Context>(Context::cast(context_->closure()->context()));
10132
- } else {
10133
- context_ = Handle<Context>(context_->previous());
10134
- }
10841
+ context_ = Handle<Context>(context_->previous(), isolate_);
10135
10842
 
10136
10843
  // If passing the local scope indicate that the current scope is now the
10137
10844
  // local scope.
10138
10845
  if (!local_done_ &&
10139
- (context_->IsGlobalContext() || (context_->is_function_context()))) {
10846
+ (context_->IsGlobalContext() || context_->IsFunctionContext())) {
10140
10847
  at_local_ = true;
10141
10848
  }
10142
10849
  }
@@ -10150,18 +10857,16 @@ class ScopeIterator {
10150
10857
  ASSERT(context_->global()->IsGlobalObject());
10151
10858
  return ScopeTypeGlobal;
10152
10859
  }
10153
- if (context_->is_function_context()) {
10860
+ if (context_->IsFunctionContext()) {
10154
10861
  return ScopeTypeClosure;
10155
10862
  }
10156
- ASSERT(context_->has_extension());
10157
- // Current scope is either an explicit with statement or a with statement
10158
- // implicitely generated for a catch block.
10159
- // If the extension object here is a JSContextExtensionObject then
10160
- // current with statement is one frome a catch block otherwise it's a
10161
- // regular with statement.
10162
- if (context_->extension()->IsJSContextExtensionObject()) {
10863
+ if (context_->IsCatchContext()) {
10163
10864
  return ScopeTypeCatch;
10164
10865
  }
10866
+ if (context_->IsBlockContext()) {
10867
+ return ScopeTypeBlock;
10868
+ }
10869
+ ASSERT(context_->IsWithContext());
10165
10870
  return ScopeTypeWith;
10166
10871
  }
10167
10872
 
@@ -10170,20 +10875,19 @@ class ScopeIterator {
10170
10875
  switch (Type()) {
10171
10876
  case ScopeIterator::ScopeTypeGlobal:
10172
10877
  return Handle<JSObject>(CurrentContext()->global());
10173
- break;
10174
10878
  case ScopeIterator::ScopeTypeLocal:
10175
10879
  // Materialize the content of the local scope into a JSObject.
10176
- return MaterializeLocalScope(isolate_, frame_);
10177
- break;
10880
+ return MaterializeLocalScope(isolate_, frame_, inlined_frame_index_);
10178
10881
  case ScopeIterator::ScopeTypeWith:
10179
- case ScopeIterator::ScopeTypeCatch:
10180
10882
  // Return the with object.
10181
- return Handle<JSObject>(CurrentContext()->extension());
10182
- break;
10883
+ return Handle<JSObject>(JSObject::cast(CurrentContext()->extension()));
10884
+ case ScopeIterator::ScopeTypeCatch:
10885
+ return MaterializeCatchScope(isolate_, CurrentContext());
10183
10886
  case ScopeIterator::ScopeTypeClosure:
10184
10887
  // Materialize the content of the closure scope into a JSObject.
10185
10888
  return MaterializeClosure(isolate_, CurrentContext());
10186
- break;
10889
+ case ScopeIterator::ScopeTypeBlock:
10890
+ return MaterializeBlockScope(isolate_, CurrentContext());
10187
10891
  }
10188
10892
  UNREACHABLE();
10189
10893
  return Handle<JSObject>();
@@ -10214,8 +10918,7 @@ class ScopeIterator {
10214
10918
  if (!CurrentContext().is_null()) {
10215
10919
  CurrentContext()->Print();
10216
10920
  if (CurrentContext()->has_extension()) {
10217
- Handle<JSObject> extension =
10218
- Handle<JSObject>(CurrentContext()->extension());
10921
+ Handle<Object> extension(CurrentContext()->extension());
10219
10922
  if (extension->IsJSContextExtensionObject()) {
10220
10923
  extension->Print();
10221
10924
  }
@@ -10224,34 +10927,27 @@ class ScopeIterator {
10224
10927
  break;
10225
10928
  }
10226
10929
 
10227
- case ScopeIterator::ScopeTypeWith: {
10930
+ case ScopeIterator::ScopeTypeWith:
10228
10931
  PrintF("With:\n");
10229
- Handle<JSObject> extension =
10230
- Handle<JSObject>(CurrentContext()->extension());
10231
- extension->Print();
10932
+ CurrentContext()->extension()->Print();
10232
10933
  break;
10233
- }
10234
10934
 
10235
- case ScopeIterator::ScopeTypeCatch: {
10935
+ case ScopeIterator::ScopeTypeCatch:
10236
10936
  PrintF("Catch:\n");
10237
- Handle<JSObject> extension =
10238
- Handle<JSObject>(CurrentContext()->extension());
10239
- extension->Print();
10937
+ CurrentContext()->extension()->Print();
10938
+ CurrentContext()->get(Context::THROWN_OBJECT_INDEX)->Print();
10240
10939
  break;
10241
- }
10242
10940
 
10243
- case ScopeIterator::ScopeTypeClosure: {
10941
+ case ScopeIterator::ScopeTypeClosure:
10244
10942
  PrintF("Closure:\n");
10245
10943
  CurrentContext()->Print();
10246
10944
  if (CurrentContext()->has_extension()) {
10247
- Handle<JSObject> extension =
10248
- Handle<JSObject>(CurrentContext()->extension());
10945
+ Handle<Object> extension(CurrentContext()->extension());
10249
10946
  if (extension->IsJSContextExtensionObject()) {
10250
10947
  extension->Print();
10251
10948
  }
10252
10949
  }
10253
10950
  break;
10254
- }
10255
10951
 
10256
10952
  default:
10257
10953
  UNREACHABLE();
@@ -10263,6 +10959,7 @@ class ScopeIterator {
10263
10959
  private:
10264
10960
  Isolate* isolate_;
10265
10961
  JavaScriptFrame* frame_;
10962
+ int inlined_frame_index_;
10266
10963
  Handle<JSFunction> function_;
10267
10964
  Handle<Context> context_;
10268
10965
  bool local_done_;
@@ -10291,7 +10988,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScopeCount) {
10291
10988
 
10292
10989
  // Count the visible scopes.
10293
10990
  int n = 0;
10294
- for (ScopeIterator it(isolate, frame); !it.Done(); it.Next()) {
10991
+ for (ScopeIterator it(isolate, frame, 0);
10992
+ !it.Done();
10993
+ it.Next()) {
10295
10994
  n++;
10296
10995
  }
10297
10996
 
@@ -10306,14 +11005,15 @@ static const int kScopeDetailsSize = 2;
10306
11005
  // Return an array with scope details
10307
11006
  // args[0]: number: break id
10308
11007
  // args[1]: number: frame index
10309
- // args[2]: number: scope index
11008
+ // args[2]: number: inlined frame index
11009
+ // args[3]: number: scope index
10310
11010
  //
10311
11011
  // The array returned contains the following information:
10312
11012
  // 0: Scope type
10313
11013
  // 1: Scope object
10314
11014
  RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScopeDetails) {
10315
11015
  HandleScope scope(isolate);
10316
- ASSERT(args.length() == 3);
11016
+ ASSERT(args.length() == 4);
10317
11017
 
10318
11018
  // Check arguments.
10319
11019
  Object* check;
@@ -10322,7 +11022,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScopeDetails) {
10322
11022
  if (!maybe_check->ToObject(&check)) return maybe_check;
10323
11023
  }
10324
11024
  CONVERT_CHECKED(Smi, wrapped_id, args[1]);
10325
- CONVERT_NUMBER_CHECKED(int, index, Int32, args[2]);
11025
+ CONVERT_NUMBER_CHECKED(int, inlined_frame_index, Int32, args[2]);
11026
+ CONVERT_NUMBER_CHECKED(int, index, Int32, args[3]);
10326
11027
 
10327
11028
  // Get the frame where the debugging is performed.
10328
11029
  StackFrame::Id id = UnwrapFrameId(wrapped_id);
@@ -10331,7 +11032,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScopeDetails) {
10331
11032
 
10332
11033
  // Find the requested scope.
10333
11034
  int n = 0;
10334
- ScopeIterator it(isolate, frame);
11035
+ ScopeIterator it(isolate, frame, inlined_frame_index);
10335
11036
  for (; !it.Done() && n < index; it.Next()) {
10336
11037
  n++;
10337
11038
  }
@@ -10361,7 +11062,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugPrintScopes) {
10361
11062
  // Print the scopes for the top frame.
10362
11063
  StackFrameLocator locator;
10363
11064
  JavaScriptFrame* frame = locator.FindJavaScriptFrame(0);
10364
- for (ScopeIterator it(isolate, frame); !it.Done(); it.Next()) {
11065
+ for (ScopeIterator it(isolate, frame, 0);
11066
+ !it.Done();
11067
+ it.Next()) {
10365
11068
  it.DebugPrint();
10366
11069
  }
10367
11070
  #endif
@@ -10718,19 +11421,46 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_ClearStepping) {
10718
11421
 
10719
11422
  // Creates a copy of the with context chain. The copy of the context chain is
10720
11423
  // is linked to the function context supplied.
10721
- static Handle<Context> CopyWithContextChain(Handle<Context> context_chain,
10722
- Handle<Context> function_context) {
10723
- // At the bottom of the chain. Return the function context to link to.
10724
- if (context_chain->is_function_context()) {
10725
- return function_context;
11424
+ static Handle<Context> CopyWithContextChain(Isolate* isolate,
11425
+ Handle<JSFunction> function,
11426
+ Handle<Context> current,
11427
+ Handle<Context> base) {
11428
+ // At the end of the chain. Return the base context to link to.
11429
+ if (current->IsFunctionContext() || current->IsGlobalContext()) {
11430
+ return base;
10726
11431
  }
10727
11432
 
10728
- // Recursively copy the with contexts.
10729
- Handle<Context> previous(context_chain->previous());
10730
- Handle<JSObject> extension(JSObject::cast(context_chain->extension()));
10731
- Handle<Context> context = CopyWithContextChain(previous, function_context);
10732
- return context->GetIsolate()->factory()->NewWithContext(
10733
- context, extension, context_chain->IsCatchContext());
11433
+ // Recursively copy the with and catch contexts.
11434
+ HandleScope scope(isolate);
11435
+ Handle<Context> previous(current->previous());
11436
+ Handle<Context> new_previous =
11437
+ CopyWithContextChain(isolate, function, previous, base);
11438
+ Handle<Context> new_current;
11439
+ if (current->IsCatchContext()) {
11440
+ Handle<String> name(String::cast(current->extension()));
11441
+ Handle<Object> thrown_object(current->get(Context::THROWN_OBJECT_INDEX));
11442
+ new_current =
11443
+ isolate->factory()->NewCatchContext(function,
11444
+ new_previous,
11445
+ name,
11446
+ thrown_object);
11447
+ } else if (current->IsBlockContext()) {
11448
+ Handle<SerializedScopeInfo> scope_info(
11449
+ SerializedScopeInfo::cast(current->extension()));
11450
+ new_current =
11451
+ isolate->factory()->NewBlockContext(function, new_previous, scope_info);
11452
+ // Copy context slots.
11453
+ int num_context_slots = scope_info->NumberOfContextSlots();
11454
+ for (int i = Context::MIN_CONTEXT_SLOTS; i < num_context_slots; ++i) {
11455
+ new_current->set(i, current->get(i));
11456
+ }
11457
+ } else {
11458
+ ASSERT(current->IsWithContext());
11459
+ Handle<JSObject> extension(JSObject::cast(current->extension()));
11460
+ new_current =
11461
+ isolate->factory()->NewWithContext(function, new_previous, extension);
11462
+ }
11463
+ return scope.CloseAndEscape(new_current);
10734
11464
  }
10735
11465
 
10736
11466
 
@@ -10738,6 +11468,7 @@ static Handle<Context> CopyWithContextChain(Handle<Context> context_chain,
10738
11468
  // Runtime_DebugEvaluate.
10739
11469
  static Handle<Object> GetArgumentsObject(Isolate* isolate,
10740
11470
  JavaScriptFrame* frame,
11471
+ int inlined_frame_index,
10741
11472
  Handle<JSFunction> function,
10742
11473
  Handle<SerializedScopeInfo> scope_info,
10743
11474
  const ScopeInfo<>* sinfo,
@@ -10761,7 +11492,9 @@ static Handle<Object> GetArgumentsObject(Isolate* isolate,
10761
11492
  }
10762
11493
  }
10763
11494
 
10764
- const int length = frame->ComputeParametersCount();
11495
+ FrameInspector frame_inspector(frame, inlined_frame_index, isolate);
11496
+
11497
+ int length = frame_inspector.GetParametersCount();
10765
11498
  Handle<JSObject> arguments =
10766
11499
  isolate->factory()->NewArgumentsObject(function, length);
10767
11500
  Handle<FixedArray> array = isolate->factory()->NewFixedArray(length);
@@ -10769,7 +11502,7 @@ static Handle<Object> GetArgumentsObject(Isolate* isolate,
10769
11502
  AssertNoAllocation no_gc;
10770
11503
  WriteBarrierMode mode = array->GetWriteBarrierMode(no_gc);
10771
11504
  for (int i = 0; i < length; i++) {
10772
- array->set(i, frame->GetParameter(i), mode);
11505
+ array->set(i, frame_inspector.GetParameter(i), mode);
10773
11506
  }
10774
11507
  arguments->set_elements(*array);
10775
11508
  return arguments;
@@ -10796,7 +11529,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) {
10796
11529
 
10797
11530
  // Check the execution state and decode arguments frame and source to be
10798
11531
  // evaluated.
10799
- ASSERT(args.length() == 5);
11532
+ ASSERT(args.length() == 6);
10800
11533
  Object* check_result;
10801
11534
  { MaybeObject* maybe_check_result = Runtime_CheckExecutionState(
10802
11535
  RUNTIME_ARGUMENTS(isolate, args));
@@ -10805,9 +11538,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) {
10805
11538
  }
10806
11539
  }
10807
11540
  CONVERT_CHECKED(Smi, wrapped_id, args[1]);
10808
- CONVERT_ARG_CHECKED(String, source, 2);
10809
- CONVERT_BOOLEAN_CHECKED(disable_break, args[3]);
10810
- Handle<Object> additional_context(args[4]);
11541
+ CONVERT_NUMBER_CHECKED(int, inlined_frame_index, Int32, args[2]);
11542
+ CONVERT_ARG_CHECKED(String, source, 3);
11543
+ CONVERT_BOOLEAN_CHECKED(disable_break, args[4]);
11544
+ Handle<Object> additional_context(args[5]);
10811
11545
 
10812
11546
  // Handle the processing of break.
10813
11547
  DisableBreak disable_break_save(disable_break);
@@ -10847,7 +11581,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) {
10847
11581
  #endif
10848
11582
 
10849
11583
  // Materialize the content of the local scope into a JSObject.
10850
- Handle<JSObject> local_scope = MaterializeLocalScope(isolate, frame);
11584
+ Handle<JSObject> local_scope = MaterializeLocalScope(
11585
+ isolate, frame, inlined_frame_index);
10851
11586
  RETURN_IF_EMPTY_HANDLE(isolate, local_scope);
10852
11587
 
10853
11588
  // Allocate a new context for the debug evaluation and set the extension
@@ -10858,12 +11593,17 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) {
10858
11593
  context->set_extension(*local_scope);
10859
11594
  // Copy any with contexts present and chain them in front of this context.
10860
11595
  Handle<Context> frame_context(Context::cast(frame->context()));
10861
- Handle<Context> function_context(frame_context->fcontext());
10862
- context = CopyWithContextChain(frame_context, context);
11596
+ Handle<Context> function_context;
11597
+ // Get the function's context if it has one.
11598
+ if (scope_info->HasHeapAllocatedLocals()) {
11599
+ function_context = Handle<Context>(frame_context->declaration_context());
11600
+ }
11601
+ context = CopyWithContextChain(isolate, go_between, frame_context, context);
10863
11602
 
10864
11603
  if (additional_context->IsJSObject()) {
10865
- context = isolate->factory()->NewWithContext(context,
10866
- Handle<JSObject>::cast(additional_context), false);
11604
+ Handle<JSObject> extension = Handle<JSObject>::cast(additional_context);
11605
+ context =
11606
+ isolate->factory()->NewWithContext(go_between, context, extension);
10867
11607
  }
10868
11608
 
10869
11609
  // Wrap the evaluation statement in a new function compiled in the newly
@@ -10895,7 +11635,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) {
10895
11635
  &has_pending_exception);
10896
11636
  if (has_pending_exception) return Failure::Exception();
10897
11637
 
10898
- Handle<Object> arguments = GetArgumentsObject(isolate, frame,
11638
+ Handle<Object> arguments = GetArgumentsObject(isolate,
11639
+ frame, inlined_frame_index,
10899
11640
  function, scope_info,
10900
11641
  &sinfo, function_context);
10901
11642
 
@@ -11585,10 +12326,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CaptureLOL) {
11585
12326
  // Deletes the specified live object list.
11586
12327
  RUNTIME_FUNCTION(MaybeObject*, Runtime_DeleteLOL) {
11587
12328
  #ifdef LIVE_OBJECT_LIST
11588
- CONVERT_SMI_CHECKED(id, args[0]);
12329
+ CONVERT_SMI_ARG_CHECKED(id, 0);
11589
12330
  bool success = LiveObjectList::Delete(id);
11590
- return success ? isolate->heap()->true_value() :
11591
- isolate->heap()->false_value();
12331
+ return isolate->heap()->ToBoolean(success);
11592
12332
  #else
11593
12333
  return isolate->heap()->undefined_value();
11594
12334
  #endif
@@ -11603,10 +12343,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeleteLOL) {
11603
12343
  RUNTIME_FUNCTION(MaybeObject*, Runtime_DumpLOL) {
11604
12344
  #ifdef LIVE_OBJECT_LIST
11605
12345
  HandleScope scope;
11606
- CONVERT_SMI_CHECKED(id1, args[0]);
11607
- CONVERT_SMI_CHECKED(id2, args[1]);
11608
- CONVERT_SMI_CHECKED(start, args[2]);
11609
- CONVERT_SMI_CHECKED(count, args[3]);
12346
+ CONVERT_SMI_ARG_CHECKED(id1, 0);
12347
+ CONVERT_SMI_ARG_CHECKED(id2, 1);
12348
+ CONVERT_SMI_ARG_CHECKED(start, 2);
12349
+ CONVERT_SMI_ARG_CHECKED(count, 3);
11610
12350
  CONVERT_ARG_CHECKED(JSObject, filter_obj, 4);
11611
12351
  EnterDebugger enter_debugger;
11612
12352
  return LiveObjectList::Dump(id1, id2, start, count, filter_obj);
@@ -11620,7 +12360,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DumpLOL) {
11620
12360
  // This is only used for obj ids shown in live object lists.
11621
12361
  RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLOLObj) {
11622
12362
  #ifdef LIVE_OBJECT_LIST
11623
- CONVERT_SMI_CHECKED(obj_id, args[0]);
12363
+ CONVERT_SMI_ARG_CHECKED(obj_id, 0);
11624
12364
  Object* result = LiveObjectList::GetObj(obj_id);
11625
12365
  return result;
11626
12366
  #else
@@ -11647,7 +12387,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLOLObjId) {
11647
12387
  RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLOLObjRetainers) {
11648
12388
  #ifdef LIVE_OBJECT_LIST
11649
12389
  HandleScope scope;
11650
- CONVERT_SMI_CHECKED(obj_id, args[0]);
12390
+ CONVERT_SMI_ARG_CHECKED(obj_id, 0);
11651
12391
  RUNTIME_ASSERT(args[1]->IsUndefined() || args[1]->IsJSObject());
11652
12392
  RUNTIME_ASSERT(args[2]->IsUndefined() || args[2]->IsBoolean());
11653
12393
  RUNTIME_ASSERT(args[3]->IsUndefined() || args[3]->IsSmi());
@@ -11664,11 +12404,11 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLOLObjRetainers) {
11664
12404
  }
11665
12405
  int start = 0;
11666
12406
  if (args[3]->IsSmi()) {
11667
- start = Smi::cast(args[3])->value();
12407
+ start = args.smi_at(3);
11668
12408
  }
11669
12409
  int limit = Smi::kMaxValue;
11670
12410
  if (args[4]->IsSmi()) {
11671
- limit = Smi::cast(args[4])->value();
12411
+ limit = args.smi_at(4);
11672
12412
  }
11673
12413
 
11674
12414
  return LiveObjectList::GetObjRetainers(obj_id,
@@ -11687,8 +12427,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLOLObjRetainers) {
11687
12427
  RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLOLPath) {
11688
12428
  #ifdef LIVE_OBJECT_LIST
11689
12429
  HandleScope scope;
11690
- CONVERT_SMI_CHECKED(obj_id1, args[0]);
11691
- CONVERT_SMI_CHECKED(obj_id2, args[1]);
12430
+ CONVERT_SMI_ARG_CHECKED(obj_id1, 0);
12431
+ CONVERT_SMI_ARG_CHECKED(obj_id2, 1);
11692
12432
  RUNTIME_ASSERT(args[2]->IsUndefined() || args[2]->IsJSObject());
11693
12433
 
11694
12434
  Handle<JSObject> instance_filter;
@@ -11709,8 +12449,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLOLPath) {
11709
12449
  // previously captured live object lists.
11710
12450
  RUNTIME_FUNCTION(MaybeObject*, Runtime_InfoLOL) {
11711
12451
  #ifdef LIVE_OBJECT_LIST
11712
- CONVERT_SMI_CHECKED(start, args[0]);
11713
- CONVERT_SMI_CHECKED(count, args[1]);
12452
+ CONVERT_SMI_ARG_CHECKED(start, 0);
12453
+ CONVERT_SMI_ARG_CHECKED(count, 1);
11714
12454
  return LiveObjectList::Info(start, count);
11715
12455
  #else
11716
12456
  return isolate->heap()->undefined_value();
@@ -11723,7 +12463,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InfoLOL) {
11723
12463
  RUNTIME_FUNCTION(MaybeObject*, Runtime_PrintLOLObj) {
11724
12464
  #ifdef LIVE_OBJECT_LIST
11725
12465
  HandleScope scope;
11726
- CONVERT_SMI_CHECKED(obj_id, args[0]);
12466
+ CONVERT_SMI_ARG_CHECKED(obj_id, 0);
11727
12467
  Object* result = LiveObjectList::PrintObj(obj_id);
11728
12468
  return result;
11729
12469
  #else
@@ -11751,8 +12491,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_ResetLOL) {
11751
12491
  RUNTIME_FUNCTION(MaybeObject*, Runtime_SummarizeLOL) {
11752
12492
  #ifdef LIVE_OBJECT_LIST
11753
12493
  HandleScope scope;
11754
- CONVERT_SMI_CHECKED(id1, args[0]);
11755
- CONVERT_SMI_CHECKED(id2, args[1]);
12494
+ CONVERT_SMI_ARG_CHECKED(id1, 0);
12495
+ CONVERT_SMI_ARG_CHECKED(id2, 1);
11756
12496
  CONVERT_ARG_CHECKED(JSObject, filter_obj, 2);
11757
12497
 
11758
12498
  EnterDebugger enter_debugger;
@@ -11765,29 +12505,19 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SummarizeLOL) {
11765
12505
  #endif // ENABLE_DEBUGGER_SUPPORT
11766
12506
 
11767
12507
 
11768
- #ifdef ENABLE_LOGGING_AND_PROFILING
11769
12508
  RUNTIME_FUNCTION(MaybeObject*, Runtime_ProfilerResume) {
11770
12509
  NoHandleAllocation ha;
11771
- ASSERT(args.length() == 2);
11772
-
11773
- CONVERT_CHECKED(Smi, smi_modules, args[0]);
11774
- CONVERT_CHECKED(Smi, smi_tag, args[1]);
11775
- v8::V8::ResumeProfilerEx(smi_modules->value(), smi_tag->value());
12510
+ v8::V8::ResumeProfiler();
11776
12511
  return isolate->heap()->undefined_value();
11777
12512
  }
11778
12513
 
11779
12514
 
11780
12515
  RUNTIME_FUNCTION(MaybeObject*, Runtime_ProfilerPause) {
11781
12516
  NoHandleAllocation ha;
11782
- ASSERT(args.length() == 2);
11783
-
11784
- CONVERT_CHECKED(Smi, smi_modules, args[0]);
11785
- CONVERT_CHECKED(Smi, smi_tag, args[1]);
11786
- v8::V8::PauseProfilerEx(smi_modules->value(), smi_tag->value());
12517
+ v8::V8::PauseProfiler();
11787
12518
  return isolate->heap()->undefined_value();
11788
12519
  }
11789
12520
 
11790
- #endif // ENABLE_LOGGING_AND_PROFILING
11791
12521
 
11792
12522
  // Finds the script object from the script data. NOTE: This operation uses
11793
12523
  // heap traversal to find the function generated for the source position
@@ -11844,8 +12574,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScript) {
11844
12574
  // call to this function is encountered it is skipped. The seen_caller
11845
12575
  // in/out parameter is used to remember if the caller has been seen
11846
12576
  // yet.
11847
- static bool ShowFrameInStackTrace(StackFrame* raw_frame, Object* caller,
11848
- bool* seen_caller) {
12577
+ static bool ShowFrameInStackTrace(StackFrame* raw_frame,
12578
+ Object* caller,
12579
+ bool* seen_caller) {
11849
12580
  // Only display JS frames.
11850
12581
  if (!raw_frame->is_java_script())
11851
12582
  return false;
@@ -11858,11 +12589,25 @@ static bool ShowFrameInStackTrace(StackFrame* raw_frame, Object* caller,
11858
12589
  *seen_caller = true;
11859
12590
  return false;
11860
12591
  }
11861
- // Skip all frames until we've seen the caller. Also, skip the most
11862
- // obvious builtin calls. Some builtin calls (such as Number.ADD
11863
- // which is invoked using 'call') are very difficult to recognize
11864
- // so we're leaving them in for now.
11865
- return *seen_caller && !frame->receiver()->IsJSBuiltinsObject();
12592
+ // Skip all frames until we've seen the caller.
12593
+ if (!(*seen_caller)) return false;
12594
+ // Also, skip the most obvious builtin calls. We recognize builtins
12595
+ // as (1) functions called with the builtins object as the receiver and
12596
+ // as (2) functions from native scripts called with undefined as the
12597
+ // receiver (direct calls to helper functions in the builtins
12598
+ // code). Some builtin calls (such as Number.ADD which is invoked
12599
+ // using 'call') are very difficult to recognize so we're leaving
12600
+ // them in for now.
12601
+ if (frame->receiver()->IsJSBuiltinsObject()) {
12602
+ return false;
12603
+ }
12604
+ JSFunction* fun = JSFunction::cast(raw_fun);
12605
+ Object* raw_script = fun->shared()->script();
12606
+ if (frame->receiver()->IsUndefined() && raw_script->IsScript()) {
12607
+ int script_type = Script::cast(raw_script)->type()->value();
12608
+ return script_type != Script::TYPE_NATIVE;
12609
+ }
12610
+ return true;
11866
12611
  }
11867
12612
 
11868
12613
 
@@ -11942,8 +12687,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetV8Version) {
11942
12687
 
11943
12688
  RUNTIME_FUNCTION(MaybeObject*, Runtime_Abort) {
11944
12689
  ASSERT(args.length() == 2);
11945
- OS::PrintError("abort: %s\n", reinterpret_cast<char*>(args[0]) +
11946
- Smi::cast(args[1])->value());
12690
+ OS::PrintError("abort: %s\n",
12691
+ reinterpret_cast<char*>(args[0]) + args.smi_at(1));
11947
12692
  isolate->PrintStack();
11948
12693
  OS::Abort();
11949
12694
  UNREACHABLE();
@@ -12133,7 +12878,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_Log) {
12133
12878
  ASSERT(args.length() == 2);
12134
12879
  CONVERT_CHECKED(String, format, args[0]);
12135
12880
  CONVERT_CHECKED(JSArray, elms, args[1]);
12136
- Vector<const char> chars = format->ToAsciiVector();
12881
+ String::FlatContent format_content = format->GetFlatContent();
12882
+ RUNTIME_ASSERT(format_content.IsAscii());
12883
+ Vector<const char> chars = format_content.ToAsciiVector();
12137
12884
  LOGGER->LogRuntime(chars, elms);
12138
12885
  return isolate->heap()->undefined_value();
12139
12886
  }
@@ -12145,6 +12892,28 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_IS_VAR) {
12145
12892
  }
12146
12893
 
12147
12894
 
12895
+ #define ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(Name) \
12896
+ RUNTIME_FUNCTION(MaybeObject*, Runtime_Has##Name) { \
12897
+ CONVERT_CHECKED(JSObject, obj, args[0]); \
12898
+ return isolate->heap()->ToBoolean(obj->Has##Name()); \
12899
+ }
12900
+
12901
+ ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastElements)
12902
+ ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastDoubleElements)
12903
+ ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(DictionaryElements)
12904
+ ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalPixelElements)
12905
+ ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalArrayElements)
12906
+ ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalByteElements)
12907
+ ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedByteElements)
12908
+ ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalShortElements)
12909
+ ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedShortElements)
12910
+ ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalIntElements)
12911
+ ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedIntElements)
12912
+ ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalFloatElements)
12913
+ ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalDoubleElements)
12914
+
12915
+ #undef ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION
12916
+
12148
12917
  // ----------------------------------------------------------------------------
12149
12918
  // Implementation of Runtime
12150
12919