johnson 1.2.0 → 2.0.0.pre0

Sign up to get free protection for your applications and to get access to all the features.
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
+