libv8 3.3.10.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (700) hide show
  1. data/.gitignore +8 -0
  2. data/.gitmodules +3 -0
  3. data/Gemfile +4 -0
  4. data/README.md +44 -0
  5. data/Rakefile +73 -0
  6. data/ext/libv8/extconf.rb +9 -0
  7. data/lib/libv8.rb +15 -0
  8. data/lib/libv8/Makefile +38 -0
  9. data/lib/libv8/detect_cpu.rb +27 -0
  10. data/lib/libv8/fpic-on-linux-amd64.patch +13 -0
  11. data/lib/libv8/scons/CHANGES.txt +5334 -0
  12. data/lib/libv8/scons/LICENSE.txt +20 -0
  13. data/lib/libv8/scons/MANIFEST +199 -0
  14. data/lib/libv8/scons/PKG-INFO +13 -0
  15. data/lib/libv8/scons/README.txt +243 -0
  16. data/lib/libv8/scons/RELEASE.txt +98 -0
  17. data/lib/libv8/scons/engine/SCons/Action.py +1241 -0
  18. data/lib/libv8/scons/engine/SCons/Builder.py +877 -0
  19. data/lib/libv8/scons/engine/SCons/CacheDir.py +216 -0
  20. data/lib/libv8/scons/engine/SCons/Conftest.py +793 -0
  21. data/lib/libv8/scons/engine/SCons/Debug.py +220 -0
  22. data/lib/libv8/scons/engine/SCons/Defaults.py +480 -0
  23. data/lib/libv8/scons/engine/SCons/Environment.py +2318 -0
  24. data/lib/libv8/scons/engine/SCons/Errors.py +205 -0
  25. data/lib/libv8/scons/engine/SCons/Executor.py +633 -0
  26. data/lib/libv8/scons/engine/SCons/Job.py +435 -0
  27. data/lib/libv8/scons/engine/SCons/Memoize.py +244 -0
  28. data/lib/libv8/scons/engine/SCons/Node/Alias.py +152 -0
  29. data/lib/libv8/scons/engine/SCons/Node/FS.py +3142 -0
  30. data/lib/libv8/scons/engine/SCons/Node/Python.py +128 -0
  31. data/lib/libv8/scons/engine/SCons/Node/__init__.py +1328 -0
  32. data/lib/libv8/scons/engine/SCons/Options/BoolOption.py +50 -0
  33. data/lib/libv8/scons/engine/SCons/Options/EnumOption.py +50 -0
  34. data/lib/libv8/scons/engine/SCons/Options/ListOption.py +50 -0
  35. data/lib/libv8/scons/engine/SCons/Options/PackageOption.py +50 -0
  36. data/lib/libv8/scons/engine/SCons/Options/PathOption.py +76 -0
  37. data/lib/libv8/scons/engine/SCons/Options/__init__.py +67 -0
  38. data/lib/libv8/scons/engine/SCons/PathList.py +231 -0
  39. data/lib/libv8/scons/engine/SCons/Platform/__init__.py +241 -0
  40. data/lib/libv8/scons/engine/SCons/Platform/aix.py +69 -0
  41. data/lib/libv8/scons/engine/SCons/Platform/cygwin.py +55 -0
  42. data/lib/libv8/scons/engine/SCons/Platform/darwin.py +46 -0
  43. data/lib/libv8/scons/engine/SCons/Platform/hpux.py +46 -0
  44. data/lib/libv8/scons/engine/SCons/Platform/irix.py +44 -0
  45. data/lib/libv8/scons/engine/SCons/Platform/os2.py +58 -0
  46. data/lib/libv8/scons/engine/SCons/Platform/posix.py +263 -0
  47. data/lib/libv8/scons/engine/SCons/Platform/sunos.py +50 -0
  48. data/lib/libv8/scons/engine/SCons/Platform/win32.py +385 -0
  49. data/lib/libv8/scons/engine/SCons/SConf.py +1030 -0
  50. data/lib/libv8/scons/engine/SCons/SConsign.py +383 -0
  51. data/lib/libv8/scons/engine/SCons/Scanner/C.py +132 -0
  52. data/lib/libv8/scons/engine/SCons/Scanner/D.py +73 -0
  53. data/lib/libv8/scons/engine/SCons/Scanner/Dir.py +109 -0
  54. data/lib/libv8/scons/engine/SCons/Scanner/Fortran.py +316 -0
  55. data/lib/libv8/scons/engine/SCons/Scanner/IDL.py +48 -0
  56. data/lib/libv8/scons/engine/SCons/Scanner/LaTeX.py +384 -0
  57. data/lib/libv8/scons/engine/SCons/Scanner/Prog.py +101 -0
  58. data/lib/libv8/scons/engine/SCons/Scanner/RC.py +55 -0
  59. data/lib/libv8/scons/engine/SCons/Scanner/__init__.py +413 -0
  60. data/lib/libv8/scons/engine/SCons/Script/Interactive.py +384 -0
  61. data/lib/libv8/scons/engine/SCons/Script/Main.py +1334 -0
  62. data/lib/libv8/scons/engine/SCons/Script/SConsOptions.py +939 -0
  63. data/lib/libv8/scons/engine/SCons/Script/SConscript.py +640 -0
  64. data/lib/libv8/scons/engine/SCons/Script/__init__.py +412 -0
  65. data/lib/libv8/scons/engine/SCons/Sig.py +63 -0
  66. data/lib/libv8/scons/engine/SCons/Subst.py +904 -0
  67. data/lib/libv8/scons/engine/SCons/Taskmaster.py +1017 -0
  68. data/lib/libv8/scons/engine/SCons/Tool/386asm.py +61 -0
  69. data/lib/libv8/scons/engine/SCons/Tool/BitKeeper.py +67 -0
  70. data/lib/libv8/scons/engine/SCons/Tool/CVS.py +73 -0
  71. data/lib/libv8/scons/engine/SCons/Tool/FortranCommon.py +246 -0
  72. data/lib/libv8/scons/engine/SCons/Tool/JavaCommon.py +323 -0
  73. data/lib/libv8/scons/engine/SCons/Tool/MSCommon/__init__.py +56 -0
  74. data/lib/libv8/scons/engine/SCons/Tool/MSCommon/arch.py +61 -0
  75. data/lib/libv8/scons/engine/SCons/Tool/MSCommon/common.py +240 -0
  76. data/lib/libv8/scons/engine/SCons/Tool/MSCommon/netframework.py +82 -0
  77. data/lib/libv8/scons/engine/SCons/Tool/MSCommon/sdk.py +391 -0
  78. data/lib/libv8/scons/engine/SCons/Tool/MSCommon/vc.py +456 -0
  79. data/lib/libv8/scons/engine/SCons/Tool/MSCommon/vs.py +499 -0
  80. data/lib/libv8/scons/engine/SCons/Tool/Perforce.py +103 -0
  81. data/lib/libv8/scons/engine/SCons/Tool/PharLapCommon.py +137 -0
  82. data/lib/libv8/scons/engine/SCons/Tool/RCS.py +64 -0
  83. data/lib/libv8/scons/engine/SCons/Tool/SCCS.py +64 -0
  84. data/lib/libv8/scons/engine/SCons/Tool/Subversion.py +71 -0
  85. data/lib/libv8/scons/engine/SCons/Tool/__init__.py +681 -0
  86. data/lib/libv8/scons/engine/SCons/Tool/aixc++.py +82 -0
  87. data/lib/libv8/scons/engine/SCons/Tool/aixcc.py +74 -0
  88. data/lib/libv8/scons/engine/SCons/Tool/aixf77.py +80 -0
  89. data/lib/libv8/scons/engine/SCons/Tool/aixlink.py +76 -0
  90. data/lib/libv8/scons/engine/SCons/Tool/applelink.py +71 -0
  91. data/lib/libv8/scons/engine/SCons/Tool/ar.py +63 -0
  92. data/lib/libv8/scons/engine/SCons/Tool/as.py +78 -0
  93. data/lib/libv8/scons/engine/SCons/Tool/bcc32.py +81 -0
  94. data/lib/libv8/scons/engine/SCons/Tool/c++.py +99 -0
  95. data/lib/libv8/scons/engine/SCons/Tool/cc.py +102 -0
  96. data/lib/libv8/scons/engine/SCons/Tool/cvf.py +58 -0
  97. data/lib/libv8/scons/engine/SCons/Tool/default.py +50 -0
  98. data/lib/libv8/scons/engine/SCons/Tool/dmd.py +223 -0
  99. data/lib/libv8/scons/engine/SCons/Tool/dvi.py +64 -0
  100. data/lib/libv8/scons/engine/SCons/Tool/dvipdf.py +124 -0
  101. data/lib/libv8/scons/engine/SCons/Tool/dvips.py +94 -0
  102. data/lib/libv8/scons/engine/SCons/Tool/f77.py +62 -0
  103. data/lib/libv8/scons/engine/SCons/Tool/f90.py +62 -0
  104. data/lib/libv8/scons/engine/SCons/Tool/f95.py +63 -0
  105. data/lib/libv8/scons/engine/SCons/Tool/filesystem.py +98 -0
  106. data/lib/libv8/scons/engine/SCons/Tool/fortran.py +62 -0
  107. data/lib/libv8/scons/engine/SCons/Tool/g++.py +90 -0
  108. data/lib/libv8/scons/engine/SCons/Tool/g77.py +73 -0
  109. data/lib/libv8/scons/engine/SCons/Tool/gas.py +53 -0
  110. data/lib/libv8/scons/engine/SCons/Tool/gcc.py +80 -0
  111. data/lib/libv8/scons/engine/SCons/Tool/gfortran.py +64 -0
  112. data/lib/libv8/scons/engine/SCons/Tool/gnulink.py +63 -0
  113. data/lib/libv8/scons/engine/SCons/Tool/gs.py +81 -0
  114. data/lib/libv8/scons/engine/SCons/Tool/hpc++.py +84 -0
  115. data/lib/libv8/scons/engine/SCons/Tool/hpcc.py +53 -0
  116. data/lib/libv8/scons/engine/SCons/Tool/hplink.py +77 -0
  117. data/lib/libv8/scons/engine/SCons/Tool/icc.py +59 -0
  118. data/lib/libv8/scons/engine/SCons/Tool/icl.py +52 -0
  119. data/lib/libv8/scons/engine/SCons/Tool/ifl.py +72 -0
  120. data/lib/libv8/scons/engine/SCons/Tool/ifort.py +88 -0
  121. data/lib/libv8/scons/engine/SCons/Tool/ilink.py +59 -0
  122. data/lib/libv8/scons/engine/SCons/Tool/ilink32.py +60 -0
  123. data/lib/libv8/scons/engine/SCons/Tool/install.py +229 -0
  124. data/lib/libv8/scons/engine/SCons/Tool/intelc.py +482 -0
  125. data/lib/libv8/scons/engine/SCons/Tool/ipkg.py +67 -0
  126. data/lib/libv8/scons/engine/SCons/Tool/jar.py +110 -0
  127. data/lib/libv8/scons/engine/SCons/Tool/javac.py +230 -0
  128. data/lib/libv8/scons/engine/SCons/Tool/javah.py +137 -0
  129. data/lib/libv8/scons/engine/SCons/Tool/latex.py +79 -0
  130. data/lib/libv8/scons/engine/SCons/Tool/lex.py +97 -0
  131. data/lib/libv8/scons/engine/SCons/Tool/link.py +121 -0
  132. data/lib/libv8/scons/engine/SCons/Tool/linkloc.py +112 -0
  133. data/lib/libv8/scons/engine/SCons/Tool/m4.py +63 -0
  134. data/lib/libv8/scons/engine/SCons/Tool/masm.py +77 -0
  135. data/lib/libv8/scons/engine/SCons/Tool/midl.py +88 -0
  136. data/lib/libv8/scons/engine/SCons/Tool/mingw.py +158 -0
  137. data/lib/libv8/scons/engine/SCons/Tool/mslib.py +64 -0
  138. data/lib/libv8/scons/engine/SCons/Tool/mslink.py +266 -0
  139. data/lib/libv8/scons/engine/SCons/Tool/mssdk.py +50 -0
  140. data/lib/libv8/scons/engine/SCons/Tool/msvc.py +268 -0
  141. data/lib/libv8/scons/engine/SCons/Tool/msvs.py +1388 -0
  142. data/lib/libv8/scons/engine/SCons/Tool/mwcc.py +207 -0
  143. data/lib/libv8/scons/engine/SCons/Tool/mwld.py +107 -0
  144. data/lib/libv8/scons/engine/SCons/Tool/nasm.py +72 -0
  145. data/lib/libv8/scons/engine/SCons/Tool/packaging/__init__.py +312 -0
  146. data/lib/libv8/scons/engine/SCons/Tool/packaging/ipk.py +185 -0
  147. data/lib/libv8/scons/engine/SCons/Tool/packaging/msi.py +527 -0
  148. data/lib/libv8/scons/engine/SCons/Tool/packaging/rpm.py +365 -0
  149. data/lib/libv8/scons/engine/SCons/Tool/packaging/src_tarbz2.py +43 -0
  150. data/lib/libv8/scons/engine/SCons/Tool/packaging/src_targz.py +43 -0
  151. data/lib/libv8/scons/engine/SCons/Tool/packaging/src_zip.py +43 -0
  152. data/lib/libv8/scons/engine/SCons/Tool/packaging/tarbz2.py +44 -0
  153. data/lib/libv8/scons/engine/SCons/Tool/packaging/targz.py +44 -0
  154. data/lib/libv8/scons/engine/SCons/Tool/packaging/zip.py +44 -0
  155. data/lib/libv8/scons/engine/SCons/Tool/pdf.py +78 -0
  156. data/lib/libv8/scons/engine/SCons/Tool/pdflatex.py +83 -0
  157. data/lib/libv8/scons/engine/SCons/Tool/pdftex.py +108 -0
  158. data/lib/libv8/scons/engine/SCons/Tool/qt.py +336 -0
  159. data/lib/libv8/scons/engine/SCons/Tool/rmic.py +120 -0
  160. data/lib/libv8/scons/engine/SCons/Tool/rpcgen.py +70 -0
  161. data/lib/libv8/scons/engine/SCons/Tool/rpm.py +132 -0
  162. data/lib/libv8/scons/engine/SCons/Tool/sgiar.py +68 -0
  163. data/lib/libv8/scons/engine/SCons/Tool/sgic++.py +58 -0
  164. data/lib/libv8/scons/engine/SCons/Tool/sgicc.py +53 -0
  165. data/lib/libv8/scons/engine/SCons/Tool/sgilink.py +63 -0
  166. data/lib/libv8/scons/engine/SCons/Tool/sunar.py +67 -0
  167. data/lib/libv8/scons/engine/SCons/Tool/sunc++.py +142 -0
  168. data/lib/libv8/scons/engine/SCons/Tool/suncc.py +58 -0
  169. data/lib/libv8/scons/engine/SCons/Tool/sunf77.py +63 -0
  170. data/lib/libv8/scons/engine/SCons/Tool/sunf90.py +64 -0
  171. data/lib/libv8/scons/engine/SCons/Tool/sunf95.py +64 -0
  172. data/lib/libv8/scons/engine/SCons/Tool/sunlink.py +77 -0
  173. data/lib/libv8/scons/engine/SCons/Tool/swig.py +182 -0
  174. data/lib/libv8/scons/engine/SCons/Tool/tar.py +73 -0
  175. data/lib/libv8/scons/engine/SCons/Tool/tex.py +813 -0
  176. data/lib/libv8/scons/engine/SCons/Tool/textfile.py +175 -0
  177. data/lib/libv8/scons/engine/SCons/Tool/tlib.py +53 -0
  178. data/lib/libv8/scons/engine/SCons/Tool/wix.py +99 -0
  179. data/lib/libv8/scons/engine/SCons/Tool/yacc.py +130 -0
  180. data/lib/libv8/scons/engine/SCons/Tool/zip.py +99 -0
  181. data/lib/libv8/scons/engine/SCons/Util.py +1492 -0
  182. data/lib/libv8/scons/engine/SCons/Variables/BoolVariable.py +89 -0
  183. data/lib/libv8/scons/engine/SCons/Variables/EnumVariable.py +103 -0
  184. data/lib/libv8/scons/engine/SCons/Variables/ListVariable.py +135 -0
  185. data/lib/libv8/scons/engine/SCons/Variables/PackageVariable.py +106 -0
  186. data/lib/libv8/scons/engine/SCons/Variables/PathVariable.py +147 -0
  187. data/lib/libv8/scons/engine/SCons/Variables/__init__.py +312 -0
  188. data/lib/libv8/scons/engine/SCons/Warnings.py +246 -0
  189. data/lib/libv8/scons/engine/SCons/__init__.py +49 -0
  190. data/lib/libv8/scons/engine/SCons/compat/__init__.py +237 -0
  191. data/lib/libv8/scons/engine/SCons/compat/_scons_builtins.py +150 -0
  192. data/lib/libv8/scons/engine/SCons/compat/_scons_collections.py +45 -0
  193. data/lib/libv8/scons/engine/SCons/compat/_scons_dbm.py +45 -0
  194. data/lib/libv8/scons/engine/SCons/compat/_scons_hashlib.py +76 -0
  195. data/lib/libv8/scons/engine/SCons/compat/_scons_io.py +45 -0
  196. data/lib/libv8/scons/engine/SCons/compat/_scons_sets.py +563 -0
  197. data/lib/libv8/scons/engine/SCons/compat/_scons_subprocess.py +1281 -0
  198. data/lib/libv8/scons/engine/SCons/cpp.py +589 -0
  199. data/lib/libv8/scons/engine/SCons/dblite.py +251 -0
  200. data/lib/libv8/scons/engine/SCons/exitfuncs.py +77 -0
  201. data/lib/libv8/scons/os_spawnv_fix.diff +83 -0
  202. data/lib/libv8/scons/scons-time.1 +1017 -0
  203. data/lib/libv8/scons/scons.1 +15219 -0
  204. data/lib/libv8/scons/sconsign.1 +208 -0
  205. data/lib/libv8/scons/script/scons +196 -0
  206. data/lib/libv8/scons/script/scons-time +1544 -0
  207. data/lib/libv8/scons/script/scons.bat +31 -0
  208. data/lib/libv8/scons/script/sconsign +513 -0
  209. data/lib/libv8/scons/setup.cfg +6 -0
  210. data/lib/libv8/scons/setup.py +425 -0
  211. data/lib/libv8/v8/.gitignore +35 -0
  212. data/lib/libv8/v8/AUTHORS +44 -0
  213. data/lib/libv8/v8/ChangeLog +2839 -0
  214. data/lib/libv8/v8/LICENSE +52 -0
  215. data/lib/libv8/v8/LICENSE.strongtalk +29 -0
  216. data/lib/libv8/v8/LICENSE.v8 +26 -0
  217. data/lib/libv8/v8/LICENSE.valgrind +45 -0
  218. data/lib/libv8/v8/SConstruct +1478 -0
  219. data/lib/libv8/v8/build/README.txt +49 -0
  220. data/lib/libv8/v8/build/all.gyp +18 -0
  221. data/lib/libv8/v8/build/armu.gypi +32 -0
  222. data/lib/libv8/v8/build/common.gypi +144 -0
  223. data/lib/libv8/v8/build/gyp_v8 +145 -0
  224. data/lib/libv8/v8/include/v8-debug.h +395 -0
  225. data/lib/libv8/v8/include/v8-preparser.h +117 -0
  226. data/lib/libv8/v8/include/v8-profiler.h +505 -0
  227. data/lib/libv8/v8/include/v8-testing.h +104 -0
  228. data/lib/libv8/v8/include/v8.h +4124 -0
  229. data/lib/libv8/v8/include/v8stdint.h +53 -0
  230. data/lib/libv8/v8/preparser/SConscript +38 -0
  231. data/lib/libv8/v8/preparser/preparser-process.cc +379 -0
  232. data/lib/libv8/v8/src/SConscript +368 -0
  233. data/lib/libv8/v8/src/accessors.cc +767 -0
  234. data/lib/libv8/v8/src/accessors.h +123 -0
  235. data/lib/libv8/v8/src/allocation-inl.h +49 -0
  236. data/lib/libv8/v8/src/allocation.cc +122 -0
  237. data/lib/libv8/v8/src/allocation.h +143 -0
  238. data/lib/libv8/v8/src/api.cc +5845 -0
  239. data/lib/libv8/v8/src/api.h +574 -0
  240. data/lib/libv8/v8/src/apinatives.js +110 -0
  241. data/lib/libv8/v8/src/apiutils.h +73 -0
  242. data/lib/libv8/v8/src/arguments.h +118 -0
  243. data/lib/libv8/v8/src/arm/assembler-arm-inl.h +353 -0
  244. data/lib/libv8/v8/src/arm/assembler-arm.cc +2661 -0
  245. data/lib/libv8/v8/src/arm/assembler-arm.h +1375 -0
  246. data/lib/libv8/v8/src/arm/builtins-arm.cc +1658 -0
  247. data/lib/libv8/v8/src/arm/code-stubs-arm.cc +6398 -0
  248. data/lib/libv8/v8/src/arm/code-stubs-arm.h +673 -0
  249. data/lib/libv8/v8/src/arm/codegen-arm.cc +52 -0
  250. data/lib/libv8/v8/src/arm/codegen-arm.h +91 -0
  251. data/lib/libv8/v8/src/arm/constants-arm.cc +152 -0
  252. data/lib/libv8/v8/src/arm/constants-arm.h +775 -0
  253. data/lib/libv8/v8/src/arm/cpu-arm.cc +120 -0
  254. data/lib/libv8/v8/src/arm/debug-arm.cc +317 -0
  255. data/lib/libv8/v8/src/arm/deoptimizer-arm.cc +754 -0
  256. data/lib/libv8/v8/src/arm/disasm-arm.cc +1506 -0
  257. data/lib/libv8/v8/src/arm/frames-arm.cc +45 -0
  258. data/lib/libv8/v8/src/arm/frames-arm.h +168 -0
  259. data/lib/libv8/v8/src/arm/full-codegen-arm.cc +4375 -0
  260. data/lib/libv8/v8/src/arm/ic-arm.cc +1562 -0
  261. data/lib/libv8/v8/src/arm/lithium-arm.cc +2206 -0
  262. data/lib/libv8/v8/src/arm/lithium-arm.h +2348 -0
  263. data/lib/libv8/v8/src/arm/lithium-codegen-arm.cc +4526 -0
  264. data/lib/libv8/v8/src/arm/lithium-codegen-arm.h +403 -0
  265. data/lib/libv8/v8/src/arm/lithium-gap-resolver-arm.cc +305 -0
  266. data/lib/libv8/v8/src/arm/lithium-gap-resolver-arm.h +84 -0
  267. data/lib/libv8/v8/src/arm/macro-assembler-arm.cc +3163 -0
  268. data/lib/libv8/v8/src/arm/macro-assembler-arm.h +1126 -0
  269. data/lib/libv8/v8/src/arm/regexp-macro-assembler-arm.cc +1287 -0
  270. data/lib/libv8/v8/src/arm/regexp-macro-assembler-arm.h +253 -0
  271. data/lib/libv8/v8/src/arm/simulator-arm.cc +3424 -0
  272. data/lib/libv8/v8/src/arm/simulator-arm.h +431 -0
  273. data/lib/libv8/v8/src/arm/stub-cache-arm.cc +4243 -0
  274. data/lib/libv8/v8/src/array.js +1366 -0
  275. data/lib/libv8/v8/src/assembler.cc +1207 -0
  276. data/lib/libv8/v8/src/assembler.h +858 -0
  277. data/lib/libv8/v8/src/ast-inl.h +112 -0
  278. data/lib/libv8/v8/src/ast.cc +1146 -0
  279. data/lib/libv8/v8/src/ast.h +2188 -0
  280. data/lib/libv8/v8/src/atomicops.h +167 -0
  281. data/lib/libv8/v8/src/atomicops_internals_arm_gcc.h +145 -0
  282. data/lib/libv8/v8/src/atomicops_internals_mips_gcc.h +169 -0
  283. data/lib/libv8/v8/src/atomicops_internals_x86_gcc.cc +133 -0
  284. data/lib/libv8/v8/src/atomicops_internals_x86_gcc.h +287 -0
  285. data/lib/libv8/v8/src/atomicops_internals_x86_macosx.h +301 -0
  286. data/lib/libv8/v8/src/atomicops_internals_x86_msvc.h +203 -0
  287. data/lib/libv8/v8/src/bignum-dtoa.cc +655 -0
  288. data/lib/libv8/v8/src/bignum-dtoa.h +81 -0
  289. data/lib/libv8/v8/src/bignum.cc +768 -0
  290. data/lib/libv8/v8/src/bignum.h +140 -0
  291. data/lib/libv8/v8/src/bootstrapper.cc +2184 -0
  292. data/lib/libv8/v8/src/bootstrapper.h +188 -0
  293. data/lib/libv8/v8/src/builtins.cc +1707 -0
  294. data/lib/libv8/v8/src/builtins.h +371 -0
  295. data/lib/libv8/v8/src/bytecodes-irregexp.h +105 -0
  296. data/lib/libv8/v8/src/cached-powers.cc +177 -0
  297. data/lib/libv8/v8/src/cached-powers.h +65 -0
  298. data/lib/libv8/v8/src/char-predicates-inl.h +94 -0
  299. data/lib/libv8/v8/src/char-predicates.h +67 -0
  300. data/lib/libv8/v8/src/checks.cc +110 -0
  301. data/lib/libv8/v8/src/checks.h +296 -0
  302. data/lib/libv8/v8/src/circular-queue-inl.h +53 -0
  303. data/lib/libv8/v8/src/circular-queue.cc +122 -0
  304. data/lib/libv8/v8/src/circular-queue.h +103 -0
  305. data/lib/libv8/v8/src/code-stubs.cc +267 -0
  306. data/lib/libv8/v8/src/code-stubs.h +1011 -0
  307. data/lib/libv8/v8/src/code.h +70 -0
  308. data/lib/libv8/v8/src/codegen.cc +231 -0
  309. data/lib/libv8/v8/src/codegen.h +84 -0
  310. data/lib/libv8/v8/src/compilation-cache.cc +540 -0
  311. data/lib/libv8/v8/src/compilation-cache.h +287 -0
  312. data/lib/libv8/v8/src/compiler.cc +786 -0
  313. data/lib/libv8/v8/src/compiler.h +312 -0
  314. data/lib/libv8/v8/src/contexts.cc +347 -0
  315. data/lib/libv8/v8/src/contexts.h +391 -0
  316. data/lib/libv8/v8/src/conversions-inl.h +106 -0
  317. data/lib/libv8/v8/src/conversions.cc +1131 -0
  318. data/lib/libv8/v8/src/conversions.h +135 -0
  319. data/lib/libv8/v8/src/counters.cc +93 -0
  320. data/lib/libv8/v8/src/counters.h +254 -0
  321. data/lib/libv8/v8/src/cpu-profiler-inl.h +101 -0
  322. data/lib/libv8/v8/src/cpu-profiler.cc +609 -0
  323. data/lib/libv8/v8/src/cpu-profiler.h +302 -0
  324. data/lib/libv8/v8/src/cpu.h +69 -0
  325. data/lib/libv8/v8/src/d8-debug.cc +367 -0
  326. data/lib/libv8/v8/src/d8-debug.h +158 -0
  327. data/lib/libv8/v8/src/d8-posix.cc +695 -0
  328. data/lib/libv8/v8/src/d8-readline.cc +130 -0
  329. data/lib/libv8/v8/src/d8-windows.cc +42 -0
  330. data/lib/libv8/v8/src/d8.cc +803 -0
  331. data/lib/libv8/v8/src/d8.gyp +91 -0
  332. data/lib/libv8/v8/src/d8.h +235 -0
  333. data/lib/libv8/v8/src/d8.js +2798 -0
  334. data/lib/libv8/v8/src/data-flow.cc +66 -0
  335. data/lib/libv8/v8/src/data-flow.h +205 -0
  336. data/lib/libv8/v8/src/date.js +1103 -0
  337. data/lib/libv8/v8/src/dateparser-inl.h +127 -0
  338. data/lib/libv8/v8/src/dateparser.cc +178 -0
  339. data/lib/libv8/v8/src/dateparser.h +266 -0
  340. data/lib/libv8/v8/src/debug-agent.cc +447 -0
  341. data/lib/libv8/v8/src/debug-agent.h +129 -0
  342. data/lib/libv8/v8/src/debug-debugger.js +2569 -0
  343. data/lib/libv8/v8/src/debug.cc +3165 -0
  344. data/lib/libv8/v8/src/debug.h +1057 -0
  345. data/lib/libv8/v8/src/deoptimizer.cc +1256 -0
  346. data/lib/libv8/v8/src/deoptimizer.h +602 -0
  347. data/lib/libv8/v8/src/disasm.h +80 -0
  348. data/lib/libv8/v8/src/disassembler.cc +343 -0
  349. data/lib/libv8/v8/src/disassembler.h +58 -0
  350. data/lib/libv8/v8/src/diy-fp.cc +58 -0
  351. data/lib/libv8/v8/src/diy-fp.h +117 -0
  352. data/lib/libv8/v8/src/double.h +238 -0
  353. data/lib/libv8/v8/src/dtoa.cc +103 -0
  354. data/lib/libv8/v8/src/dtoa.h +85 -0
  355. data/lib/libv8/v8/src/execution.cc +849 -0
  356. data/lib/libv8/v8/src/execution.h +297 -0
  357. data/lib/libv8/v8/src/extensions/experimental/break-iterator.cc +250 -0
  358. data/lib/libv8/v8/src/extensions/experimental/break-iterator.h +89 -0
  359. data/lib/libv8/v8/src/extensions/experimental/collator.cc +218 -0
  360. data/lib/libv8/v8/src/extensions/experimental/collator.h +69 -0
  361. data/lib/libv8/v8/src/extensions/experimental/experimental.gyp +94 -0
  362. data/lib/libv8/v8/src/extensions/experimental/i18n-extension.cc +78 -0
  363. data/lib/libv8/v8/src/extensions/experimental/i18n-extension.h +54 -0
  364. data/lib/libv8/v8/src/extensions/experimental/i18n-locale.cc +112 -0
  365. data/lib/libv8/v8/src/extensions/experimental/i18n-locale.h +60 -0
  366. data/lib/libv8/v8/src/extensions/experimental/i18n-utils.cc +43 -0
  367. data/lib/libv8/v8/src/extensions/experimental/i18n-utils.h +49 -0
  368. data/lib/libv8/v8/src/extensions/experimental/i18n.js +180 -0
  369. data/lib/libv8/v8/src/extensions/experimental/language-matcher.cc +251 -0
  370. data/lib/libv8/v8/src/extensions/experimental/language-matcher.h +95 -0
  371. data/lib/libv8/v8/src/extensions/externalize-string-extension.cc +141 -0
  372. data/lib/libv8/v8/src/extensions/externalize-string-extension.h +50 -0
  373. data/lib/libv8/v8/src/extensions/gc-extension.cc +58 -0
  374. data/lib/libv8/v8/src/extensions/gc-extension.h +49 -0
  375. data/lib/libv8/v8/src/factory.cc +1222 -0
  376. data/lib/libv8/v8/src/factory.h +442 -0
  377. data/lib/libv8/v8/src/fast-dtoa.cc +736 -0
  378. data/lib/libv8/v8/src/fast-dtoa.h +83 -0
  379. data/lib/libv8/v8/src/fixed-dtoa.cc +405 -0
  380. data/lib/libv8/v8/src/fixed-dtoa.h +55 -0
  381. data/lib/libv8/v8/src/flag-definitions.h +560 -0
  382. data/lib/libv8/v8/src/flags.cc +551 -0
  383. data/lib/libv8/v8/src/flags.h +79 -0
  384. data/lib/libv8/v8/src/frames-inl.h +247 -0
  385. data/lib/libv8/v8/src/frames.cc +1243 -0
  386. data/lib/libv8/v8/src/frames.h +870 -0
  387. data/lib/libv8/v8/src/full-codegen.cc +1374 -0
  388. data/lib/libv8/v8/src/full-codegen.h +771 -0
  389. data/lib/libv8/v8/src/func-name-inferrer.cc +92 -0
  390. data/lib/libv8/v8/src/func-name-inferrer.h +111 -0
  391. data/lib/libv8/v8/src/gdb-jit.cc +1555 -0
  392. data/lib/libv8/v8/src/gdb-jit.h +143 -0
  393. data/lib/libv8/v8/src/global-handles.cc +665 -0
  394. data/lib/libv8/v8/src/global-handles.h +284 -0
  395. data/lib/libv8/v8/src/globals.h +325 -0
  396. data/lib/libv8/v8/src/handles-inl.h +177 -0
  397. data/lib/libv8/v8/src/handles.cc +987 -0
  398. data/lib/libv8/v8/src/handles.h +382 -0
  399. data/lib/libv8/v8/src/hashmap.cc +230 -0
  400. data/lib/libv8/v8/src/hashmap.h +123 -0
  401. data/lib/libv8/v8/src/heap-inl.h +704 -0
  402. data/lib/libv8/v8/src/heap-profiler.cc +1173 -0
  403. data/lib/libv8/v8/src/heap-profiler.h +397 -0
  404. data/lib/libv8/v8/src/heap.cc +5930 -0
  405. data/lib/libv8/v8/src/heap.h +2268 -0
  406. data/lib/libv8/v8/src/hydrogen-instructions.cc +1769 -0
  407. data/lib/libv8/v8/src/hydrogen-instructions.h +3971 -0
  408. data/lib/libv8/v8/src/hydrogen.cc +6239 -0
  409. data/lib/libv8/v8/src/hydrogen.h +1202 -0
  410. data/lib/libv8/v8/src/ia32/assembler-ia32-inl.h +446 -0
  411. data/lib/libv8/v8/src/ia32/assembler-ia32.cc +2487 -0
  412. data/lib/libv8/v8/src/ia32/assembler-ia32.h +1144 -0
  413. data/lib/libv8/v8/src/ia32/builtins-ia32.cc +1621 -0
  414. data/lib/libv8/v8/src/ia32/code-stubs-ia32.cc +6198 -0
  415. data/lib/libv8/v8/src/ia32/code-stubs-ia32.h +517 -0
  416. data/lib/libv8/v8/src/ia32/codegen-ia32.cc +265 -0
  417. data/lib/libv8/v8/src/ia32/codegen-ia32.h +79 -0
  418. data/lib/libv8/v8/src/ia32/cpu-ia32.cc +88 -0
  419. data/lib/libv8/v8/src/ia32/debug-ia32.cc +312 -0
  420. data/lib/libv8/v8/src/ia32/deoptimizer-ia32.cc +774 -0
  421. data/lib/libv8/v8/src/ia32/disasm-ia32.cc +1628 -0
  422. data/lib/libv8/v8/src/ia32/frames-ia32.cc +45 -0
  423. data/lib/libv8/v8/src/ia32/frames-ia32.h +142 -0
  424. data/lib/libv8/v8/src/ia32/full-codegen-ia32.cc +4338 -0
  425. data/lib/libv8/v8/src/ia32/ic-ia32.cc +1597 -0
  426. data/lib/libv8/v8/src/ia32/lithium-codegen-ia32.cc +4461 -0
  427. data/lib/libv8/v8/src/ia32/lithium-codegen-ia32.h +375 -0
  428. data/lib/libv8/v8/src/ia32/lithium-gap-resolver-ia32.cc +475 -0
  429. data/lib/libv8/v8/src/ia32/lithium-gap-resolver-ia32.h +110 -0
  430. data/lib/libv8/v8/src/ia32/lithium-ia32.cc +2261 -0
  431. data/lib/libv8/v8/src/ia32/lithium-ia32.h +2396 -0
  432. data/lib/libv8/v8/src/ia32/macro-assembler-ia32.cc +2136 -0
  433. data/lib/libv8/v8/src/ia32/macro-assembler-ia32.h +775 -0
  434. data/lib/libv8/v8/src/ia32/regexp-macro-assembler-ia32.cc +1263 -0
  435. data/lib/libv8/v8/src/ia32/regexp-macro-assembler-ia32.h +216 -0
  436. data/lib/libv8/v8/src/ia32/simulator-ia32.cc +30 -0
  437. data/lib/libv8/v8/src/ia32/simulator-ia32.h +74 -0
  438. data/lib/libv8/v8/src/ia32/stub-cache-ia32.cc +3847 -0
  439. data/lib/libv8/v8/src/ic-inl.h +130 -0
  440. data/lib/libv8/v8/src/ic.cc +2577 -0
  441. data/lib/libv8/v8/src/ic.h +736 -0
  442. data/lib/libv8/v8/src/inspector.cc +63 -0
  443. data/lib/libv8/v8/src/inspector.h +62 -0
  444. data/lib/libv8/v8/src/interpreter-irregexp.cc +659 -0
  445. data/lib/libv8/v8/src/interpreter-irregexp.h +49 -0
  446. data/lib/libv8/v8/src/isolate-inl.h +50 -0
  447. data/lib/libv8/v8/src/isolate.cc +1869 -0
  448. data/lib/libv8/v8/src/isolate.h +1382 -0
  449. data/lib/libv8/v8/src/json-parser.cc +504 -0
  450. data/lib/libv8/v8/src/json-parser.h +161 -0
  451. data/lib/libv8/v8/src/json.js +342 -0
  452. data/lib/libv8/v8/src/jsregexp.cc +5385 -0
  453. data/lib/libv8/v8/src/jsregexp.h +1492 -0
  454. data/lib/libv8/v8/src/list-inl.h +212 -0
  455. data/lib/libv8/v8/src/list.h +174 -0
  456. data/lib/libv8/v8/src/lithium-allocator-inl.h +142 -0
  457. data/lib/libv8/v8/src/lithium-allocator.cc +2123 -0
  458. data/lib/libv8/v8/src/lithium-allocator.h +630 -0
  459. data/lib/libv8/v8/src/lithium.cc +190 -0
  460. data/lib/libv8/v8/src/lithium.h +597 -0
  461. data/lib/libv8/v8/src/liveedit-debugger.js +1082 -0
  462. data/lib/libv8/v8/src/liveedit.cc +1691 -0
  463. data/lib/libv8/v8/src/liveedit.h +180 -0
  464. data/lib/libv8/v8/src/liveobjectlist-inl.h +126 -0
  465. data/lib/libv8/v8/src/liveobjectlist.cc +2589 -0
  466. data/lib/libv8/v8/src/liveobjectlist.h +322 -0
  467. data/lib/libv8/v8/src/log-inl.h +59 -0
  468. data/lib/libv8/v8/src/log-utils.cc +428 -0
  469. data/lib/libv8/v8/src/log-utils.h +231 -0
  470. data/lib/libv8/v8/src/log.cc +1993 -0
  471. data/lib/libv8/v8/src/log.h +476 -0
  472. data/lib/libv8/v8/src/macro-assembler.h +120 -0
  473. data/lib/libv8/v8/src/macros.py +178 -0
  474. data/lib/libv8/v8/src/mark-compact.cc +3143 -0
  475. data/lib/libv8/v8/src/mark-compact.h +506 -0
  476. data/lib/libv8/v8/src/math.js +264 -0
  477. data/lib/libv8/v8/src/messages.cc +179 -0
  478. data/lib/libv8/v8/src/messages.h +113 -0
  479. data/lib/libv8/v8/src/messages.js +1096 -0
  480. data/lib/libv8/v8/src/mips/assembler-mips-inl.h +312 -0
  481. data/lib/libv8/v8/src/mips/assembler-mips.cc +1960 -0
  482. data/lib/libv8/v8/src/mips/assembler-mips.h +1138 -0
  483. data/lib/libv8/v8/src/mips/builtins-mips.cc +1628 -0
  484. data/lib/libv8/v8/src/mips/code-stubs-mips.cc +6656 -0
  485. data/lib/libv8/v8/src/mips/code-stubs-mips.h +682 -0
  486. data/lib/libv8/v8/src/mips/codegen-mips.cc +52 -0
  487. data/lib/libv8/v8/src/mips/codegen-mips.h +98 -0
  488. data/lib/libv8/v8/src/mips/constants-mips.cc +352 -0
  489. data/lib/libv8/v8/src/mips/constants-mips.h +739 -0
  490. data/lib/libv8/v8/src/mips/cpu-mips.cc +96 -0
  491. data/lib/libv8/v8/src/mips/debug-mips.cc +308 -0
  492. data/lib/libv8/v8/src/mips/deoptimizer-mips.cc +91 -0
  493. data/lib/libv8/v8/src/mips/disasm-mips.cc +1050 -0
  494. data/lib/libv8/v8/src/mips/frames-mips.cc +47 -0
  495. data/lib/libv8/v8/src/mips/frames-mips.h +219 -0
  496. data/lib/libv8/v8/src/mips/full-codegen-mips.cc +4388 -0
  497. data/lib/libv8/v8/src/mips/ic-mips.cc +1580 -0
  498. data/lib/libv8/v8/src/mips/lithium-codegen-mips.h +65 -0
  499. data/lib/libv8/v8/src/mips/lithium-mips.h +307 -0
  500. data/lib/libv8/v8/src/mips/macro-assembler-mips.cc +4056 -0
  501. data/lib/libv8/v8/src/mips/macro-assembler-mips.h +1214 -0
  502. data/lib/libv8/v8/src/mips/regexp-macro-assembler-mips.cc +1251 -0
  503. data/lib/libv8/v8/src/mips/regexp-macro-assembler-mips.h +252 -0
  504. data/lib/libv8/v8/src/mips/simulator-mips.cc +2621 -0
  505. data/lib/libv8/v8/src/mips/simulator-mips.h +401 -0
  506. data/lib/libv8/v8/src/mips/stub-cache-mips.cc +4285 -0
  507. data/lib/libv8/v8/src/mirror-debugger.js +2382 -0
  508. data/lib/libv8/v8/src/mksnapshot.cc +328 -0
  509. data/lib/libv8/v8/src/natives.h +64 -0
  510. data/lib/libv8/v8/src/objects-debug.cc +738 -0
  511. data/lib/libv8/v8/src/objects-inl.h +4323 -0
  512. data/lib/libv8/v8/src/objects-printer.cc +829 -0
  513. data/lib/libv8/v8/src/objects-visiting.cc +148 -0
  514. data/lib/libv8/v8/src/objects-visiting.h +424 -0
  515. data/lib/libv8/v8/src/objects.cc +10585 -0
  516. data/lib/libv8/v8/src/objects.h +6838 -0
  517. data/lib/libv8/v8/src/parser.cc +4997 -0
  518. data/lib/libv8/v8/src/parser.h +765 -0
  519. data/lib/libv8/v8/src/platform-cygwin.cc +779 -0
  520. data/lib/libv8/v8/src/platform-freebsd.cc +826 -0
  521. data/lib/libv8/v8/src/platform-linux.cc +1149 -0
  522. data/lib/libv8/v8/src/platform-macos.cc +830 -0
  523. data/lib/libv8/v8/src/platform-nullos.cc +479 -0
  524. data/lib/libv8/v8/src/platform-openbsd.cc +640 -0
  525. data/lib/libv8/v8/src/platform-posix.cc +424 -0
  526. data/lib/libv8/v8/src/platform-solaris.cc +762 -0
  527. data/lib/libv8/v8/src/platform-tls-mac.h +62 -0
  528. data/lib/libv8/v8/src/platform-tls-win32.h +62 -0
  529. data/lib/libv8/v8/src/platform-tls.h +50 -0
  530. data/lib/libv8/v8/src/platform-win32.cc +2021 -0
  531. data/lib/libv8/v8/src/platform.h +667 -0
  532. data/lib/libv8/v8/src/preparse-data-format.h +62 -0
  533. data/lib/libv8/v8/src/preparse-data.cc +183 -0
  534. data/lib/libv8/v8/src/preparse-data.h +225 -0
  535. data/lib/libv8/v8/src/preparser-api.cc +220 -0
  536. data/lib/libv8/v8/src/preparser.cc +1450 -0
  537. data/lib/libv8/v8/src/preparser.h +493 -0
  538. data/lib/libv8/v8/src/prettyprinter.cc +1493 -0
  539. data/lib/libv8/v8/src/prettyprinter.h +223 -0
  540. data/lib/libv8/v8/src/profile-generator-inl.h +128 -0
  541. data/lib/libv8/v8/src/profile-generator.cc +3098 -0
  542. data/lib/libv8/v8/src/profile-generator.h +1126 -0
  543. data/lib/libv8/v8/src/property.cc +105 -0
  544. data/lib/libv8/v8/src/property.h +365 -0
  545. data/lib/libv8/v8/src/proxy.js +83 -0
  546. data/lib/libv8/v8/src/regexp-macro-assembler-irregexp-inl.h +78 -0
  547. data/lib/libv8/v8/src/regexp-macro-assembler-irregexp.cc +471 -0
  548. data/lib/libv8/v8/src/regexp-macro-assembler-irregexp.h +142 -0
  549. data/lib/libv8/v8/src/regexp-macro-assembler-tracer.cc +373 -0
  550. data/lib/libv8/v8/src/regexp-macro-assembler-tracer.h +104 -0
  551. data/lib/libv8/v8/src/regexp-macro-assembler.cc +267 -0
  552. data/lib/libv8/v8/src/regexp-macro-assembler.h +243 -0
  553. data/lib/libv8/v8/src/regexp-stack.cc +111 -0
  554. data/lib/libv8/v8/src/regexp-stack.h +147 -0
  555. data/lib/libv8/v8/src/regexp.js +483 -0
  556. data/lib/libv8/v8/src/rewriter.cc +360 -0
  557. data/lib/libv8/v8/src/rewriter.h +50 -0
  558. data/lib/libv8/v8/src/runtime-profiler.cc +489 -0
  559. data/lib/libv8/v8/src/runtime-profiler.h +201 -0
  560. data/lib/libv8/v8/src/runtime.cc +12227 -0
  561. data/lib/libv8/v8/src/runtime.h +652 -0
  562. data/lib/libv8/v8/src/runtime.js +649 -0
  563. data/lib/libv8/v8/src/safepoint-table.cc +256 -0
  564. data/lib/libv8/v8/src/safepoint-table.h +270 -0
  565. data/lib/libv8/v8/src/scanner-base.cc +952 -0
  566. data/lib/libv8/v8/src/scanner-base.h +670 -0
  567. data/lib/libv8/v8/src/scanner.cc +345 -0
  568. data/lib/libv8/v8/src/scanner.h +146 -0
  569. data/lib/libv8/v8/src/scopeinfo.cc +646 -0
  570. data/lib/libv8/v8/src/scopeinfo.h +254 -0
  571. data/lib/libv8/v8/src/scopes.cc +1150 -0
  572. data/lib/libv8/v8/src/scopes.h +507 -0
  573. data/lib/libv8/v8/src/serialize.cc +1574 -0
  574. data/lib/libv8/v8/src/serialize.h +589 -0
  575. data/lib/libv8/v8/src/shell.h +55 -0
  576. data/lib/libv8/v8/src/simulator.h +43 -0
  577. data/lib/libv8/v8/src/small-pointer-list.h +163 -0
  578. data/lib/libv8/v8/src/smart-pointer.h +109 -0
  579. data/lib/libv8/v8/src/snapshot-common.cc +83 -0
  580. data/lib/libv8/v8/src/snapshot-empty.cc +54 -0
  581. data/lib/libv8/v8/src/snapshot.h +91 -0
  582. data/lib/libv8/v8/src/spaces-inl.h +529 -0
  583. data/lib/libv8/v8/src/spaces.cc +3145 -0
  584. data/lib/libv8/v8/src/spaces.h +2369 -0
  585. data/lib/libv8/v8/src/splay-tree-inl.h +310 -0
  586. data/lib/libv8/v8/src/splay-tree.h +205 -0
  587. data/lib/libv8/v8/src/string-search.cc +41 -0
  588. data/lib/libv8/v8/src/string-search.h +568 -0
  589. data/lib/libv8/v8/src/string-stream.cc +592 -0
  590. data/lib/libv8/v8/src/string-stream.h +191 -0
  591. data/lib/libv8/v8/src/string.js +994 -0
  592. data/lib/libv8/v8/src/strtod.cc +440 -0
  593. data/lib/libv8/v8/src/strtod.h +40 -0
  594. data/lib/libv8/v8/src/stub-cache.cc +1965 -0
  595. data/lib/libv8/v8/src/stub-cache.h +924 -0
  596. data/lib/libv8/v8/src/third_party/valgrind/valgrind.h +3925 -0
  597. data/lib/libv8/v8/src/token.cc +63 -0
  598. data/lib/libv8/v8/src/token.h +288 -0
  599. data/lib/libv8/v8/src/type-info.cc +507 -0
  600. data/lib/libv8/v8/src/type-info.h +272 -0
  601. data/lib/libv8/v8/src/unbound-queue-inl.h +95 -0
  602. data/lib/libv8/v8/src/unbound-queue.h +69 -0
  603. data/lib/libv8/v8/src/unicode-inl.h +238 -0
  604. data/lib/libv8/v8/src/unicode.cc +1624 -0
  605. data/lib/libv8/v8/src/unicode.h +280 -0
  606. data/lib/libv8/v8/src/uri.js +408 -0
  607. data/lib/libv8/v8/src/utils-inl.h +48 -0
  608. data/lib/libv8/v8/src/utils.cc +371 -0
  609. data/lib/libv8/v8/src/utils.h +800 -0
  610. data/lib/libv8/v8/src/v8-counters.cc +62 -0
  611. data/lib/libv8/v8/src/v8-counters.h +314 -0
  612. data/lib/libv8/v8/src/v8.cc +213 -0
  613. data/lib/libv8/v8/src/v8.h +131 -0
  614. data/lib/libv8/v8/src/v8checks.h +64 -0
  615. data/lib/libv8/v8/src/v8dll-main.cc +44 -0
  616. data/lib/libv8/v8/src/v8globals.h +512 -0
  617. data/lib/libv8/v8/src/v8memory.h +82 -0
  618. data/lib/libv8/v8/src/v8natives.js +1310 -0
  619. data/lib/libv8/v8/src/v8preparserdll-main.cc +39 -0
  620. data/lib/libv8/v8/src/v8threads.cc +464 -0
  621. data/lib/libv8/v8/src/v8threads.h +165 -0
  622. data/lib/libv8/v8/src/v8utils.h +319 -0
  623. data/lib/libv8/v8/src/variables.cc +114 -0
  624. data/lib/libv8/v8/src/variables.h +167 -0
  625. data/lib/libv8/v8/src/version.cc +116 -0
  626. data/lib/libv8/v8/src/version.h +68 -0
  627. data/lib/libv8/v8/src/vm-state-inl.h +138 -0
  628. data/lib/libv8/v8/src/vm-state.h +71 -0
  629. data/lib/libv8/v8/src/win32-headers.h +96 -0
  630. data/lib/libv8/v8/src/x64/assembler-x64-inl.h +462 -0
  631. data/lib/libv8/v8/src/x64/assembler-x64.cc +3027 -0
  632. data/lib/libv8/v8/src/x64/assembler-x64.h +1633 -0
  633. data/lib/libv8/v8/src/x64/builtins-x64.cc +1520 -0
  634. data/lib/libv8/v8/src/x64/code-stubs-x64.cc +5132 -0
  635. data/lib/libv8/v8/src/x64/code-stubs-x64.h +514 -0
  636. data/lib/libv8/v8/src/x64/codegen-x64.cc +146 -0
  637. data/lib/libv8/v8/src/x64/codegen-x64.h +76 -0
  638. data/lib/libv8/v8/src/x64/cpu-x64.cc +88 -0
  639. data/lib/libv8/v8/src/x64/debug-x64.cc +319 -0
  640. data/lib/libv8/v8/src/x64/deoptimizer-x64.cc +815 -0
  641. data/lib/libv8/v8/src/x64/disasm-x64.cc +1832 -0
  642. data/lib/libv8/v8/src/x64/frames-x64.cc +45 -0
  643. data/lib/libv8/v8/src/x64/frames-x64.h +130 -0
  644. data/lib/libv8/v8/src/x64/full-codegen-x64.cc +4318 -0
  645. data/lib/libv8/v8/src/x64/ic-x64.cc +1608 -0
  646. data/lib/libv8/v8/src/x64/lithium-codegen-x64.cc +4267 -0
  647. data/lib/libv8/v8/src/x64/lithium-codegen-x64.h +367 -0
  648. data/lib/libv8/v8/src/x64/lithium-gap-resolver-x64.cc +320 -0
  649. data/lib/libv8/v8/src/x64/lithium-gap-resolver-x64.h +74 -0
  650. data/lib/libv8/v8/src/x64/lithium-x64.cc +2202 -0
  651. data/lib/libv8/v8/src/x64/lithium-x64.h +2333 -0
  652. data/lib/libv8/v8/src/x64/macro-assembler-x64.cc +3745 -0
  653. data/lib/libv8/v8/src/x64/macro-assembler-x64.h +1290 -0
  654. data/lib/libv8/v8/src/x64/regexp-macro-assembler-x64.cc +1398 -0
  655. data/lib/libv8/v8/src/x64/regexp-macro-assembler-x64.h +282 -0
  656. data/lib/libv8/v8/src/x64/simulator-x64.cc +27 -0
  657. data/lib/libv8/v8/src/x64/simulator-x64.h +72 -0
  658. data/lib/libv8/v8/src/x64/stub-cache-x64.cc +3610 -0
  659. data/lib/libv8/v8/src/zone-inl.h +140 -0
  660. data/lib/libv8/v8/src/zone.cc +196 -0
  661. data/lib/libv8/v8/src/zone.h +240 -0
  662. data/lib/libv8/v8/tools/codemap.js +265 -0
  663. data/lib/libv8/v8/tools/consarray.js +93 -0
  664. data/lib/libv8/v8/tools/csvparser.js +78 -0
  665. data/lib/libv8/v8/tools/disasm.py +92 -0
  666. data/lib/libv8/v8/tools/freebsd-tick-processor +10 -0
  667. data/lib/libv8/v8/tools/gc-nvp-trace-processor.py +342 -0
  668. data/lib/libv8/v8/tools/gcmole/README +62 -0
  669. data/lib/libv8/v8/tools/gcmole/gccause.lua +60 -0
  670. data/lib/libv8/v8/tools/gcmole/gcmole.cc +1261 -0
  671. data/lib/libv8/v8/tools/gcmole/gcmole.lua +378 -0
  672. data/lib/libv8/v8/tools/generate-ten-powers.scm +286 -0
  673. data/lib/libv8/v8/tools/grokdump.py +841 -0
  674. data/lib/libv8/v8/tools/gyp/v8.gyp +995 -0
  675. data/lib/libv8/v8/tools/js2c.py +364 -0
  676. data/lib/libv8/v8/tools/jsmin.py +280 -0
  677. data/lib/libv8/v8/tools/linux-tick-processor +35 -0
  678. data/lib/libv8/v8/tools/ll_prof.py +942 -0
  679. data/lib/libv8/v8/tools/logreader.js +185 -0
  680. data/lib/libv8/v8/tools/mac-nm +18 -0
  681. data/lib/libv8/v8/tools/mac-tick-processor +6 -0
  682. data/lib/libv8/v8/tools/oom_dump/README +31 -0
  683. data/lib/libv8/v8/tools/oom_dump/SConstruct +42 -0
  684. data/lib/libv8/v8/tools/oom_dump/oom_dump.cc +288 -0
  685. data/lib/libv8/v8/tools/presubmit.py +305 -0
  686. data/lib/libv8/v8/tools/process-heap-prof.py +120 -0
  687. data/lib/libv8/v8/tools/profile.js +751 -0
  688. data/lib/libv8/v8/tools/profile_view.js +219 -0
  689. data/lib/libv8/v8/tools/run-valgrind.py +77 -0
  690. data/lib/libv8/v8/tools/splaytree.js +316 -0
  691. data/lib/libv8/v8/tools/stats-viewer.py +468 -0
  692. data/lib/libv8/v8/tools/test.py +1510 -0
  693. data/lib/libv8/v8/tools/tickprocessor-driver.js +59 -0
  694. data/lib/libv8/v8/tools/tickprocessor.js +877 -0
  695. data/lib/libv8/v8/tools/utils.py +96 -0
  696. data/lib/libv8/v8/tools/visual_studio/README.txt +12 -0
  697. data/lib/libv8/v8/tools/windows-tick-processor.bat +30 -0
  698. data/lib/libv8/version.rb +4 -0
  699. data/libv8.gemspec +31 -0
  700. metadata +800 -0
@@ -0,0 +1,231 @@
1
+ // Copyright 2006-2009 the V8 project authors. All rights reserved.
2
+ // Redistribution and use in source and binary forms, with or without
3
+ // modification, are permitted provided that the following conditions are
4
+ // met:
5
+ //
6
+ // * Redistributions of source code must retain the above copyright
7
+ // notice, this list of conditions and the following disclaimer.
8
+ // * Redistributions in binary form must reproduce the above
9
+ // copyright notice, this list of conditions and the following
10
+ // disclaimer in the documentation and/or other materials provided
11
+ // with the distribution.
12
+ // * Neither the name of Google Inc. nor the names of its
13
+ // contributors may be used to endorse or promote products derived
14
+ // from this software without specific prior written permission.
15
+ //
16
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
+ // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
+ // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
+ // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20
+ // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
+ // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
+ // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
+ // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
+ // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
+ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
+ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
+
28
+ #ifndef V8_LOG_UTILS_H_
29
+ #define V8_LOG_UTILS_H_
30
+
31
+ #include "allocation.h"
32
+
33
+ namespace v8 {
34
+ namespace internal {
35
+
36
+ #ifdef ENABLE_LOGGING_AND_PROFILING
37
+
38
+ class Logger;
39
+
40
+ // A memory buffer that increments its size as you write in it. Size
41
+ // is incremented with 'block_size' steps, never exceeding 'max_size'.
42
+ // During growth, memory contents are never copied. At the end of the
43
+ // buffer an amount of memory specified in 'seal_size' is reserved.
44
+ // When writing position reaches max_size - seal_size, buffer auto-seals
45
+ // itself with 'seal' and allows no further writes. Data pointed by
46
+ // 'seal' must be available during entire LogDynamicBuffer lifetime.
47
+ //
48
+ // An instance of this class is created dynamically by Log.
49
+ class LogDynamicBuffer {
50
+ public:
51
+ LogDynamicBuffer(
52
+ int block_size, int max_size, const char* seal, int seal_size);
53
+
54
+ ~LogDynamicBuffer();
55
+
56
+ // Reads contents of the buffer starting from 'from_pos'. Upon
57
+ // return, 'dest_buf' is filled with the data. Actual amount of data
58
+ // filled is returned, it is <= 'buf_size'.
59
+ int Read(int from_pos, char* dest_buf, int buf_size);
60
+
61
+ // Writes 'data' to the buffer, making it larger if necessary. If
62
+ // data is too big to fit in the buffer, it doesn't get written at
63
+ // all. In that case, buffer auto-seals itself and stops to accept
64
+ // any incoming writes. Returns amount of data written (it is either
65
+ // 'data_size', or 0, if 'data' is too big).
66
+ int Write(const char* data, int data_size);
67
+
68
+ private:
69
+ void AllocateBlock(int index) {
70
+ blocks_[index] = NewArray<char>(block_size_);
71
+ }
72
+
73
+ int BlockIndex(int pos) const { return pos / block_size_; }
74
+
75
+ int BlocksCount() const { return BlockIndex(max_size_) + 1; }
76
+
77
+ int PosInBlock(int pos) const { return pos % block_size_; }
78
+
79
+ int Seal();
80
+
81
+ int WriteInternal(const char* data, int data_size);
82
+
83
+ const int block_size_;
84
+ const int max_size_;
85
+ const char* seal_;
86
+ const int seal_size_;
87
+ ScopedVector<char*> blocks_;
88
+ int write_pos_;
89
+ int block_index_;
90
+ int block_write_pos_;
91
+ bool is_sealed_;
92
+ };
93
+
94
+
95
+ // Functions and data for performing output of log messages.
96
+ class Log {
97
+ public:
98
+
99
+ // Performs process-wide initialization.
100
+ void Initialize();
101
+
102
+ // Disables logging, but preserves acquired resources.
103
+ void stop() { is_stopped_ = true; }
104
+
105
+ // Frees all resources acquired in Initialize and Open... functions.
106
+ void Close();
107
+
108
+ // See description in include/v8.h.
109
+ int GetLogLines(int from_pos, char* dest_buf, int max_size);
110
+
111
+ // Returns whether logging is enabled.
112
+ bool IsEnabled() {
113
+ return !is_stopped_ && (output_handle_ != NULL || output_buffer_ != NULL);
114
+ }
115
+
116
+ // Size of buffer used for formatting log messages.
117
+ static const int kMessageBufferSize = v8::V8::kMinimumSizeForLogLinesBuffer;
118
+
119
+ private:
120
+ explicit Log(Logger* logger);
121
+
122
+ // Opens stdout for logging.
123
+ void OpenStdout();
124
+
125
+ // Opens file for logging.
126
+ void OpenFile(const char* name);
127
+
128
+ // Opens memory buffer for logging.
129
+ void OpenMemoryBuffer();
130
+
131
+ // Implementation of writing to a log file.
132
+ int WriteToFile(const char* msg, int length) {
133
+ ASSERT(output_handle_ != NULL);
134
+ size_t rv = fwrite(msg, 1, length, output_handle_);
135
+ ASSERT(static_cast<size_t>(length) == rv);
136
+ USE(rv);
137
+ fflush(output_handle_);
138
+ return length;
139
+ }
140
+
141
+ // Implementation of writing to a memory buffer.
142
+ int WriteToMemory(const char* msg, int length) {
143
+ ASSERT(output_buffer_ != NULL);
144
+ return output_buffer_->Write(msg, length);
145
+ }
146
+
147
+ bool write_to_file_;
148
+
149
+ // Whether logging is stopped (e.g. due to insufficient resources).
150
+ bool is_stopped_;
151
+
152
+ // When logging is active, either output_handle_ or output_buffer_ is used
153
+ // to store a pointer to log destination. If logging was opened via OpenStdout
154
+ // or OpenFile, then output_handle_ is used. If logging was opened
155
+ // via OpenMemoryBuffer, then output_buffer_ is used.
156
+ // mutex_ should be acquired before using output_handle_ or output_buffer_.
157
+ FILE* output_handle_;
158
+
159
+ // Used when low-level profiling is active.
160
+ FILE* ll_output_handle_;
161
+
162
+ LogDynamicBuffer* output_buffer_;
163
+
164
+ // Size of dynamic buffer block (and dynamic buffer initial size).
165
+ static const int kDynamicBufferBlockSize = 65536;
166
+
167
+ // Maximum size of dynamic buffer.
168
+ static const int kMaxDynamicBufferSize = 50 * 1024 * 1024;
169
+
170
+ // Message to "seal" dynamic buffer with.
171
+ static const char* const kDynamicBufferSeal;
172
+
173
+ // mutex_ is a Mutex used for enforcing exclusive
174
+ // access to the formatting buffer and the log file or log memory buffer.
175
+ Mutex* mutex_;
176
+
177
+ // Buffer used for formatting log messages. This is a singleton buffer and
178
+ // mutex_ should be acquired before using it.
179
+ char* message_buffer_;
180
+
181
+ Logger* logger_;
182
+
183
+ friend class Logger;
184
+ friend class LogMessageBuilder;
185
+ };
186
+
187
+
188
+ // Utility class for formatting log messages. It fills the message into the
189
+ // static buffer in Log.
190
+ class LogMessageBuilder BASE_EMBEDDED {
191
+ public:
192
+ // Create a message builder starting from position 0. This acquires the mutex
193
+ // in the log as well.
194
+ explicit LogMessageBuilder(Logger* logger);
195
+ ~LogMessageBuilder() { }
196
+
197
+ // Append string data to the log message.
198
+ void Append(const char* format, ...);
199
+
200
+ // Append string data to the log message.
201
+ void AppendVA(const char* format, va_list args);
202
+
203
+ // Append a character to the log message.
204
+ void Append(const char c);
205
+
206
+ // Append a heap string.
207
+ void Append(String* str);
208
+
209
+ // Appends an address.
210
+ void AppendAddress(Address addr);
211
+
212
+ void AppendDetailed(String* str, bool show_impl_info);
213
+
214
+ // Append a portion of a string.
215
+ void AppendStringPart(const char* str, int len);
216
+
217
+ // Write the log message to the log file currently opened.
218
+ void WriteToLogFile();
219
+
220
+ private:
221
+
222
+ Log* log_;
223
+ ScopedLock sl;
224
+ int pos_;
225
+ };
226
+
227
+ #endif // ENABLE_LOGGING_AND_PROFILING
228
+
229
+ } } // namespace v8::internal
230
+
231
+ #endif // V8_LOG_UTILS_H_
@@ -0,0 +1,1993 @@
1
+ // Copyright 2011 the V8 project authors. All rights reserved.
2
+ // Redistribution and use in source and binary forms, with or without
3
+ // modification, are permitted provided that the following conditions are
4
+ // met:
5
+ //
6
+ // * Redistributions of source code must retain the above copyright
7
+ // notice, this list of conditions and the following disclaimer.
8
+ // * Redistributions in binary form must reproduce the above
9
+ // copyright notice, this list of conditions and the following
10
+ // disclaimer in the documentation and/or other materials provided
11
+ // with the distribution.
12
+ // * Neither the name of Google Inc. nor the names of its
13
+ // contributors may be used to endorse or promote products derived
14
+ // from this software without specific prior written permission.
15
+ //
16
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
+ // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
+ // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
+ // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20
+ // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
+ // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
+ // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
+ // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
+ // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
+ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
+ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
+
28
+ #include <stdarg.h>
29
+
30
+ #include "v8.h"
31
+
32
+ #include "bootstrapper.h"
33
+ #include "code-stubs.h"
34
+ #include "deoptimizer.h"
35
+ #include "global-handles.h"
36
+ #include "log.h"
37
+ #include "macro-assembler.h"
38
+ #include "runtime-profiler.h"
39
+ #include "serialize.h"
40
+ #include "string-stream.h"
41
+ #include "vm-state-inl.h"
42
+
43
+ namespace v8 {
44
+ namespace internal {
45
+
46
+ #ifdef ENABLE_LOGGING_AND_PROFILING
47
+
48
+ //
49
+ // Sliding state window. Updates counters to keep track of the last
50
+ // window of kBufferSize states. This is useful to track where we
51
+ // spent our time.
52
+ //
53
+ class SlidingStateWindow {
54
+ public:
55
+ explicit SlidingStateWindow(Isolate* isolate);
56
+ ~SlidingStateWindow();
57
+ void AddState(StateTag state);
58
+
59
+ private:
60
+ static const int kBufferSize = 256;
61
+ Counters* counters_;
62
+ int current_index_;
63
+ bool is_full_;
64
+ byte buffer_[kBufferSize];
65
+
66
+
67
+ void IncrementStateCounter(StateTag state) {
68
+ counters_->state_counters(state)->Increment();
69
+ }
70
+
71
+
72
+ void DecrementStateCounter(StateTag state) {
73
+ counters_->state_counters(state)->Decrement();
74
+ }
75
+ };
76
+
77
+
78
+ //
79
+ // The Profiler samples pc and sp values for the main thread.
80
+ // Each sample is appended to a circular buffer.
81
+ // An independent thread removes data and writes it to the log.
82
+ // This design minimizes the time spent in the sampler.
83
+ //
84
+ class Profiler: public Thread {
85
+ public:
86
+ explicit Profiler(Isolate* isolate);
87
+ void Engage();
88
+ void Disengage();
89
+
90
+ // Inserts collected profiling data into buffer.
91
+ void Insert(TickSample* sample) {
92
+ if (paused_)
93
+ return;
94
+
95
+ if (Succ(head_) == tail_) {
96
+ overflow_ = true;
97
+ } else {
98
+ buffer_[head_] = *sample;
99
+ head_ = Succ(head_);
100
+ buffer_semaphore_->Signal(); // Tell we have an element.
101
+ }
102
+ }
103
+
104
+ // Waits for a signal and removes profiling data.
105
+ bool Remove(TickSample* sample) {
106
+ buffer_semaphore_->Wait(); // Wait for an element.
107
+ *sample = buffer_[tail_];
108
+ bool result = overflow_;
109
+ tail_ = Succ(tail_);
110
+ overflow_ = false;
111
+ return result;
112
+ }
113
+
114
+ void Run();
115
+
116
+ // Pause and Resume TickSample data collection.
117
+ bool paused() const { return paused_; }
118
+ void pause() { paused_ = true; }
119
+ void resume() { paused_ = false; }
120
+
121
+ private:
122
+ // Returns the next index in the cyclic buffer.
123
+ int Succ(int index) { return (index + 1) % kBufferSize; }
124
+
125
+ // Cyclic buffer for communicating profiling samples
126
+ // between the signal handler and the worker thread.
127
+ static const int kBufferSize = 128;
128
+ TickSample buffer_[kBufferSize]; // Buffer storage.
129
+ int head_; // Index to the buffer head.
130
+ int tail_; // Index to the buffer tail.
131
+ bool overflow_; // Tell whether a buffer overflow has occurred.
132
+ Semaphore* buffer_semaphore_; // Sempahore used for buffer synchronization.
133
+
134
+ // Tells whether profiler is engaged, that is, processing thread is stated.
135
+ bool engaged_;
136
+
137
+ // Tells whether worker thread should continue running.
138
+ bool running_;
139
+
140
+ // Tells whether we are currently recording tick samples.
141
+ bool paused_;
142
+ };
143
+
144
+
145
+ //
146
+ // StackTracer implementation
147
+ //
148
+ void StackTracer::Trace(Isolate* isolate, TickSample* sample) {
149
+ ASSERT(isolate->IsInitialized());
150
+
151
+ sample->tos = NULL;
152
+ sample->frames_count = 0;
153
+ sample->has_external_callback = false;
154
+
155
+ // Avoid collecting traces while doing GC.
156
+ if (sample->state == GC) return;
157
+
158
+ const Address js_entry_sp =
159
+ Isolate::js_entry_sp(isolate->thread_local_top());
160
+ if (js_entry_sp == 0) {
161
+ // Not executing JS now.
162
+ return;
163
+ }
164
+
165
+ const Address callback = isolate->external_callback();
166
+ if (callback != NULL) {
167
+ sample->external_callback = callback;
168
+ sample->has_external_callback = true;
169
+ } else {
170
+ // Sample potential return address value for frameless invocation of
171
+ // stubs (we'll figure out later, if this value makes sense).
172
+ sample->tos = Memory::Address_at(sample->sp);
173
+ sample->has_external_callback = false;
174
+ }
175
+
176
+ SafeStackTraceFrameIterator it(isolate,
177
+ sample->fp, sample->sp,
178
+ sample->sp, js_entry_sp);
179
+ int i = 0;
180
+ while (!it.done() && i < TickSample::kMaxFramesCount) {
181
+ sample->stack[i++] = it.frame()->pc();
182
+ it.Advance();
183
+ }
184
+ sample->frames_count = i;
185
+ }
186
+
187
+
188
+ //
189
+ // Ticker used to provide ticks to the profiler and the sliding state
190
+ // window.
191
+ //
192
+ class Ticker: public Sampler {
193
+ public:
194
+ Ticker(Isolate* isolate, int interval):
195
+ Sampler(isolate, interval),
196
+ window_(NULL),
197
+ profiler_(NULL) {}
198
+
199
+ ~Ticker() { if (IsActive()) Stop(); }
200
+
201
+ virtual void Tick(TickSample* sample) {
202
+ if (profiler_) profiler_->Insert(sample);
203
+ if (window_) window_->AddState(sample->state);
204
+ }
205
+
206
+ void SetWindow(SlidingStateWindow* window) {
207
+ window_ = window;
208
+ if (!IsActive()) Start();
209
+ }
210
+
211
+ void ClearWindow() {
212
+ window_ = NULL;
213
+ if (!profiler_ && IsActive() && !RuntimeProfiler::IsEnabled()) Stop();
214
+ }
215
+
216
+ void SetProfiler(Profiler* profiler) {
217
+ ASSERT(profiler_ == NULL);
218
+ profiler_ = profiler;
219
+ IncreaseProfilingDepth();
220
+ if (!FLAG_prof_lazy && !IsActive()) Start();
221
+ }
222
+
223
+ void ClearProfiler() {
224
+ DecreaseProfilingDepth();
225
+ profiler_ = NULL;
226
+ if (!window_ && IsActive() && !RuntimeProfiler::IsEnabled()) Stop();
227
+ }
228
+
229
+ protected:
230
+ virtual void DoSampleStack(TickSample* sample) {
231
+ StackTracer::Trace(isolate(), sample);
232
+ }
233
+
234
+ private:
235
+ SlidingStateWindow* window_;
236
+ Profiler* profiler_;
237
+ };
238
+
239
+
240
+ //
241
+ // SlidingStateWindow implementation.
242
+ //
243
+ SlidingStateWindow::SlidingStateWindow(Isolate* isolate)
244
+ : counters_(isolate->counters()), current_index_(0), is_full_(false) {
245
+ for (int i = 0; i < kBufferSize; i++) {
246
+ buffer_[i] = static_cast<byte>(OTHER);
247
+ }
248
+ isolate->logger()->ticker_->SetWindow(this);
249
+ }
250
+
251
+
252
+ SlidingStateWindow::~SlidingStateWindow() {
253
+ LOGGER->ticker_->ClearWindow();
254
+ }
255
+
256
+
257
+ void SlidingStateWindow::AddState(StateTag state) {
258
+ if (is_full_) {
259
+ DecrementStateCounter(static_cast<StateTag>(buffer_[current_index_]));
260
+ } else if (current_index_ == kBufferSize - 1) {
261
+ is_full_ = true;
262
+ }
263
+ buffer_[current_index_] = static_cast<byte>(state);
264
+ IncrementStateCounter(state);
265
+ ASSERT(IsPowerOf2(kBufferSize));
266
+ current_index_ = (current_index_ + 1) & (kBufferSize - 1);
267
+ }
268
+
269
+
270
+ //
271
+ // Profiler implementation.
272
+ //
273
+ Profiler::Profiler(Isolate* isolate)
274
+ : Thread(isolate, "v8:Profiler"),
275
+ head_(0),
276
+ tail_(0),
277
+ overflow_(false),
278
+ buffer_semaphore_(OS::CreateSemaphore(0)),
279
+ engaged_(false),
280
+ running_(false),
281
+ paused_(false) {
282
+ }
283
+
284
+
285
+ void Profiler::Engage() {
286
+ if (engaged_) return;
287
+ engaged_ = true;
288
+
289
+ // TODO(mnaganov): This is actually "Chromium" mode. Flags need to be revised.
290
+ // http://code.google.com/p/v8/issues/detail?id=487
291
+ if (!FLAG_prof_lazy) {
292
+ OS::LogSharedLibraryAddresses();
293
+ }
294
+
295
+ // Start thread processing the profiler buffer.
296
+ running_ = true;
297
+ Start();
298
+
299
+ // Register to get ticks.
300
+ LOGGER->ticker_->SetProfiler(this);
301
+
302
+ LOGGER->ProfilerBeginEvent();
303
+ }
304
+
305
+
306
+ void Profiler::Disengage() {
307
+ if (!engaged_) return;
308
+
309
+ // Stop receiving ticks.
310
+ LOGGER->ticker_->ClearProfiler();
311
+
312
+ // Terminate the worker thread by setting running_ to false,
313
+ // inserting a fake element in the queue and then wait for
314
+ // the thread to terminate.
315
+ running_ = false;
316
+ TickSample sample;
317
+ // Reset 'paused_' flag, otherwise semaphore may not be signalled.
318
+ resume();
319
+ Insert(&sample);
320
+ Join();
321
+
322
+ LOG(ISOLATE, UncheckedStringEvent("profiler", "end"));
323
+ }
324
+
325
+
326
+ void Profiler::Run() {
327
+ TickSample sample;
328
+ bool overflow = Remove(&sample);
329
+ i::Isolate* isolate = ISOLATE;
330
+ while (running_) {
331
+ LOG(isolate, TickEvent(&sample, overflow));
332
+ overflow = Remove(&sample);
333
+ }
334
+ }
335
+
336
+
337
+ // Low-level profiling event structures.
338
+
339
+ struct LowLevelCodeCreateStruct {
340
+ static const char kTag = 'C';
341
+
342
+ int32_t name_size;
343
+ Address code_address;
344
+ int32_t code_size;
345
+ };
346
+
347
+
348
+ struct LowLevelCodeMoveStruct {
349
+ static const char kTag = 'M';
350
+
351
+ Address from_address;
352
+ Address to_address;
353
+ };
354
+
355
+
356
+ struct LowLevelCodeDeleteStruct {
357
+ static const char kTag = 'D';
358
+
359
+ Address address;
360
+ };
361
+
362
+
363
+ struct LowLevelSnapshotPositionStruct {
364
+ static const char kTag = 'P';
365
+
366
+ Address address;
367
+ int32_t position;
368
+ };
369
+
370
+
371
+ static const char kCodeMovingGCTag = 'G';
372
+
373
+
374
+ //
375
+ // Logger class implementation.
376
+ //
377
+
378
+ class Logger::NameMap {
379
+ public:
380
+ NameMap() : impl_(&PointerEquals) {}
381
+
382
+ ~NameMap() {
383
+ for (HashMap::Entry* p = impl_.Start(); p != NULL; p = impl_.Next(p)) {
384
+ DeleteArray(static_cast<const char*>(p->value));
385
+ }
386
+ }
387
+
388
+ void Insert(Address code_address, const char* name, int name_size) {
389
+ HashMap::Entry* entry = FindOrCreateEntry(code_address);
390
+ if (entry->value == NULL) {
391
+ entry->value = CopyName(name, name_size);
392
+ }
393
+ }
394
+
395
+ const char* Lookup(Address code_address) {
396
+ HashMap::Entry* entry = FindEntry(code_address);
397
+ return (entry != NULL) ? static_cast<const char*>(entry->value) : NULL;
398
+ }
399
+
400
+ void Remove(Address code_address) {
401
+ HashMap::Entry* entry = FindEntry(code_address);
402
+ if (entry != NULL) DeleteArray(static_cast<const char*>(entry->value));
403
+ RemoveEntry(entry);
404
+ }
405
+
406
+ void Move(Address from, Address to) {
407
+ if (from == to) return;
408
+ HashMap::Entry* from_entry = FindEntry(from);
409
+ ASSERT(from_entry != NULL);
410
+ void* value = from_entry->value;
411
+ RemoveEntry(from_entry);
412
+ HashMap::Entry* to_entry = FindOrCreateEntry(to);
413
+ ASSERT(to_entry->value == NULL);
414
+ to_entry->value = value;
415
+ }
416
+
417
+ private:
418
+ static bool PointerEquals(void* lhs, void* rhs) {
419
+ return lhs == rhs;
420
+ }
421
+
422
+ static char* CopyName(const char* name, int name_size) {
423
+ char* result = NewArray<char>(name_size + 1);
424
+ for (int i = 0; i < name_size; ++i) {
425
+ char c = name[i];
426
+ if (c == '\0') c = ' ';
427
+ result[i] = c;
428
+ }
429
+ result[name_size] = '\0';
430
+ return result;
431
+ }
432
+
433
+ HashMap::Entry* FindOrCreateEntry(Address code_address) {
434
+ return impl_.Lookup(code_address, ComputePointerHash(code_address), true);
435
+ }
436
+
437
+ HashMap::Entry* FindEntry(Address code_address) {
438
+ return impl_.Lookup(code_address, ComputePointerHash(code_address), false);
439
+ }
440
+
441
+ void RemoveEntry(HashMap::Entry* entry) {
442
+ impl_.Remove(entry->key, entry->hash);
443
+ }
444
+
445
+ HashMap impl_;
446
+
447
+ DISALLOW_COPY_AND_ASSIGN(NameMap);
448
+ };
449
+
450
+
451
+ class Logger::NameBuffer {
452
+ public:
453
+ NameBuffer() { Reset(); }
454
+
455
+ void Reset() {
456
+ utf8_pos_ = 0;
457
+ }
458
+
459
+ void AppendString(String* str) {
460
+ if (str == NULL) return;
461
+ if (str->HasOnlyAsciiChars()) {
462
+ int utf8_length = Min(str->length(), kUtf8BufferSize - utf8_pos_);
463
+ String::WriteToFlat(str, utf8_buffer_ + utf8_pos_, 0, utf8_length);
464
+ utf8_pos_ += utf8_length;
465
+ return;
466
+ }
467
+ int uc16_length = Min(str->length(), kUc16BufferSize);
468
+ String::WriteToFlat(str, uc16_buffer_, 0, uc16_length);
469
+ for (int i = 0; i < uc16_length && utf8_pos_ < kUtf8BufferSize; ++i) {
470
+ uc16 c = uc16_buffer_[i];
471
+ if (c <= String::kMaxAsciiCharCodeU) {
472
+ utf8_buffer_[utf8_pos_++] = static_cast<char>(c);
473
+ } else {
474
+ int char_length = unibrow::Utf8::Length(c);
475
+ if (utf8_pos_ + char_length > kUtf8BufferSize) break;
476
+ unibrow::Utf8::Encode(utf8_buffer_ + utf8_pos_, c);
477
+ utf8_pos_ += char_length;
478
+ }
479
+ }
480
+ }
481
+
482
+ void AppendBytes(const char* bytes, int size) {
483
+ size = Min(size, kUtf8BufferSize - utf8_pos_);
484
+ memcpy(utf8_buffer_ + utf8_pos_, bytes, size);
485
+ utf8_pos_ += size;
486
+ }
487
+
488
+ void AppendBytes(const char* bytes) {
489
+ AppendBytes(bytes, StrLength(bytes));
490
+ }
491
+
492
+ void AppendByte(char c) {
493
+ if (utf8_pos_ >= kUtf8BufferSize) return;
494
+ utf8_buffer_[utf8_pos_++] = c;
495
+ }
496
+
497
+ void AppendInt(int n) {
498
+ Vector<char> buffer(utf8_buffer_ + utf8_pos_, kUtf8BufferSize - utf8_pos_);
499
+ int size = OS::SNPrintF(buffer, "%d", n);
500
+ if (size > 0 && utf8_pos_ + size <= kUtf8BufferSize) {
501
+ utf8_pos_ += size;
502
+ }
503
+ }
504
+
505
+ const char* get() { return utf8_buffer_; }
506
+ int size() const { return utf8_pos_; }
507
+
508
+ private:
509
+ static const int kUtf8BufferSize = 512;
510
+ static const int kUc16BufferSize = 128;
511
+
512
+ int utf8_pos_;
513
+ char utf8_buffer_[kUtf8BufferSize];
514
+ uc16 uc16_buffer_[kUc16BufferSize];
515
+ };
516
+
517
+
518
+ Logger::Logger()
519
+ : ticker_(NULL),
520
+ profiler_(NULL),
521
+ sliding_state_window_(NULL),
522
+ log_events_(NULL),
523
+ logging_nesting_(0),
524
+ cpu_profiler_nesting_(0),
525
+ heap_profiler_nesting_(0),
526
+ log_(new Log(this)),
527
+ name_buffer_(new NameBuffer),
528
+ address_to_name_map_(NULL),
529
+ is_initialized_(false),
530
+ last_address_(NULL),
531
+ prev_sp_(NULL),
532
+ prev_function_(NULL),
533
+ prev_to_(NULL),
534
+ prev_code_(NULL) {
535
+ }
536
+
537
+
538
+ Logger::~Logger() {
539
+ delete address_to_name_map_;
540
+ delete name_buffer_;
541
+ delete log_;
542
+ }
543
+
544
+
545
+ #define DECLARE_EVENT(ignore1, name) name,
546
+ static const char* const kLogEventsNames[Logger::NUMBER_OF_LOG_EVENTS] = {
547
+ LOG_EVENTS_AND_TAGS_LIST(DECLARE_EVENT)
548
+ };
549
+ #undef DECLARE_EVENT
550
+
551
+
552
+ void Logger::ProfilerBeginEvent() {
553
+ if (!log_->IsEnabled()) return;
554
+ LogMessageBuilder msg(this);
555
+ msg.Append("profiler,\"begin\",%d\n", kSamplingIntervalMs);
556
+ msg.WriteToLogFile();
557
+ }
558
+
559
+ #endif // ENABLE_LOGGING_AND_PROFILING
560
+
561
+
562
+ void Logger::StringEvent(const char* name, const char* value) {
563
+ #ifdef ENABLE_LOGGING_AND_PROFILING
564
+ if (FLAG_log) UncheckedStringEvent(name, value);
565
+ #endif
566
+ }
567
+
568
+
569
+ #ifdef ENABLE_LOGGING_AND_PROFILING
570
+ void Logger::UncheckedStringEvent(const char* name, const char* value) {
571
+ if (!log_->IsEnabled()) return;
572
+ LogMessageBuilder msg(this);
573
+ msg.Append("%s,\"%s\"\n", name, value);
574
+ msg.WriteToLogFile();
575
+ }
576
+ #endif
577
+
578
+
579
+ void Logger::IntEvent(const char* name, int value) {
580
+ #ifdef ENABLE_LOGGING_AND_PROFILING
581
+ if (FLAG_log) UncheckedIntEvent(name, value);
582
+ #endif
583
+ }
584
+
585
+
586
+ void Logger::IntPtrTEvent(const char* name, intptr_t value) {
587
+ #ifdef ENABLE_LOGGING_AND_PROFILING
588
+ if (FLAG_log) UncheckedIntPtrTEvent(name, value);
589
+ #endif
590
+ }
591
+
592
+
593
+ #ifdef ENABLE_LOGGING_AND_PROFILING
594
+ void Logger::UncheckedIntEvent(const char* name, int value) {
595
+ if (!log_->IsEnabled()) return;
596
+ LogMessageBuilder msg(this);
597
+ msg.Append("%s,%d\n", name, value);
598
+ msg.WriteToLogFile();
599
+ }
600
+ #endif
601
+
602
+
603
+ #ifdef ENABLE_LOGGING_AND_PROFILING
604
+ void Logger::UncheckedIntPtrTEvent(const char* name, intptr_t value) {
605
+ if (!log_->IsEnabled()) return;
606
+ LogMessageBuilder msg(this);
607
+ msg.Append("%s,%" V8_PTR_PREFIX "d\n", name, value);
608
+ msg.WriteToLogFile();
609
+ }
610
+ #endif
611
+
612
+
613
+ void Logger::HandleEvent(const char* name, Object** location) {
614
+ #ifdef ENABLE_LOGGING_AND_PROFILING
615
+ if (!log_->IsEnabled() || !FLAG_log_handles) return;
616
+ LogMessageBuilder msg(this);
617
+ msg.Append("%s,0x%" V8PRIxPTR "\n", name, location);
618
+ msg.WriteToLogFile();
619
+ #endif
620
+ }
621
+
622
+
623
+ #ifdef ENABLE_LOGGING_AND_PROFILING
624
+ // ApiEvent is private so all the calls come from the Logger class. It is the
625
+ // caller's responsibility to ensure that log is enabled and that
626
+ // FLAG_log_api is true.
627
+ void Logger::ApiEvent(const char* format, ...) {
628
+ ASSERT(log_->IsEnabled() && FLAG_log_api);
629
+ LogMessageBuilder msg(this);
630
+ va_list ap;
631
+ va_start(ap, format);
632
+ msg.AppendVA(format, ap);
633
+ va_end(ap);
634
+ msg.WriteToLogFile();
635
+ }
636
+ #endif
637
+
638
+
639
+ void Logger::ApiNamedSecurityCheck(Object* key) {
640
+ #ifdef ENABLE_LOGGING_AND_PROFILING
641
+ if (!log_->IsEnabled() || !FLAG_log_api) return;
642
+ if (key->IsString()) {
643
+ SmartPointer<char> str =
644
+ String::cast(key)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
645
+ ApiEvent("api,check-security,\"%s\"\n", *str);
646
+ } else if (key->IsUndefined()) {
647
+ ApiEvent("api,check-security,undefined\n");
648
+ } else {
649
+ ApiEvent("api,check-security,['no-name']\n");
650
+ }
651
+ #endif
652
+ }
653
+
654
+
655
+ void Logger::SharedLibraryEvent(const char* library_path,
656
+ uintptr_t start,
657
+ uintptr_t end) {
658
+ #ifdef ENABLE_LOGGING_AND_PROFILING
659
+ if (!log_->IsEnabled() || !FLAG_prof) return;
660
+ LogMessageBuilder msg(this);
661
+ msg.Append("shared-library,\"%s\",0x%08" V8PRIxPTR ",0x%08" V8PRIxPTR "\n",
662
+ library_path,
663
+ start,
664
+ end);
665
+ msg.WriteToLogFile();
666
+ #endif
667
+ }
668
+
669
+
670
+ void Logger::SharedLibraryEvent(const wchar_t* library_path,
671
+ uintptr_t start,
672
+ uintptr_t end) {
673
+ #ifdef ENABLE_LOGGING_AND_PROFILING
674
+ if (!log_->IsEnabled() || !FLAG_prof) return;
675
+ LogMessageBuilder msg(this);
676
+ msg.Append("shared-library,\"%ls\",0x%08" V8PRIxPTR ",0x%08" V8PRIxPTR "\n",
677
+ library_path,
678
+ start,
679
+ end);
680
+ msg.WriteToLogFile();
681
+ #endif
682
+ }
683
+
684
+
685
+ #ifdef ENABLE_LOGGING_AND_PROFILING
686
+ void Logger::LogRegExpSource(Handle<JSRegExp> regexp) {
687
+ // Prints "/" + re.source + "/" +
688
+ // (re.global?"g":"") + (re.ignorecase?"i":"") + (re.multiline?"m":"")
689
+ LogMessageBuilder msg(this);
690
+
691
+ Handle<Object> source = GetProperty(regexp, "source");
692
+ if (!source->IsString()) {
693
+ msg.Append("no source");
694
+ return;
695
+ }
696
+
697
+ switch (regexp->TypeTag()) {
698
+ case JSRegExp::ATOM:
699
+ msg.Append('a');
700
+ break;
701
+ default:
702
+ break;
703
+ }
704
+ msg.Append('/');
705
+ msg.AppendDetailed(*Handle<String>::cast(source), false);
706
+ msg.Append('/');
707
+
708
+ // global flag
709
+ Handle<Object> global = GetProperty(regexp, "global");
710
+ if (global->IsTrue()) {
711
+ msg.Append('g');
712
+ }
713
+ // ignorecase flag
714
+ Handle<Object> ignorecase = GetProperty(regexp, "ignoreCase");
715
+ if (ignorecase->IsTrue()) {
716
+ msg.Append('i');
717
+ }
718
+ // multiline flag
719
+ Handle<Object> multiline = GetProperty(regexp, "multiline");
720
+ if (multiline->IsTrue()) {
721
+ msg.Append('m');
722
+ }
723
+
724
+ msg.WriteToLogFile();
725
+ }
726
+ #endif // ENABLE_LOGGING_AND_PROFILING
727
+
728
+
729
+ void Logger::RegExpCompileEvent(Handle<JSRegExp> regexp, bool in_cache) {
730
+ #ifdef ENABLE_LOGGING_AND_PROFILING
731
+ if (!log_->IsEnabled() || !FLAG_log_regexp) return;
732
+ LogMessageBuilder msg(this);
733
+ msg.Append("regexp-compile,");
734
+ LogRegExpSource(regexp);
735
+ msg.Append(in_cache ? ",hit\n" : ",miss\n");
736
+ msg.WriteToLogFile();
737
+ #endif
738
+ }
739
+
740
+
741
+ void Logger::LogRuntime(Vector<const char> format, JSArray* args) {
742
+ #ifdef ENABLE_LOGGING_AND_PROFILING
743
+ if (!log_->IsEnabled() || !FLAG_log_runtime) return;
744
+ HandleScope scope;
745
+ LogMessageBuilder msg(this);
746
+ for (int i = 0; i < format.length(); i++) {
747
+ char c = format[i];
748
+ if (c == '%' && i <= format.length() - 2) {
749
+ i++;
750
+ ASSERT('0' <= format[i] && format[i] <= '9');
751
+ MaybeObject* maybe = args->GetElement(format[i] - '0');
752
+ Object* obj;
753
+ if (!maybe->ToObject(&obj)) {
754
+ msg.Append("<exception>");
755
+ continue;
756
+ }
757
+ i++;
758
+ switch (format[i]) {
759
+ case 's':
760
+ msg.AppendDetailed(String::cast(obj), false);
761
+ break;
762
+ case 'S':
763
+ msg.AppendDetailed(String::cast(obj), true);
764
+ break;
765
+ case 'r':
766
+ Logger::LogRegExpSource(Handle<JSRegExp>(JSRegExp::cast(obj)));
767
+ break;
768
+ case 'x':
769
+ msg.Append("0x%x", Smi::cast(obj)->value());
770
+ break;
771
+ case 'i':
772
+ msg.Append("%i", Smi::cast(obj)->value());
773
+ break;
774
+ default:
775
+ UNREACHABLE();
776
+ }
777
+ } else {
778
+ msg.Append(c);
779
+ }
780
+ }
781
+ msg.Append('\n');
782
+ msg.WriteToLogFile();
783
+ #endif
784
+ }
785
+
786
+
787
+ void Logger::ApiIndexedSecurityCheck(uint32_t index) {
788
+ #ifdef ENABLE_LOGGING_AND_PROFILING
789
+ if (!log_->IsEnabled() || !FLAG_log_api) return;
790
+ ApiEvent("api,check-security,%u\n", index);
791
+ #endif
792
+ }
793
+
794
+
795
+ void Logger::ApiNamedPropertyAccess(const char* tag,
796
+ JSObject* holder,
797
+ Object* name) {
798
+ #ifdef ENABLE_LOGGING_AND_PROFILING
799
+ ASSERT(name->IsString());
800
+ if (!log_->IsEnabled() || !FLAG_log_api) return;
801
+ String* class_name_obj = holder->class_name();
802
+ SmartPointer<char> class_name =
803
+ class_name_obj->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
804
+ SmartPointer<char> property_name =
805
+ String::cast(name)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
806
+ ApiEvent("api,%s,\"%s\",\"%s\"\n", tag, *class_name, *property_name);
807
+ #endif
808
+ }
809
+
810
+ void Logger::ApiIndexedPropertyAccess(const char* tag,
811
+ JSObject* holder,
812
+ uint32_t index) {
813
+ #ifdef ENABLE_LOGGING_AND_PROFILING
814
+ if (!log_->IsEnabled() || !FLAG_log_api) return;
815
+ String* class_name_obj = holder->class_name();
816
+ SmartPointer<char> class_name =
817
+ class_name_obj->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
818
+ ApiEvent("api,%s,\"%s\",%u\n", tag, *class_name, index);
819
+ #endif
820
+ }
821
+
822
+ void Logger::ApiObjectAccess(const char* tag, JSObject* object) {
823
+ #ifdef ENABLE_LOGGING_AND_PROFILING
824
+ if (!log_->IsEnabled() || !FLAG_log_api) return;
825
+ String* class_name_obj = object->class_name();
826
+ SmartPointer<char> class_name =
827
+ class_name_obj->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
828
+ ApiEvent("api,%s,\"%s\"\n", tag, *class_name);
829
+ #endif
830
+ }
831
+
832
+
833
+ void Logger::ApiEntryCall(const char* name) {
834
+ #ifdef ENABLE_LOGGING_AND_PROFILING
835
+ if (!log_->IsEnabled() || !FLAG_log_api) return;
836
+ ApiEvent("api,%s\n", name);
837
+ #endif
838
+ }
839
+
840
+
841
+ void Logger::NewEvent(const char* name, void* object, size_t size) {
842
+ #ifdef ENABLE_LOGGING_AND_PROFILING
843
+ if (!log_->IsEnabled() || !FLAG_log) return;
844
+ LogMessageBuilder msg(this);
845
+ msg.Append("new,%s,0x%" V8PRIxPTR ",%u\n", name, object,
846
+ static_cast<unsigned int>(size));
847
+ msg.WriteToLogFile();
848
+ #endif
849
+ }
850
+
851
+
852
+ void Logger::DeleteEvent(const char* name, void* object) {
853
+ #ifdef ENABLE_LOGGING_AND_PROFILING
854
+ if (!log_->IsEnabled() || !FLAG_log) return;
855
+ LogMessageBuilder msg(this);
856
+ msg.Append("delete,%s,0x%" V8PRIxPTR "\n", name, object);
857
+ msg.WriteToLogFile();
858
+ #endif
859
+ }
860
+
861
+
862
+ void Logger::NewEventStatic(const char* name, void* object, size_t size) {
863
+ LOGGER->NewEvent(name, object, size);
864
+ }
865
+
866
+
867
+ void Logger::DeleteEventStatic(const char* name, void* object) {
868
+ LOGGER->DeleteEvent(name, object);
869
+ }
870
+
871
+ #ifdef ENABLE_LOGGING_AND_PROFILING
872
+ void Logger::CallbackEventInternal(const char* prefix, const char* name,
873
+ Address entry_point) {
874
+ if (!log_->IsEnabled() || !FLAG_log_code) return;
875
+ LogMessageBuilder msg(this);
876
+ msg.Append("%s,%s,",
877
+ kLogEventsNames[CODE_CREATION_EVENT],
878
+ kLogEventsNames[CALLBACK_TAG]);
879
+ msg.AppendAddress(entry_point);
880
+ msg.Append(",1,\"%s%s\"", prefix, name);
881
+ msg.Append('\n');
882
+ msg.WriteToLogFile();
883
+ }
884
+ #endif
885
+
886
+
887
+ void Logger::CallbackEvent(String* name, Address entry_point) {
888
+ #ifdef ENABLE_LOGGING_AND_PROFILING
889
+ if (!log_->IsEnabled() || !FLAG_log_code) return;
890
+ SmartPointer<char> str =
891
+ name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
892
+ CallbackEventInternal("", *str, entry_point);
893
+ #endif
894
+ }
895
+
896
+
897
+ void Logger::GetterCallbackEvent(String* name, Address entry_point) {
898
+ #ifdef ENABLE_LOGGING_AND_PROFILING
899
+ if (!log_->IsEnabled() || !FLAG_log_code) return;
900
+ SmartPointer<char> str =
901
+ name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
902
+ CallbackEventInternal("get ", *str, entry_point);
903
+ #endif
904
+ }
905
+
906
+
907
+ void Logger::SetterCallbackEvent(String* name, Address entry_point) {
908
+ #ifdef ENABLE_LOGGING_AND_PROFILING
909
+ if (!log_->IsEnabled() || !FLAG_log_code) return;
910
+ SmartPointer<char> str =
911
+ name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
912
+ CallbackEventInternal("set ", *str, entry_point);
913
+ #endif
914
+ }
915
+
916
+
917
+ void Logger::CodeCreateEvent(LogEventsAndTags tag,
918
+ Code* code,
919
+ const char* comment) {
920
+ #ifdef ENABLE_LOGGING_AND_PROFILING
921
+ if (!log_->IsEnabled()) return;
922
+ if (FLAG_ll_prof || Serializer::enabled()) {
923
+ name_buffer_->Reset();
924
+ name_buffer_->AppendBytes(kLogEventsNames[tag]);
925
+ name_buffer_->AppendByte(':');
926
+ name_buffer_->AppendBytes(comment);
927
+ }
928
+ if (FLAG_ll_prof) {
929
+ LowLevelCodeCreateEvent(code, name_buffer_->get(), name_buffer_->size());
930
+ }
931
+ if (Serializer::enabled()) {
932
+ RegisterSnapshotCodeName(code, name_buffer_->get(), name_buffer_->size());
933
+ }
934
+ if (!FLAG_log_code) return;
935
+ LogMessageBuilder msg(this);
936
+ msg.Append("%s,%s,",
937
+ kLogEventsNames[CODE_CREATION_EVENT],
938
+ kLogEventsNames[tag]);
939
+ msg.AppendAddress(code->address());
940
+ msg.Append(",%d,\"", code->ExecutableSize());
941
+ for (const char* p = comment; *p != '\0'; p++) {
942
+ if (*p == '"') {
943
+ msg.Append('\\');
944
+ }
945
+ msg.Append(*p);
946
+ }
947
+ msg.Append('"');
948
+ msg.Append('\n');
949
+ msg.WriteToLogFile();
950
+ #endif
951
+ }
952
+
953
+
954
+ void Logger::CodeCreateEvent(LogEventsAndTags tag,
955
+ Code* code,
956
+ String* name) {
957
+ #ifdef ENABLE_LOGGING_AND_PROFILING
958
+ if (!log_->IsEnabled()) return;
959
+ if (FLAG_ll_prof || Serializer::enabled()) {
960
+ name_buffer_->Reset();
961
+ name_buffer_->AppendBytes(kLogEventsNames[tag]);
962
+ name_buffer_->AppendByte(':');
963
+ name_buffer_->AppendString(name);
964
+ }
965
+ if (FLAG_ll_prof) {
966
+ LowLevelCodeCreateEvent(code, name_buffer_->get(), name_buffer_->size());
967
+ }
968
+ if (Serializer::enabled()) {
969
+ RegisterSnapshotCodeName(code, name_buffer_->get(), name_buffer_->size());
970
+ }
971
+ if (!FLAG_log_code) return;
972
+ LogMessageBuilder msg(this);
973
+ msg.Append("%s,%s,",
974
+ kLogEventsNames[CODE_CREATION_EVENT],
975
+ kLogEventsNames[tag]);
976
+ msg.AppendAddress(code->address());
977
+ msg.Append(",%d,\"", code->ExecutableSize());
978
+ msg.AppendDetailed(name, false);
979
+ msg.Append('"');
980
+ msg.Append('\n');
981
+ msg.WriteToLogFile();
982
+ #endif
983
+ }
984
+
985
+
986
+ #ifdef ENABLE_LOGGING_AND_PROFILING
987
+ // ComputeMarker must only be used when SharedFunctionInfo is known.
988
+ static const char* ComputeMarker(Code* code) {
989
+ switch (code->kind()) {
990
+ case Code::FUNCTION: return code->optimizable() ? "~" : "";
991
+ case Code::OPTIMIZED_FUNCTION: return "*";
992
+ default: return "";
993
+ }
994
+ }
995
+ #endif
996
+
997
+
998
+ void Logger::CodeCreateEvent(LogEventsAndTags tag,
999
+ Code* code,
1000
+ SharedFunctionInfo* shared,
1001
+ String* name) {
1002
+ #ifdef ENABLE_LOGGING_AND_PROFILING
1003
+ if (!log_->IsEnabled()) return;
1004
+ if (FLAG_ll_prof || Serializer::enabled()) {
1005
+ name_buffer_->Reset();
1006
+ name_buffer_->AppendBytes(kLogEventsNames[tag]);
1007
+ name_buffer_->AppendByte(':');
1008
+ name_buffer_->AppendBytes(ComputeMarker(code));
1009
+ name_buffer_->AppendString(name);
1010
+ }
1011
+ if (FLAG_ll_prof) {
1012
+ LowLevelCodeCreateEvent(code, name_buffer_->get(), name_buffer_->size());
1013
+ }
1014
+ if (Serializer::enabled()) {
1015
+ RegisterSnapshotCodeName(code, name_buffer_->get(), name_buffer_->size());
1016
+ }
1017
+ if (!FLAG_log_code) return;
1018
+ if (code == Isolate::Current()->builtins()->builtin(
1019
+ Builtins::kLazyCompile))
1020
+ return;
1021
+
1022
+ LogMessageBuilder msg(this);
1023
+ SmartPointer<char> str =
1024
+ name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
1025
+ msg.Append("%s,%s,",
1026
+ kLogEventsNames[CODE_CREATION_EVENT],
1027
+ kLogEventsNames[tag]);
1028
+ msg.AppendAddress(code->address());
1029
+ msg.Append(",%d,\"%s\",", code->ExecutableSize(), *str);
1030
+ msg.AppendAddress(shared->address());
1031
+ msg.Append(",%s", ComputeMarker(code));
1032
+ msg.Append('\n');
1033
+ msg.WriteToLogFile();
1034
+ #endif
1035
+ }
1036
+
1037
+
1038
+ // Although, it is possible to extract source and line from
1039
+ // the SharedFunctionInfo object, we left it to caller
1040
+ // to leave logging functions free from heap allocations.
1041
+ void Logger::CodeCreateEvent(LogEventsAndTags tag,
1042
+ Code* code,
1043
+ SharedFunctionInfo* shared,
1044
+ String* source, int line) {
1045
+ #ifdef ENABLE_LOGGING_AND_PROFILING
1046
+ if (!log_->IsEnabled()) return;
1047
+ if (FLAG_ll_prof || Serializer::enabled()) {
1048
+ name_buffer_->Reset();
1049
+ name_buffer_->AppendBytes(kLogEventsNames[tag]);
1050
+ name_buffer_->AppendByte(':');
1051
+ name_buffer_->AppendBytes(ComputeMarker(code));
1052
+ name_buffer_->AppendString(shared->DebugName());
1053
+ name_buffer_->AppendByte(' ');
1054
+ name_buffer_->AppendString(source);
1055
+ name_buffer_->AppendByte(':');
1056
+ name_buffer_->AppendInt(line);
1057
+ }
1058
+ if (FLAG_ll_prof) {
1059
+ LowLevelCodeCreateEvent(code, name_buffer_->get(), name_buffer_->size());
1060
+ }
1061
+ if (Serializer::enabled()) {
1062
+ RegisterSnapshotCodeName(code, name_buffer_->get(), name_buffer_->size());
1063
+ }
1064
+ if (!FLAG_log_code) return;
1065
+ LogMessageBuilder msg(this);
1066
+ SmartPointer<char> name =
1067
+ shared->DebugName()->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
1068
+ SmartPointer<char> sourcestr =
1069
+ source->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
1070
+ msg.Append("%s,%s,",
1071
+ kLogEventsNames[CODE_CREATION_EVENT],
1072
+ kLogEventsNames[tag]);
1073
+ msg.AppendAddress(code->address());
1074
+ msg.Append(",%d,\"%s %s:%d\",",
1075
+ code->ExecutableSize(),
1076
+ *name,
1077
+ *sourcestr,
1078
+ line);
1079
+ msg.AppendAddress(shared->address());
1080
+ msg.Append(",%s", ComputeMarker(code));
1081
+ msg.Append('\n');
1082
+ msg.WriteToLogFile();
1083
+ #endif
1084
+ }
1085
+
1086
+
1087
+ void Logger::CodeCreateEvent(LogEventsAndTags tag, Code* code, int args_count) {
1088
+ #ifdef ENABLE_LOGGING_AND_PROFILING
1089
+ if (!log_->IsEnabled()) return;
1090
+ if (FLAG_ll_prof || Serializer::enabled()) {
1091
+ name_buffer_->Reset();
1092
+ name_buffer_->AppendBytes(kLogEventsNames[tag]);
1093
+ name_buffer_->AppendByte(':');
1094
+ name_buffer_->AppendInt(args_count);
1095
+ }
1096
+ if (FLAG_ll_prof) {
1097
+ LowLevelCodeCreateEvent(code, name_buffer_->get(), name_buffer_->size());
1098
+ }
1099
+ if (Serializer::enabled()) {
1100
+ RegisterSnapshotCodeName(code, name_buffer_->get(), name_buffer_->size());
1101
+ }
1102
+ if (!FLAG_log_code) return;
1103
+ LogMessageBuilder msg(this);
1104
+ msg.Append("%s,%s,",
1105
+ kLogEventsNames[CODE_CREATION_EVENT],
1106
+ kLogEventsNames[tag]);
1107
+ msg.AppendAddress(code->address());
1108
+ msg.Append(",%d,\"args_count: %d\"", code->ExecutableSize(), args_count);
1109
+ msg.Append('\n');
1110
+ msg.WriteToLogFile();
1111
+ #endif
1112
+ }
1113
+
1114
+
1115
+ void Logger::CodeMovingGCEvent() {
1116
+ #ifdef ENABLE_LOGGING_AND_PROFILING
1117
+ if (!log_->IsEnabled() || !FLAG_ll_prof) return;
1118
+ LowLevelLogWriteBytes(&kCodeMovingGCTag, sizeof(kCodeMovingGCTag));
1119
+ OS::SignalCodeMovingGC();
1120
+ #endif
1121
+ }
1122
+
1123
+
1124
+ void Logger::RegExpCodeCreateEvent(Code* code, String* source) {
1125
+ #ifdef ENABLE_LOGGING_AND_PROFILING
1126
+ if (!log_->IsEnabled()) return;
1127
+ if (FLAG_ll_prof || Serializer::enabled()) {
1128
+ name_buffer_->Reset();
1129
+ name_buffer_->AppendBytes(kLogEventsNames[REG_EXP_TAG]);
1130
+ name_buffer_->AppendByte(':');
1131
+ name_buffer_->AppendString(source);
1132
+ }
1133
+ if (FLAG_ll_prof) {
1134
+ LowLevelCodeCreateEvent(code, name_buffer_->get(), name_buffer_->size());
1135
+ }
1136
+ if (Serializer::enabled()) {
1137
+ RegisterSnapshotCodeName(code, name_buffer_->get(), name_buffer_->size());
1138
+ }
1139
+ if (!FLAG_log_code) return;
1140
+ LogMessageBuilder msg(this);
1141
+ msg.Append("%s,%s,",
1142
+ kLogEventsNames[CODE_CREATION_EVENT],
1143
+ kLogEventsNames[REG_EXP_TAG]);
1144
+ msg.AppendAddress(code->address());
1145
+ msg.Append(",%d,\"", code->ExecutableSize());
1146
+ msg.AppendDetailed(source, false);
1147
+ msg.Append('\"');
1148
+ msg.Append('\n');
1149
+ msg.WriteToLogFile();
1150
+ #endif
1151
+ }
1152
+
1153
+
1154
+ void Logger::CodeMoveEvent(Address from, Address to) {
1155
+ #ifdef ENABLE_LOGGING_AND_PROFILING
1156
+ if (!log_->IsEnabled()) return;
1157
+ if (FLAG_ll_prof) LowLevelCodeMoveEvent(from, to);
1158
+ if (Serializer::enabled() && address_to_name_map_ != NULL) {
1159
+ address_to_name_map_->Move(from, to);
1160
+ }
1161
+ MoveEventInternal(CODE_MOVE_EVENT, from, to);
1162
+ #endif
1163
+ }
1164
+
1165
+
1166
+ void Logger::CodeDeleteEvent(Address from) {
1167
+ #ifdef ENABLE_LOGGING_AND_PROFILING
1168
+ if (!log_->IsEnabled()) return;
1169
+ if (FLAG_ll_prof) LowLevelCodeDeleteEvent(from);
1170
+ if (Serializer::enabled() && address_to_name_map_ != NULL) {
1171
+ address_to_name_map_->Remove(from);
1172
+ }
1173
+ DeleteEventInternal(CODE_DELETE_EVENT, from);
1174
+ #endif
1175
+ }
1176
+
1177
+
1178
+ void Logger::SnapshotPositionEvent(Address addr, int pos) {
1179
+ #ifdef ENABLE_LOGGING_AND_PROFILING
1180
+ if (!log_->IsEnabled()) return;
1181
+ if (FLAG_ll_prof) LowLevelSnapshotPositionEvent(addr, pos);
1182
+ if (Serializer::enabled() && address_to_name_map_ != NULL) {
1183
+ const char* code_name = address_to_name_map_->Lookup(addr);
1184
+ if (code_name == NULL) return; // Not a code object.
1185
+ LogMessageBuilder msg(this);
1186
+ msg.Append("%s,%d,\"", kLogEventsNames[SNAPSHOT_CODE_NAME_EVENT], pos);
1187
+ for (const char* p = code_name; *p != '\0'; ++p) {
1188
+ if (*p == '"') msg.Append('\\');
1189
+ msg.Append(*p);
1190
+ }
1191
+ msg.Append("\"\n");
1192
+ msg.WriteToLogFile();
1193
+ }
1194
+ if (!FLAG_log_snapshot_positions) return;
1195
+ LogMessageBuilder msg(this);
1196
+ msg.Append("%s,", kLogEventsNames[SNAPSHOT_POSITION_EVENT]);
1197
+ msg.AppendAddress(addr);
1198
+ msg.Append(",%d", pos);
1199
+ msg.Append('\n');
1200
+ msg.WriteToLogFile();
1201
+ #endif
1202
+ }
1203
+
1204
+
1205
+ void Logger::SharedFunctionInfoMoveEvent(Address from, Address to) {
1206
+ #ifdef ENABLE_LOGGING_AND_PROFILING
1207
+ MoveEventInternal(SHARED_FUNC_MOVE_EVENT, from, to);
1208
+ #endif
1209
+ }
1210
+
1211
+
1212
+ #ifdef ENABLE_LOGGING_AND_PROFILING
1213
+ void Logger::MoveEventInternal(LogEventsAndTags event,
1214
+ Address from,
1215
+ Address to) {
1216
+ if (!log_->IsEnabled() || !FLAG_log_code) return;
1217
+ LogMessageBuilder msg(this);
1218
+ msg.Append("%s,", kLogEventsNames[event]);
1219
+ msg.AppendAddress(from);
1220
+ msg.Append(',');
1221
+ msg.AppendAddress(to);
1222
+ msg.Append('\n');
1223
+ msg.WriteToLogFile();
1224
+ }
1225
+ #endif
1226
+
1227
+
1228
+ #ifdef ENABLE_LOGGING_AND_PROFILING
1229
+ void Logger::DeleteEventInternal(LogEventsAndTags event, Address from) {
1230
+ if (!log_->IsEnabled() || !FLAG_log_code) return;
1231
+ LogMessageBuilder msg(this);
1232
+ msg.Append("%s,", kLogEventsNames[event]);
1233
+ msg.AppendAddress(from);
1234
+ msg.Append('\n');
1235
+ msg.WriteToLogFile();
1236
+ }
1237
+ #endif
1238
+
1239
+
1240
+ void Logger::ResourceEvent(const char* name, const char* tag) {
1241
+ #ifdef ENABLE_LOGGING_AND_PROFILING
1242
+ if (!log_->IsEnabled() || !FLAG_log) return;
1243
+ LogMessageBuilder msg(this);
1244
+ msg.Append("%s,%s,", name, tag);
1245
+
1246
+ uint32_t sec, usec;
1247
+ if (OS::GetUserTime(&sec, &usec) != -1) {
1248
+ msg.Append("%d,%d,", sec, usec);
1249
+ }
1250
+ msg.Append("%.0f", OS::TimeCurrentMillis());
1251
+
1252
+ msg.Append('\n');
1253
+ msg.WriteToLogFile();
1254
+ #endif
1255
+ }
1256
+
1257
+
1258
+ void Logger::SuspectReadEvent(String* name, Object* obj) {
1259
+ #ifdef ENABLE_LOGGING_AND_PROFILING
1260
+ if (!log_->IsEnabled() || !FLAG_log_suspect) return;
1261
+ LogMessageBuilder msg(this);
1262
+ String* class_name = obj->IsJSObject()
1263
+ ? JSObject::cast(obj)->class_name()
1264
+ : HEAP->empty_string();
1265
+ msg.Append("suspect-read,");
1266
+ msg.Append(class_name);
1267
+ msg.Append(',');
1268
+ msg.Append('"');
1269
+ msg.Append(name);
1270
+ msg.Append('"');
1271
+ msg.Append('\n');
1272
+ msg.WriteToLogFile();
1273
+ #endif
1274
+ }
1275
+
1276
+
1277
+ void Logger::HeapSampleBeginEvent(const char* space, const char* kind) {
1278
+ #ifdef ENABLE_LOGGING_AND_PROFILING
1279
+ if (!log_->IsEnabled() || !FLAG_log_gc) return;
1280
+ LogMessageBuilder msg(this);
1281
+ // Using non-relative system time in order to be able to synchronize with
1282
+ // external memory profiling events (e.g. DOM memory size).
1283
+ msg.Append("heap-sample-begin,\"%s\",\"%s\",%.0f\n",
1284
+ space, kind, OS::TimeCurrentMillis());
1285
+ msg.WriteToLogFile();
1286
+ #endif
1287
+ }
1288
+
1289
+
1290
+ void Logger::HeapSampleStats(const char* space, const char* kind,
1291
+ intptr_t capacity, intptr_t used) {
1292
+ #ifdef ENABLE_LOGGING_AND_PROFILING
1293
+ if (!log_->IsEnabled() || !FLAG_log_gc) return;
1294
+ LogMessageBuilder msg(this);
1295
+ msg.Append("heap-sample-stats,\"%s\",\"%s\","
1296
+ "%" V8_PTR_PREFIX "d,%" V8_PTR_PREFIX "d\n",
1297
+ space, kind, capacity, used);
1298
+ msg.WriteToLogFile();
1299
+ #endif
1300
+ }
1301
+
1302
+
1303
+ void Logger::HeapSampleEndEvent(const char* space, const char* kind) {
1304
+ #ifdef ENABLE_LOGGING_AND_PROFILING
1305
+ if (!log_->IsEnabled() || !FLAG_log_gc) return;
1306
+ LogMessageBuilder msg(this);
1307
+ msg.Append("heap-sample-end,\"%s\",\"%s\"\n", space, kind);
1308
+ msg.WriteToLogFile();
1309
+ #endif
1310
+ }
1311
+
1312
+
1313
+ void Logger::HeapSampleItemEvent(const char* type, int number, int bytes) {
1314
+ #ifdef ENABLE_LOGGING_AND_PROFILING
1315
+ if (!log_->IsEnabled() || !FLAG_log_gc) return;
1316
+ LogMessageBuilder msg(this);
1317
+ msg.Append("heap-sample-item,%s,%d,%d\n", type, number, bytes);
1318
+ msg.WriteToLogFile();
1319
+ #endif
1320
+ }
1321
+
1322
+
1323
+ void Logger::HeapSampleJSConstructorEvent(const char* constructor,
1324
+ int number, int bytes) {
1325
+ #ifdef ENABLE_LOGGING_AND_PROFILING
1326
+ if (!log_->IsEnabled() || !FLAG_log_gc) return;
1327
+ LogMessageBuilder msg(this);
1328
+ msg.Append("heap-js-cons-item,%s,%d,%d\n", constructor, number, bytes);
1329
+ msg.WriteToLogFile();
1330
+ #endif
1331
+ }
1332
+
1333
+ // Event starts with comma, so we don't have it in the format string.
1334
+ static const char kEventText[] = "heap-js-ret-item,%s";
1335
+ // We take placeholder strings into account, but it's OK to be conservative.
1336
+ static const int kEventTextLen = sizeof(kEventText)/sizeof(kEventText[0]);
1337
+
1338
+ void Logger::HeapSampleJSRetainersEvent(
1339
+ const char* constructor, const char* event) {
1340
+ #ifdef ENABLE_LOGGING_AND_PROFILING
1341
+ if (!log_->IsEnabled() || !FLAG_log_gc) return;
1342
+ const int cons_len = StrLength(constructor);
1343
+ const int event_len = StrLength(event);
1344
+ int pos = 0;
1345
+ // Retainer lists can be long. We may need to split them into multiple events.
1346
+ do {
1347
+ LogMessageBuilder msg(this);
1348
+ msg.Append(kEventText, constructor);
1349
+ int to_write = event_len - pos;
1350
+ if (to_write > Log::kMessageBufferSize - (cons_len + kEventTextLen)) {
1351
+ int cut_pos = pos + Log::kMessageBufferSize - (cons_len + kEventTextLen);
1352
+ ASSERT(cut_pos < event_len);
1353
+ while (cut_pos > pos && event[cut_pos] != ',') --cut_pos;
1354
+ if (event[cut_pos] != ',') {
1355
+ // Crash in debug mode, skip in release mode.
1356
+ ASSERT(false);
1357
+ return;
1358
+ }
1359
+ // Append a piece of event that fits, without trailing comma.
1360
+ msg.AppendStringPart(event + pos, cut_pos - pos);
1361
+ // Start next piece with comma.
1362
+ pos = cut_pos;
1363
+ } else {
1364
+ msg.Append("%s", event + pos);
1365
+ pos += event_len;
1366
+ }
1367
+ msg.Append('\n');
1368
+ msg.WriteToLogFile();
1369
+ } while (pos < event_len);
1370
+ #endif
1371
+ }
1372
+
1373
+
1374
+ void Logger::HeapSampleJSProducerEvent(const char* constructor,
1375
+ Address* stack) {
1376
+ #ifdef ENABLE_LOGGING_AND_PROFILING
1377
+ if (!log_->IsEnabled() || !FLAG_log_gc) return;
1378
+ LogMessageBuilder msg(this);
1379
+ msg.Append("heap-js-prod-item,%s", constructor);
1380
+ while (*stack != NULL) {
1381
+ msg.Append(",0x%" V8PRIxPTR, *stack++);
1382
+ }
1383
+ msg.Append("\n");
1384
+ msg.WriteToLogFile();
1385
+ #endif
1386
+ }
1387
+
1388
+
1389
+ void Logger::DebugTag(const char* call_site_tag) {
1390
+ #ifdef ENABLE_LOGGING_AND_PROFILING
1391
+ if (!log_->IsEnabled() || !FLAG_log) return;
1392
+ LogMessageBuilder msg(this);
1393
+ msg.Append("debug-tag,%s\n", call_site_tag);
1394
+ msg.WriteToLogFile();
1395
+ #endif
1396
+ }
1397
+
1398
+
1399
+ void Logger::DebugEvent(const char* event_type, Vector<uint16_t> parameter) {
1400
+ #ifdef ENABLE_LOGGING_AND_PROFILING
1401
+ if (!log_->IsEnabled() || !FLAG_log) return;
1402
+ StringBuilder s(parameter.length() + 1);
1403
+ for (int i = 0; i < parameter.length(); ++i) {
1404
+ s.AddCharacter(static_cast<char>(parameter[i]));
1405
+ }
1406
+ char* parameter_string = s.Finalize();
1407
+ LogMessageBuilder msg(this);
1408
+ msg.Append("debug-queue-event,%s,%15.3f,%s\n",
1409
+ event_type,
1410
+ OS::TimeCurrentMillis(),
1411
+ parameter_string);
1412
+ DeleteArray(parameter_string);
1413
+ msg.WriteToLogFile();
1414
+ #endif
1415
+ }
1416
+
1417
+
1418
+ #ifdef ENABLE_LOGGING_AND_PROFILING
1419
+ void Logger::TickEvent(TickSample* sample, bool overflow) {
1420
+ if (!log_->IsEnabled() || !FLAG_prof) return;
1421
+ LogMessageBuilder msg(this);
1422
+ msg.Append("%s,", kLogEventsNames[TICK_EVENT]);
1423
+ msg.AppendAddress(sample->pc);
1424
+ msg.Append(',');
1425
+ msg.AppendAddress(sample->sp);
1426
+ if (sample->has_external_callback) {
1427
+ msg.Append(",1,");
1428
+ msg.AppendAddress(sample->external_callback);
1429
+ } else {
1430
+ msg.Append(",0,");
1431
+ msg.AppendAddress(sample->tos);
1432
+ }
1433
+ msg.Append(",%d", static_cast<int>(sample->state));
1434
+ if (overflow) {
1435
+ msg.Append(",overflow");
1436
+ }
1437
+ for (int i = 0; i < sample->frames_count; ++i) {
1438
+ msg.Append(',');
1439
+ msg.AppendAddress(sample->stack[i]);
1440
+ }
1441
+ msg.Append('\n');
1442
+ msg.WriteToLogFile();
1443
+ }
1444
+
1445
+
1446
+ int Logger::GetActiveProfilerModules() {
1447
+ int result = PROFILER_MODULE_NONE;
1448
+ if (profiler_ != NULL && !profiler_->paused()) {
1449
+ result |= PROFILER_MODULE_CPU;
1450
+ }
1451
+ if (FLAG_log_gc) {
1452
+ result |= PROFILER_MODULE_HEAP_STATS | PROFILER_MODULE_JS_CONSTRUCTORS;
1453
+ }
1454
+ return result;
1455
+ }
1456
+
1457
+
1458
+ void Logger::PauseProfiler(int flags, int tag) {
1459
+ if (!log_->IsEnabled()) return;
1460
+ if (profiler_ != NULL && (flags & PROFILER_MODULE_CPU)) {
1461
+ // It is OK to have negative nesting.
1462
+ if (--cpu_profiler_nesting_ == 0) {
1463
+ profiler_->pause();
1464
+ if (FLAG_prof_lazy) {
1465
+ if (!FLAG_sliding_state_window && !RuntimeProfiler::IsEnabled()) {
1466
+ ticker_->Stop();
1467
+ }
1468
+ FLAG_log_code = false;
1469
+ // Must be the same message as Log::kDynamicBufferSeal.
1470
+ LOG(ISOLATE, UncheckedStringEvent("profiler", "pause"));
1471
+ }
1472
+ --logging_nesting_;
1473
+ }
1474
+ }
1475
+ if (flags &
1476
+ (PROFILER_MODULE_HEAP_STATS | PROFILER_MODULE_JS_CONSTRUCTORS)) {
1477
+ if (--heap_profiler_nesting_ == 0) {
1478
+ FLAG_log_gc = false;
1479
+ --logging_nesting_;
1480
+ }
1481
+ }
1482
+ if (tag != 0) {
1483
+ UncheckedIntEvent("close-tag", tag);
1484
+ }
1485
+ }
1486
+
1487
+
1488
+ void Logger::ResumeProfiler(int flags, int tag) {
1489
+ if (!log_->IsEnabled()) return;
1490
+ if (tag != 0) {
1491
+ UncheckedIntEvent("open-tag", tag);
1492
+ }
1493
+ if (profiler_ != NULL && (flags & PROFILER_MODULE_CPU)) {
1494
+ if (cpu_profiler_nesting_++ == 0) {
1495
+ ++logging_nesting_;
1496
+ if (FLAG_prof_lazy) {
1497
+ profiler_->Engage();
1498
+ LOG(ISOLATE, UncheckedStringEvent("profiler", "resume"));
1499
+ FLAG_log_code = true;
1500
+ LogCompiledFunctions();
1501
+ LogAccessorCallbacks();
1502
+ if (!FLAG_sliding_state_window && !ticker_->IsActive()) {
1503
+ ticker_->Start();
1504
+ }
1505
+ }
1506
+ profiler_->resume();
1507
+ }
1508
+ }
1509
+ if (flags &
1510
+ (PROFILER_MODULE_HEAP_STATS | PROFILER_MODULE_JS_CONSTRUCTORS)) {
1511
+ if (heap_profiler_nesting_++ == 0) {
1512
+ ++logging_nesting_;
1513
+ FLAG_log_gc = true;
1514
+ }
1515
+ }
1516
+ }
1517
+
1518
+
1519
+ // This function can be called when Log's mutex is acquired,
1520
+ // either from main or Profiler's thread.
1521
+ void Logger::LogFailure() {
1522
+ PauseProfiler(PROFILER_MODULE_CPU, 0);
1523
+ }
1524
+
1525
+
1526
+ bool Logger::IsProfilerSamplerActive() {
1527
+ return ticker_->IsActive();
1528
+ }
1529
+
1530
+
1531
+ int Logger::GetLogLines(int from_pos, char* dest_buf, int max_size) {
1532
+ return log_->GetLogLines(from_pos, dest_buf, max_size);
1533
+ }
1534
+
1535
+
1536
+ class EnumerateOptimizedFunctionsVisitor: public OptimizedFunctionVisitor {
1537
+ public:
1538
+ EnumerateOptimizedFunctionsVisitor(Handle<SharedFunctionInfo>* sfis,
1539
+ Handle<Code>* code_objects,
1540
+ int* count)
1541
+ : sfis_(sfis), code_objects_(code_objects), count_(count) { }
1542
+
1543
+ virtual void EnterContext(Context* context) {}
1544
+ virtual void LeaveContext(Context* context) {}
1545
+
1546
+ virtual void VisitFunction(JSFunction* function) {
1547
+ if (sfis_ != NULL) {
1548
+ sfis_[*count_] = Handle<SharedFunctionInfo>(function->shared());
1549
+ }
1550
+ if (code_objects_ != NULL) {
1551
+ ASSERT(function->code()->kind() == Code::OPTIMIZED_FUNCTION);
1552
+ code_objects_[*count_] = Handle<Code>(function->code());
1553
+ }
1554
+ *count_ = *count_ + 1;
1555
+ }
1556
+
1557
+ private:
1558
+ Handle<SharedFunctionInfo>* sfis_;
1559
+ Handle<Code>* code_objects_;
1560
+ int* count_;
1561
+ };
1562
+
1563
+
1564
+ static int EnumerateCompiledFunctions(Handle<SharedFunctionInfo>* sfis,
1565
+ Handle<Code>* code_objects) {
1566
+ AssertNoAllocation no_alloc;
1567
+ int compiled_funcs_count = 0;
1568
+
1569
+ // Iterate the heap to find shared function info objects and record
1570
+ // the unoptimized code for them.
1571
+ HeapIterator iterator;
1572
+ for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) {
1573
+ if (!obj->IsSharedFunctionInfo()) continue;
1574
+ SharedFunctionInfo* sfi = SharedFunctionInfo::cast(obj);
1575
+ if (sfi->is_compiled()
1576
+ && (!sfi->script()->IsScript()
1577
+ || Script::cast(sfi->script())->HasValidSource())) {
1578
+ if (sfis != NULL) {
1579
+ sfis[compiled_funcs_count] = Handle<SharedFunctionInfo>(sfi);
1580
+ }
1581
+ if (code_objects != NULL) {
1582
+ code_objects[compiled_funcs_count] = Handle<Code>(sfi->code());
1583
+ }
1584
+ ++compiled_funcs_count;
1585
+ }
1586
+ }
1587
+
1588
+ // Iterate all optimized functions in all contexts.
1589
+ EnumerateOptimizedFunctionsVisitor visitor(sfis,
1590
+ code_objects,
1591
+ &compiled_funcs_count);
1592
+ Deoptimizer::VisitAllOptimizedFunctions(&visitor);
1593
+
1594
+ return compiled_funcs_count;
1595
+ }
1596
+
1597
+
1598
+ void Logger::LogCodeObject(Object* object) {
1599
+ if (FLAG_log_code || FLAG_ll_prof) {
1600
+ Code* code_object = Code::cast(object);
1601
+ LogEventsAndTags tag = Logger::STUB_TAG;
1602
+ const char* description = "Unknown code from the snapshot";
1603
+ switch (code_object->kind()) {
1604
+ case Code::FUNCTION:
1605
+ case Code::OPTIMIZED_FUNCTION:
1606
+ return; // We log this later using LogCompiledFunctions.
1607
+ case Code::UNARY_OP_IC: // fall through
1608
+ case Code::BINARY_OP_IC: // fall through
1609
+ case Code::COMPARE_IC: // fall through
1610
+ case Code::STUB:
1611
+ description =
1612
+ CodeStub::MajorName(CodeStub::GetMajorKey(code_object), true);
1613
+ if (description == NULL)
1614
+ description = "A stub from the snapshot";
1615
+ tag = Logger::STUB_TAG;
1616
+ break;
1617
+ case Code::BUILTIN:
1618
+ description = "A builtin from the snapshot";
1619
+ tag = Logger::BUILTIN_TAG;
1620
+ break;
1621
+ case Code::KEYED_LOAD_IC:
1622
+ description = "A keyed load IC from the snapshot";
1623
+ tag = Logger::KEYED_LOAD_IC_TAG;
1624
+ break;
1625
+ case Code::LOAD_IC:
1626
+ description = "A load IC from the snapshot";
1627
+ tag = Logger::LOAD_IC_TAG;
1628
+ break;
1629
+ case Code::STORE_IC:
1630
+ description = "A store IC from the snapshot";
1631
+ tag = Logger::STORE_IC_TAG;
1632
+ break;
1633
+ case Code::KEYED_STORE_IC:
1634
+ description = "A keyed store IC from the snapshot";
1635
+ tag = Logger::KEYED_STORE_IC_TAG;
1636
+ break;
1637
+ case Code::CALL_IC:
1638
+ description = "A call IC from the snapshot";
1639
+ tag = Logger::CALL_IC_TAG;
1640
+ break;
1641
+ case Code::KEYED_CALL_IC:
1642
+ description = "A keyed call IC from the snapshot";
1643
+ tag = Logger::KEYED_CALL_IC_TAG;
1644
+ break;
1645
+ }
1646
+ PROFILE(ISOLATE, CodeCreateEvent(tag, code_object, description));
1647
+ }
1648
+ }
1649
+
1650
+
1651
+ void Logger::LogCodeInfo() {
1652
+ #ifdef ENABLE_LOGGING_AND_PROFILING
1653
+ if (!log_->IsEnabled() || !FLAG_ll_prof) return;
1654
+ #if V8_TARGET_ARCH_IA32
1655
+ const char arch[] = "ia32";
1656
+ #elif V8_TARGET_ARCH_X64
1657
+ const char arch[] = "x64";
1658
+ #elif V8_TARGET_ARCH_ARM
1659
+ const char arch[] = "arm";
1660
+ #else
1661
+ const char arch[] = "unknown";
1662
+ #endif
1663
+ LowLevelLogWriteBytes(arch, sizeof(arch));
1664
+ #endif // ENABLE_LOGGING_AND_PROFILING
1665
+ }
1666
+
1667
+
1668
+ void Logger::RegisterSnapshotCodeName(Code* code,
1669
+ const char* name,
1670
+ int name_size) {
1671
+ ASSERT(Serializer::enabled());
1672
+ if (address_to_name_map_ == NULL) {
1673
+ address_to_name_map_ = new NameMap;
1674
+ }
1675
+ address_to_name_map_->Insert(code->address(), name, name_size);
1676
+ }
1677
+
1678
+
1679
+ void Logger::LowLevelCodeCreateEvent(Code* code,
1680
+ const char* name,
1681
+ int name_size) {
1682
+ if (log_->ll_output_handle_ == NULL) return;
1683
+ LowLevelCodeCreateStruct event;
1684
+ event.name_size = name_size;
1685
+ event.code_address = code->instruction_start();
1686
+ ASSERT(event.code_address == code->address() + Code::kHeaderSize);
1687
+ event.code_size = code->instruction_size();
1688
+ LowLevelLogWriteStruct(event);
1689
+ LowLevelLogWriteBytes(name, name_size);
1690
+ LowLevelLogWriteBytes(
1691
+ reinterpret_cast<const char*>(code->instruction_start()),
1692
+ code->instruction_size());
1693
+ }
1694
+
1695
+
1696
+ void Logger::LowLevelCodeMoveEvent(Address from, Address to) {
1697
+ if (log_->ll_output_handle_ == NULL) return;
1698
+ LowLevelCodeMoveStruct event;
1699
+ event.from_address = from + Code::kHeaderSize;
1700
+ event.to_address = to + Code::kHeaderSize;
1701
+ LowLevelLogWriteStruct(event);
1702
+ }
1703
+
1704
+
1705
+ void Logger::LowLevelCodeDeleteEvent(Address from) {
1706
+ if (log_->ll_output_handle_ == NULL) return;
1707
+ LowLevelCodeDeleteStruct event;
1708
+ event.address = from + Code::kHeaderSize;
1709
+ LowLevelLogWriteStruct(event);
1710
+ }
1711
+
1712
+
1713
+ void Logger::LowLevelSnapshotPositionEvent(Address addr, int pos) {
1714
+ if (log_->ll_output_handle_ == NULL) return;
1715
+ LowLevelSnapshotPositionStruct event;
1716
+ event.address = addr + Code::kHeaderSize;
1717
+ event.position = pos;
1718
+ LowLevelLogWriteStruct(event);
1719
+ }
1720
+
1721
+
1722
+ void Logger::LowLevelLogWriteBytes(const char* bytes, int size) {
1723
+ size_t rv = fwrite(bytes, 1, size, log_->ll_output_handle_);
1724
+ ASSERT(static_cast<size_t>(size) == rv);
1725
+ USE(rv);
1726
+ }
1727
+
1728
+
1729
+ void Logger::LogCodeObjects() {
1730
+ AssertNoAllocation no_alloc;
1731
+ HeapIterator iterator;
1732
+ for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) {
1733
+ if (obj->IsCode()) LogCodeObject(obj);
1734
+ }
1735
+ }
1736
+
1737
+
1738
+ void Logger::LogCompiledFunctions() {
1739
+ HandleScope scope;
1740
+ const int compiled_funcs_count = EnumerateCompiledFunctions(NULL, NULL);
1741
+ ScopedVector< Handle<SharedFunctionInfo> > sfis(compiled_funcs_count);
1742
+ ScopedVector< Handle<Code> > code_objects(compiled_funcs_count);
1743
+ EnumerateCompiledFunctions(sfis.start(), code_objects.start());
1744
+
1745
+ // During iteration, there can be heap allocation due to
1746
+ // GetScriptLineNumber call.
1747
+ for (int i = 0; i < compiled_funcs_count; ++i) {
1748
+ if (*code_objects[i] == Isolate::Current()->builtins()->builtin(
1749
+ Builtins::kLazyCompile))
1750
+ continue;
1751
+ Handle<SharedFunctionInfo> shared = sfis[i];
1752
+ Handle<String> func_name(shared->DebugName());
1753
+ if (shared->script()->IsScript()) {
1754
+ Handle<Script> script(Script::cast(shared->script()));
1755
+ if (script->name()->IsString()) {
1756
+ Handle<String> script_name(String::cast(script->name()));
1757
+ int line_num = GetScriptLineNumber(script, shared->start_position());
1758
+ if (line_num > 0) {
1759
+ PROFILE(ISOLATE,
1760
+ CodeCreateEvent(
1761
+ Logger::ToNativeByScript(Logger::LAZY_COMPILE_TAG, *script),
1762
+ *code_objects[i], *shared,
1763
+ *script_name, line_num + 1));
1764
+ } else {
1765
+ // Can't distinguish eval and script here, so always use Script.
1766
+ PROFILE(ISOLATE,
1767
+ CodeCreateEvent(
1768
+ Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script),
1769
+ *code_objects[i], *shared, *script_name));
1770
+ }
1771
+ } else {
1772
+ PROFILE(ISOLATE,
1773
+ CodeCreateEvent(
1774
+ Logger::ToNativeByScript(Logger::LAZY_COMPILE_TAG, *script),
1775
+ *code_objects[i], *shared, *func_name));
1776
+ }
1777
+ } else if (shared->IsApiFunction()) {
1778
+ // API function.
1779
+ FunctionTemplateInfo* fun_data = shared->get_api_func_data();
1780
+ Object* raw_call_data = fun_data->call_code();
1781
+ if (!raw_call_data->IsUndefined()) {
1782
+ CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data);
1783
+ Object* callback_obj = call_data->callback();
1784
+ Address entry_point = v8::ToCData<Address>(callback_obj);
1785
+ PROFILE(ISOLATE, CallbackEvent(*func_name, entry_point));
1786
+ }
1787
+ } else {
1788
+ PROFILE(ISOLATE,
1789
+ CodeCreateEvent(
1790
+ Logger::LAZY_COMPILE_TAG, *code_objects[i],
1791
+ *shared, *func_name));
1792
+ }
1793
+ }
1794
+ }
1795
+
1796
+
1797
+ void Logger::LogAccessorCallbacks() {
1798
+ AssertNoAllocation no_alloc;
1799
+ HeapIterator iterator;
1800
+ i::Isolate* isolate = ISOLATE;
1801
+ for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) {
1802
+ if (!obj->IsAccessorInfo()) continue;
1803
+ AccessorInfo* ai = AccessorInfo::cast(obj);
1804
+ if (!ai->name()->IsString()) continue;
1805
+ String* name = String::cast(ai->name());
1806
+ Address getter_entry = v8::ToCData<Address>(ai->getter());
1807
+ if (getter_entry != 0) {
1808
+ PROFILE(isolate, GetterCallbackEvent(name, getter_entry));
1809
+ }
1810
+ Address setter_entry = v8::ToCData<Address>(ai->setter());
1811
+ if (setter_entry != 0) {
1812
+ PROFILE(isolate, SetterCallbackEvent(name, setter_entry));
1813
+ }
1814
+ }
1815
+ }
1816
+
1817
+ #endif
1818
+
1819
+
1820
+ bool Logger::Setup() {
1821
+ #ifdef ENABLE_LOGGING_AND_PROFILING
1822
+ // Tests and EnsureInitialize() can call this twice in a row. It's harmless.
1823
+ if (is_initialized_) return true;
1824
+ is_initialized_ = true;
1825
+
1826
+ // --ll-prof implies --log-code and --log-snapshot-positions.
1827
+ if (FLAG_ll_prof) {
1828
+ FLAG_log_snapshot_positions = true;
1829
+ }
1830
+
1831
+ // --prof_lazy controls --log-code, implies --noprof_auto.
1832
+ if (FLAG_prof_lazy) {
1833
+ FLAG_log_code = false;
1834
+ FLAG_prof_auto = false;
1835
+ }
1836
+
1837
+ // TODO(isolates): this assert introduces cyclic dependency (logger
1838
+ // -> thread local top -> heap -> logger).
1839
+ // ASSERT(VMState::is_outermost_external());
1840
+
1841
+ log_->Initialize();
1842
+
1843
+ if (FLAG_ll_prof) LogCodeInfo();
1844
+
1845
+ ticker_ = new Ticker(Isolate::Current(), kSamplingIntervalMs);
1846
+
1847
+ Isolate* isolate = Isolate::Current();
1848
+ if (FLAG_sliding_state_window && sliding_state_window_ == NULL) {
1849
+ sliding_state_window_ = new SlidingStateWindow(isolate);
1850
+ }
1851
+
1852
+ bool start_logging = FLAG_log || FLAG_log_runtime || FLAG_log_api
1853
+ || FLAG_log_code || FLAG_log_gc || FLAG_log_handles || FLAG_log_suspect
1854
+ || FLAG_log_regexp || FLAG_log_state_changes || FLAG_ll_prof;
1855
+
1856
+ if (start_logging) {
1857
+ logging_nesting_ = 1;
1858
+ }
1859
+
1860
+ if (FLAG_prof) {
1861
+ profiler_ = new Profiler(isolate);
1862
+ if (!FLAG_prof_auto) {
1863
+ profiler_->pause();
1864
+ } else {
1865
+ logging_nesting_ = 1;
1866
+ }
1867
+ if (!FLAG_prof_lazy) {
1868
+ profiler_->Engage();
1869
+ }
1870
+ }
1871
+
1872
+ return true;
1873
+
1874
+ #else
1875
+ return false;
1876
+ #endif
1877
+ }
1878
+
1879
+
1880
+ Sampler* Logger::sampler() {
1881
+ return ticker_;
1882
+ }
1883
+
1884
+
1885
+ void Logger::EnsureTickerStarted() {
1886
+ #ifdef ENABLE_LOGGING_AND_PROFILING
1887
+ ASSERT(ticker_ != NULL);
1888
+ if (!ticker_->IsActive()) ticker_->Start();
1889
+ #endif
1890
+ }
1891
+
1892
+
1893
+ void Logger::EnsureTickerStopped() {
1894
+ #ifdef ENABLE_LOGGING_AND_PROFILING
1895
+ if (ticker_ != NULL && ticker_->IsActive()) ticker_->Stop();
1896
+ #endif
1897
+ }
1898
+
1899
+
1900
+ void Logger::TearDown() {
1901
+ #ifdef ENABLE_LOGGING_AND_PROFILING
1902
+ if (!is_initialized_) return;
1903
+ is_initialized_ = false;
1904
+
1905
+ // Stop the profiler before closing the file.
1906
+ if (profiler_ != NULL) {
1907
+ profiler_->Disengage();
1908
+ delete profiler_;
1909
+ profiler_ = NULL;
1910
+ }
1911
+
1912
+ delete sliding_state_window_;
1913
+ sliding_state_window_ = NULL;
1914
+
1915
+ delete ticker_;
1916
+ ticker_ = NULL;
1917
+
1918
+ log_->Close();
1919
+ #endif
1920
+ }
1921
+
1922
+
1923
+ void Logger::EnableSlidingStateWindow() {
1924
+ #ifdef ENABLE_LOGGING_AND_PROFILING
1925
+ // If the ticker is NULL, Logger::Setup has not been called yet. In
1926
+ // that case, we set the sliding_state_window flag so that the
1927
+ // sliding window computation will be started when Logger::Setup is
1928
+ // called.
1929
+ if (ticker_ == NULL) {
1930
+ FLAG_sliding_state_window = true;
1931
+ return;
1932
+ }
1933
+ // Otherwise, if the sliding state window computation has not been
1934
+ // started we do it now.
1935
+ if (sliding_state_window_ == NULL) {
1936
+ sliding_state_window_ = new SlidingStateWindow(Isolate::Current());
1937
+ }
1938
+ #endif
1939
+ }
1940
+
1941
+
1942
+ Mutex* SamplerRegistry::mutex_ = OS::CreateMutex();
1943
+ List<Sampler*>* SamplerRegistry::active_samplers_ = NULL;
1944
+
1945
+
1946
+ bool SamplerRegistry::IterateActiveSamplers(VisitSampler func, void* param) {
1947
+ ScopedLock lock(mutex_);
1948
+ for (int i = 0;
1949
+ ActiveSamplersExist() && i < active_samplers_->length();
1950
+ ++i) {
1951
+ func(active_samplers_->at(i), param);
1952
+ }
1953
+ return ActiveSamplersExist();
1954
+ }
1955
+
1956
+
1957
+ static void ComputeCpuProfiling(Sampler* sampler, void* flag_ptr) {
1958
+ bool* flag = reinterpret_cast<bool*>(flag_ptr);
1959
+ *flag |= sampler->IsProfiling();
1960
+ }
1961
+
1962
+
1963
+ SamplerRegistry::State SamplerRegistry::GetState() {
1964
+ bool flag = false;
1965
+ if (!IterateActiveSamplers(&ComputeCpuProfiling, &flag)) {
1966
+ return HAS_NO_SAMPLERS;
1967
+ }
1968
+ return flag ? HAS_CPU_PROFILING_SAMPLERS : HAS_SAMPLERS;
1969
+ }
1970
+
1971
+
1972
+ void SamplerRegistry::AddActiveSampler(Sampler* sampler) {
1973
+ ASSERT(sampler->IsActive());
1974
+ ScopedLock lock(mutex_);
1975
+ if (active_samplers_ == NULL) {
1976
+ active_samplers_ = new List<Sampler*>;
1977
+ } else {
1978
+ ASSERT(!active_samplers_->Contains(sampler));
1979
+ }
1980
+ active_samplers_->Add(sampler);
1981
+ }
1982
+
1983
+
1984
+ void SamplerRegistry::RemoveActiveSampler(Sampler* sampler) {
1985
+ ASSERT(sampler->IsActive());
1986
+ ScopedLock lock(mutex_);
1987
+ ASSERT(active_samplers_ != NULL);
1988
+ bool removed = active_samplers_->RemoveElement(sampler);
1989
+ ASSERT(removed);
1990
+ USE(removed);
1991
+ }
1992
+
1993
+ } } // namespace v8::internal