johnson 1.2.0 → 2.0.0.pre0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (782) hide show
  1. data/CHANGELOG.rdoc +8 -0
  2. data/Manifest.txt +762 -48
  3. data/README.rdoc +2 -1
  4. data/Rakefile +90 -18
  5. data/ext/spidermonkey/conversions.c +9 -2
  6. data/ext/spidermonkey/ruby_land_proxy.c +1 -1
  7. data/ext/spidermonkey/runtime.h +1 -1
  8. data/ext/tracemonkey/context.cc +125 -0
  9. data/ext/tracemonkey/context.h +19 -0
  10. data/ext/tracemonkey/conversions.cc +365 -0
  11. data/ext/tracemonkey/conversions.h +32 -0
  12. data/ext/tracemonkey/debugger.cc +234 -0
  13. data/ext/tracemonkey/debugger.h +10 -0
  14. data/ext/tracemonkey/extconf.rb +37 -0
  15. data/ext/tracemonkey/extensions.cc +37 -0
  16. data/ext/tracemonkey/extensions.h +12 -0
  17. data/ext/tracemonkey/global.cc +40 -0
  18. data/ext/tracemonkey/global.h +11 -0
  19. data/ext/tracemonkey/idhash.cc +16 -0
  20. data/ext/tracemonkey/idhash.h +8 -0
  21. data/ext/tracemonkey/immutable_node.cc +1199 -0
  22. data/ext/tracemonkey/immutable_node.cc.erb +559 -0
  23. data/ext/tracemonkey/immutable_node.h +22 -0
  24. data/ext/tracemonkey/jroot.h +215 -0
  25. data/ext/tracemonkey/js_land_proxy.cc +620 -0
  26. data/ext/tracemonkey/js_land_proxy.h +20 -0
  27. data/ext/tracemonkey/ruby_land_proxy.cc +618 -0
  28. data/ext/tracemonkey/ruby_land_proxy.h +38 -0
  29. data/ext/tracemonkey/runtime.cc +454 -0
  30. data/ext/tracemonkey/runtime.h +27 -0
  31. data/ext/tracemonkey/split_global.cc +392 -0
  32. data/ext/tracemonkey/split_global.h +11 -0
  33. data/ext/tracemonkey/tracemonkey.cc +23 -0
  34. data/ext/tracemonkey/tracemonkey.h +32 -0
  35. data/lib/johnson.rb +12 -4
  36. data/lib/johnson/error.rb +5 -0
  37. data/lib/johnson/js/prelude.js +16 -1
  38. data/lib/johnson/parser.rb +2 -1
  39. data/lib/johnson/runtime.rb +87 -26
  40. data/lib/johnson/spidermonkey/runtime.rb +7 -16
  41. data/lib/johnson/tracemonkey.rb +13 -0
  42. data/lib/johnson/tracemonkey/context.rb +10 -0
  43. data/lib/johnson/tracemonkey/debugger.rb +67 -0
  44. data/lib/johnson/tracemonkey/immutable_node.rb +282 -0
  45. data/lib/johnson/tracemonkey/js_land_proxy.rb +64 -0
  46. data/lib/johnson/tracemonkey/mutable_tree_visitor.rb +242 -0
  47. data/lib/johnson/tracemonkey/ruby_land_proxy.rb +17 -0
  48. data/lib/johnson/tracemonkey/runtime.rb +80 -0
  49. data/test/{johnson_test.rb → generic/johnson_test.rb} +1 -1
  50. data/test/{parser_test.rb → generic/parser_test.rb} +1 -1
  51. data/test/helper.rb +23 -4
  52. data/test/johnson/{browser_test.rb → generic/browser_test.rb} +1 -1
  53. data/test/johnson/{conversions → generic/conversions}/array_test.rb +1 -1
  54. data/test/johnson/{conversions → generic/conversions}/boolean_test.rb +1 -1
  55. data/test/johnson/{conversions → generic/conversions}/callable_test.rb +1 -1
  56. data/test/johnson/{conversions → generic/conversions}/file_test.rb +1 -1
  57. data/test/johnson/generic/conversions/helper.rb +1 -0
  58. data/test/johnson/{conversions → generic/conversions}/nil_test.rb +1 -1
  59. data/test/johnson/{conversions → generic/conversions}/number_test.rb +1 -1
  60. data/test/johnson/{conversions → generic/conversions}/regexp_test.rb +1 -1
  61. data/test/johnson/{conversions → generic/conversions}/string_test.rb +1 -1
  62. data/test/johnson/{conversions → generic/conversions}/struct_test.rb +1 -1
  63. data/test/johnson/{conversions → generic/conversions}/symbol_test.rb +1 -1
  64. data/test/johnson/{conversions → generic/conversions}/thread_test.rb +1 -1
  65. data/test/johnson/{custom_conversions_test.rb → generic/custom_conversions_test.rb} +1 -1
  66. data/test/johnson/generic/default_test.rb +12 -0
  67. data/test/johnson/{error_test.rb → generic/error_test.rb} +1 -1
  68. data/test/johnson/{extensions_test.rb → generic/extensions_test.rb} +1 -1
  69. data/test/johnson/generic/helper.rb +1 -0
  70. data/test/johnson/{nodes → generic/nodes}/array_literal_test.rb +1 -1
  71. data/test/johnson/{nodes → generic/nodes}/array_node_test.rb +1 -1
  72. data/test/johnson/{nodes → generic/nodes}/binary_node_test.rb +1 -1
  73. data/test/johnson/{nodes → generic/nodes}/bracket_access_test.rb +1 -1
  74. data/test/johnson/{nodes → generic/nodes}/delete_test.rb +1 -1
  75. data/test/johnson/{nodes → generic/nodes}/do_while_test.rb +1 -1
  76. data/test/johnson/{nodes → generic/nodes}/dot_accessor_test.rb +1 -1
  77. data/test/johnson/generic/nodes/export_test.rb +11 -0
  78. data/test/johnson/{nodes → generic/nodes}/for_test.rb +1 -1
  79. data/test/johnson/{nodes → generic/nodes}/function_test.rb +1 -1
  80. data/test/johnson/generic/nodes/helper.rb +1 -0
  81. data/test/johnson/{nodes → generic/nodes}/if_test.rb +16 -6
  82. data/test/johnson/generic/nodes/import_test.rb +15 -0
  83. data/test/johnson/{nodes → generic/nodes}/label_test.rb +1 -1
  84. data/test/johnson/{nodes → generic/nodes}/let_test.rb +1 -1
  85. data/test/johnson/{nodes → generic/nodes}/object_literal_test.rb +1 -1
  86. data/test/johnson/{nodes → generic/nodes}/return_test.rb +1 -1
  87. data/test/johnson/{nodes → generic/nodes}/semi_test.rb +1 -1
  88. data/test/johnson/{nodes → generic/nodes}/switch_test.rb +1 -1
  89. data/test/johnson/{nodes → generic/nodes}/ternary_test.rb +1 -1
  90. data/test/johnson/{nodes → generic/nodes}/throw_test.rb +1 -1
  91. data/test/johnson/{nodes → generic/nodes}/try_node_test.rb +36 -6
  92. data/test/johnson/{nodes → generic/nodes}/typeof_test.rb +1 -1
  93. data/test/johnson/{nodes → generic/nodes}/unary_node_test.rb +1 -1
  94. data/test/johnson/{nodes → generic/nodes}/void_test.rb +1 -1
  95. data/test/johnson/{nodes → generic/nodes}/while_test.rb +1 -1
  96. data/test/johnson/{nodes → generic/nodes}/with_test.rb +1 -1
  97. data/test/johnson/{prelude_test.rb → generic/prelude_test.rb} +1 -1
  98. data/test/johnson/{runtime_test.rb → generic/runtime_test.rb} +3 -6
  99. data/test/johnson/generic/version_test.rb +13 -0
  100. data/test/johnson/{visitors → generic/visitors}/dot_visitor_test.rb +1 -1
  101. data/test/johnson/{visitors → generic/visitors}/enumerating_visitor_test.rb +1 -1
  102. data/test/johnson/generic/visitors/helper.rb +1 -0
  103. data/test/johnson/spidermonkey/js_land_proxy_test.rb +1 -5
  104. data/test/johnson/spidermonkey/ruby_land_proxy_test.rb +11 -7
  105. data/test/johnson/tracemonkey/context_test.rb +21 -0
  106. data/test/johnson/tracemonkey/immutable_node_test.rb +34 -0
  107. data/test/johnson/tracemonkey/js_land_proxy_test.rb +273 -0
  108. data/test/johnson/tracemonkey/ruby_land_proxy_test.rb +274 -0
  109. data/test/johnson/tracemonkey/runtime_test.rb +41 -0
  110. data/test/johnson/tracemonkey/split_global_test.rb +32 -0
  111. data/vendor/spidermonkey/js.pkg +2 -0
  112. data/vendor/tracemonkey/Makefile.in +668 -0
  113. data/vendor/tracemonkey/Makefile.ref +483 -0
  114. data/vendor/tracemonkey/README.html +54 -0
  115. data/vendor/tracemonkey/SpiderMonkey.rsp +11 -0
  116. data/vendor/tracemonkey/Y.js +19 -0
  117. data/vendor/tracemonkey/aclocal.m4 +9 -0
  118. data/vendor/tracemonkey/bench.sh +5 -0
  119. data/vendor/tracemonkey/build/autoconf/acoutput-fast.pl +202 -0
  120. data/vendor/tracemonkey/build/autoconf/altoptions.m4 +154 -0
  121. data/vendor/tracemonkey/build/autoconf/config.guess +1537 -0
  122. data/vendor/tracemonkey/build/autoconf/config.sub +1595 -0
  123. data/vendor/tracemonkey/build/autoconf/install-sh +119 -0
  124. data/vendor/tracemonkey/build/autoconf/make-makefile +315 -0
  125. data/vendor/tracemonkey/build/autoconf/match-dir.sh +101 -0
  126. data/vendor/tracemonkey/build/autoconf/moznbytetype.m4 +136 -0
  127. data/vendor/tracemonkey/build/autoconf/nspr.m4 +82 -0
  128. data/vendor/tracemonkey/build/autoconf/pkg.m4 +59 -0
  129. data/vendor/tracemonkey/build/autoconf/update-makefile.sh +118 -0
  130. data/vendor/tracemonkey/build/cygwin-wrapper +75 -0
  131. data/vendor/tracemonkey/build/hcc +111 -0
  132. data/vendor/tracemonkey/build/hcpp +155 -0
  133. data/vendor/tracemonkey/build/unix/mddepend.pl +165 -0
  134. data/vendor/tracemonkey/build/unix/uniq.pl +63 -0
  135. data/vendor/tracemonkey/build/win32/pgomerge.py +40 -0
  136. data/vendor/tracemonkey/builtins.tbl +91 -0
  137. data/vendor/tracemonkey/call.js +13 -0
  138. data/vendor/tracemonkey/config.mk +206 -0
  139. data/vendor/tracemonkey/config/Makefile.in +106 -0
  140. data/vendor/tracemonkey/config/Moz/Milestone.pm +232 -0
  141. data/vendor/tracemonkey/config/autoconf.mk.in +362 -0
  142. data/vendor/tracemonkey/config/check-sync-dirs.py +103 -0
  143. data/vendor/tracemonkey/config/check-sync-exceptions +7 -0
  144. data/vendor/tracemonkey/config/config.mk +881 -0
  145. data/vendor/tracemonkey/config/fastcwd.pl +66 -0
  146. data/vendor/tracemonkey/config/gcc_hidden.h +2 -0
  147. data/vendor/tracemonkey/config/insure.mk +53 -0
  148. data/vendor/tracemonkey/config/make-system-wrappers.pl +59 -0
  149. data/vendor/tracemonkey/config/milestone.pl +112 -0
  150. data/vendor/tracemonkey/config/milestone.txt +13 -0
  151. data/vendor/tracemonkey/config/mkdepend/Makefile.in +84 -0
  152. data/vendor/tracemonkey/config/mkdepend/cppsetup.c +233 -0
  153. data/vendor/tracemonkey/config/mkdepend/def.h +184 -0
  154. data/vendor/tracemonkey/config/mkdepend/ifparser.c +551 -0
  155. data/vendor/tracemonkey/config/mkdepend/ifparser.h +83 -0
  156. data/vendor/tracemonkey/config/mkdepend/imakemdep.h +733 -0
  157. data/vendor/tracemonkey/config/mkdepend/include.c +337 -0
  158. data/vendor/tracemonkey/config/mkdepend/main.c +860 -0
  159. data/vendor/tracemonkey/config/mkdepend/mkdepend.man +382 -0
  160. data/vendor/tracemonkey/config/mkdepend/parse.c +686 -0
  161. data/vendor/tracemonkey/config/mkdepend/pr.c +124 -0
  162. data/vendor/tracemonkey/config/nfspwd.pl +50 -0
  163. data/vendor/tracemonkey/config/nsinstall.c +481 -0
  164. data/vendor/tracemonkey/config/nsinstall.py +155 -0
  165. data/vendor/tracemonkey/config/pathsub.c +247 -0
  166. data/vendor/tracemonkey/config/pathsub.h +74 -0
  167. data/vendor/tracemonkey/config/preprocessor.pl +671 -0
  168. data/vendor/tracemonkey/config/revdepth-nt.pl +48 -0
  169. data/vendor/tracemonkey/config/revdepth.pl +51 -0
  170. data/vendor/tracemonkey/config/rules.mk +2310 -0
  171. data/vendor/tracemonkey/config/static-checking-config.mk +21 -0
  172. data/vendor/tracemonkey/config/static-checking.js +92 -0
  173. data/vendor/tracemonkey/config/string-format.js +61 -0
  174. data/vendor/tracemonkey/config/system-headers +1035 -0
  175. data/vendor/tracemonkey/config/version.mk +85 -0
  176. data/vendor/tracemonkey/config/version_win.pl +442 -0
  177. data/vendor/tracemonkey/configure +14183 -0
  178. data/vendor/tracemonkey/configure.in +5363 -0
  179. data/vendor/tracemonkey/correct.sh +23 -0
  180. data/vendor/tracemonkey/correct/check-3d-morph.js +55 -0
  181. data/vendor/tracemonkey/correct/check-3d-raytrace.js +445 -0
  182. data/vendor/tracemonkey/correct/check-access-binary-trees.js +52 -0
  183. data/vendor/tracemonkey/correct/check-access-fannkuch.js +66 -0
  184. data/vendor/tracemonkey/correct/check-access-nbody.js +171 -0
  185. data/vendor/tracemonkey/correct/check-access-nsieve.js +40 -0
  186. data/vendor/tracemonkey/correct/check-bitops-3bit-bits-in-byte.js +35 -0
  187. data/vendor/tracemonkey/correct/check-bitops-bits-in-byte.js +24 -0
  188. data/vendor/tracemonkey/correct/check-bitops-bitwise-and.js +29 -0
  189. data/vendor/tracemonkey/correct/check-bitops-nsieve-bits.js +40 -0
  190. data/vendor/tracemonkey/correct/check-controlflow-recursive.js +27 -0
  191. data/vendor/tracemonkey/correct/check-date-format-tofte.js +302 -0
  192. data/vendor/tracemonkey/correct/check-date-format-xparb.js +421 -0
  193. data/vendor/tracemonkey/correct/check-mont.js +119 -0
  194. data/vendor/tracemonkey/dtoa.c +3335 -0
  195. data/vendor/tracemonkey/editline/Makefile.in +55 -0
  196. data/vendor/tracemonkey/editline/Makefile.ref +143 -0
  197. data/vendor/tracemonkey/editline/README +83 -0
  198. data/vendor/tracemonkey/editline/editline.3 +175 -0
  199. data/vendor/tracemonkey/editline/editline.c +1371 -0
  200. data/vendor/tracemonkey/editline/editline.h +135 -0
  201. data/vendor/tracemonkey/editline/sysunix.c +182 -0
  202. data/vendor/tracemonkey/editline/unix.h +82 -0
  203. data/vendor/tracemonkey/if.js +13 -0
  204. data/vendor/tracemonkey/imacro_asm.js.in +396 -0
  205. data/vendor/tracemonkey/imacros.c.out +1034 -0
  206. data/vendor/tracemonkey/imacros.jsasm +770 -0
  207. data/vendor/tracemonkey/javascript-trace.d +73 -0
  208. data/vendor/tracemonkey/jitstats.tbl +55 -0
  209. data/vendor/tracemonkey/js-config.h.in +82 -0
  210. data/vendor/tracemonkey/js-config.in +111 -0
  211. data/vendor/tracemonkey/js.mdp +0 -0
  212. data/vendor/tracemonkey/js.msg +312 -0
  213. data/vendor/tracemonkey/js3240.rc +79 -0
  214. data/vendor/tracemonkey/jsOS240.def +654 -0
  215. data/vendor/tracemonkey/jsapi.cpp +6005 -0
  216. data/vendor/tracemonkey/jsapi.h +2727 -0
  217. data/vendor/tracemonkey/jsarena.cpp +450 -0
  218. data/vendor/tracemonkey/jsarena.h +318 -0
  219. data/vendor/tracemonkey/jsarray.cpp +3664 -0
  220. data/vendor/tracemonkey/jsarray.h +238 -0
  221. data/vendor/tracemonkey/jsatom.cpp +1244 -0
  222. data/vendor/tracemonkey/jsatom.h +493 -0
  223. data/vendor/tracemonkey/jsbit.h +249 -0
  224. data/vendor/tracemonkey/jsbool.cpp +184 -0
  225. data/vendor/tracemonkey/jsbool.h +88 -0
  226. data/vendor/tracemonkey/jsbuiltins.cpp +415 -0
  227. data/vendor/tracemonkey/jsbuiltins.h +456 -0
  228. data/vendor/tracemonkey/jsclist.h +139 -0
  229. data/vendor/tracemonkey/jscntxt.cpp +1816 -0
  230. data/vendor/tracemonkey/jscntxt.h +1541 -0
  231. data/vendor/tracemonkey/jscompat.h +57 -0
  232. data/vendor/tracemonkey/jsconfig.mk +181 -0
  233. data/vendor/tracemonkey/jscpucfg.cpp +194 -0
  234. data/vendor/tracemonkey/jscpucfg.h +91 -0
  235. data/vendor/tracemonkey/jsdate.cpp +2465 -0
  236. data/vendor/tracemonkey/jsdate.h +129 -0
  237. data/vendor/tracemonkey/jsdbgapi.cpp +2017 -0
  238. data/vendor/tracemonkey/jsdbgapi.h +500 -0
  239. data/vendor/tracemonkey/jsdhash.cpp +876 -0
  240. data/vendor/tracemonkey/jsdhash.h +588 -0
  241. data/vendor/tracemonkey/jsdtoa.cpp +572 -0
  242. data/vendor/tracemonkey/jsdtoa.h +131 -0
  243. data/vendor/tracemonkey/jsdtracef.c +318 -0
  244. data/vendor/tracemonkey/jsdtracef.h +81 -0
  245. data/vendor/tracemonkey/jsemit.cpp +7292 -0
  246. data/vendor/tracemonkey/jsemit.h +802 -0
  247. data/vendor/tracemonkey/jsexn.cpp +1337 -0
  248. data/vendor/tracemonkey/jsexn.h +96 -0
  249. data/vendor/tracemonkey/jsfile.cpp +2747 -0
  250. data/vendor/tracemonkey/jsfile.h +56 -0
  251. data/vendor/tracemonkey/jsfile.msg +90 -0
  252. data/vendor/tracemonkey/jsfun.cpp +3089 -0
  253. data/vendor/tracemonkey/jsfun.h +366 -0
  254. data/vendor/tracemonkey/jsgc.cpp +3816 -0
  255. data/vendor/tracemonkey/jsgc.h +429 -0
  256. data/vendor/tracemonkey/jshash.cpp +477 -0
  257. data/vendor/tracemonkey/jshash.h +151 -0
  258. data/vendor/tracemonkey/jsify.pl +483 -0
  259. data/vendor/tracemonkey/jsinterp.cpp +7441 -0
  260. data/vendor/tracemonkey/jsinterp.h +666 -0
  261. data/vendor/tracemonkey/jsinvoke.cpp +42 -0
  262. data/vendor/tracemonkey/jsiter.cpp +1040 -0
  263. data/vendor/tracemonkey/jsiter.h +140 -0
  264. data/vendor/tracemonkey/jskeyword.tbl +124 -0
  265. data/vendor/tracemonkey/jskwgen.cpp +460 -0
  266. data/vendor/tracemonkey/jslibmath.h +69 -0
  267. data/vendor/tracemonkey/jslock.cpp +1512 -0
  268. data/vendor/tracemonkey/jslock.h +325 -0
  269. data/vendor/tracemonkey/jslocko.asm +60 -0
  270. data/vendor/tracemonkey/jslog2.cpp +111 -0
  271. data/vendor/tracemonkey/jslong.h +167 -0
  272. data/vendor/tracemonkey/jsmath.cpp +806 -0
  273. data/vendor/tracemonkey/jsmath.h +63 -0
  274. data/vendor/tracemonkey/jsnum.cpp +1374 -0
  275. data/vendor/tracemonkey/jsnum.h +280 -0
  276. data/vendor/tracemonkey/jsobj.cpp +6165 -0
  277. data/vendor/tracemonkey/jsobj.h +870 -0
  278. data/vendor/tracemonkey/json.cpp +1338 -0
  279. data/vendor/tracemonkey/json.h +108 -0
  280. data/vendor/tracemonkey/jsopcode.cpp +5484 -0
  281. data/vendor/tracemonkey/jsopcode.h +434 -0
  282. data/vendor/tracemonkey/jsopcode.tbl +591 -0
  283. data/vendor/tracemonkey/jsoplengen.cpp +121 -0
  284. data/vendor/tracemonkey/jsotypes.h +202 -0
  285. data/vendor/tracemonkey/jsparse.cpp +9257 -0
  286. data/vendor/tracemonkey/jsparse.h +900 -0
  287. data/vendor/tracemonkey/jsprf.cpp +1262 -0
  288. data/vendor/tracemonkey/jsprf.h +150 -0
  289. data/vendor/tracemonkey/jsproto.tbl +117 -0
  290. data/vendor/tracemonkey/jsprvtd.h +366 -0
  291. data/vendor/tracemonkey/jspubtd.h +585 -0
  292. data/vendor/tracemonkey/jsregexp.cpp +5051 -0
  293. data/vendor/tracemonkey/jsregexp.h +199 -0
  294. data/vendor/tracemonkey/jsreops.tbl +145 -0
  295. data/vendor/tracemonkey/jsscan.cpp +2040 -0
  296. data/vendor/tracemonkey/jsscan.h +467 -0
  297. data/vendor/tracemonkey/jsscope.cpp +1966 -0
  298. data/vendor/tracemonkey/jsscope.h +487 -0
  299. data/vendor/tracemonkey/jsscript.cpp +1932 -0
  300. data/vendor/tracemonkey/jsscript.h +345 -0
  301. data/vendor/tracemonkey/jsshell.msg +54 -0
  302. data/vendor/tracemonkey/jsstack.js +167 -0
  303. data/vendor/tracemonkey/jsstaticcheck.h +69 -0
  304. data/vendor/tracemonkey/jsstddef.h +87 -0
  305. data/vendor/tracemonkey/jsstdint.h +96 -0
  306. data/vendor/tracemonkey/jsstr.cpp +5277 -0
  307. data/vendor/tracemonkey/jsstr.h +702 -0
  308. data/vendor/tracemonkey/jstracer.cpp +10991 -0
  309. data/vendor/tracemonkey/jstracer.h +794 -0
  310. data/vendor/tracemonkey/jstypes.h +481 -0
  311. data/vendor/tracemonkey/jsutil.cpp +361 -0
  312. data/vendor/tracemonkey/jsutil.h +178 -0
  313. data/vendor/tracemonkey/jsversion.h +243 -0
  314. data/vendor/tracemonkey/jswince.asm +44 -0
  315. data/vendor/tracemonkey/jsxdrapi.cpp +800 -0
  316. data/vendor/tracemonkey/jsxdrapi.h +220 -0
  317. data/vendor/tracemonkey/jsxml.cpp +8327 -0
  318. data/vendor/tracemonkey/jsxml.h +305 -0
  319. data/vendor/tracemonkey/liveconnect/LiveConnect.dsp +157 -0
  320. data/vendor/tracemonkey/liveconnect/LiveConnectShell.dsp +120 -0
  321. data/vendor/tracemonkey/liveconnect/LiveConnectShell.dsw +44 -0
  322. data/vendor/tracemonkey/liveconnect/Makefile.in +105 -0
  323. data/vendor/tracemonkey/liveconnect/Makefile.ref +169 -0
  324. data/vendor/tracemonkey/liveconnect/README.html +712 -0
  325. data/vendor/tracemonkey/liveconnect/_jni/netscape_javascript_JSException.h +14 -0
  326. data/vendor/tracemonkey/liveconnect/_jni/netscape_javascript_JSObject.h +155 -0
  327. data/vendor/tracemonkey/liveconnect/classes/Makefile.in +89 -0
  328. data/vendor/tracemonkey/liveconnect/classes/Makefile.ref +57 -0
  329. data/vendor/tracemonkey/liveconnect/classes/netscape/Makefile.ref +47 -0
  330. data/vendor/tracemonkey/liveconnect/classes/netscape/javascript/JSException.java +140 -0
  331. data/vendor/tracemonkey/liveconnect/classes/netscape/javascript/JSObject.java +183 -0
  332. data/vendor/tracemonkey/liveconnect/classes/netscape/javascript/JSProxy.java +58 -0
  333. data/vendor/tracemonkey/liveconnect/classes/netscape/javascript/JSRunnable.java +70 -0
  334. data/vendor/tracemonkey/liveconnect/classes/netscape/javascript/JSUtil.java +59 -0
  335. data/vendor/tracemonkey/liveconnect/classes/netscape/javascript/Makefile.ref +53 -0
  336. data/vendor/tracemonkey/liveconnect/config/AIX4.1.mk +45 -0
  337. data/vendor/tracemonkey/liveconnect/config/AIX4.2.mk +45 -0
  338. data/vendor/tracemonkey/liveconnect/config/AIX4.3.mk +50 -0
  339. data/vendor/tracemonkey/liveconnect/config/HP-UXB.10.10.mk +43 -0
  340. data/vendor/tracemonkey/liveconnect/config/HP-UXB.10.20.mk +43 -0
  341. data/vendor/tracemonkey/liveconnect/config/HP-UXB.11.00.mk +43 -0
  342. data/vendor/tracemonkey/liveconnect/config/IRIX6.2.mk +43 -0
  343. data/vendor/tracemonkey/liveconnect/config/IRIX6.3.mk +43 -0
  344. data/vendor/tracemonkey/liveconnect/config/IRIX6.5.mk +43 -0
  345. data/vendor/tracemonkey/liveconnect/config/Linux_All.mk +73 -0
  346. data/vendor/tracemonkey/liveconnect/config/OSF1V4.0.mk +65 -0
  347. data/vendor/tracemonkey/liveconnect/config/OSF1V5.0.mk +62 -0
  348. data/vendor/tracemonkey/liveconnect/config/SunOS5.5.1.mk +55 -0
  349. data/vendor/tracemonkey/liveconnect/config/SunOS5.6.mk +39 -0
  350. data/vendor/tracemonkey/liveconnect/config/SunOS5.7.mk +39 -0
  351. data/vendor/tracemonkey/liveconnect/config/SunOS5.8.mk +39 -0
  352. data/vendor/tracemonkey/liveconnect/config/WINNT4.0.mk +53 -0
  353. data/vendor/tracemonkey/liveconnect/jsj.c +886 -0
  354. data/vendor/tracemonkey/liveconnect/jsj.msg +98 -0
  355. data/vendor/tracemonkey/liveconnect/jsj_JSObject.c +1377 -0
  356. data/vendor/tracemonkey/liveconnect/jsj_JavaArray.c +474 -0
  357. data/vendor/tracemonkey/liveconnect/jsj_JavaClass.c +737 -0
  358. data/vendor/tracemonkey/liveconnect/jsj_JavaMember.c +191 -0
  359. data/vendor/tracemonkey/liveconnect/jsj_JavaObject.c +1079 -0
  360. data/vendor/tracemonkey/liveconnect/jsj_JavaPackage.c +569 -0
  361. data/vendor/tracemonkey/liveconnect/jsj_array.c +207 -0
  362. data/vendor/tracemonkey/liveconnect/jsj_class.c +770 -0
  363. data/vendor/tracemonkey/liveconnect/jsj_convert.c +902 -0
  364. data/vendor/tracemonkey/liveconnect/jsj_field.c +421 -0
  365. data/vendor/tracemonkey/liveconnect/jsj_hash.c +488 -0
  366. data/vendor/tracemonkey/liveconnect/jsj_hash.h +161 -0
  367. data/vendor/tracemonkey/liveconnect/jsj_method.c +1825 -0
  368. data/vendor/tracemonkey/liveconnect/jsj_nodl.c +1 -0
  369. data/vendor/tracemonkey/liveconnect/jsj_private.h +677 -0
  370. data/vendor/tracemonkey/liveconnect/jsj_simpleapi.c +219 -0
  371. data/vendor/tracemonkey/liveconnect/jsj_utils.c +513 -0
  372. data/vendor/tracemonkey/liveconnect/jsjava.h +316 -0
  373. data/vendor/tracemonkey/liveconnect/netscape_javascript_JSObject.h +155 -0
  374. data/vendor/tracemonkey/liveconnect/nsCLiveconnect.cpp +785 -0
  375. data/vendor/tracemonkey/liveconnect/nsCLiveconnect.h +197 -0
  376. data/vendor/tracemonkey/liveconnect/nsCLiveconnectFactory.cpp +118 -0
  377. data/vendor/tracemonkey/liveconnect/nsCLiveconnectFactory.h +76 -0
  378. data/vendor/tracemonkey/liveconnect/nsILiveconnect.h +197 -0
  379. data/vendor/tracemonkey/liveconnect/nsISecureLiveconnect.h +94 -0
  380. data/vendor/tracemonkey/liveconnect/nsISecurityContext.h +136 -0
  381. data/vendor/tracemonkey/lock_SunOS.s +119 -0
  382. data/vendor/tracemonkey/mandelbrot-results.js +3 -0
  383. data/vendor/tracemonkey/math-partial-sums.js +32 -0
  384. data/vendor/tracemonkey/math-trace-tests.js +507 -0
  385. data/vendor/tracemonkey/md5.js +289 -0
  386. data/vendor/tracemonkey/nanojit/Assembler.cpp +1984 -0
  387. data/vendor/tracemonkey/nanojit/Assembler.h +375 -0
  388. data/vendor/tracemonkey/nanojit/Fragmento.cpp +651 -0
  389. data/vendor/tracemonkey/nanojit/Fragmento.h +237 -0
  390. data/vendor/tracemonkey/nanojit/LIR.cpp +2314 -0
  391. data/vendor/tracemonkey/nanojit/LIR.h +879 -0
  392. data/vendor/tracemonkey/nanojit/LIRopcode.tbl +252 -0
  393. data/vendor/tracemonkey/nanojit/Native.h +127 -0
  394. data/vendor/tracemonkey/nanojit/NativeARM.cpp +1742 -0
  395. data/vendor/tracemonkey/nanojit/NativeARM.h +844 -0
  396. data/vendor/tracemonkey/nanojit/NativeSparc.cpp +1130 -0
  397. data/vendor/tracemonkey/nanojit/NativeSparc.h +948 -0
  398. data/vendor/tracemonkey/nanojit/NativeThumb.cpp +1322 -0
  399. data/vendor/tracemonkey/nanojit/NativeThumb.h +525 -0
  400. data/vendor/tracemonkey/nanojit/Nativei386.cpp +1748 -0
  401. data/vendor/tracemonkey/nanojit/Nativei386.h +857 -0
  402. data/vendor/tracemonkey/nanojit/RegAlloc.cpp +183 -0
  403. data/vendor/tracemonkey/nanojit/RegAlloc.h +95 -0
  404. data/vendor/tracemonkey/nanojit/TraceTreeDrawer.cpp +306 -0
  405. data/vendor/tracemonkey/nanojit/TraceTreeDrawer.h +88 -0
  406. data/vendor/tracemonkey/nanojit/avmplus.cpp +56 -0
  407. data/vendor/tracemonkey/nanojit/avmplus.h +1016 -0
  408. data/vendor/tracemonkey/nanojit/nanojit.h +253 -0
  409. data/vendor/tracemonkey/perfect.js +39 -0
  410. data/vendor/tracemonkey/plify_jsdhash.sed +35 -0
  411. data/vendor/tracemonkey/prmjtime.cpp +869 -0
  412. data/vendor/tracemonkey/prmjtime.h +103 -0
  413. data/vendor/tracemonkey/ref-config/AIX4.1.mk +65 -0
  414. data/vendor/tracemonkey/ref-config/AIX4.2.mk +64 -0
  415. data/vendor/tracemonkey/ref-config/AIX4.3.mk +65 -0
  416. data/vendor/tracemonkey/ref-config/Darwin.mk +85 -0
  417. data/vendor/tracemonkey/ref-config/Darwin1.3.mk +81 -0
  418. data/vendor/tracemonkey/ref-config/Darwin1.4.mk +41 -0
  419. data/vendor/tracemonkey/ref-config/Darwin5.2.mk +81 -0
  420. data/vendor/tracemonkey/ref-config/Darwin5.3.mk +81 -0
  421. data/vendor/tracemonkey/ref-config/Darwin64.mk +72 -0
  422. data/vendor/tracemonkey/ref-config/HP-UXB.10.10.mk +77 -0
  423. data/vendor/tracemonkey/ref-config/HP-UXB.10.20.mk +77 -0
  424. data/vendor/tracemonkey/ref-config/HP-UXB.11.00.mk +80 -0
  425. data/vendor/tracemonkey/ref-config/IRIX.mk +87 -0
  426. data/vendor/tracemonkey/ref-config/IRIX5.3.mk +44 -0
  427. data/vendor/tracemonkey/ref-config/IRIX6.1.mk +44 -0
  428. data/vendor/tracemonkey/ref-config/IRIX6.2.mk +44 -0
  429. data/vendor/tracemonkey/ref-config/IRIX6.3.mk +44 -0
  430. data/vendor/tracemonkey/ref-config/IRIX6.5.mk +44 -0
  431. data/vendor/tracemonkey/ref-config/Linux_All.mk +105 -0
  432. data/vendor/tracemonkey/ref-config/Mac_OS10.0.mk +82 -0
  433. data/vendor/tracemonkey/ref-config/OSF1V4.0.mk +72 -0
  434. data/vendor/tracemonkey/ref-config/OSF1V5.0.mk +69 -0
  435. data/vendor/tracemonkey/ref-config/SunOS4.1.4.mk +101 -0
  436. data/vendor/tracemonkey/ref-config/SunOS5.10.mk +50 -0
  437. data/vendor/tracemonkey/ref-config/SunOS5.3.mk +91 -0
  438. data/vendor/tracemonkey/ref-config/SunOS5.4.mk +92 -0
  439. data/vendor/tracemonkey/ref-config/SunOS5.5.1.mk +44 -0
  440. data/vendor/tracemonkey/ref-config/SunOS5.5.mk +87 -0
  441. data/vendor/tracemonkey/ref-config/SunOS5.6.mk +89 -0
  442. data/vendor/tracemonkey/ref-config/SunOS5.7.mk +44 -0
  443. data/vendor/tracemonkey/ref-config/SunOS5.8.mk +44 -0
  444. data/vendor/tracemonkey/ref-config/SunOS5.9.mk +44 -0
  445. data/vendor/tracemonkey/ref-config/WINNT4.0.mk +118 -0
  446. data/vendor/tracemonkey/ref-config/WINNT5.0.mk +118 -0
  447. data/vendor/tracemonkey/ref-config/WINNT5.1.mk +118 -0
  448. data/vendor/tracemonkey/ref-config/WINNT5.2.mk +118 -0
  449. data/vendor/tracemonkey/ref-config/WINNT6.0.mk +118 -0
  450. data/vendor/tracemonkey/ref-config/dgux.mk +64 -0
  451. data/vendor/tracemonkey/resource.h +15 -0
  452. data/vendor/tracemonkey/rules.mk +206 -0
  453. data/vendor/tracemonkey/shell/Makefile.in +72 -0
  454. data/vendor/tracemonkey/shell/js.cpp +4719 -0
  455. data/vendor/tracemonkey/t/3d-cube.js +337 -0
  456. data/vendor/tracemonkey/t/3d-morph.js +54 -0
  457. data/vendor/tracemonkey/t/3d-raytrace.js +441 -0
  458. data/vendor/tracemonkey/t/access-binary-trees.js +50 -0
  459. data/vendor/tracemonkey/t/access-fannkuch.js +66 -0
  460. data/vendor/tracemonkey/t/access-nbody.js +169 -0
  461. data/vendor/tracemonkey/t/access-nsieve.js +38 -0
  462. data/vendor/tracemonkey/t/bitops-3bit-bits-in-byte.js +32 -0
  463. data/vendor/tracemonkey/t/bitops-bits-in-byte.js +21 -0
  464. data/vendor/tracemonkey/t/bitops-bitwise-and.js +28 -0
  465. data/vendor/tracemonkey/t/bitops-nsieve-bits.js +32 -0
  466. data/vendor/tracemonkey/t/controlflow-recursive.js +25 -0
  467. data/vendor/tracemonkey/t/crypto-aes.js +422 -0
  468. data/vendor/tracemonkey/t/crypto-md5.js +286 -0
  469. data/vendor/tracemonkey/t/crypto-sha1.js +224 -0
  470. data/vendor/tracemonkey/t/date-format-tofte.js +299 -0
  471. data/vendor/tracemonkey/t/date-format-xparb.js +417 -0
  472. data/vendor/tracemonkey/t/math-cordic.js +95 -0
  473. data/vendor/tracemonkey/t/math-partial-sums.js +33 -0
  474. data/vendor/tracemonkey/t/math-spectral-norm.js +51 -0
  475. data/vendor/tracemonkey/t/regexp-dna.js +1712 -0
  476. data/vendor/tracemonkey/t/string-base64.js +135 -0
  477. data/vendor/tracemonkey/t/string-fasta.js +85 -0
  478. data/vendor/tracemonkey/t/string-tagcloud.js +265 -0
  479. data/vendor/tracemonkey/t/string-unpack-code.js +68 -0
  480. data/vendor/tracemonkey/t/string-validate-input.js +89 -0
  481. data/vendor/tracemonkey/time.sh +13 -0
  482. data/vendor/tracemonkey/trace-test.js +5564 -0
  483. data/vendor/tracemonkey/v8/base.js +187 -0
  484. data/vendor/tracemonkey/v8/crypto.js +1689 -0
  485. data/vendor/tracemonkey/v8/deltablue.js +880 -0
  486. data/vendor/tracemonkey/v8/earley-boyer.js +4682 -0
  487. data/vendor/tracemonkey/v8/raytrace.js +3418 -0
  488. data/vendor/tracemonkey/v8/richards.js +539 -0
  489. data/vendor/tracemonkey/v8/run-crypto.js +44 -0
  490. data/vendor/tracemonkey/v8/run-deltablue.js +44 -0
  491. data/vendor/tracemonkey/v8/run-earley-boyer.js +44 -0
  492. data/vendor/tracemonkey/v8/run-raytrace.js +44 -0
  493. data/vendor/tracemonkey/v8/run-richards.js +44 -0
  494. data/vendor/tracemonkey/v8/run.js +49 -0
  495. data/vendor/tracemonkey/vprof/readme.txt +93 -0
  496. data/vendor/tracemonkey/vprof/vprof.cpp +360 -0
  497. data/vendor/tracemonkey/vprof/vprof.h +245 -0
  498. data/vendor/tracemonkey/xpconnect/Makefile.in +67 -0
  499. data/vendor/tracemonkey/xpconnect/crashtests/117307-1.html +20 -0
  500. data/vendor/tracemonkey/xpconnect/crashtests/193710.html +11 -0
  501. data/vendor/tracemonkey/xpconnect/crashtests/290162-1.html +5 -0
  502. data/vendor/tracemonkey/xpconnect/crashtests/326615-1.html +16 -0
  503. data/vendor/tracemonkey/xpconnect/crashtests/328553-1.html +13 -0
  504. data/vendor/tracemonkey/xpconnect/crashtests/346258-1.html +12 -0
  505. data/vendor/tracemonkey/xpconnect/crashtests/346512-1-frame1.xhtml +16 -0
  506. data/vendor/tracemonkey/xpconnect/crashtests/346512-1-frame2.xhtml +15 -0
  507. data/vendor/tracemonkey/xpconnect/crashtests/346512-1.xhtml +30 -0
  508. data/vendor/tracemonkey/xpconnect/crashtests/382133-1.html +3 -0
  509. data/vendor/tracemonkey/xpconnect/crashtests/386680-1.html +22 -0
  510. data/vendor/tracemonkey/xpconnect/crashtests/394810-1.html +4 -0
  511. data/vendor/tracemonkey/xpconnect/crashtests/400349-1.html +20 -0
  512. data/vendor/tracemonkey/xpconnect/crashtests/403356-1.html +13 -0
  513. data/vendor/tracemonkey/xpconnect/crashtests/418139-1.svg +22 -0
  514. data/vendor/tracemonkey/xpconnect/crashtests/420513-1.html +11 -0
  515. data/vendor/tracemonkey/xpconnect/crashtests/453935-1.html +37 -0
  516. data/vendor/tracemonkey/xpconnect/crashtests/462926.html +12 -0
  517. data/vendor/tracemonkey/xpconnect/crashtests/468552-1.html +18 -0
  518. data/vendor/tracemonkey/xpconnect/crashtests/471366-1.html +12 -0
  519. data/vendor/tracemonkey/xpconnect/crashtests/475185-1.html +13 -0
  520. data/vendor/tracemonkey/xpconnect/crashtests/475291-1.html +14 -0
  521. data/vendor/tracemonkey/xpconnect/crashtests/503286-1.html +23 -0
  522. data/vendor/tracemonkey/xpconnect/crashtests/crashtests.list +21 -0
  523. data/vendor/tracemonkey/xpconnect/idl/Makefile.in +78 -0
  524. data/vendor/tracemonkey/xpconnect/idl/XPCIDispatch.idl +51 -0
  525. data/vendor/tracemonkey/xpconnect/idl/mozIJSSubScriptLoader.idl +64 -0
  526. data/vendor/tracemonkey/xpconnect/idl/nsIActiveXSecurityPolicy.idl +67 -0
  527. data/vendor/tracemonkey/xpconnect/idl/nsIDispatchSupport.idl +119 -0
  528. data/vendor/tracemonkey/xpconnect/idl/nsIJSContextStack.idl +85 -0
  529. data/vendor/tracemonkey/xpconnect/idl/nsIJSRuntimeService.idl +51 -0
  530. data/vendor/tracemonkey/xpconnect/idl/nsIScriptError.idl +102 -0
  531. data/vendor/tracemonkey/xpconnect/idl/nsIScriptableInterfaces.idl +67 -0
  532. data/vendor/tracemonkey/xpconnect/idl/nsIXPCScriptNotify.idl +66 -0
  533. data/vendor/tracemonkey/xpconnect/idl/nsIXPCScriptable.idl +183 -0
  534. data/vendor/tracemonkey/xpconnect/idl/nsIXPCSecurityManager.idl +114 -0
  535. data/vendor/tracemonkey/xpconnect/idl/nsIXPConnect.idl +819 -0
  536. data/vendor/tracemonkey/xpconnect/idl/xpcIJSModuleLoader.idl +95 -0
  537. data/vendor/tracemonkey/xpconnect/idl/xpcIJSWeakReference.idl +49 -0
  538. data/vendor/tracemonkey/xpconnect/idl/xpccomponents.idl +254 -0
  539. data/vendor/tracemonkey/xpconnect/idl/xpcexception.idl +66 -0
  540. data/vendor/tracemonkey/xpconnect/idl/xpcjsid.idl +83 -0
  541. data/vendor/tracemonkey/xpconnect/loader/ISO8601DateUtils.jsm +176 -0
  542. data/vendor/tracemonkey/xpconnect/loader/Makefile.in +63 -0
  543. data/vendor/tracemonkey/xpconnect/loader/XPCOMUtils.jsm +267 -0
  544. data/vendor/tracemonkey/xpconnect/loader/mozJSComponentLoader.cpp +1717 -0
  545. data/vendor/tracemonkey/xpconnect/loader/mozJSComponentLoader.h +172 -0
  546. data/vendor/tracemonkey/xpconnect/loader/mozJSLoaderConstructors.h +101 -0
  547. data/vendor/tracemonkey/xpconnect/loader/mozJSSubScriptLoader.cpp +360 -0
  548. data/vendor/tracemonkey/xpconnect/loader/mozJSSubScriptLoader.h +66 -0
  549. data/vendor/tracemonkey/xpconnect/public/Makefile.in +54 -0
  550. data/vendor/tracemonkey/xpconnect/public/nsAXPCNativeCallContext.h +89 -0
  551. data/vendor/tracemonkey/xpconnect/public/nsAutoJSValHolder.h +168 -0
  552. data/vendor/tracemonkey/xpconnect/public/xpc_map_end.h +327 -0
  553. data/vendor/tracemonkey/xpconnect/sample/Makefile.in +71 -0
  554. data/vendor/tracemonkey/xpconnect/sample/README +39 -0
  555. data/vendor/tracemonkey/xpconnect/sample/xpcsample1.cpp +337 -0
  556. data/vendor/tracemonkey/xpconnect/sample/xpcsample1.idl +82 -0
  557. data/vendor/tracemonkey/xpconnect/sample/xpcsample1.js +21 -0
  558. data/vendor/tracemonkey/xpconnect/shell/Makefile.in +106 -0
  559. data/vendor/tracemonkey/xpconnect/shell/jsshell.msg +50 -0
  560. data/vendor/tracemonkey/xpconnect/shell/xpcshell.cpp +1817 -0
  561. data/vendor/tracemonkey/xpconnect/shell/xpcshellMacUtils.h +43 -0
  562. data/vendor/tracemonkey/xpconnect/shell/xpcshellMacUtils.mm +54 -0
  563. data/vendor/tracemonkey/xpconnect/src/Makefile.in +228 -0
  564. data/vendor/tracemonkey/xpconnect/src/README +3 -0
  565. data/vendor/tracemonkey/xpconnect/src/XPCCrossOriginWrapper.cpp +1186 -0
  566. data/vendor/tracemonkey/xpconnect/src/XPCDispConvert.cpp +593 -0
  567. data/vendor/tracemonkey/xpconnect/src/XPCDispInlines.h +667 -0
  568. data/vendor/tracemonkey/xpconnect/src/XPCDispInterface.cpp +383 -0
  569. data/vendor/tracemonkey/xpconnect/src/XPCDispObject.cpp +516 -0
  570. data/vendor/tracemonkey/xpconnect/src/XPCDispParamPropJSClass.cpp +223 -0
  571. data/vendor/tracemonkey/xpconnect/src/XPCDispParams.cpp +103 -0
  572. data/vendor/tracemonkey/xpconnect/src/XPCDispPrivate.h +1401 -0
  573. data/vendor/tracemonkey/xpconnect/src/XPCDispTearOff.cpp +547 -0
  574. data/vendor/tracemonkey/xpconnect/src/XPCDispTypeInfo.cpp +471 -0
  575. data/vendor/tracemonkey/xpconnect/src/XPCIDispatchClassInfo.cpp +139 -0
  576. data/vendor/tracemonkey/xpconnect/src/XPCIDispatchExtension.cpp +362 -0
  577. data/vendor/tracemonkey/xpconnect/src/XPCNativeWrapper.cpp +1350 -0
  578. data/vendor/tracemonkey/xpconnect/src/XPCNativeWrapper.h +88 -0
  579. data/vendor/tracemonkey/xpconnect/src/XPCSafeJSObjectWrapper.cpp +1148 -0
  580. data/vendor/tracemonkey/xpconnect/src/XPCSystemOnlyWrapper.cpp +718 -0
  581. data/vendor/tracemonkey/xpconnect/src/XPCWrapper.cpp +850 -0
  582. data/vendor/tracemonkey/xpconnect/src/XPCWrapper.h +394 -0
  583. data/vendor/tracemonkey/xpconnect/src/dom_quickstubs.qsconf +568 -0
  584. data/vendor/tracemonkey/xpconnect/src/nsDispatchSupport.cpp +348 -0
  585. data/vendor/tracemonkey/xpconnect/src/nsScriptError.cpp +201 -0
  586. data/vendor/tracemonkey/xpconnect/src/nsXPConnect.cpp +2609 -0
  587. data/vendor/tracemonkey/xpconnect/src/qsgen.py +1487 -0
  588. data/vendor/tracemonkey/xpconnect/src/xpc.msg +217 -0
  589. data/vendor/tracemonkey/xpconnect/src/xpcJSWeakReference.cpp +148 -0
  590. data/vendor/tracemonkey/xpconnect/src/xpcJSWeakReference.h +56 -0
  591. data/vendor/tracemonkey/xpconnect/src/xpccallcontext.cpp +579 -0
  592. data/vendor/tracemonkey/xpconnect/src/xpccomponents.cpp +4144 -0
  593. data/vendor/tracemonkey/xpconnect/src/xpccontext.cpp +115 -0
  594. data/vendor/tracemonkey/xpconnect/src/xpcconvert.cpp +2298 -0
  595. data/vendor/tracemonkey/xpconnect/src/xpcdebug.cpp +481 -0
  596. data/vendor/tracemonkey/xpconnect/src/xpcexception.cpp +502 -0
  597. data/vendor/tracemonkey/xpconnect/src/xpcforwards.h +114 -0
  598. data/vendor/tracemonkey/xpconnect/src/xpcinlines.h +772 -0
  599. data/vendor/tracemonkey/xpconnect/src/xpcjsid.cpp +1025 -0
  600. data/vendor/tracemonkey/xpconnect/src/xpcjsruntime.cpp +1342 -0
  601. data/vendor/tracemonkey/xpconnect/src/xpclog.cpp +128 -0
  602. data/vendor/tracemonkey/xpconnect/src/xpclog.h +101 -0
  603. data/vendor/tracemonkey/xpconnect/src/xpcmaps.cpp +761 -0
  604. data/vendor/tracemonkey/xpconnect/src/xpcmaps.h +713 -0
  605. data/vendor/tracemonkey/xpconnect/src/xpcmodule.cpp +136 -0
  606. data/vendor/tracemonkey/xpconnect/src/xpcprivate.h +4138 -0
  607. data/vendor/tracemonkey/xpconnect/src/xpcquickstubs.cpp +1128 -0
  608. data/vendor/tracemonkey/xpconnect/src/xpcquickstubs.h +480 -0
  609. data/vendor/tracemonkey/xpconnect/src/xpcruntimesvc.cpp +179 -0
  610. data/vendor/tracemonkey/xpconnect/src/xpcstack.cpp +342 -0
  611. data/vendor/tracemonkey/xpconnect/src/xpcstring.cpp +139 -0
  612. data/vendor/tracemonkey/xpconnect/src/xpcthreadcontext.cpp +599 -0
  613. data/vendor/tracemonkey/xpconnect/src/xpcthrower.cpp +399 -0
  614. data/vendor/tracemonkey/xpconnect/src/xpcvariant.cpp +850 -0
  615. data/vendor/tracemonkey/xpconnect/src/xpcwrappedjs.cpp +670 -0
  616. data/vendor/tracemonkey/xpconnect/src/xpcwrappedjsclass.cpp +2015 -0
  617. data/vendor/tracemonkey/xpconnect/src/xpcwrappednative.cpp +3482 -0
  618. data/vendor/tracemonkey/xpconnect/src/xpcwrappednativeinfo.cpp +945 -0
  619. data/vendor/tracemonkey/xpconnect/src/xpcwrappednativejsops.cpp +2003 -0
  620. data/vendor/tracemonkey/xpconnect/src/xpcwrappednativeproto.cpp +302 -0
  621. data/vendor/tracemonkey/xpconnect/src/xpcwrappednativescope.cpp +991 -0
  622. data/vendor/tracemonkey/xpconnect/tests/Makefile.in +75 -0
  623. data/vendor/tracemonkey/xpconnect/tests/TestXPC.cpp +785 -0
  624. data/vendor/tracemonkey/xpconnect/tests/chrome/Makefile.in +51 -0
  625. data/vendor/tracemonkey/xpconnect/tests/chrome/test_bug500931.xul +43 -0
  626. data/vendor/tracemonkey/xpconnect/tests/components/Makefile.in +85 -0
  627. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_array.cpp +388 -0
  628. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_attributes.cpp +305 -0
  629. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_calljs.cpp +135 -0
  630. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_child.cpp +225 -0
  631. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_const.cpp +76 -0
  632. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_domstring.cpp +118 -0
  633. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_echo.cpp +616 -0
  634. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_in.cpp +204 -0
  635. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_inout.cpp +171 -0
  636. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_module.cpp +77 -0
  637. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_multiple.cpp +554 -0
  638. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_noisy.cpp +154 -0
  639. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_out.cpp +335 -0
  640. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_overloaded.cpp +250 -0
  641. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_private.h +192 -0
  642. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_string.cpp +185 -0
  643. data/vendor/tracemonkey/xpconnect/tests/components/xpctest_variant.cpp +355 -0
  644. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/StdAfx.cpp +12 -0
  645. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/StdAfx.h +28 -0
  646. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/XPCDispUtilities.h +28 -0
  647. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/XPCIDispatchTest.cpp +86 -0
  648. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/XPCIDispatchTest.def +9 -0
  649. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/XPCIDispatchTest.dsp +318 -0
  650. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/XPCIDispatchTest.dsw +29 -0
  651. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/XPCIDispatchTest.idl +454 -0
  652. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/XPCIDispatchTest.rc +145 -0
  653. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispSimple.cpp +44 -0
  654. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispSimple.h +56 -0
  655. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispSimple.rgs +23 -0
  656. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestArrays.cpp +221 -0
  657. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestArrays.h +53 -0
  658. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestArrays.rgs +23 -0
  659. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestMethods.cpp +699 -0
  660. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestMethods.h +138 -0
  661. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestMethods.rgs +23 -0
  662. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestNoIDispatch.cpp +23 -0
  663. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestNoIDispatch.h +41 -0
  664. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestNoIDispatch.rgs +23 -0
  665. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestProperties.cpp +256 -0
  666. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestProperties.h +88 -0
  667. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestProperties.rgs +23 -0
  668. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestScriptOff.cpp +23 -0
  669. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestScriptOff.h +43 -0
  670. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestScriptOff.rgs +23 -0
  671. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestScriptOn.cpp +29 -0
  672. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestScriptOn.h +45 -0
  673. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestScriptOn.rgs +23 -0
  674. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestWrappedJS.cpp +177 -0
  675. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestWrappedJS.h +50 -0
  676. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestWrappedJS.rgs +23 -0
  677. data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/resource.h +36 -0
  678. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedCOM/Arrays/XPCIDispatchArrayTests.js +54 -0
  679. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedCOM/Attributes/XPCIDispatchAttributeTests.js +150 -0
  680. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedCOM/General/XPCIDispatchInstantiations.js +122 -0
  681. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedCOM/General/XPCStress.js +58 -0
  682. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedCOM/Methods/XPCIDispatchMethodTests.js +376 -0
  683. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedCOM/shell.js +377 -0
  684. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedJS/General/XPCIDispatchTestWrappedJS.js +76 -0
  685. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedJS/shell.js +377 -0
  686. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/exectests.cmd +1 -0
  687. data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/jsDriver.pl +1288 -0
  688. data/vendor/tracemonkey/xpconnect/tests/idl/Makefile.in +61 -0
  689. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest.idl +312 -0
  690. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest2.idl +51 -0
  691. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_attributes.idl +67 -0
  692. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_calljs.idl +59 -0
  693. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_const.idl +61 -0
  694. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_domstring.idl +59 -0
  695. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_in.idl +88 -0
  696. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_inout.idl +86 -0
  697. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_multiple.idl +77 -0
  698. data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_out.idl +142 -0
  699. data/vendor/tracemonkey/xpconnect/tests/js/checkid.js +82 -0
  700. data/vendor/tracemonkey/xpconnect/tests/js/evaluate.js +311 -0
  701. data/vendor/tracemonkey/xpconnect/tests/js/exceptions-2.js +153 -0
  702. data/vendor/tracemonkey/xpconnect/tests/js/exceptions-3.js +194 -0
  703. data/vendor/tracemonkey/xpconnect/tests/js/exceptions-4.js +297 -0
  704. data/vendor/tracemonkey/xpconnect/tests/js/exceptions-5.js +343 -0
  705. data/vendor/tracemonkey/xpconnect/tests/js/exceptions.js +230 -0
  706. data/vendor/tracemonkey/xpconnect/tests/js/javascript.js +96 -0
  707. data/vendor/tracemonkey/xpconnect/tests/js/multiple-2.js +151 -0
  708. data/vendor/tracemonkey/xpconnect/tests/js/multiple-3.js +148 -0
  709. data/vendor/tracemonkey/xpconnect/tests/js/multiple-4.js +152 -0
  710. data/vendor/tracemonkey/xpconnect/tests/js/multiple.js +137 -0
  711. data/vendor/tracemonkey/xpconnect/tests/js/notscriptable.js +104 -0
  712. data/vendor/tracemonkey/xpconnect/tests/js/old/simpletest.js +36 -0
  713. data/vendor/tracemonkey/xpconnect/tests/js/old/speed.js +60 -0
  714. data/vendor/tracemonkey/xpconnect/tests/js/old/testxpc.js +464 -0
  715. data/vendor/tracemonkey/xpconnect/tests/js/old/threads.js +74 -0
  716. data/vendor/tracemonkey/xpconnect/tests/js/old/try.js +27 -0
  717. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_array.js +308 -0
  718. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_callcontext.js +68 -0
  719. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_echo.js +636 -0
  720. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_enum_and_sort.js +28 -0
  721. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_enum_constants.js +15 -0
  722. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_enum_create.js +200 -0
  723. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_exceptions.js +167 -0
  724. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_ids.js +135 -0
  725. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_observer.js +36 -0
  726. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_overloaded.js +14 -0
  727. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_primitives.js +141 -0
  728. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_propertybag.js +36 -0
  729. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_variant.js +339 -0
  730. data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_variant_array.js +30 -0
  731. data/vendor/tracemonkey/xpconnect/tests/js/readonlyattributes.js +74 -0
  732. data/vendor/tracemonkey/xpconnect/tests/js/readwriteattributes.js +101 -0
  733. data/vendor/tracemonkey/xpconnect/tests/js/scriptable.js +120 -0
  734. data/vendor/tracemonkey/xpconnect/tests/js/testin.js +203 -0
  735. data/vendor/tracemonkey/xpconnect/tests/js/xpcfun.js +234 -0
  736. data/vendor/tracemonkey/xpconnect/tests/js/xpctest_primitives.js +200 -0
  737. data/vendor/tracemonkey/xpconnect/tests/mochitest/Makefile.in +66 -0
  738. data/vendor/tracemonkey/xpconnect/tests/mochitest/bug500931_helper.html +7 -0
  739. data/vendor/tracemonkey/xpconnect/tests/mochitest/inner.html +7 -0
  740. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug361111.xul +29 -0
  741. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug384632.html +32 -0
  742. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug390488.html +65 -0
  743. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug393269.html +46 -0
  744. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug396851.html +43 -0
  745. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug428021.html +41 -0
  746. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug446584.html +49 -0
  747. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug448587.html +31 -0
  748. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug462428.html +42 -0
  749. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug478438.html +66 -0
  750. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug484107.html +100 -0
  751. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug484459.html +36 -0
  752. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug500691.html +28 -0
  753. data/vendor/tracemonkey/xpconnect/tests/mochitest/test_wrappers.html +116 -0
  754. data/vendor/tracemonkey/xpconnect/tests/unit/bogus_element_type.jsm +1 -0
  755. data/vendor/tracemonkey/xpconnect/tests/unit/bogus_exports_type.jsm +1 -0
  756. data/vendor/tracemonkey/xpconnect/tests/unit/bug451678_subscript.js +2 -0
  757. data/vendor/tracemonkey/xpconnect/tests/unit/component_import.js +144 -0
  758. data/vendor/tracemonkey/xpconnect/tests/unit/recursive_importA.jsm +44 -0
  759. data/vendor/tracemonkey/xpconnect/tests/unit/recursive_importB.jsm +45 -0
  760. data/vendor/tracemonkey/xpconnect/tests/unit/syntax_error.jsm +1 -0
  761. data/vendor/tracemonkey/xpconnect/tests/unit/test_bogus_files.js +88 -0
  762. data/vendor/tracemonkey/xpconnect/tests/unit/test_bug408412.js +51 -0
  763. data/vendor/tracemonkey/xpconnect/tests/unit/test_bug451678.js +52 -0
  764. data/vendor/tracemonkey/xpconnect/tests/unit/test_bug_442086.js +68 -0
  765. data/vendor/tracemonkey/xpconnect/tests/unit/test_import.js +127 -0
  766. data/vendor/tracemonkey/xpconnect/tests/unit/test_js_weak_references.js +63 -0
  767. data/vendor/tracemonkey/xpconnect/tests/unit/test_recursive_import.js +62 -0
  768. data/vendor/tracemonkey/xpconnect/tools/Makefile.in +49 -0
  769. data/vendor/tracemonkey/xpconnect/tools/idl/Makefile.in +53 -0
  770. data/vendor/tracemonkey/xpconnect/tools/idl/nsIXPCToolsCompiler.idl +60 -0
  771. data/vendor/tracemonkey/xpconnect/tools/idl/nsIXPCToolsProfiler.idl +57 -0
  772. data/vendor/tracemonkey/xpconnect/tools/js/CompileJSFiles.js +28 -0
  773. data/vendor/tracemonkey/xpconnect/tools/js/ListJSFiles.js +18 -0
  774. data/vendor/tracemonkey/xpconnect/tools/src/Makefile.in +76 -0
  775. data/vendor/tracemonkey/xpconnect/tools/src/nsXPCToolsCompiler.cpp +161 -0
  776. data/vendor/tracemonkey/xpconnect/tools/src/nsXPCToolsModule.cpp +65 -0
  777. data/vendor/tracemonkey/xpconnect/tools/src/nsXPCToolsProfiler.cpp +370 -0
  778. data/vendor/tracemonkey/xpconnect/tools/src/xpctools_private.h +236 -0
  779. metadata +782 -107
  780. data/test/johnson/nodes/export_test.rb +0 -9
  781. data/test/johnson/nodes/import_test.rb +0 -13
  782. data/test/johnson/version_test.rb +0 -13
@@ -0,0 +1,237 @@
1
+ /* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 4 -*- */
2
+ /* ***** BEGIN LICENSE BLOCK *****
3
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4
+ *
5
+ * The contents of this file are subject to the Mozilla Public License Version
6
+ * 1.1 (the "License"); you may not use this file except in compliance with
7
+ * the License. You may obtain a copy of the License at
8
+ * http://www.mozilla.org/MPL/
9
+ *
10
+ * Software distributed under the License is distributed on an "AS IS" basis,
11
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12
+ * for the specific language governing rights and limitations under the
13
+ * License.
14
+ *
15
+ * The Original Code is [Open Source Virtual Machine].
16
+ *
17
+ * The Initial Developer of the Original Code is
18
+ * Adobe System Incorporated.
19
+ * Portions created by the Initial Developer are Copyright (C) 2004-2007
20
+ * the Initial Developer. All Rights Reserved.
21
+ *
22
+ * Contributor(s):
23
+ * Adobe AS3 Team
24
+ * Mozilla TraceMonkey Team
25
+ * Asko Tontti <atontti@cc.hut.fi>
26
+ *
27
+ * Alternatively, the contents of this file may be used under the terms of
28
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
29
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
30
+ * in which case the provisions of the GPL or the LGPL are applicable instead
31
+ * of those above. If you wish to allow use of your version of this file only
32
+ * under the terms of either the GPL or the LGPL, and not to allow others to
33
+ * use your version of this file under the terms of the MPL, indicate your
34
+ * decision by deleting the provisions above and replace them with the notice
35
+ * and other provisions required by the GPL or the LGPL. If you do not delete
36
+ * the provisions above, a recipient may use your version of this file under
37
+ * the terms of any one of the MPL, the GPL or the LGPL.
38
+ *
39
+ * ***** END LICENSE BLOCK ***** */
40
+
41
+
42
+ #ifndef __nanojit_Fragmento__
43
+ #define __nanojit_Fragmento__
44
+
45
+ #ifdef AVMPLUS_VERBOSE
46
+ extern void drawTraceTrees(Fragmento *frago, FragmentMap * _frags, avmplus::AvmCore *core, char *fileName);
47
+ #endif
48
+
49
+ namespace nanojit
50
+ {
51
+ struct GuardRecord;
52
+ class Assembler;
53
+
54
+ struct PageHeader
55
+ {
56
+ struct Page *next;
57
+ };
58
+ struct Page: public PageHeader
59
+ {
60
+ union {
61
+ LIns lir[(NJ_PAGE_SIZE-sizeof(PageHeader))/sizeof(LIns)];
62
+ NIns code[(NJ_PAGE_SIZE-sizeof(PageHeader))/sizeof(NIns)];
63
+ };
64
+ };
65
+ struct AllocEntry : public avmplus::GCObject
66
+ {
67
+ Page *page;
68
+ uint32_t allocSize;
69
+ };
70
+ typedef avmplus::List<AllocEntry*,avmplus::LIST_NonGCObjects> AllocList;
71
+
72
+ typedef avmplus::GCSortedMap<const void*, uint32_t, avmplus::LIST_NonGCObjects> BlockSortedMap;
73
+ class BlockHist: public BlockSortedMap
74
+ {
75
+ public:
76
+ BlockHist(avmplus::GC*gc) : BlockSortedMap(gc)
77
+ {
78
+ }
79
+ uint32_t count(const void *p) {
80
+ uint32_t c = 1+get(p);
81
+ put(p, c);
82
+ return c;
83
+ }
84
+ };
85
+
86
+ struct fragstats;
87
+ /*
88
+ *
89
+ * This is the main control center for creating and managing fragments.
90
+ */
91
+ class Fragmento : public avmplus::GCFinalizedObject
92
+ {
93
+ public:
94
+ Fragmento(AvmCore* core, uint32_t cacheSizeLog2);
95
+ ~Fragmento();
96
+
97
+ void addMemory(void* firstPage, uint32_t pageCount); // gives memory to the Assembler
98
+ Assembler* assm();
99
+ AvmCore* core();
100
+ Page* pageAlloc();
101
+ void pageFree(Page* page);
102
+ void pagesRelease(PageList& list);
103
+
104
+ Fragment* getLoop(const void* ip);
105
+ Fragment* getAnchor(const void* ip);
106
+ // Remove one fragment. The caller is responsible for making sure
107
+ // that this does not destroy any resources shared with other
108
+ // fragments (such as a LirBuffer or this fragment itself as a
109
+ // jump target).
110
+ void clearFrag(const void* ip);
111
+ void clearFrags(); // clear all fragments from the cache
112
+ Fragment* getMerge(GuardRecord *lr, const void* ip);
113
+ Fragment* createBranch(SideExit *exit, const void* ip);
114
+ Fragment* newFrag(const void* ip);
115
+ Fragment* newBranch(Fragment *from, const void* ip);
116
+
117
+ verbose_only ( uint32_t pageCount(); )
118
+ verbose_only ( void dumpStats(); )
119
+ verbose_only ( void dumpRatio(const char*, BlockHist*);)
120
+ verbose_only ( void dumpFragStats(Fragment*, int level, fragstats&); )
121
+ verbose_only ( void countBlock(BlockHist*, const void* pc); )
122
+ verbose_only ( void countIL(uint32_t il, uint32_t abc); )
123
+ verbose_only( void addLabel(Fragment* f, const char *prefix, int id); )
124
+
125
+ // stats
126
+ struct
127
+ {
128
+ uint32_t pages; // pages consumed
129
+ uint32_t maxPageUse; // highwater mark of (pages-freePages)
130
+ uint32_t flushes, ilsize, abcsize, compiles, totalCompiles;
131
+ }
132
+ _stats;
133
+
134
+ verbose_only( DWB(BlockHist*) enterCounts; )
135
+ verbose_only( DWB(BlockHist*) mergeCounts; )
136
+ verbose_only( DWB(LabelMap*) labels; )
137
+
138
+ #ifdef AVMPLUS_VERBOSE
139
+ void drawTrees(char *fileName);
140
+ #endif
141
+
142
+ uint32_t cacheUsed() const { return (_stats.pages-_freePages.size())<<NJ_LOG2_PAGE_SIZE; }
143
+ uint32_t cacheUsedMax() const { return (_stats.maxPageUse)<<NJ_LOG2_PAGE_SIZE; }
144
+ void clearFragment(Fragment *f);
145
+ private:
146
+ void pagesGrow(int32_t count);
147
+ void trackPages();
148
+
149
+ AvmCore* _core;
150
+ DWB(Assembler*) _assm;
151
+ FragmentMap _frags; /* map from ip -> Fragment ptr */
152
+ PageList _freePages;
153
+
154
+ /* unmanaged mem */
155
+ AllocList _allocList;
156
+ avmplus::GCHeap* _gcHeap;
157
+
158
+ const uint32_t _max_pages;
159
+ uint32_t _pagesGrowth;
160
+ };
161
+
162
+ enum TraceKind {
163
+ LoopTrace,
164
+ BranchTrace,
165
+ MergeTrace
166
+ };
167
+
168
+ /**
169
+ * Fragments are linear sequences of native code that have a single entry
170
+ * point at the start of the fragment and may have one or more exit points
171
+ *
172
+ * It may turn out that that this arrangement causes too much traffic
173
+ * between d and i-caches and that we need to carve up the structure differently.
174
+ */
175
+ class Fragment : public avmplus::GCFinalizedObject
176
+ {
177
+ public:
178
+ Fragment(const void*);
179
+ ~Fragment();
180
+
181
+ NIns* code() { return _code; }
182
+ void setCode(NIns* codee, Page* pages) { _code = codee; _pages = pages; }
183
+ GuardRecord* links() { return _links; }
184
+ int32_t& hits() { return _hits; }
185
+ void resetHits();
186
+ void blacklist();
187
+ bool isBlacklisted() { return _hits < 0; }
188
+ debug_only( bool hasOnlyTreeLinks(); )
189
+ void releaseLirBuffer();
190
+ void releaseCode(Fragmento* frago);
191
+ void releaseTreeMem(Fragmento* frago);
192
+ bool isAnchor() { return anchor == this; }
193
+ bool isRoot() { return root == this; }
194
+ void onDestroy();
195
+
196
+ verbose_only( uint32_t _called; )
197
+ verbose_only( uint32_t _native; )
198
+ verbose_only( uint32_t _exitNative; )
199
+ verbose_only( uint32_t _lir; )
200
+ verbose_only( uint32_t _lirbytes; )
201
+ verbose_only( const char* _token; )
202
+ verbose_only( uint64_t traceTicks; )
203
+ verbose_only( uint64_t interpTicks; )
204
+ verbose_only( DWB(Fragment*) eot_target; )
205
+ verbose_only( uint32_t sid;)
206
+ verbose_only( uint32_t compileNbr;)
207
+
208
+ DWB(Fragment*) treeBranches;
209
+ DWB(Fragment*) branches;
210
+ DWB(Fragment*) nextbranch;
211
+ DWB(Fragment*) anchor;
212
+ DWB(Fragment*) root;
213
+ DWB(Fragment*) parent;
214
+ DWB(Fragment*) first;
215
+ DWB(Fragment*) peer;
216
+ DWB(LirBuffer*) lirbuf;
217
+ LIns* lastIns;
218
+ SideExit* spawnedFrom;
219
+
220
+ TraceKind kind;
221
+ const void* ip;
222
+ uint32_t guardCount;
223
+ uint32_t xjumpCount;
224
+ uint32_t recordAttempts;
225
+ int32_t blacklistLevel;
226
+ NIns* fragEntry;
227
+ NIns* loopEntry;
228
+ void* vmprivate;
229
+
230
+ private:
231
+ NIns* _code; // ptr to start of code
232
+ GuardRecord* _links; // code which is linked (or pending to be) to this fragment
233
+ int32_t _hits;
234
+ Page* _pages; // native code pages
235
+ };
236
+ }
237
+ #endif // __nanojit_Fragmento__
@@ -0,0 +1,2314 @@
1
+ /* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 4 -*- */
2
+ /* ***** BEGIN LICENSE BLOCK *****
3
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4
+ *
5
+ * The contents of this file are subject to the Mozilla Public License Version
6
+ * 1.1 (the "License"); you may not use this file except in compliance with
7
+ * the License. You may obtain a copy of the License at
8
+ * http://www.mozilla.org/MPL/
9
+ *
10
+ * Software distributed under the License is distributed on an "AS IS" basis,
11
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12
+ * for the specific language governing rights and limitations under the
13
+ * License.
14
+ *
15
+ * The Original Code is [Open Source Virtual Machine].
16
+ *
17
+ * The Initial Developer of the Original Code is
18
+ * Adobe System Incorporated.
19
+ * Portions created by the Initial Developer are Copyright (C) 2004-2007
20
+ * the Initial Developer. All Rights Reserved.
21
+ *
22
+ * Contributor(s):
23
+ * Adobe AS3 Team
24
+ *
25
+ * Alternatively, the contents of this file may be used under the terms of
26
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
27
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28
+ * in which case the provisions of the GPL or the LGPL are applicable instead
29
+ * of those above. If you wish to allow use of your version of this file only
30
+ * under the terms of either the GPL or the LGPL, and not to allow others to
31
+ * use your version of this file under the terms of the MPL, indicate your
32
+ * decision by deleting the provisions above and replace them with the notice
33
+ * and other provisions required by the GPL or the LGPL. If you do not delete
34
+ * the provisions above, a recipient may use your version of this file under
35
+ * the terms of any one of the MPL, the GPL or the LGPL.
36
+ *
37
+ * ***** END LICENSE BLOCK ***** */
38
+
39
+ #include "nanojit.h"
40
+ #include <stdio.h>
41
+ #include <ctype.h>
42
+
43
+ #ifdef PERFM
44
+ #include "../vprof/vprof.h"
45
+ #endif /* PERFM */
46
+
47
+ namespace nanojit
48
+ {
49
+ using namespace avmplus;
50
+ #ifdef FEATURE_NANOJIT
51
+
52
+ const uint8_t operandCount[] = {
53
+ #define OPDEF(op, number, operands) \
54
+ operands,
55
+ #define OPDEF64(op, number, operands) \
56
+ operands,
57
+ #include "LIRopcode.tbl"
58
+ #undef OPDEF
59
+ #undef OPDEF64
60
+ 0
61
+ };
62
+
63
+ // LIR verbose specific
64
+ #ifdef NJ_VERBOSE
65
+
66
+ const char* lirNames[] = {
67
+ #define OPDEF(op, number, operands) \
68
+ #op,
69
+ #define OPDEF64(op, number, operands) \
70
+ #op,
71
+ #include "LIRopcode.tbl"
72
+ #undef OPDEF
73
+ #undef OPDEF64
74
+ NULL
75
+ };
76
+
77
+ #endif /* NANOJIT_VEBROSE */
78
+
79
+ // implementation
80
+
81
+ #ifdef NJ_PROFILE
82
+ // @todo fixup move to nanojit.h
83
+ #undef counter_value
84
+ #define counter_value(x) x
85
+ #endif /* NJ_PROFILE */
86
+
87
+ //static int32_t buffer_count = 0;
88
+
89
+ // LCompressedBuffer
90
+ LirBuffer::LirBuffer(Fragmento* frago, const CallInfo* functions)
91
+ : _frago(frago),
92
+ #ifdef NJ_VERBOSE
93
+ names(NULL),
94
+ #endif
95
+ _functions(functions), abi(ABI_FASTCALL),
96
+ state(NULL), param1(NULL), sp(NULL), rp(NULL),
97
+ _pages(frago->core()->GetGC())
98
+ {
99
+ rewind();
100
+ }
101
+
102
+ LirBuffer::~LirBuffer()
103
+ {
104
+ clear();
105
+ verbose_only(if (names) NJ_DELETE(names);)
106
+ _frago = 0;
107
+ }
108
+
109
+ void LirBuffer::clear()
110
+ {
111
+ // free all the memory and clear the stats
112
+ _frago->pagesRelease(_pages);
113
+ NanoAssert(!_pages.size());
114
+ _unused = 0;
115
+ _stats.lir = 0;
116
+ _noMem = 0;
117
+ _nextPage = 0;
118
+ for (int i = 0; i < NumSavedRegs; ++i)
119
+ savedRegs[i] = NULL;
120
+ explicitSavedRegs = false;
121
+ }
122
+
123
+ void LirBuffer::rewind()
124
+ {
125
+ clear();
126
+ // pre-allocate the current and the next page we will be using
127
+ Page* start = pageAlloc();
128
+ _unused = start ? &start->lir[0] : NULL;
129
+ _nextPage = pageAlloc();
130
+ NanoAssert((_unused && _nextPage) || _noMem);
131
+ }
132
+
133
+ int32_t LirBuffer::insCount()
134
+ {
135
+ // doesn't include embedded constants nor LIR_skip payload
136
+ return _stats.lir;
137
+ }
138
+
139
+ int32_t LirBuffer::byteCount()
140
+ {
141
+ return ((_pages.size() ? _pages.size()-1 : 0) * sizeof(Page)) +
142
+ ((int32_t)_unused - (int32_t)pageTop(_unused));
143
+ }
144
+
145
+ Page* LirBuffer::pageAlloc()
146
+ {
147
+ Page* page = _frago->pageAlloc();
148
+ if (page)
149
+ _pages.add(page);
150
+ else
151
+ _noMem = 1;
152
+ return page;
153
+ }
154
+
155
+ LInsp LirBuffer::next()
156
+ {
157
+ return _unused;
158
+ }
159
+
160
+ void LirBufWriter::ensureRoom(uint32_t count)
161
+ {
162
+ NanoAssert(count * sizeof(LIns) <= MAX_SKIP_BYTES);
163
+ LInsp before = _buf->next();
164
+ LInsp after = before+count+LIR_FAR_SLOTS;
165
+ // transition to the next page?
166
+ if (!samepage(before,after))
167
+ {
168
+ // we don't want this to fail, so we always have a page in reserve
169
+ NanoAssert(_buf->_nextPage);
170
+ _buf->_unused = &_buf->_nextPage->lir[0];
171
+ // link LIR stream back to prior instruction (careful insLink relies on _unused...)
172
+ insLinkTo(LIR_skip, before-1);
173
+ _buf->_nextPage = _buf->pageAlloc();
174
+ NanoAssert(_buf->_nextPage || _buf->_noMem);
175
+ }
176
+ }
177
+
178
+ LInsp LirBufWriter::insLinkTo(LOpcode op, LInsp to)
179
+ {
180
+ LInsp l = _buf->next();
181
+ NanoAssert(samepage(l,l+LIR_FAR_SLOTS)); // must have called ensureRoom()
182
+ if (can24bReach(l,to))
183
+ {
184
+ NanoStaticAssert(LIR_nearskip == LIR_skip - 1);
185
+ NanoStaticAssert(LIR_neartramp == LIR_tramp - 1);
186
+ l->initOpcode(LOpcode(op-1)); // nearskip or neartramp
187
+ l->setimm24(to-l);
188
+ _buf->commit(1);
189
+ _buf->_stats.lir++;
190
+ }
191
+ else
192
+ {
193
+ l = insLinkToFar(op,to);
194
+ }
195
+ return l;
196
+ }
197
+
198
+ LInsp LirBufWriter::insLinkToFar(LOpcode op, LInsp to)
199
+ {
200
+ LirFarIns* ov = (LirFarIns*) _buf->next();
201
+ ov->v = to;
202
+ ov->i.initOpcode(op);
203
+ _buf->commit(LIR_FAR_SLOTS);
204
+ _buf->_stats.lir++;
205
+
206
+ NanoAssert( (LInsp)(ov+1) == _buf->next() );
207
+ return &(ov->i);
208
+ }
209
+
210
+ void LirBufWriter::makeReachable(LInsp& o, LInsp from)
211
+ {
212
+ if (o && !can8bReach(from,o))
213
+ {
214
+ if (o == _buf->sp && spref && can8bReach(from, spref)) {
215
+ o = spref;
216
+ return;
217
+ }
218
+ if (o == _buf->rp && rpref && can8bReach(from, rpref)) {
219
+ o = rpref;
220
+ return;
221
+ }
222
+
223
+ // need a trampoline to get to from
224
+ LInsp tramp = insLinkTo(LIR_tramp, o); // will produce neartramp if possible
225
+ NanoAssert( tramp->ref() == o && samepage(from,tramp) );
226
+ if (o == _buf->sp)
227
+ spref = tramp;
228
+ else if (o == _buf->rp)
229
+ rpref = tramp;
230
+ o = tramp;
231
+ }
232
+ }
233
+
234
+ void LirBufWriter::prepFor(LInsp& i1, LInsp& i2, LInsp& i3)
235
+ {
236
+ uint32_t i = 0; // count of operands
237
+ i += (i1) ? 1 : 0;
238
+ i += (i2) ? 1 : 0;
239
+ i += (i3) ? 1 : 0;
240
+
241
+ uint32_t count = (LIR_FAR_SLOTS*i)+1; // count of LIns if all operands require tramp
242
+ ensureRoom(count);
243
+ NanoAssert( samepage(_buf->next()+count,_buf->next()) );
244
+
245
+ // guaranteed space for far tramps if necc.
246
+ LInsp from = _buf->next()+count;
247
+ makeReachable(i1, from);
248
+ makeReachable(i2, from);
249
+ makeReachable(i3, from);
250
+ NanoAssert(from>i1 && from>i2 && from>i3);
251
+ }
252
+
253
+ LInsp LirBuffer::commit(uint32_t count)
254
+ {
255
+ NanoAssertMsg( samepage(_unused, _unused+count), "You need to call ensureRoom first!" );
256
+ return _unused += count;
257
+ }
258
+
259
+ uint32_t LIns::reference(LIns *r) const
260
+ {
261
+ int delta = this-r-1;
262
+ NanoAssert(isU8(delta));
263
+ return delta;
264
+ }
265
+
266
+ LIns* LIns::deref(int32_t off) const
267
+ {
268
+ LInsp i = (LInsp) this-1 - off;
269
+ while (i && i->isTramp()) {
270
+ i = i->ref();
271
+ }
272
+ return i;
273
+ }
274
+
275
+ LInsp LirBufWriter::insStore(LInsp val, LInsp base, LInsp off)
276
+ {
277
+ LOpcode op = val->isQuad() ? LIR_stq : LIR_st;
278
+ NanoAssert(val && base && off);
279
+ prepFor(val, base, off);
280
+ LInsp l = _buf->next();
281
+ l->initOpcode(op);
282
+ l->setOprnd1(val);
283
+ l->setOprnd2(base);
284
+ l->setOprnd3(off);
285
+ _buf->commit(1);
286
+ _buf->_stats.lir++;
287
+ return l;
288
+ }
289
+
290
+ LInsp LirBufWriter::insStorei(LInsp val, LInsp base, int32_t d)
291
+ {
292
+ if (!isS8(d)) {
293
+ return insStore(val, base, insImm(d));
294
+ }
295
+
296
+ LOpcode op = val->isQuad() ? LIR_stqi : LIR_sti;
297
+ NanoAssert(val && base && isS8(d));
298
+ LInsp u3=0;
299
+ prepFor(val, base, u3);
300
+ LInsp l = _buf->next();
301
+ l->initOpcode(op);
302
+ l->setOprnd1(val);
303
+ l->setOprnd2(base);
304
+ l->setDisp(int8_t(d));
305
+ _buf->commit(1);
306
+ _buf->_stats.lir++;
307
+ return l;
308
+ }
309
+
310
+ LInsp LirBufWriter::ins0(LOpcode op)
311
+ {
312
+ ensureRoom(1);
313
+ LirBuffer *b = this->_buf;
314
+ LInsp l = b->next();
315
+ l->initOpcode(op);
316
+ b->commit(1);
317
+ b->_stats.lir++;
318
+ return l;
319
+ }
320
+
321
+ LInsp LirBufWriter::ins1(LOpcode op, LInsp o1)
322
+ {
323
+ LInsp u2=0,u3=0;
324
+ prepFor(o1,u2,u3);
325
+ LInsp l = _buf->next();
326
+ l->initOpcode(op);
327
+ l->setOprnd1(o1);
328
+ _buf->commit(1);
329
+ _buf->_stats.lir++;
330
+ return l;
331
+ }
332
+
333
+ LInsp LirBufWriter::ins2(LOpcode op, LInsp o1, LInsp o2)
334
+ {
335
+ LInsp u3=0;
336
+ prepFor(o1,o2,u3);
337
+ LInsp l = _buf->next();
338
+ l->initOpcode(op);
339
+ l->setOprnd1(o1);
340
+ l->setOprnd2(o2);
341
+ _buf->commit(1);
342
+ _buf->_stats.lir++;
343
+ return l;
344
+ }
345
+
346
+ LInsp LirBufWriter::insLoad(LOpcode op, LInsp base, LInsp d)
347
+ {
348
+ return ins2(op,base,d);
349
+ }
350
+
351
+ LInsp LirBufWriter::insGuard(LOpcode op, LInsp c, LInsp data)
352
+ {
353
+ return ins2(op, c, data);
354
+ }
355
+
356
+ LInsp LirBufWriter::insBranch(LOpcode op, LInsp condition, LInsp toLabel)
357
+ {
358
+ if (!toLabel)
359
+ toLabel = insFar(LIR_tramp,0); //empty tramp
360
+ if (!condition) {
361
+ // unconditional, just point to something
362
+ condition = toLabel;
363
+ }
364
+ return ins2(op,condition,toLabel);
365
+ }
366
+
367
+ LInsp LirBufWriter::insAlloc(int32_t size)
368
+ {
369
+ size = (size+3)>>2; // # of required 32bit words
370
+ NanoAssert(isU16(size));
371
+ ensureRoom(1);
372
+ LInsp l = _buf->next();
373
+ l->initOpcode(LIR_alloc);
374
+ l->i.imm16 = uint16_t(size);
375
+ _buf->commit(1);
376
+ _buf->_stats.lir++;
377
+ return l;
378
+ }
379
+
380
+ LInsp LirBufWriter::insParam(int32_t arg, int32_t kind)
381
+ {
382
+ ensureRoom(1);
383
+ LirBuffer *b = this->_buf;
384
+ LInsp l = b->next();
385
+ l->initOpcode(LIR_param);
386
+ NanoAssert(isU8(arg) && isU8(kind));
387
+ l->c.imm8a = arg;
388
+ l->c.imm8b = kind;
389
+ if (kind) {
390
+ NanoAssert(arg < NumSavedRegs);
391
+ b->savedRegs[arg] = l;
392
+ b->explicitSavedRegs = true;
393
+ }
394
+ b->commit(1);
395
+ b->_stats.lir++;
396
+ return l;
397
+ }
398
+
399
+ LInsp LirBufWriter::insFar(LOpcode op, LInsp target)
400
+ {
401
+ ensureRoom(LIR_FAR_SLOTS); // make room for it
402
+ LInsp l = insLinkToFar(op, target);
403
+ _buf->_stats.lir++;
404
+ return l;
405
+ }
406
+
407
+ LInsp LirBufWriter::insImm(int32_t imm)
408
+ {
409
+ if (isS16(imm)) {
410
+ ensureRoom(1);
411
+ LInsp l = _buf->next();
412
+ l->initOpcode(LIR_short);
413
+ l->setimm16(imm);
414
+ _buf->commit(1);
415
+ _buf->_stats.lir++;
416
+ return l;
417
+ } else {
418
+ ensureRoom(LIR_IMM32_SLOTS);
419
+ LirImm32Ins* l = (LirImm32Ins*)_buf->next();
420
+ l->v = imm;
421
+ l->i.initOpcode(LIR_int);
422
+ _buf->commit(LIR_IMM32_SLOTS);
423
+ _buf->_stats.lir++;
424
+ NanoAssert((LInsp)(l+1)==_buf->next());
425
+ return &(l->i);
426
+ }
427
+ }
428
+
429
+ LInsp LirBufWriter::insImmq(uint64_t imm)
430
+ {
431
+ ensureRoom(LIR_IMM64_SLOTS);
432
+ LirImm64Ins* l = (LirImm64Ins*)_buf->next();
433
+ l->v[0] = int32_t(imm);
434
+ l->v[1] = int32_t(imm>>32);
435
+ l->i.initOpcode(LIR_quad);
436
+ _buf->commit(LIR_IMM64_SLOTS);
437
+ _buf->_stats.lir++;
438
+ NanoAssert((LInsp)(l+1)==_buf->next());
439
+ return &(l->i);
440
+ }
441
+
442
+ LInsp LirBufWriter::skip(size_t size)
443
+ {
444
+ const uint32_t n = (size+sizeof(LIns)-1)/sizeof(LIns);
445
+ ensureRoom(n); // make room for it
446
+ LInsp last = _buf->next()-1; // safe, next()-1+n guaranteed to be on same page
447
+ _buf->commit(n);
448
+ NanoAssert(samepage(last,_buf->next()));
449
+ ensureRoom(LIR_FAR_SLOTS);
450
+ return insLinkTo(LIR_skip, last);
451
+ }
452
+
453
+ LInsp LirReader::read()
454
+ {
455
+ LInsp cur = _i;
456
+ if (!cur)
457
+ return 0;
458
+ LIns* i = cur;
459
+ LOpcode iop = i->opcode();
460
+ do
461
+ {
462
+ switch (iop)
463
+ {
464
+ default:
465
+ i--;
466
+ break;
467
+
468
+ #if defined NANOJIT_64BIT
469
+ case LIR_callh:
470
+ #endif
471
+ case LIR_call:
472
+ case LIR_fcall:
473
+ case LIR_calli:
474
+ case LIR_fcalli:
475
+ NanoAssert( samepage(i,i+1-i->callInsWords()) );
476
+ i -= i->callInsWords();
477
+ break;
478
+
479
+ case LIR_skip:
480
+ case LIR_nearskip:
481
+ NanoAssert(i->ref() != i);
482
+ i = i->ref();
483
+ break;
484
+
485
+ case LIR_tramp:
486
+ NanoAssert(samepage(i,i+1-LIR_FAR_SLOTS));
487
+ i -= LIR_FAR_SLOTS;
488
+ break;
489
+
490
+ case LIR_int:
491
+ NanoAssert(samepage(i,i+1-LIR_IMM32_SLOTS));
492
+ i -= LIR_IMM32_SLOTS;
493
+ break;
494
+
495
+ case LIR_quad:
496
+ NanoAssert(samepage(i,i+1-LIR_IMM64_SLOTS));
497
+ i -= LIR_IMM64_SLOTS;
498
+ break;
499
+
500
+ case LIR_start:
501
+ _i = 0; // start of trace
502
+ return cur;
503
+ }
504
+ iop = i->opcode();
505
+ }
506
+ while (is_trace_skip_tramp(iop)||iop==LIR_2);
507
+ _i = i;
508
+ return cur;
509
+ }
510
+
511
+ bool FASTCALL isCmp(LOpcode c) {
512
+ return (c >= LIR_eq && c <= LIR_uge) || (c >= LIR_feq && c <= LIR_fge);
513
+ }
514
+
515
+ bool FASTCALL isCond(LOpcode c) {
516
+ return (c == LIR_ov) || (c == LIR_cs) || isCmp(c);
517
+ }
518
+
519
+ bool FASTCALL isFloat(LOpcode c) {
520
+ switch (c) {
521
+ default:
522
+ return false;
523
+ case LIR_fadd:
524
+ case LIR_fsub:
525
+ case LIR_fmul:
526
+ case LIR_fdiv:
527
+ case LIR_fneg:
528
+ case LIR_fcall:
529
+ case LIR_fcalli:
530
+ case LIR_i2f:
531
+ case LIR_u2f:
532
+ return true;
533
+ }
534
+ }
535
+
536
+ bool LIns::isCmp() const {
537
+ return nanojit::isCmp(u.code);
538
+ }
539
+
540
+ bool LIns::isCond() const {
541
+ return nanojit::isCond(u.code);
542
+ }
543
+
544
+ bool LIns::isQuad() const {
545
+ #ifdef AVMPLUS_64BIT
546
+ // callh in 64bit cpu's means a call that returns an int64 in a single register
547
+ return (u.code & LIR64) != 0 || u.code == LIR_callh;
548
+ #else
549
+ // callh in 32bit cpu's means the 32bit MSW of an int64 result in 2 registers
550
+ return (u.code & LIR64) != 0;
551
+ #endif
552
+ }
553
+
554
+ bool LIns::isconstval(int32_t val) const
555
+ {
556
+ return isconst() && constval()==val;
557
+ }
558
+
559
+ bool LIns::isconstq() const
560
+ {
561
+ return isop(LIR_quad);
562
+ }
563
+
564
+ bool LIns::isconstp() const
565
+ {
566
+ #ifdef AVMPLUS_64BIT
567
+ return isconstq();
568
+ #else
569
+ return isconst();
570
+ #endif
571
+ }
572
+
573
+ bool FASTCALL isCse(LOpcode op) {
574
+ op = LOpcode(op & ~LIR64);
575
+ return op >= LIR_ldcs && op <= LIR_uge;
576
+ }
577
+
578
+ bool LIns::isCse(const CallInfo *functions) const
579
+ {
580
+ return nanojit::isCse(u.code) || (isCall() && callInfo()->_cse);
581
+ }
582
+
583
+ void LIns::setimm16(int32_t x)
584
+ {
585
+ NanoAssert(isS16(x));
586
+ i.imm16 = int16_t(x);
587
+ }
588
+
589
+ void LIns::setimm24(int32_t x)
590
+ {
591
+ NanoAssert(isS24(x));
592
+ t.imm24 = x;
593
+ }
594
+
595
+ void LIns::setresv(uint32_t resv)
596
+ {
597
+ NanoAssert(isU8(resv));
598
+ g.resv = resv;
599
+ }
600
+
601
+ void LIns::initOpcode(LOpcode op)
602
+ {
603
+ i.code = op;
604
+ i.imm16 = 0;
605
+ i.resv = 0;
606
+ }
607
+
608
+ void LIns::setOprnd1(LInsp r)
609
+ {
610
+ u.oprnd_1 = reference(r);
611
+ }
612
+
613
+ void LIns::setOprnd2(LInsp r)
614
+ {
615
+ u.oprnd_2 = reference(r);
616
+ }
617
+
618
+ void LIns::setOprnd3(LInsp r)
619
+ {
620
+ u.oprnd_3 = reference(r);
621
+ }
622
+
623
+ void LIns::setDisp(int8_t d)
624
+ {
625
+ sti.disp = d;
626
+ }
627
+
628
+ LIns **LIns::targetAddr() {
629
+ NanoAssert(isBranch());
630
+ LInsp i = (LInsp) this-1 - u.oprnd_2;
631
+ NanoAssert(i->isTramp());
632
+ LInsp ref;
633
+ while ((ref=i->ref()) != 0 && ref->isTramp())
634
+ i = ref;
635
+ NanoAssert(i->isop(LIR_tramp));
636
+ LirFarIns* ov = (LirFarIns*)(i-LIR_FAR_SLOTS+1);
637
+ return &(ov->v);
638
+ }
639
+
640
+ void LIns::target(LInsp label) {
641
+ NanoAssert(label && label->isop(LIR_label));
642
+ *(targetAddr()) = label;
643
+ }
644
+
645
+ LInsp LIns::getTarget()
646
+ {
647
+ NanoAssert(isBranch());
648
+ return oprnd2();
649
+ }
650
+
651
+ LInsp LIns::oprnd1() const
652
+ {
653
+ return deref(u.oprnd_1);
654
+ }
655
+
656
+ LInsp LIns::oprnd2() const
657
+ {
658
+ return deref(u.oprnd_2);
659
+ }
660
+
661
+ LInsp LIns::oprnd3() const
662
+ {
663
+ return deref(u.oprnd_3);
664
+ }
665
+
666
+ void *LIns::payload() const
667
+ {
668
+ NanoAssert(opcode()==LIR_skip || opcode()==LIR_nearskip);
669
+ return (void*) (ref()+1);
670
+ }
671
+
672
+ LIns* LIns::ref() const
673
+ {
674
+ LIns const *r = 0;
675
+ if (t.code&1)
676
+ r = this + t.imm24;
677
+ else
678
+ {
679
+ LirFarIns* l = (LirFarIns*)(this-LIR_FAR_SLOTS+1);
680
+ r = l->v;
681
+ }
682
+ return (const LInsp)r;
683
+ }
684
+
685
+ int32_t LIns::imm32() const
686
+ {
687
+ LirImm32Ins* l = (LirImm32Ins*)(this-LIR_IMM32_SLOTS+1);
688
+ return l->v;
689
+ }
690
+
691
+ uint64_t LIns::constvalq() const
692
+ {
693
+ LirImm64Ins* l = (LirImm64Ins*)(this-LIR_IMM64_SLOTS+1);
694
+ #ifdef AVMPLUS_UNALIGNED_ACCESS
695
+ int* ptr = (int*)l->v;
696
+ return *(const uint64_t*)ptr;
697
+ #else
698
+ union { uint64_t tmp; int32_t dst[2]; } u;
699
+ #ifdef AVMPLUS_BIG_ENDIAN
700
+ u.dst[0] = l->v[1];
701
+ u.dst[1] = l->v[0];
702
+ #else
703
+ u.dst[0] = l->v[0];
704
+ u.dst[1] = l->v[1];
705
+ #endif
706
+ return u.tmp;
707
+ #endif
708
+ }
709
+
710
+ double LIns::constvalf() const
711
+ {
712
+ LirImm64Ins* l = (LirImm64Ins*)(this-LIR_IMM64_SLOTS+1);
713
+ NanoAssert(isconstq());
714
+ #ifdef AVMPLUS_UNALIGNED_ACCESS
715
+ int* ptr = (int*)l->v;
716
+ return *(const double*)ptr;
717
+ #else
718
+ union { uint32_t dst[2]; double tmpf; } u;
719
+ #ifdef AVMPLUS_BIG_ENDIAN
720
+ u.dst[0] = l->v[1];
721
+ u.dst[1] = l->v[0];
722
+ #else
723
+ u.dst[0] = l->v[0];
724
+ u.dst[1] = l->v[1];
725
+ #endif
726
+ return u.tmpf;
727
+ #endif
728
+ }
729
+
730
+ size_t LIns::callInsWords() const
731
+ {
732
+ return LIR_CALL_SLOTS + argwords(argc());
733
+ }
734
+
735
+ const CallInfo* LIns::callInfo() const
736
+ {
737
+ LirCallIns* l = (LirCallIns*)(this-LIR_CALL_SLOTS+1);
738
+ return l->ci;
739
+ }
740
+
741
+ // index args in r-l order. arg(0) is rightmost arg
742
+ LIns* LIns::arg(uint32_t i)
743
+ {
744
+ NanoAssert(i < argc());
745
+ LirCallIns* l = (LirCallIns*)(this-LIR_CALL_SLOTS+1);
746
+ uint8_t* offs = (uint8_t*)l - (i+1);
747
+ return deref(*offs);
748
+ }
749
+
750
+ LIns* LirWriter::ins2i(LOpcode v, LIns* oprnd1, int32_t imm)
751
+ {
752
+ return ins2(v, oprnd1, insImm(imm));
753
+ }
754
+
755
+ bool insIsS16(LInsp i)
756
+ {
757
+ if (i->isconst()) {
758
+ int c = i->constval();
759
+ return isS16(c);
760
+ }
761
+ if (i->isop(LIR_cmov) || i->isop(LIR_qcmov)) {
762
+ LInsp vals = i->oprnd2();
763
+ return insIsS16(vals->oprnd1()) && insIsS16(vals->oprnd2());
764
+ }
765
+ if (i->isCmp())
766
+ return true;
767
+ // many other possibilities too.
768
+ return false;
769
+ }
770
+
771
+ LIns* ExprFilter::ins1(LOpcode v, LIns* i)
772
+ {
773
+ if (v == LIR_qlo) {
774
+ if (i->isconstq())
775
+ return insImm(int32_t(i->constvalq()));
776
+ if (i->isop(LIR_qjoin))
777
+ return i->oprnd1();
778
+ }
779
+ else if (v == LIR_qhi) {
780
+ if (i->isconstq())
781
+ return insImm(int32_t(i->constvalq()>>32));
782
+ if (i->isop(LIR_qjoin))
783
+ return i->oprnd2();
784
+ }
785
+ else if (i->isconst()) {
786
+ int32_t c = i->constval();
787
+ if (v == LIR_neg)
788
+ return insImm(-c);
789
+ if (v == LIR_not)
790
+ return insImm(~c);
791
+ }
792
+ else if (v == i->opcode() && (v == LIR_not || v == LIR_neg || v == LIR_fneg)) {
793
+ // not(not(x)) = x; neg(neg(x)) = x; fneg(fneg(x)) = x;
794
+ return i->oprnd1();
795
+ }
796
+ /* [ed 8.27.08] this causes a big slowdown in gameoflife.as. why?
797
+ else if (i->isconst()) {
798
+ if (v == LIR_i2f) {
799
+ return insImmf(i->constval());
800
+ }
801
+ else if (v == LIR_u2f) {
802
+ return insImmf((uint32_t)i->constval());
803
+ }
804
+ }*/
805
+
806
+ // todo
807
+ // -(a-b) = b-a
808
+
809
+ return out->ins1(v, i);
810
+ }
811
+
812
+ LIns* ExprFilter::ins2(LOpcode v, LIns* oprnd1, LIns* oprnd2)
813
+ {
814
+ NanoAssert(oprnd1 && oprnd2);
815
+ if (v == LIR_cmov || v == LIR_qcmov) {
816
+ if (oprnd2->oprnd1() == oprnd2->oprnd2()) {
817
+ // c ? a : a => a
818
+ return oprnd2->oprnd1();
819
+ }
820
+ if (oprnd1->isconst()) {
821
+ // const ? x : y => return x or y depending on const
822
+ return oprnd1->constval() ? oprnd2->oprnd1() : oprnd2->oprnd2();
823
+ }
824
+ }
825
+ if (oprnd1 == oprnd2)
826
+ {
827
+ if (v == LIR_xor || v == LIR_sub ||
828
+ v == LIR_ult || v == LIR_ugt || v == LIR_gt || v == LIR_lt)
829
+ return insImm(0);
830
+ if (v == LIR_or || v == LIR_and)
831
+ return oprnd1;
832
+ if (v == LIR_le || v == LIR_ule || v == LIR_ge || v == LIR_uge) {
833
+ // x <= x == 1; x >= x == 1
834
+ return insImm(1);
835
+ }
836
+ }
837
+ if (oprnd1->isconst() && oprnd2->isconst())
838
+ {
839
+ int c1 = oprnd1->constval();
840
+ int c2 = oprnd2->constval();
841
+ if (v == LIR_qjoin) {
842
+ uint64_t q = c1 | uint64_t(c2)<<32;
843
+ return insImmq(q);
844
+ }
845
+ if (v == LIR_eq)
846
+ return insImm(c1 == c2);
847
+ if (v == LIR_ov)
848
+ return insImm((c2 != 0) && ((c1 + c2) <= c1));
849
+ if (v == LIR_cs)
850
+ return insImm((c2 != 0) && ((uint32_t(c1) + uint32_t(c2)) <= uint32_t(c1)));
851
+ if (v == LIR_lt)
852
+ return insImm(c1 < c2);
853
+ if (v == LIR_gt)
854
+ return insImm(c1 > c2);
855
+ if (v == LIR_le)
856
+ return insImm(c1 <= c2);
857
+ if (v == LIR_ge)
858
+ return insImm(c1 >= c2);
859
+ if (v == LIR_ult)
860
+ return insImm(uint32_t(c1) < uint32_t(c2));
861
+ if (v == LIR_ugt)
862
+ return insImm(uint32_t(c1) > uint32_t(c2));
863
+ if (v == LIR_ule)
864
+ return insImm(uint32_t(c1) <= uint32_t(c2));
865
+ if (v == LIR_uge)
866
+ return insImm(uint32_t(c1) >= uint32_t(c2));
867
+ if (v == LIR_rsh)
868
+ return insImm(int32_t(c1) >> int32_t(c2));
869
+ if (v == LIR_lsh)
870
+ return insImm(int32_t(c1) << int32_t(c2));
871
+ if (v == LIR_ush)
872
+ return insImm(uint32_t(c1) >> int32_t(c2));
873
+ if (v == LIR_or)
874
+ return insImm(uint32_t(c1) | int32_t(c2));
875
+ if (v == LIR_and)
876
+ return insImm(uint32_t(c1) & int32_t(c2));
877
+ if (v == LIR_xor)
878
+ return insImm(uint32_t(c1) ^ int32_t(c2));
879
+ }
880
+ else if (oprnd1->isconstq() && oprnd2->isconstq())
881
+ {
882
+ double c1 = oprnd1->constvalf();
883
+ double c2 = oprnd2->constvalf();
884
+ if (v == LIR_feq)
885
+ return insImm(c1 == c2);
886
+ if (v == LIR_flt)
887
+ return insImm(c1 < c2);
888
+ if (v == LIR_fgt)
889
+ return insImm(c1 > c2);
890
+ if (v == LIR_fle)
891
+ return insImm(c1 <= c2);
892
+ if (v == LIR_fge)
893
+ return insImm(c1 >= c2);
894
+ }
895
+ else if (oprnd1->isconst() && !oprnd2->isconst())
896
+ {
897
+ if (v == LIR_add || v == LIR_addp || v == LIR_mul ||
898
+ v == LIR_fadd || v == LIR_fmul ||
899
+ v == LIR_xor || v == LIR_or || v == LIR_and ||
900
+ v == LIR_eq) {
901
+ // move const to rhs
902
+ LIns* t = oprnd2;
903
+ oprnd2 = oprnd1;
904
+ oprnd1 = t;
905
+ }
906
+ else if (v >= LIR_lt && v <= LIR_uge) {
907
+ NanoStaticAssert((LIR_lt ^ 1) == LIR_gt);
908
+ NanoStaticAssert((LIR_le ^ 1) == LIR_ge);
909
+ NanoStaticAssert((LIR_ult ^ 1) == LIR_ugt);
910
+ NanoStaticAssert((LIR_ule ^ 1) == LIR_uge);
911
+
912
+ // move const to rhs, swap the operator
913
+ LIns *t = oprnd2;
914
+ oprnd2 = oprnd1;
915
+ oprnd1 = t;
916
+ v = LOpcode(v^1);
917
+ }
918
+ }
919
+
920
+ if (oprnd2->isconst())
921
+ {
922
+ int c = oprnd2->constval();
923
+ if (v == LIR_add && oprnd1->isop(LIR_add) && oprnd1->oprnd2()->isconst()) {
924
+ // add(add(x,c1),c2) => add(x,c1+c2)
925
+ c += oprnd1->oprnd2()->constval();
926
+ oprnd2 = insImm(c);
927
+ oprnd1 = oprnd1->oprnd1();
928
+ }
929
+ else if (v == LIR_sub && oprnd1->isop(LIR_add) && oprnd1->oprnd2()->isconst()) {
930
+ // sub(add(x,c1),c2) => add(x,c1-c2)
931
+ c = oprnd1->oprnd2()->constval() - c;
932
+ oprnd2 = insImm(c);
933
+ oprnd1 = oprnd1->oprnd1();
934
+ v = LIR_add;
935
+ }
936
+ else if (v == LIR_rsh && c == 16 && oprnd1->isop(LIR_lsh) &&
937
+ oprnd1->oprnd2()->isconstval(16)) {
938
+ if (insIsS16(oprnd1->oprnd1())) {
939
+ // rsh(lhs(x,16),16) == x, if x is S16
940
+ return oprnd1->oprnd1();
941
+ }
942
+ }
943
+ else if (v == LIR_ult) {
944
+ if (oprnd1->isop(LIR_cmov) || oprnd1->isop(LIR_qcmov)) {
945
+ LInsp a = oprnd1->oprnd2()->oprnd1();
946
+ LInsp b = oprnd1->oprnd2()->oprnd2();
947
+ if (a->isconst() && b->isconst()) {
948
+ bool a_lt = uint32_t(a->constval()) < uint32_t(oprnd2->constval());
949
+ bool b_lt = uint32_t(b->constval()) < uint32_t(oprnd2->constval());
950
+ if (a_lt == b_lt)
951
+ return insImm(a_lt);
952
+ }
953
+ }
954
+ }
955
+
956
+ if (c == 0)
957
+ {
958
+ if (v == LIR_add || v == LIR_addp || v == LIR_or || v == LIR_xor ||
959
+ v == LIR_sub || v == LIR_lsh || v == LIR_rsh || v == LIR_ush)
960
+ return oprnd1;
961
+ else if (v == LIR_and || v == LIR_mul)
962
+ return oprnd2;
963
+ else if (v == LIR_eq && oprnd1->isop(LIR_or) &&
964
+ oprnd1->oprnd2()->isconst() &&
965
+ oprnd1->oprnd2()->constval() != 0) {
966
+ // (x or c) != 0 if c != 0
967
+ return insImm(0);
968
+ }
969
+ }
970
+ else if (c == -1 || (c == 1 && oprnd1->isCmp())) {
971
+ if (v == LIR_or) {
972
+ // x | -1 = -1, cmp | 1 = 1
973
+ return oprnd2;
974
+ }
975
+ else if (v == LIR_and) {
976
+ // x & -1 = x, cmp & 1 = cmp
977
+ return oprnd1;
978
+ }
979
+ }
980
+ }
981
+
982
+ LInsp i;
983
+ if (v == LIR_qjoin && oprnd1->isop(LIR_qlo) && oprnd2->isop(LIR_qhi)
984
+ && (i = oprnd1->oprnd1()) == oprnd2->oprnd1()) {
985
+ // qjoin(qlo(x),qhi(x)) == x
986
+ return i;
987
+ }
988
+
989
+ return out->ins2(v, oprnd1, oprnd2);
990
+ }
991
+
992
+ LIns* ExprFilter::insGuard(LOpcode v, LInsp c, LInsp x)
993
+ {
994
+ if (v == LIR_xt || v == LIR_xf) {
995
+ if (c->isconst()) {
996
+ if ((v == LIR_xt && !c->constval()) || (v == LIR_xf && c->constval())) {
997
+ return 0; // no guard needed
998
+ }
999
+ else {
1000
+ #ifdef JS_TRACER
1001
+ // We're emitting a guard that will always fail. Any code
1002
+ // emitted after this guard is dead code. We could
1003
+ // silently optimize out the rest of the emitted code, but
1004
+ // this could indicate a performance problem or other bug,
1005
+ // so assert in debug builds.
1006
+ NanoAssertMsg(0, "Constantly false guard detected");
1007
+ #endif
1008
+ return out->insGuard(LIR_x, out->insImm(1), x);
1009
+ }
1010
+ }
1011
+ else {
1012
+ NanoStaticAssert((LIR_xt ^ 1) == LIR_xf);
1013
+ while (c->isop(LIR_eq) && c->oprnd1()->isCmp() &&
1014
+ c->oprnd2()->isconstval(0)) {
1015
+ // xt(eq(cmp,0)) => xf(cmp) or xf(eq(cmp,0)) => xt(cmp)
1016
+ v = LOpcode(v^1);
1017
+ c = c->oprnd1();
1018
+ }
1019
+ }
1020
+ }
1021
+ return out->insGuard(v, c, x);
1022
+ }
1023
+
1024
+ LIns* ExprFilter::insBranch(LOpcode v, LIns *c, LIns *t)
1025
+ {
1026
+ if (v == LIR_jt || v == LIR_jf) {
1027
+ while (c->isop(LIR_eq) && c->oprnd1()->isCmp() && c->oprnd2()->isconstval(0)) {
1028
+ // jt(eq(cmp,0)) => jf(cmp) or jf(eq(cmp,0)) => jt(cmp)
1029
+ v = LOpcode(v ^ 1);
1030
+ c = c->oprnd1();
1031
+ }
1032
+ }
1033
+ return out->insBranch(v, c, t);
1034
+ }
1035
+
1036
+ LIns* LirWriter::insLoadi(LIns *base, int disp)
1037
+ {
1038
+ return insLoad(LIR_ld,base,disp);
1039
+ }
1040
+
1041
+ LIns* LirWriter::insLoad(LOpcode op, LIns *base, int disp)
1042
+ {
1043
+ return insLoad(op, base, insImm(disp));
1044
+ }
1045
+
1046
+ LIns* LirWriter::store(LInsp value, LInsp base, int32_t d)
1047
+ {
1048
+ return isS8(d) ? insStorei(value, base, d)
1049
+ : insStore(value, base, insImm(d));
1050
+ }
1051
+
1052
+ LIns* LirWriter::ins_eq0(LIns* oprnd1)
1053
+ {
1054
+ return ins2i(LIR_eq, oprnd1, 0);
1055
+ }
1056
+
1057
+ LIns* LirWriter::insImmf(double f)
1058
+ {
1059
+ union {
1060
+ double f;
1061
+ uint64_t q;
1062
+ } u;
1063
+ u.f = f;
1064
+ return insImmq(u.q);
1065
+ }
1066
+
1067
+ LIns* LirWriter::qjoin(LInsp lo, LInsp hi)
1068
+ {
1069
+ return ins2(LIR_qjoin, lo, hi);
1070
+ }
1071
+
1072
+ LIns* LirWriter::insImmPtr(const void *ptr)
1073
+ {
1074
+ return sizeof(ptr) == 8 ? insImmq((uintptr_t)ptr) : insImm((intptr_t)ptr);
1075
+ }
1076
+
1077
+ LIns* LirWriter::ins_choose(LIns* cond, LIns* iftrue, LIns* iffalse)
1078
+ {
1079
+ // if not a conditional, make it implicitly an ==0 test (then flop results)
1080
+ if (!cond->isCmp())
1081
+ {
1082
+ cond = ins_eq0(cond);
1083
+ LInsp tmp = iftrue;
1084
+ iftrue = iffalse;
1085
+ iffalse = tmp;
1086
+ }
1087
+
1088
+ if (avmplus::AvmCore::use_cmov())
1089
+ {
1090
+ return ins2((iftrue->isQuad() || iffalse->isQuad()) ? LIR_qcmov : LIR_cmov, cond, ins2(LIR_2, iftrue, iffalse));
1091
+ }
1092
+
1093
+ // @todo -- it might be better to use a short conditional branch rather than
1094
+ // the bit-twiddling on systems that don't provide a conditional move instruction.
1095
+ LInsp ncond = ins1(LIR_neg, cond); // cond ? -1 : 0
1096
+ return ins2(LIR_or,
1097
+ ins2(LIR_and, iftrue, ncond),
1098
+ ins2(LIR_and, iffalse, ins1(LIR_not, ncond)));
1099
+ }
1100
+
1101
+ LIns* LirBufWriter::insCall(const CallInfo *ci, LInsp args[])
1102
+ {
1103
+ static const LOpcode k_callmap[] = { LIR_call, LIR_fcall, LIR_call, LIR_callh };
1104
+ static const LOpcode k_callimap[] = { LIR_calli, LIR_fcalli, LIR_calli, LIR_skip };
1105
+
1106
+ uint32_t argt = ci->_argtypes;
1107
+ LOpcode op = (ci->isIndirect() ? k_callimap : k_callmap)[argt & 3];
1108
+ NanoAssert(op != LIR_skip); // LIR_skip here is just an error condition
1109
+
1110
+ ArgSize sizes[MAXARGS];
1111
+ int32_t argc = ci->get_sizes(sizes);
1112
+
1113
+ if (AvmCore::config.soft_float) {
1114
+ if (op == LIR_fcall)
1115
+ op = LIR_callh;
1116
+ }
1117
+
1118
+ //
1119
+ // An example of the what we're trying to serialize:
1120
+ //
1121
+ // byte word
1122
+ // ---- ----
1123
+ // N [ arg tramp #0 ------------------------ ] K
1124
+ // N+4 [ arg tramp #1 ------------------------ ] K+1
1125
+ // N+8 [ arg tramp #2 ------------------------ ] K+2
1126
+ // N+12 [ arg tramp #3 ------------------------ ] K+3
1127
+ // N+16 [ argoff3 | argoff2 | argoff1 | argoff0 ] K+4
1128
+ // N+20 [ CallInfo* --------------------------- ] K+5
1129
+ // N+24 [ LIR_call ---------| imm8a=0 | imm8b=4 ] K+6
1130
+ //
1131
+ // In this example:
1132
+ // 32 bit words
1133
+ // 'argc' = 4
1134
+ // 'words' = argwords(argc) = 1 (word K+4 )
1135
+ // 'LIR_CALL_SLOTS' = 2 (words K+5 - K+6)
1136
+ // 'insSz' = 1+2 = 3 (words K+4 - K+6)
1137
+ // 'from' = next + (insSz - 1) (word K+6 )
1138
+ //
1139
+
1140
+ NanoAssert(argc <= (int)MAXARGS);
1141
+ uint32_t words = argwords(argc);
1142
+ int32_t insSz = words + LIR_CALL_SLOTS; // words need for offsets + size of instruction
1143
+ ensureRoom(argc * LIR_FAR_SLOTS + insSz); // argc=# possible tramps for args
1144
+
1145
+ // Argument deltas are calculated relative to the final LIns,
1146
+ // which is the last word in the cluster.
1147
+ LInsp from = _buf->next() + argc * LIR_FAR_SLOTS + insSz - 1;
1148
+ for (int32_t i=0; i < argc; i++)
1149
+ makeReachable(args[i], from);
1150
+
1151
+ // skip 'words' needed for call parameters
1152
+ LirCallIns *l = (LirCallIns*) (_buf->next()+words);
1153
+ l->ci = ci;
1154
+
1155
+ // call parameters laid in reverse order
1156
+ uint8_t* offs = (uint8_t*)l;
1157
+ for (int32_t i=0; i < argc; i++)
1158
+ *--offs = (uint8_t) l->i.reference(args[i]);
1159
+ NanoAssert((LInsp)offs>=_buf->next());
1160
+
1161
+ #ifndef NANOJIT_64BIT
1162
+ l->i.initOpcode(op==LIR_callh ? LIR_call : op);
1163
+ #else
1164
+ l->i.initOpcode(op);
1165
+ #endif
1166
+ l->i.c.imm8a = 0;
1167
+ l->i.c.imm8b = argc;
1168
+ _buf->commit(insSz);
1169
+ _buf->_stats.lir++;
1170
+ NanoAssert((LInsp)(l+1)==_buf->next());
1171
+ return &(l->i);
1172
+ }
1173
+
1174
+ using namespace avmplus;
1175
+
1176
+ StackFilter::StackFilter(LirFilter *in, GC *gc, LirBuffer *lirbuf, LInsp sp)
1177
+ : LirFilter(in), gc(gc), lirbuf(lirbuf), sp(sp), top(0)
1178
+ {}
1179
+
1180
+ LInsp StackFilter::read()
1181
+ {
1182
+ for (;;)
1183
+ {
1184
+ LInsp i = in->read();
1185
+ if (!i)
1186
+ return i;
1187
+ if (i->isStore())
1188
+ {
1189
+ LInsp base = i->oprnd2();
1190
+ if (base == sp)
1191
+ {
1192
+ LInsp v = i->oprnd1();
1193
+ int d = i->immdisp() >> 2;
1194
+ if (d >= top) {
1195
+ continue;
1196
+ } else {
1197
+ d = top - d;
1198
+ if (v->isQuad()) {
1199
+ // storing 8 bytes
1200
+ if (stk.get(d) && stk.get(d-1)) {
1201
+ continue;
1202
+ } else {
1203
+ stk.set(gc, d);
1204
+ stk.set(gc, d-1);
1205
+ }
1206
+ }
1207
+ else {
1208
+ // storing 4 bytes
1209
+ if (stk.get(d))
1210
+ continue;
1211
+ else
1212
+ stk.set(gc, d);
1213
+ }
1214
+ }
1215
+ }
1216
+ }
1217
+ /*
1218
+ * NB: If there is a backward branch other than the loop-restart branch, this is
1219
+ * going to be wrong. Unfortunately there doesn't seem to be an easy way to detect
1220
+ * such branches. Just do not create any.
1221
+ */
1222
+ else if (i->isGuard())
1223
+ {
1224
+ stk.reset();
1225
+ top = getTop(i) >> 2;
1226
+ }
1227
+ return i;
1228
+ }
1229
+ }
1230
+
1231
+ //
1232
+ // inlined/separated version of SuperFastHash
1233
+ // This content is copyrighted by Paul Hsieh, For reference see : http://www.azillionmonkeys.com/qed/hash.html
1234
+ //
1235
+ inline uint32_t _hash8(uint32_t hash, const uint8_t data)
1236
+ {
1237
+ hash += data;
1238
+ hash ^= hash << 10;
1239
+ hash += hash >> 1;
1240
+ return hash;
1241
+ }
1242
+
1243
+ inline uint32_t _hash32(uint32_t hash, const uint32_t data)
1244
+ {
1245
+ const uint32_t dlo = data & 0xffff;
1246
+ const uint32_t dhi = data >> 16;
1247
+ hash += dlo;
1248
+ const uint32_t tmp = (dhi << 11) ^ hash;
1249
+ hash = (hash << 16) ^ tmp;
1250
+ hash += hash >> 11;
1251
+ return hash;
1252
+ }
1253
+
1254
+ inline uint32_t _hashptr(uint32_t hash, const void* data)
1255
+ {
1256
+ #ifdef NANOJIT_64BIT
1257
+ hash = _hash32(hash, uint32_t(uintptr_t(data) >> 32));
1258
+ hash = _hash32(hash, uint32_t(uintptr_t(data)));
1259
+ return hash;
1260
+ #else
1261
+ return _hash32(hash, uint32_t(data));
1262
+ #endif
1263
+ }
1264
+
1265
+ inline uint32_t _hashfinish(uint32_t hash)
1266
+ {
1267
+ /* Force "avalanching" of final 127 bits */
1268
+ hash ^= hash << 3;
1269
+ hash += hash >> 5;
1270
+ hash ^= hash << 4;
1271
+ hash += hash >> 17;
1272
+ hash ^= hash << 25;
1273
+ hash += hash >> 6;
1274
+ return hash;
1275
+ }
1276
+
1277
+ LInsHashSet::LInsHashSet(GC* gc) :
1278
+ m_used(0), m_cap(kInitialCap), m_gc(gc)
1279
+ {
1280
+ #ifdef MEMORY_INFO
1281
+ // m_list.set_meminfo_name("LInsHashSet.list");
1282
+ #endif
1283
+ LInsp *list = (LInsp*) gc->Alloc(sizeof(LInsp)*m_cap, GC::kZero);
1284
+ WB(gc, this, &m_list, list);
1285
+ }
1286
+
1287
+ LInsHashSet::~LInsHashSet()
1288
+ {
1289
+ m_gc->Free(m_list);
1290
+ }
1291
+
1292
+ void LInsHashSet::clear() {
1293
+ memset(m_list, 0, sizeof(LInsp)*m_cap);
1294
+ m_used = 0;
1295
+ }
1296
+
1297
+ /*static*/ uint32_t FASTCALL LInsHashSet::hashcode(LInsp i)
1298
+ {
1299
+ const LOpcode op = i->opcode();
1300
+ switch (op)
1301
+ {
1302
+ case LIR_short:
1303
+ return hashimm(i->imm16());
1304
+ case LIR_int:
1305
+ return hashimm(i->imm32());
1306
+ case LIR_quad:
1307
+ return hashimmq(i->constvalq());
1308
+ case LIR_call:
1309
+ case LIR_fcall:
1310
+ #if defined NANOJIT_64BIT
1311
+ case LIR_callh:
1312
+ #endif
1313
+ {
1314
+ LInsp args[10];
1315
+ int32_t argc = i->argc();
1316
+ NanoAssert(argc < 10);
1317
+ for (int32_t j=0; j < argc; j++)
1318
+ args[j] = i->arg(j);
1319
+ return hashcall(i->callInfo(), argc, args);
1320
+ }
1321
+ default:
1322
+ if (operandCount[op] == 2)
1323
+ return hash2(op, i->oprnd1(), i->oprnd2());
1324
+ else
1325
+ return hash1(op, i->oprnd1());
1326
+ }
1327
+ }
1328
+
1329
+ /*static*/ bool FASTCALL LInsHashSet::equals(LInsp a, LInsp b)
1330
+ {
1331
+ if (a==b)
1332
+ return true;
1333
+ AvmAssert(a->opcode() == b->opcode());
1334
+ const LOpcode op = a->opcode();
1335
+ switch (op)
1336
+ {
1337
+ case LIR_short:
1338
+ {
1339
+ return a->imm16() == b->imm16();
1340
+ }
1341
+ case LIR_int:
1342
+ {
1343
+ return a->imm32() == b->imm32();
1344
+ }
1345
+ case LIR_quad:
1346
+ {
1347
+ return a->constvalq() == b->constvalq();
1348
+ }
1349
+ case LIR_call:
1350
+ case LIR_fcall:
1351
+ #if defined NANOJIT_64BIT
1352
+ case LIR_callh:
1353
+ #endif
1354
+ {
1355
+ if (a->callInfo() != b->callInfo()) return false;
1356
+ uint32_t argc=a->argc();
1357
+ NanoAssert(argc == b->argc());
1358
+ for (uint32_t i=0; i < argc; i++)
1359
+ if (a->arg(i) != b->arg(i))
1360
+ return false;
1361
+ return true;
1362
+ }
1363
+ default:
1364
+ {
1365
+ const uint32_t count = operandCount[op];
1366
+ if ((count >= 1 && a->oprnd1() != b->oprnd1()) ||
1367
+ (count >= 2 && a->oprnd2() != b->oprnd2()))
1368
+ return false;
1369
+ return true;
1370
+ }
1371
+ }
1372
+ }
1373
+
1374
+ void FASTCALL LInsHashSet::grow()
1375
+ {
1376
+ const uint32_t newcap = m_cap << 1;
1377
+ LInsp *newlist = (LInsp*) m_gc->Alloc(newcap * sizeof(LInsp), GC::kZero);
1378
+ LInsp *list = m_list;
1379
+ #ifdef MEMORY_INFO
1380
+ // newlist.set_meminfo_name("LInsHashSet.list");
1381
+ #endif
1382
+ for (uint32_t i=0, n=m_cap; i < n; i++) {
1383
+ LInsp name = list[i];
1384
+ if (!name) continue;
1385
+ uint32_t j = find(name, hashcode(name), newlist, newcap);
1386
+ newlist[j] = name;
1387
+ }
1388
+ m_cap = newcap;
1389
+ m_gc->Free(list);
1390
+ WB(m_gc, this, &m_list, newlist);
1391
+ }
1392
+
1393
+ uint32_t FASTCALL LInsHashSet::find(LInsp name, uint32_t hash, const LInsp *list, uint32_t cap)
1394
+ {
1395
+ const uint32_t bitmask = (cap - 1) & ~0x1;
1396
+
1397
+ uint32_t n = 7 << 1;
1398
+ hash &= bitmask;
1399
+ LInsp k;
1400
+ while ((k = list[hash]) != NULL &&
1401
+ (!LIns::sameop(k,name) || !equals(k, name)))
1402
+ {
1403
+ hash = (hash + (n += 2)) & bitmask; // quadratic probe
1404
+ }
1405
+ return hash;
1406
+ }
1407
+
1408
+ LInsp LInsHashSet::add(LInsp name, uint32_t k)
1409
+ {
1410
+ // this is relatively short-lived so let's try a more aggressive load factor
1411
+ // in the interest of improving performance
1412
+ if (((m_used+1)<<1) >= m_cap) // 0.50
1413
+ {
1414
+ grow();
1415
+ k = find(name, hashcode(name), m_list, m_cap);
1416
+ }
1417
+ NanoAssert(!m_list[k]);
1418
+ m_used++;
1419
+ return m_list[k] = name;
1420
+ }
1421
+
1422
+ void LInsHashSet::replace(LInsp i)
1423
+ {
1424
+ LInsp *list = m_list;
1425
+ uint32_t k = find(i, hashcode(i), list, m_cap);
1426
+ if (list[k]) {
1427
+ // already there, so replace it
1428
+ list[k] = i;
1429
+ } else {
1430
+ add(i, k);
1431
+ }
1432
+ }
1433
+
1434
+ uint32_t LInsHashSet::hashimm(int32_t a) {
1435
+ return _hashfinish(_hash32(0,a));
1436
+ }
1437
+
1438
+ uint32_t LInsHashSet::hashimmq(uint64_t a) {
1439
+ uint32_t hash = _hash32(0, uint32_t(a >> 32));
1440
+ return _hashfinish(_hash32(hash, uint32_t(a)));
1441
+ }
1442
+
1443
+ uint32_t LInsHashSet::hash1(LOpcode op, LInsp a) {
1444
+ uint32_t hash = _hash8(0,uint8_t(op));
1445
+ return _hashfinish(_hashptr(hash, a));
1446
+ }
1447
+
1448
+ uint32_t LInsHashSet::hash2(LOpcode op, LInsp a, LInsp b) {
1449
+ uint32_t hash = _hash8(0,uint8_t(op));
1450
+ hash = _hashptr(hash, a);
1451
+ return _hashfinish(_hashptr(hash, b));
1452
+ }
1453
+
1454
+ uint32_t LInsHashSet::hashcall(const CallInfo *ci, uint32_t argc, LInsp args[]) {
1455
+ uint32_t hash = _hashptr(0, ci);
1456
+ for (int32_t j=argc-1; j >= 0; j--)
1457
+ hash = _hashptr(hash,args[j]);
1458
+ return _hashfinish(hash);
1459
+ }
1460
+
1461
+ LInsp LInsHashSet::find32(int32_t a, uint32_t &i)
1462
+ {
1463
+ uint32_t cap = m_cap;
1464
+ const LInsp *list = m_list;
1465
+ const uint32_t bitmask = (cap - 1) & ~0x1;
1466
+ uint32_t hash = hashimm(a) & bitmask;
1467
+ uint32_t n = 7 << 1;
1468
+ LInsp k;
1469
+ while ((k = list[hash]) != NULL &&
1470
+ (!k->isconst() || k->constval() != a))
1471
+ {
1472
+ hash = (hash + (n += 2)) & bitmask; // quadratic probe
1473
+ }
1474
+ i = hash;
1475
+ return k;
1476
+ }
1477
+
1478
+ LInsp LInsHashSet::find64(uint64_t a, uint32_t &i)
1479
+ {
1480
+ uint32_t cap = m_cap;
1481
+ const LInsp *list = m_list;
1482
+ const uint32_t bitmask = (cap - 1) & ~0x1;
1483
+ uint32_t hash = hashimmq(a) & bitmask;
1484
+ uint32_t n = 7 << 1;
1485
+ LInsp k;
1486
+ while ((k = list[hash]) != NULL &&
1487
+ (!k->isconstq() || k->constvalq() != a))
1488
+ {
1489
+ hash = (hash + (n += 2)) & bitmask; // quadratic probe
1490
+ }
1491
+ i = hash;
1492
+ return k;
1493
+ }
1494
+
1495
+ LInsp LInsHashSet::find1(LOpcode op, LInsp a, uint32_t &i)
1496
+ {
1497
+ uint32_t cap = m_cap;
1498
+ const LInsp *list = m_list;
1499
+ const uint32_t bitmask = (cap - 1) & ~0x1;
1500
+ uint32_t hash = hash1(op,a) & bitmask;
1501
+ uint32_t n = 7 << 1;
1502
+ LInsp k;
1503
+ while ((k = list[hash]) != NULL &&
1504
+ (k->opcode() != op || k->oprnd1() != a))
1505
+ {
1506
+ hash = (hash + (n += 2)) & bitmask; // quadratic probe
1507
+ }
1508
+ i = hash;
1509
+ return k;
1510
+ }
1511
+
1512
+ LInsp LInsHashSet::find2(LOpcode op, LInsp a, LInsp b, uint32_t &i)
1513
+ {
1514
+ uint32_t cap = m_cap;
1515
+ const LInsp *list = m_list;
1516
+ const uint32_t bitmask = (cap - 1) & ~0x1;
1517
+ uint32_t hash = hash2(op,a,b) & bitmask;
1518
+ uint32_t n = 7 << 1;
1519
+ LInsp k;
1520
+ while ((k = list[hash]) != NULL &&
1521
+ (k->opcode() != op || k->oprnd1() != a || k->oprnd2() != b))
1522
+ {
1523
+ hash = (hash + (n += 2)) & bitmask; // quadratic probe
1524
+ }
1525
+ i = hash;
1526
+ return k;
1527
+ }
1528
+
1529
+ bool argsmatch(LInsp i, uint32_t argc, LInsp args[])
1530
+ {
1531
+ for (uint32_t j=0; j < argc; j++)
1532
+ if (i->arg(j) != args[j])
1533
+ return false;
1534
+ return true;
1535
+ }
1536
+
1537
+ LInsp LInsHashSet::findcall(const CallInfo *ci, uint32_t argc, LInsp args[], uint32_t &i)
1538
+ {
1539
+ uint32_t cap = m_cap;
1540
+ const LInsp *list = m_list;
1541
+ const uint32_t bitmask = (cap - 1) & ~0x1;
1542
+ uint32_t hash = hashcall(ci, argc, args) & bitmask;
1543
+ uint32_t n = 7 << 1;
1544
+ LInsp k;
1545
+ while ((k = list[hash]) != NULL &&
1546
+ (!k->isCall() || k->callInfo() != ci || !argsmatch(k, argc, args)))
1547
+ {
1548
+ hash = (hash + (n += 2)) & bitmask; // quadratic probe
1549
+ }
1550
+ i = hash;
1551
+ return k;
1552
+ }
1553
+
1554
+ GuardRecord *LIns::record()
1555
+ {
1556
+ NanoAssert(isGuard());
1557
+ return (GuardRecord*)oprnd2()->payload();
1558
+ }
1559
+
1560
+ #ifdef NJ_VERBOSE
1561
+ class RetiredEntry: public GCObject
1562
+ {
1563
+ public:
1564
+ List<LInsp, LIST_NonGCObjects> live;
1565
+ LInsp i;
1566
+ RetiredEntry(GC *gc): live(gc) {}
1567
+ };
1568
+ class LiveTable
1569
+ {
1570
+ public:
1571
+ SortedMap<LInsp,LInsp,LIST_NonGCObjects> live;
1572
+ List<RetiredEntry*, LIST_GCObjects> retired;
1573
+ int maxlive;
1574
+ LiveTable(GC *gc) : live(gc), retired(gc), maxlive(0) {}
1575
+ ~LiveTable()
1576
+ {
1577
+ for (size_t i = 0; i < retired.size(); i++) {
1578
+ NJ_DELETE(retired.get(i));
1579
+ }
1580
+
1581
+ }
1582
+ void add(LInsp i, LInsp use) {
1583
+ if (!i->isconst() && !i->isconstq() && !live.containsKey(i)) {
1584
+ NanoAssert(size_t(i->opcode()) < sizeof(lirNames) / sizeof(lirNames[0]));
1585
+ live.put(i,use);
1586
+ }
1587
+ }
1588
+ void retire(LInsp i, GC *gc) {
1589
+ RetiredEntry *e = NJ_NEW(gc, RetiredEntry)(gc);
1590
+ e->i = i;
1591
+ for (int j=0, n=live.size(); j < n; j++) {
1592
+ LInsp l = live.keyAt(j);
1593
+ if (!l->isStore() && !l->isGuard())
1594
+ e->live.add(l);
1595
+ }
1596
+ int size=0;
1597
+ if ((size = e->live.size()) > maxlive)
1598
+ maxlive = size;
1599
+
1600
+ live.remove(i);
1601
+ retired.add(e);
1602
+ }
1603
+ bool contains(LInsp i) {
1604
+ return live.containsKey(i);
1605
+ }
1606
+ };
1607
+
1608
+ void live(GC *gc, LirBuffer *lirbuf)
1609
+ {
1610
+ // traverse backwards to find live exprs and a few other stats.
1611
+
1612
+ LiveTable live(gc);
1613
+ uint32_t exits = 0;
1614
+ LirReader br(lirbuf);
1615
+ StackFilter sf(&br, gc, lirbuf, lirbuf->sp);
1616
+ StackFilter r(&sf, gc, lirbuf, lirbuf->rp);
1617
+ int total = 0;
1618
+ if (lirbuf->state)
1619
+ live.add(lirbuf->state, r.pos());
1620
+ for (LInsp i = r.read(); i != 0; i = r.read())
1621
+ {
1622
+ total++;
1623
+
1624
+ // first handle side-effect instructions
1625
+ if (!i->isCse(lirbuf->_functions))
1626
+ {
1627
+ live.add(i,0);
1628
+ if (i->isGuard())
1629
+ exits++;
1630
+ }
1631
+
1632
+ // now propagate liveness
1633
+ if (live.contains(i))
1634
+ {
1635
+ live.retire(i,gc);
1636
+ NanoAssert(size_t(i->opcode()) < sizeof(operandCount) / sizeof(operandCount[0]));
1637
+ if (i->isStore()) {
1638
+ live.add(i->oprnd2(),i); // base
1639
+ live.add(i->oprnd1(),i); // val
1640
+ }
1641
+ else if (i->isop(LIR_cmov) || i->isop(LIR_qcmov)) {
1642
+ live.add(i->oprnd1(),i);
1643
+ live.add(i->oprnd2()->oprnd1(),i);
1644
+ live.add(i->oprnd2()->oprnd2(),i);
1645
+ }
1646
+ else if (operandCount[i->opcode()] == 1) {
1647
+ live.add(i->oprnd1(),i);
1648
+ }
1649
+ else if (operandCount[i->opcode()] == 2) {
1650
+ live.add(i->oprnd1(),i);
1651
+ live.add(i->oprnd2(),i);
1652
+ }
1653
+ else if (i->isCall()) {
1654
+ for (int j=0, c=i->argc(); j < c; j++)
1655
+ live.add(i->arg(j),i);
1656
+ }
1657
+ }
1658
+ }
1659
+
1660
+ printf("live instruction count %d, total %u, max pressure %d\n",
1661
+ live.retired.size(), total, live.maxlive);
1662
+ printf("side exits %u\n", exits);
1663
+
1664
+ // print live exprs, going forwards
1665
+ LirNameMap *names = lirbuf->names;
1666
+ bool newblock = true;
1667
+ for (int j=live.retired.size()-1; j >= 0; j--)
1668
+ {
1669
+ RetiredEntry *e = live.retired[j];
1670
+ char livebuf[4000], *s=livebuf;
1671
+ *s = 0;
1672
+ if (!newblock && e->i->isop(LIR_label)) {
1673
+ printf("\n");
1674
+ }
1675
+ newblock = false;
1676
+ for (int k=0,n=e->live.size(); k < n; k++) {
1677
+ strcpy(s, names->formatRef(e->live[k]));
1678
+ s += strlen(s);
1679
+ *s++ = ' '; *s = 0;
1680
+ NanoAssert(s < livebuf+sizeof(livebuf));
1681
+ }
1682
+ printf("%-60s %s\n", livebuf, names->formatIns(e->i));
1683
+ if (e->i->isGuard() || e->i->isBranch() || isRet(e->i->opcode())) {
1684
+ printf("\n");
1685
+ newblock = true;
1686
+ }
1687
+ }
1688
+ }
1689
+
1690
+ LabelMap::Entry::~Entry()
1691
+ {
1692
+ }
1693
+
1694
+ LirNameMap::Entry::~Entry()
1695
+ {
1696
+ }
1697
+
1698
+ LirNameMap::~LirNameMap()
1699
+ {
1700
+ Entry *e;
1701
+
1702
+ while ((e = names.removeLast()) != NULL) {
1703
+ labels->core->freeString(e->name);
1704
+ NJ_DELETE(e);
1705
+ }
1706
+ }
1707
+
1708
+ bool LirNameMap::addName(LInsp i, Stringp name) {
1709
+ if (!names.containsKey(i)) {
1710
+ Entry *e = NJ_NEW(labels->core->gc, Entry)(name);
1711
+ names.put(i, e);
1712
+ return true;
1713
+ }
1714
+ return false;
1715
+ }
1716
+ void LirNameMap::addName(LInsp i, const char *name) {
1717
+ Stringp new_name = labels->core->newString(name);
1718
+ if (!addName(i, new_name)) {
1719
+ labels->core->freeString(new_name);
1720
+ }
1721
+ }
1722
+
1723
+ void LirNameMap::copyName(LInsp i, const char *s, int suffix) {
1724
+ char s2[200];
1725
+ if (isdigit(s[strlen(s)-1])) {
1726
+ // if s ends with a digit, add '_' to clarify the suffix
1727
+ sprintf(s2,"%s_%d", s, suffix);
1728
+ } else {
1729
+ sprintf(s2,"%s%d", s, suffix);
1730
+ }
1731
+ addName(i, labels->core->newString(s2));
1732
+ }
1733
+
1734
+ void LirNameMap::formatImm(int32_t c, char *buf) {
1735
+ if (c >= 10000 || c <= -10000)
1736
+ sprintf(buf,"#%s",labels->format((void*)c));
1737
+ else
1738
+ sprintf(buf,"%d", c);
1739
+ }
1740
+
1741
+ const char* LirNameMap::formatRef(LIns *ref)
1742
+ {
1743
+ char buffer[200], *buf=buffer;
1744
+ buf[0]=0;
1745
+ GC *gc = labels->core->gc;
1746
+ if (names.containsKey(ref)) {
1747
+ StringNullTerminatedUTF8 cname(gc, names.get(ref)->name);
1748
+ strcat(buf, cname.c_str());
1749
+ }
1750
+ else if (ref->isconstq()) {
1751
+ #if defined NANOJIT_64BIT
1752
+ sprintf(buf, "#0x%lx", (nj_printf_ld)ref->constvalq());
1753
+ #else
1754
+ formatImm(uint32_t(ref->constvalq()>>32), buf);
1755
+ buf += strlen(buf);
1756
+ *buf++ = ':';
1757
+ formatImm(uint32_t(ref->constvalq()), buf);
1758
+ #endif
1759
+ }
1760
+ else if (ref->isconst()) {
1761
+ formatImm(ref->constval(), buf);
1762
+ }
1763
+ else {
1764
+ if (ref->isCall()) {
1765
+ #if !defined NANOJIT_64BIT
1766
+ if (ref->isop(LIR_callh)) {
1767
+ // we've presumably seen the other half already
1768
+ ref = ref->oprnd1();
1769
+ } else {
1770
+ #endif
1771
+ copyName(ref, ref->callInfo()->_name, funccounts.add(ref->callInfo()));
1772
+ #if !defined NANOJIT_64BIT
1773
+ }
1774
+ #endif
1775
+ } else {
1776
+ NanoAssert(size_t(ref->opcode()) < sizeof(lirNames) / sizeof(lirNames[0]));
1777
+ copyName(ref, lirNames[ref->opcode()], lircounts.add(ref->opcode()));
1778
+ }
1779
+ StringNullTerminatedUTF8 cname(gc, names.get(ref)->name);
1780
+ strcat(buf, cname.c_str());
1781
+ }
1782
+ return labels->dup(buffer);
1783
+ }
1784
+
1785
+ const char* LirNameMap::formatIns(LIns* i)
1786
+ {
1787
+ char sbuf[200];
1788
+ char *s = sbuf;
1789
+ LOpcode op = i->opcode();
1790
+ switch(op)
1791
+ {
1792
+ case LIR_short:
1793
+ case LIR_int:
1794
+ {
1795
+ sprintf(s, "%s", formatRef(i));
1796
+ break;
1797
+ }
1798
+
1799
+ case LIR_alloc: {
1800
+ sprintf(s, "%s = %s %d", formatRef(i), lirNames[op], i->size());
1801
+ break;
1802
+ }
1803
+
1804
+ case LIR_quad:
1805
+ {
1806
+ int32_t *p = (int32_t*) (i-2);
1807
+ sprintf(s, "#%X:%X /* %g */", p[1], p[0], i->constvalf());
1808
+ break;
1809
+ }
1810
+
1811
+ case LIR_loop:
1812
+ case LIR_start:
1813
+ sprintf(s, "%s", lirNames[op]);
1814
+ break;
1815
+
1816
+ #if defined NANOJIT_64BIT
1817
+ case LIR_callh:
1818
+ #endif
1819
+ case LIR_fcall:
1820
+ case LIR_call: {
1821
+ sprintf(s, "%s = %s ( ", formatRef(i), i->callInfo()->_name);
1822
+ for (int32_t j=i->argc()-1; j >= 0; j--) {
1823
+ s += strlen(s);
1824
+ sprintf(s, "%s ",formatRef(i->arg(j)));
1825
+ }
1826
+ s += strlen(s);
1827
+ sprintf(s, ")");
1828
+ break;
1829
+ }
1830
+ case LIR_fcalli:
1831
+ case LIR_calli: {
1832
+ int32_t argc = i->argc();
1833
+ sprintf(s, "%s = [%s] ( ", formatRef(i), formatRef(i->arg(argc-1)));
1834
+ s += strlen(s);
1835
+ argc--;
1836
+ for (int32_t j=argc-1; j >= 0; j--) {
1837
+ s += strlen(s);
1838
+ sprintf(s, "%s ",formatRef(i->arg(j)));
1839
+ }
1840
+ s += strlen(s);
1841
+ sprintf(s, ")");
1842
+ break;
1843
+ }
1844
+
1845
+ case LIR_param: {
1846
+ uint32_t arg = i->imm8();
1847
+ if (!i->imm8b()) {
1848
+ if (arg < sizeof(Assembler::argRegs)/sizeof(Assembler::argRegs[0])) {
1849
+ sprintf(s, "%s = %s %d %s", formatRef(i), lirNames[op],
1850
+ arg, gpn(Assembler::argRegs[arg]));
1851
+ } else {
1852
+ sprintf(s, "%s = %s %d", formatRef(i), lirNames[op], arg);
1853
+ }
1854
+ } else {
1855
+ sprintf(s, "%s = %s %d %s", formatRef(i), lirNames[op],
1856
+ arg, gpn(Assembler::savedRegs[arg]));
1857
+ }
1858
+ break;
1859
+ }
1860
+
1861
+ case LIR_label:
1862
+ sprintf(s, "%s:", formatRef(i));
1863
+ break;
1864
+
1865
+ case LIR_jt:
1866
+ case LIR_jf:
1867
+ sprintf(s, "%s %s -> %s", lirNames[op], formatRef(i->oprnd1()),
1868
+ i->oprnd2() ? formatRef(i->oprnd2()) : "unpatched");
1869
+ break;
1870
+
1871
+ case LIR_j:
1872
+ sprintf(s, "%s -> %s", lirNames[op],
1873
+ i->oprnd2() ? formatRef(i->oprnd2()) : "unpatched");
1874
+ break;
1875
+
1876
+ case LIR_live:
1877
+ case LIR_ret:
1878
+ case LIR_fret:
1879
+ sprintf(s, "%s %s", lirNames[op], formatRef(i->oprnd1()));
1880
+ break;
1881
+
1882
+ case LIR_callh:
1883
+ case LIR_neg:
1884
+ case LIR_fneg:
1885
+ case LIR_i2f:
1886
+ case LIR_u2f:
1887
+ case LIR_qlo:
1888
+ case LIR_qhi:
1889
+ case LIR_ov:
1890
+ case LIR_cs:
1891
+ case LIR_not:
1892
+ sprintf(s, "%s = %s %s", formatRef(i), lirNames[op], formatRef(i->oprnd1()));
1893
+ break;
1894
+
1895
+ case LIR_x:
1896
+ case LIR_xt:
1897
+ case LIR_xf:
1898
+ case LIR_xbarrier:
1899
+ case LIR_xtbl:
1900
+ formatGuard(i, s);
1901
+ break;
1902
+
1903
+ case LIR_add:
1904
+ case LIR_addp:
1905
+ case LIR_sub:
1906
+ case LIR_mul:
1907
+ case LIR_fadd:
1908
+ case LIR_fsub:
1909
+ case LIR_fmul:
1910
+ case LIR_fdiv:
1911
+ case LIR_and:
1912
+ case LIR_or:
1913
+ case LIR_xor:
1914
+ case LIR_lsh:
1915
+ case LIR_rsh:
1916
+ case LIR_ush:
1917
+ case LIR_eq:
1918
+ case LIR_lt:
1919
+ case LIR_le:
1920
+ case LIR_gt:
1921
+ case LIR_ge:
1922
+ case LIR_ult:
1923
+ case LIR_ule:
1924
+ case LIR_ugt:
1925
+ case LIR_uge:
1926
+ case LIR_feq:
1927
+ case LIR_flt:
1928
+ case LIR_fle:
1929
+ case LIR_fgt:
1930
+ case LIR_fge:
1931
+ case LIR_qiadd:
1932
+ case LIR_qiand:
1933
+ case LIR_qilsh:
1934
+ case LIR_qior:
1935
+ sprintf(s, "%s = %s %s, %s", formatRef(i), lirNames[op],
1936
+ formatRef(i->oprnd1()),
1937
+ formatRef(i->oprnd2()));
1938
+ break;
1939
+
1940
+ case LIR_qjoin:
1941
+ sprintf(s, "%s (%s), %s", lirNames[op],
1942
+ formatIns(i->oprnd1()),
1943
+ formatRef(i->oprnd2()));
1944
+ break;
1945
+
1946
+ case LIR_qcmov:
1947
+ case LIR_cmov:
1948
+ sprintf(s, "%s = %s %s ? %s : %s", formatRef(i), lirNames[op],
1949
+ formatRef(i->oprnd1()),
1950
+ formatRef(i->oprnd2()->oprnd1()),
1951
+ formatRef(i->oprnd2()->oprnd2()));
1952
+ break;
1953
+
1954
+ case LIR_ld:
1955
+ case LIR_ldc:
1956
+ case LIR_ldq:
1957
+ case LIR_ldqc:
1958
+ case LIR_ldcb:
1959
+ case LIR_ldcs:
1960
+ sprintf(s, "%s = %s %s[%s]", formatRef(i), lirNames[op],
1961
+ formatRef(i->oprnd1()),
1962
+ formatRef(i->oprnd2()));
1963
+ break;
1964
+
1965
+ case LIR_st:
1966
+ case LIR_sti:
1967
+ case LIR_stq:
1968
+ case LIR_stqi:
1969
+ sprintf(s, "%s %s[%d] = %s", lirNames[op],
1970
+ formatRef(i->oprnd2()),
1971
+ i->immdisp(),
1972
+ formatRef(i->oprnd1()));
1973
+ break;
1974
+
1975
+ default:
1976
+ sprintf(s, "?");
1977
+ break;
1978
+ }
1979
+ return labels->dup(sbuf);
1980
+ }
1981
+
1982
+
1983
+ #endif
1984
+ CseFilter::CseFilter(LirWriter *out, GC *gc)
1985
+ : LirWriter(out), exprs(gc) {}
1986
+
1987
+ LIns* CseFilter::insImm(int32_t imm)
1988
+ {
1989
+ uint32_t k;
1990
+ LInsp found = exprs.find32(imm, k);
1991
+ if (found)
1992
+ return found;
1993
+ return exprs.add(out->insImm(imm), k);
1994
+ }
1995
+
1996
+ LIns* CseFilter::insImmq(uint64_t q)
1997
+ {
1998
+ uint32_t k;
1999
+ LInsp found = exprs.find64(q, k);
2000
+ if (found)
2001
+ return found;
2002
+ return exprs.add(out->insImmq(q), k);
2003
+ }
2004
+
2005
+ LIns* CseFilter::ins0(LOpcode v)
2006
+ {
2007
+ if (v == LIR_label)
2008
+ exprs.clear();
2009
+ return out->ins0(v);
2010
+ }
2011
+
2012
+ LIns* CseFilter::ins1(LOpcode v, LInsp a)
2013
+ {
2014
+ if (isCse(v)) {
2015
+ NanoAssert(operandCount[v]==1);
2016
+ uint32_t k;
2017
+ LInsp found = exprs.find1(v, a, k);
2018
+ if (found)
2019
+ return found;
2020
+ return exprs.add(out->ins1(v,a), k);
2021
+ }
2022
+ return out->ins1(v,a);
2023
+ }
2024
+
2025
+ LIns* CseFilter::ins2(LOpcode v, LInsp a, LInsp b)
2026
+ {
2027
+ if (isCse(v)) {
2028
+ NanoAssert(operandCount[v]==2);
2029
+ uint32_t k;
2030
+ LInsp found = exprs.find2(v, a, b, k);
2031
+ if (found)
2032
+ return found;
2033
+ return exprs.add(out->ins2(v,a,b), k);
2034
+ }
2035
+ return out->ins2(v,a,b);
2036
+ }
2037
+
2038
+ LIns* CseFilter::insLoad(LOpcode v, LInsp base, LInsp disp)
2039
+ {
2040
+ if (isCse(v)) {
2041
+ NanoAssert(operandCount[v]==2);
2042
+ uint32_t k;
2043
+ LInsp found = exprs.find2(v, base, disp, k);
2044
+ if (found)
2045
+ return found;
2046
+ return exprs.add(out->insLoad(v,base,disp), k);
2047
+ }
2048
+ return out->insLoad(v,base,disp);
2049
+ }
2050
+
2051
+ LInsp CseFilter::insGuard(LOpcode v, LInsp c, LInsp x)
2052
+ {
2053
+ if (isCse(v)) {
2054
+ // conditional guard
2055
+ NanoAssert(operandCount[v]==1);
2056
+ uint32_t k;
2057
+ LInsp found = exprs.find1(v, c, k);
2058
+ if (found)
2059
+ return 0;
2060
+ return exprs.add(out->insGuard(v,c,x), k);
2061
+ }
2062
+ return out->insGuard(v, c, x);
2063
+ }
2064
+
2065
+ LInsp CseFilter::insCall(const CallInfo *ci, LInsp args[])
2066
+ {
2067
+ if (ci->_cse) {
2068
+ uint32_t k;
2069
+ uint32_t argc = ci->count_args();
2070
+ LInsp found = exprs.findcall(ci, argc, args, k);
2071
+ if (found)
2072
+ return found;
2073
+ return exprs.add(out->insCall(ci, args), k);
2074
+ }
2075
+ return out->insCall(ci, args);
2076
+ }
2077
+
2078
+ CseReader::CseReader(LirFilter *in, LInsHashSet *exprs, const CallInfo *functions)
2079
+ : LirFilter(in), exprs(exprs), functions(functions)
2080
+ {}
2081
+
2082
+ LInsp CseReader::read()
2083
+ {
2084
+ LInsp i = in->read();
2085
+ if (i) {
2086
+ if (i->isCse(functions))
2087
+ exprs->replace(i);
2088
+ }
2089
+ return i;
2090
+ }
2091
+
2092
+ LIns* FASTCALL callArgN(LIns* i, uint32_t n)
2093
+ {
2094
+ return i->arg(i->argc()-n-1);
2095
+ }
2096
+
2097
+ void compile(Assembler* assm, Fragment* triggerFrag)
2098
+ {
2099
+ Fragmento *frago = triggerFrag->lirbuf->_frago;
2100
+ AvmCore *core = frago->core();
2101
+ GC *gc = core->gc;
2102
+
2103
+ verbose_only( StringList asmOutput(gc); )
2104
+ verbose_only( assm->_outputCache = &asmOutput; )
2105
+
2106
+ verbose_only(if (assm->_verbose && core->config.verbose_live)
2107
+ live(gc, triggerFrag->lirbuf);)
2108
+
2109
+ bool treeCompile = core->config.tree_opt && (triggerFrag->kind == BranchTrace);
2110
+ RegAllocMap regMap(gc);
2111
+ NInsList loopJumps(gc);
2112
+ #ifdef MEMORY_INFO
2113
+ // loopJumps.set_meminfo_name("LIR loopjumps");
2114
+ #endif
2115
+ assm->beginAssembly(triggerFrag, &regMap);
2116
+ if (assm->error())
2117
+ return;
2118
+
2119
+ //fprintf(stderr, "recompile trigger %X kind %d\n", (int)triggerFrag, triggerFrag->kind);
2120
+ Fragment* root = triggerFrag;
2121
+ if (treeCompile)
2122
+ {
2123
+ // recompile the entire tree
2124
+ root = triggerFrag->root;
2125
+ root->fragEntry = 0;
2126
+ root->loopEntry = 0;
2127
+ root->releaseCode(frago);
2128
+
2129
+ // do the tree branches
2130
+ Fragment* frag = root->treeBranches;
2131
+ while(frag)
2132
+ {
2133
+ // compile til no more frags
2134
+ if (frag->lastIns)
2135
+ {
2136
+ assm->assemble(frag, loopJumps);
2137
+ verbose_only(if (assm->_verbose)
2138
+ assm->outputf("compiling branch %s ip %s",
2139
+ frago->labels->format(frag),
2140
+ frago->labels->format(frag->ip)); )
2141
+
2142
+ NanoAssert(frag->kind == BranchTrace);
2143
+ RegAlloc* regs = NJ_NEW(gc, RegAlloc)();
2144
+ assm->copyRegisters(regs);
2145
+ assm->releaseRegisters();
2146
+ SideExit* exit = frag->spawnedFrom;
2147
+ regMap.put(exit, regs);
2148
+ }
2149
+ frag = frag->treeBranches;
2150
+ }
2151
+ }
2152
+
2153
+ // now the the main trunk
2154
+ assm->assemble(root, loopJumps);
2155
+ verbose_only(if (assm->_verbose)
2156
+ assm->outputf("compiling trunk %s",
2157
+ frago->labels->format(root));)
2158
+ NanoAssert(!frago->core()->config.tree_opt || root == root->anchor || root->kind == MergeTrace);
2159
+ assm->endAssembly(root, loopJumps);
2160
+
2161
+ // reverse output so that assembly is displayed low-to-high
2162
+ verbose_only( assm->_outputCache = 0; )
2163
+ verbose_only(for(int i=asmOutput.size()-1; i>=0; --i) { assm->outputf("%s",asmOutput.get(i)); } );
2164
+
2165
+ if (assm->error()) {
2166
+ root->fragEntry = 0;
2167
+ root->loopEntry = 0;
2168
+ }
2169
+ }
2170
+
2171
+ LInsp LoadFilter::insLoad(LOpcode v, LInsp base, LInsp disp)
2172
+ {
2173
+ if (base != sp && base != rp && (v == LIR_ld || v == LIR_ldq)) {
2174
+ uint32_t k;
2175
+ LInsp found = exprs.find2(v, base, disp, k);
2176
+ if (found)
2177
+ return found;
2178
+ return exprs.add(out->insLoad(v,base,disp), k);
2179
+ }
2180
+ return out->insLoad(v, base, disp);
2181
+ }
2182
+
2183
+ void LoadFilter::clear(LInsp p)
2184
+ {
2185
+ if (p != sp && p != rp)
2186
+ exprs.clear();
2187
+ }
2188
+
2189
+ LInsp LoadFilter::insStore(LInsp v, LInsp b, LInsp d)
2190
+ {
2191
+ clear(b);
2192
+ return out->insStore(v, b, d);
2193
+ }
2194
+
2195
+ LInsp LoadFilter::insStorei(LInsp v, LInsp b, int32_t d)
2196
+ {
2197
+ clear(b);
2198
+ return out->insStorei(v, b, d);
2199
+ }
2200
+
2201
+ LInsp LoadFilter::insCall(const CallInfo *ci, LInsp args[])
2202
+ {
2203
+ if (!ci->_cse)
2204
+ exprs.clear();
2205
+ return out->insCall(ci, args);
2206
+ }
2207
+
2208
+ LInsp LoadFilter::ins0(LOpcode op)
2209
+ {
2210
+ if (op == LIR_label)
2211
+ exprs.clear();
2212
+ return out->ins0(op);
2213
+ }
2214
+
2215
+ #endif /* FEATURE_NANOJIT */
2216
+
2217
+ #if defined(NJ_VERBOSE)
2218
+ LabelMap::LabelMap(AvmCore *core, LabelMap* parent)
2219
+ : parent(parent), names(core->gc), addrs(core->config.verbose_addrs), end(buf), core(core)
2220
+ {}
2221
+
2222
+ LabelMap::~LabelMap()
2223
+ {
2224
+ clear();
2225
+ }
2226
+
2227
+ void LabelMap::clear()
2228
+ {
2229
+ Entry *e;
2230
+ while ((e = names.removeLast()) != NULL) {
2231
+ core->freeString(e->name);
2232
+ NJ_DELETE(e);
2233
+ }
2234
+ }
2235
+
2236
+ void LabelMap::add(const void *p, size_t size, size_t align, const char *name)
2237
+ {
2238
+ if (!this || names.containsKey(p))
2239
+ return;
2240
+ add(p, size, align, core->newString(name));
2241
+ }
2242
+
2243
+ void LabelMap::add(const void *p, size_t size, size_t align, Stringp name)
2244
+ {
2245
+ if (!this || names.containsKey(p))
2246
+ return;
2247
+ Entry *e = NJ_NEW(core->gc, Entry)(name, size<<align, align);
2248
+ names.put(p, e);
2249
+ }
2250
+
2251
+ const char *LabelMap::format(const void *p)
2252
+ {
2253
+ char b[200];
2254
+ int i = names.findNear(p);
2255
+ if (i >= 0) {
2256
+ const void *start = names.keyAt(i);
2257
+ Entry *e = names.at(i);
2258
+ const void *end = (const char*)start + e->size;
2259
+ avmplus::StringNullTerminatedUTF8 cname(core->gc, e->name);
2260
+ const char *name = cname.c_str();
2261
+ if (p == start) {
2262
+ if (addrs)
2263
+ sprintf(b,"%p %s",p,name);
2264
+ else
2265
+ strcpy(b, name);
2266
+ return dup(b);
2267
+ }
2268
+ else if (p > start && p < end) {
2269
+ int32_t d = int32_t(intptr_t(p)-intptr_t(start)) >> e->align;
2270
+ if (addrs)
2271
+ sprintf(b, "%p %s+%d", p, name, d);
2272
+ else
2273
+ sprintf(b,"%s+%d", name, d);
2274
+ return dup(b);
2275
+ }
2276
+ else {
2277
+ if (parent)
2278
+ return parent->format(p);
2279
+
2280
+ sprintf(b, "%p", p);
2281
+ return dup(b);
2282
+ }
2283
+ }
2284
+ if (parent)
2285
+ return parent->format(p);
2286
+
2287
+ sprintf(b, "%p", p);
2288
+ return dup(b);
2289
+ }
2290
+
2291
+ const char *LabelMap::dup(const char *b)
2292
+ {
2293
+ size_t need = strlen(b)+1;
2294
+ char *s = end;
2295
+ end += need;
2296
+ if (end > buf+sizeof(buf)) {
2297
+ s = buf;
2298
+ end = s+need;
2299
+ }
2300
+ strcpy(s, b);
2301
+ return s;
2302
+ }
2303
+
2304
+ // copy all labels to parent, adding newbase to label addresses
2305
+ void LabelMap::promoteAll(const void *newbase)
2306
+ {
2307
+ for (int i=0, n=names.size(); i < n; i++) {
2308
+ void *base = (char*)newbase + (intptr_t)names.keyAt(i);
2309
+ parent->names.put(base, names.at(i));
2310
+ }
2311
+ }
2312
+ #endif // NJ_VERBOSE
2313
+ }
2314
+