johnson 1.2.0 → 2.0.0.pre0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.rdoc +8 -0
- data/Manifest.txt +762 -48
- data/README.rdoc +2 -1
- data/Rakefile +90 -18
- data/ext/spidermonkey/conversions.c +9 -2
- data/ext/spidermonkey/ruby_land_proxy.c +1 -1
- data/ext/spidermonkey/runtime.h +1 -1
- data/ext/tracemonkey/context.cc +125 -0
- data/ext/tracemonkey/context.h +19 -0
- data/ext/tracemonkey/conversions.cc +365 -0
- data/ext/tracemonkey/conversions.h +32 -0
- data/ext/tracemonkey/debugger.cc +234 -0
- data/ext/tracemonkey/debugger.h +10 -0
- data/ext/tracemonkey/extconf.rb +37 -0
- data/ext/tracemonkey/extensions.cc +37 -0
- data/ext/tracemonkey/extensions.h +12 -0
- data/ext/tracemonkey/global.cc +40 -0
- data/ext/tracemonkey/global.h +11 -0
- data/ext/tracemonkey/idhash.cc +16 -0
- data/ext/tracemonkey/idhash.h +8 -0
- data/ext/tracemonkey/immutable_node.cc +1199 -0
- data/ext/tracemonkey/immutable_node.cc.erb +559 -0
- data/ext/tracemonkey/immutable_node.h +22 -0
- data/ext/tracemonkey/jroot.h +215 -0
- data/ext/tracemonkey/js_land_proxy.cc +620 -0
- data/ext/tracemonkey/js_land_proxy.h +20 -0
- data/ext/tracemonkey/ruby_land_proxy.cc +618 -0
- data/ext/tracemonkey/ruby_land_proxy.h +38 -0
- data/ext/tracemonkey/runtime.cc +454 -0
- data/ext/tracemonkey/runtime.h +27 -0
- data/ext/tracemonkey/split_global.cc +392 -0
- data/ext/tracemonkey/split_global.h +11 -0
- data/ext/tracemonkey/tracemonkey.cc +23 -0
- data/ext/tracemonkey/tracemonkey.h +32 -0
- data/lib/johnson.rb +12 -4
- data/lib/johnson/error.rb +5 -0
- data/lib/johnson/js/prelude.js +16 -1
- data/lib/johnson/parser.rb +2 -1
- data/lib/johnson/runtime.rb +87 -26
- data/lib/johnson/spidermonkey/runtime.rb +7 -16
- data/lib/johnson/tracemonkey.rb +13 -0
- data/lib/johnson/tracemonkey/context.rb +10 -0
- data/lib/johnson/tracemonkey/debugger.rb +67 -0
- data/lib/johnson/tracemonkey/immutable_node.rb +282 -0
- data/lib/johnson/tracemonkey/js_land_proxy.rb +64 -0
- data/lib/johnson/tracemonkey/mutable_tree_visitor.rb +242 -0
- data/lib/johnson/tracemonkey/ruby_land_proxy.rb +17 -0
- data/lib/johnson/tracemonkey/runtime.rb +80 -0
- data/test/{johnson_test.rb → generic/johnson_test.rb} +1 -1
- data/test/{parser_test.rb → generic/parser_test.rb} +1 -1
- data/test/helper.rb +23 -4
- data/test/johnson/{browser_test.rb → generic/browser_test.rb} +1 -1
- data/test/johnson/{conversions → generic/conversions}/array_test.rb +1 -1
- data/test/johnson/{conversions → generic/conversions}/boolean_test.rb +1 -1
- data/test/johnson/{conversions → generic/conversions}/callable_test.rb +1 -1
- data/test/johnson/{conversions → generic/conversions}/file_test.rb +1 -1
- data/test/johnson/generic/conversions/helper.rb +1 -0
- data/test/johnson/{conversions → generic/conversions}/nil_test.rb +1 -1
- data/test/johnson/{conversions → generic/conversions}/number_test.rb +1 -1
- data/test/johnson/{conversions → generic/conversions}/regexp_test.rb +1 -1
- data/test/johnson/{conversions → generic/conversions}/string_test.rb +1 -1
- data/test/johnson/{conversions → generic/conversions}/struct_test.rb +1 -1
- data/test/johnson/{conversions → generic/conversions}/symbol_test.rb +1 -1
- data/test/johnson/{conversions → generic/conversions}/thread_test.rb +1 -1
- data/test/johnson/{custom_conversions_test.rb → generic/custom_conversions_test.rb} +1 -1
- data/test/johnson/generic/default_test.rb +12 -0
- data/test/johnson/{error_test.rb → generic/error_test.rb} +1 -1
- data/test/johnson/{extensions_test.rb → generic/extensions_test.rb} +1 -1
- data/test/johnson/generic/helper.rb +1 -0
- data/test/johnson/{nodes → generic/nodes}/array_literal_test.rb +1 -1
- data/test/johnson/{nodes → generic/nodes}/array_node_test.rb +1 -1
- data/test/johnson/{nodes → generic/nodes}/binary_node_test.rb +1 -1
- data/test/johnson/{nodes → generic/nodes}/bracket_access_test.rb +1 -1
- data/test/johnson/{nodes → generic/nodes}/delete_test.rb +1 -1
- data/test/johnson/{nodes → generic/nodes}/do_while_test.rb +1 -1
- data/test/johnson/{nodes → generic/nodes}/dot_accessor_test.rb +1 -1
- data/test/johnson/generic/nodes/export_test.rb +11 -0
- data/test/johnson/{nodes → generic/nodes}/for_test.rb +1 -1
- data/test/johnson/{nodes → generic/nodes}/function_test.rb +1 -1
- data/test/johnson/generic/nodes/helper.rb +1 -0
- data/test/johnson/{nodes → generic/nodes}/if_test.rb +16 -6
- data/test/johnson/generic/nodes/import_test.rb +15 -0
- data/test/johnson/{nodes → generic/nodes}/label_test.rb +1 -1
- data/test/johnson/{nodes → generic/nodes}/let_test.rb +1 -1
- data/test/johnson/{nodes → generic/nodes}/object_literal_test.rb +1 -1
- data/test/johnson/{nodes → generic/nodes}/return_test.rb +1 -1
- data/test/johnson/{nodes → generic/nodes}/semi_test.rb +1 -1
- data/test/johnson/{nodes → generic/nodes}/switch_test.rb +1 -1
- data/test/johnson/{nodes → generic/nodes}/ternary_test.rb +1 -1
- data/test/johnson/{nodes → generic/nodes}/throw_test.rb +1 -1
- data/test/johnson/{nodes → generic/nodes}/try_node_test.rb +36 -6
- data/test/johnson/{nodes → generic/nodes}/typeof_test.rb +1 -1
- data/test/johnson/{nodes → generic/nodes}/unary_node_test.rb +1 -1
- data/test/johnson/{nodes → generic/nodes}/void_test.rb +1 -1
- data/test/johnson/{nodes → generic/nodes}/while_test.rb +1 -1
- data/test/johnson/{nodes → generic/nodes}/with_test.rb +1 -1
- data/test/johnson/{prelude_test.rb → generic/prelude_test.rb} +1 -1
- data/test/johnson/{runtime_test.rb → generic/runtime_test.rb} +3 -6
- data/test/johnson/generic/version_test.rb +13 -0
- data/test/johnson/{visitors → generic/visitors}/dot_visitor_test.rb +1 -1
- data/test/johnson/{visitors → generic/visitors}/enumerating_visitor_test.rb +1 -1
- data/test/johnson/generic/visitors/helper.rb +1 -0
- data/test/johnson/spidermonkey/js_land_proxy_test.rb +1 -5
- data/test/johnson/spidermonkey/ruby_land_proxy_test.rb +11 -7
- data/test/johnson/tracemonkey/context_test.rb +21 -0
- data/test/johnson/tracemonkey/immutable_node_test.rb +34 -0
- data/test/johnson/tracemonkey/js_land_proxy_test.rb +273 -0
- data/test/johnson/tracemonkey/ruby_land_proxy_test.rb +274 -0
- data/test/johnson/tracemonkey/runtime_test.rb +41 -0
- data/test/johnson/tracemonkey/split_global_test.rb +32 -0
- data/vendor/spidermonkey/js.pkg +2 -0
- data/vendor/tracemonkey/Makefile.in +668 -0
- data/vendor/tracemonkey/Makefile.ref +483 -0
- data/vendor/tracemonkey/README.html +54 -0
- data/vendor/tracemonkey/SpiderMonkey.rsp +11 -0
- data/vendor/tracemonkey/Y.js +19 -0
- data/vendor/tracemonkey/aclocal.m4 +9 -0
- data/vendor/tracemonkey/bench.sh +5 -0
- data/vendor/tracemonkey/build/autoconf/acoutput-fast.pl +202 -0
- data/vendor/tracemonkey/build/autoconf/altoptions.m4 +154 -0
- data/vendor/tracemonkey/build/autoconf/config.guess +1537 -0
- data/vendor/tracemonkey/build/autoconf/config.sub +1595 -0
- data/vendor/tracemonkey/build/autoconf/install-sh +119 -0
- data/vendor/tracemonkey/build/autoconf/make-makefile +315 -0
- data/vendor/tracemonkey/build/autoconf/match-dir.sh +101 -0
- data/vendor/tracemonkey/build/autoconf/moznbytetype.m4 +136 -0
- data/vendor/tracemonkey/build/autoconf/nspr.m4 +82 -0
- data/vendor/tracemonkey/build/autoconf/pkg.m4 +59 -0
- data/vendor/tracemonkey/build/autoconf/update-makefile.sh +118 -0
- data/vendor/tracemonkey/build/cygwin-wrapper +75 -0
- data/vendor/tracemonkey/build/hcc +111 -0
- data/vendor/tracemonkey/build/hcpp +155 -0
- data/vendor/tracemonkey/build/unix/mddepend.pl +165 -0
- data/vendor/tracemonkey/build/unix/uniq.pl +63 -0
- data/vendor/tracemonkey/build/win32/pgomerge.py +40 -0
- data/vendor/tracemonkey/builtins.tbl +91 -0
- data/vendor/tracemonkey/call.js +13 -0
- data/vendor/tracemonkey/config.mk +206 -0
- data/vendor/tracemonkey/config/Makefile.in +106 -0
- data/vendor/tracemonkey/config/Moz/Milestone.pm +232 -0
- data/vendor/tracemonkey/config/autoconf.mk.in +362 -0
- data/vendor/tracemonkey/config/check-sync-dirs.py +103 -0
- data/vendor/tracemonkey/config/check-sync-exceptions +7 -0
- data/vendor/tracemonkey/config/config.mk +881 -0
- data/vendor/tracemonkey/config/fastcwd.pl +66 -0
- data/vendor/tracemonkey/config/gcc_hidden.h +2 -0
- data/vendor/tracemonkey/config/insure.mk +53 -0
- data/vendor/tracemonkey/config/make-system-wrappers.pl +59 -0
- data/vendor/tracemonkey/config/milestone.pl +112 -0
- data/vendor/tracemonkey/config/milestone.txt +13 -0
- data/vendor/tracemonkey/config/mkdepend/Makefile.in +84 -0
- data/vendor/tracemonkey/config/mkdepend/cppsetup.c +233 -0
- data/vendor/tracemonkey/config/mkdepend/def.h +184 -0
- data/vendor/tracemonkey/config/mkdepend/ifparser.c +551 -0
- data/vendor/tracemonkey/config/mkdepend/ifparser.h +83 -0
- data/vendor/tracemonkey/config/mkdepend/imakemdep.h +733 -0
- data/vendor/tracemonkey/config/mkdepend/include.c +337 -0
- data/vendor/tracemonkey/config/mkdepend/main.c +860 -0
- data/vendor/tracemonkey/config/mkdepend/mkdepend.man +382 -0
- data/vendor/tracemonkey/config/mkdepend/parse.c +686 -0
- data/vendor/tracemonkey/config/mkdepend/pr.c +124 -0
- data/vendor/tracemonkey/config/nfspwd.pl +50 -0
- data/vendor/tracemonkey/config/nsinstall.c +481 -0
- data/vendor/tracemonkey/config/nsinstall.py +155 -0
- data/vendor/tracemonkey/config/pathsub.c +247 -0
- data/vendor/tracemonkey/config/pathsub.h +74 -0
- data/vendor/tracemonkey/config/preprocessor.pl +671 -0
- data/vendor/tracemonkey/config/revdepth-nt.pl +48 -0
- data/vendor/tracemonkey/config/revdepth.pl +51 -0
- data/vendor/tracemonkey/config/rules.mk +2310 -0
- data/vendor/tracemonkey/config/static-checking-config.mk +21 -0
- data/vendor/tracemonkey/config/static-checking.js +92 -0
- data/vendor/tracemonkey/config/string-format.js +61 -0
- data/vendor/tracemonkey/config/system-headers +1035 -0
- data/vendor/tracemonkey/config/version.mk +85 -0
- data/vendor/tracemonkey/config/version_win.pl +442 -0
- data/vendor/tracemonkey/configure +14183 -0
- data/vendor/tracemonkey/configure.in +5363 -0
- data/vendor/tracemonkey/correct.sh +23 -0
- data/vendor/tracemonkey/correct/check-3d-morph.js +55 -0
- data/vendor/tracemonkey/correct/check-3d-raytrace.js +445 -0
- data/vendor/tracemonkey/correct/check-access-binary-trees.js +52 -0
- data/vendor/tracemonkey/correct/check-access-fannkuch.js +66 -0
- data/vendor/tracemonkey/correct/check-access-nbody.js +171 -0
- data/vendor/tracemonkey/correct/check-access-nsieve.js +40 -0
- data/vendor/tracemonkey/correct/check-bitops-3bit-bits-in-byte.js +35 -0
- data/vendor/tracemonkey/correct/check-bitops-bits-in-byte.js +24 -0
- data/vendor/tracemonkey/correct/check-bitops-bitwise-and.js +29 -0
- data/vendor/tracemonkey/correct/check-bitops-nsieve-bits.js +40 -0
- data/vendor/tracemonkey/correct/check-controlflow-recursive.js +27 -0
- data/vendor/tracemonkey/correct/check-date-format-tofte.js +302 -0
- data/vendor/tracemonkey/correct/check-date-format-xparb.js +421 -0
- data/vendor/tracemonkey/correct/check-mont.js +119 -0
- data/vendor/tracemonkey/dtoa.c +3335 -0
- data/vendor/tracemonkey/editline/Makefile.in +55 -0
- data/vendor/tracemonkey/editline/Makefile.ref +143 -0
- data/vendor/tracemonkey/editline/README +83 -0
- data/vendor/tracemonkey/editline/editline.3 +175 -0
- data/vendor/tracemonkey/editline/editline.c +1371 -0
- data/vendor/tracemonkey/editline/editline.h +135 -0
- data/vendor/tracemonkey/editline/sysunix.c +182 -0
- data/vendor/tracemonkey/editline/unix.h +82 -0
- data/vendor/tracemonkey/if.js +13 -0
- data/vendor/tracemonkey/imacro_asm.js.in +396 -0
- data/vendor/tracemonkey/imacros.c.out +1034 -0
- data/vendor/tracemonkey/imacros.jsasm +770 -0
- data/vendor/tracemonkey/javascript-trace.d +73 -0
- data/vendor/tracemonkey/jitstats.tbl +55 -0
- data/vendor/tracemonkey/js-config.h.in +82 -0
- data/vendor/tracemonkey/js-config.in +111 -0
- data/vendor/tracemonkey/js.mdp +0 -0
- data/vendor/tracemonkey/js.msg +312 -0
- data/vendor/tracemonkey/js3240.rc +79 -0
- data/vendor/tracemonkey/jsOS240.def +654 -0
- data/vendor/tracemonkey/jsapi.cpp +6005 -0
- data/vendor/tracemonkey/jsapi.h +2727 -0
- data/vendor/tracemonkey/jsarena.cpp +450 -0
- data/vendor/tracemonkey/jsarena.h +318 -0
- data/vendor/tracemonkey/jsarray.cpp +3664 -0
- data/vendor/tracemonkey/jsarray.h +238 -0
- data/vendor/tracemonkey/jsatom.cpp +1244 -0
- data/vendor/tracemonkey/jsatom.h +493 -0
- data/vendor/tracemonkey/jsbit.h +249 -0
- data/vendor/tracemonkey/jsbool.cpp +184 -0
- data/vendor/tracemonkey/jsbool.h +88 -0
- data/vendor/tracemonkey/jsbuiltins.cpp +415 -0
- data/vendor/tracemonkey/jsbuiltins.h +456 -0
- data/vendor/tracemonkey/jsclist.h +139 -0
- data/vendor/tracemonkey/jscntxt.cpp +1816 -0
- data/vendor/tracemonkey/jscntxt.h +1541 -0
- data/vendor/tracemonkey/jscompat.h +57 -0
- data/vendor/tracemonkey/jsconfig.mk +181 -0
- data/vendor/tracemonkey/jscpucfg.cpp +194 -0
- data/vendor/tracemonkey/jscpucfg.h +91 -0
- data/vendor/tracemonkey/jsdate.cpp +2465 -0
- data/vendor/tracemonkey/jsdate.h +129 -0
- data/vendor/tracemonkey/jsdbgapi.cpp +2017 -0
- data/vendor/tracemonkey/jsdbgapi.h +500 -0
- data/vendor/tracemonkey/jsdhash.cpp +876 -0
- data/vendor/tracemonkey/jsdhash.h +588 -0
- data/vendor/tracemonkey/jsdtoa.cpp +572 -0
- data/vendor/tracemonkey/jsdtoa.h +131 -0
- data/vendor/tracemonkey/jsdtracef.c +318 -0
- data/vendor/tracemonkey/jsdtracef.h +81 -0
- data/vendor/tracemonkey/jsemit.cpp +7292 -0
- data/vendor/tracemonkey/jsemit.h +802 -0
- data/vendor/tracemonkey/jsexn.cpp +1337 -0
- data/vendor/tracemonkey/jsexn.h +96 -0
- data/vendor/tracemonkey/jsfile.cpp +2747 -0
- data/vendor/tracemonkey/jsfile.h +56 -0
- data/vendor/tracemonkey/jsfile.msg +90 -0
- data/vendor/tracemonkey/jsfun.cpp +3089 -0
- data/vendor/tracemonkey/jsfun.h +366 -0
- data/vendor/tracemonkey/jsgc.cpp +3816 -0
- data/vendor/tracemonkey/jsgc.h +429 -0
- data/vendor/tracemonkey/jshash.cpp +477 -0
- data/vendor/tracemonkey/jshash.h +151 -0
- data/vendor/tracemonkey/jsify.pl +483 -0
- data/vendor/tracemonkey/jsinterp.cpp +7441 -0
- data/vendor/tracemonkey/jsinterp.h +666 -0
- data/vendor/tracemonkey/jsinvoke.cpp +42 -0
- data/vendor/tracemonkey/jsiter.cpp +1040 -0
- data/vendor/tracemonkey/jsiter.h +140 -0
- data/vendor/tracemonkey/jskeyword.tbl +124 -0
- data/vendor/tracemonkey/jskwgen.cpp +460 -0
- data/vendor/tracemonkey/jslibmath.h +69 -0
- data/vendor/tracemonkey/jslock.cpp +1512 -0
- data/vendor/tracemonkey/jslock.h +325 -0
- data/vendor/tracemonkey/jslocko.asm +60 -0
- data/vendor/tracemonkey/jslog2.cpp +111 -0
- data/vendor/tracemonkey/jslong.h +167 -0
- data/vendor/tracemonkey/jsmath.cpp +806 -0
- data/vendor/tracemonkey/jsmath.h +63 -0
- data/vendor/tracemonkey/jsnum.cpp +1374 -0
- data/vendor/tracemonkey/jsnum.h +280 -0
- data/vendor/tracemonkey/jsobj.cpp +6165 -0
- data/vendor/tracemonkey/jsobj.h +870 -0
- data/vendor/tracemonkey/json.cpp +1338 -0
- data/vendor/tracemonkey/json.h +108 -0
- data/vendor/tracemonkey/jsopcode.cpp +5484 -0
- data/vendor/tracemonkey/jsopcode.h +434 -0
- data/vendor/tracemonkey/jsopcode.tbl +591 -0
- data/vendor/tracemonkey/jsoplengen.cpp +121 -0
- data/vendor/tracemonkey/jsotypes.h +202 -0
- data/vendor/tracemonkey/jsparse.cpp +9257 -0
- data/vendor/tracemonkey/jsparse.h +900 -0
- data/vendor/tracemonkey/jsprf.cpp +1262 -0
- data/vendor/tracemonkey/jsprf.h +150 -0
- data/vendor/tracemonkey/jsproto.tbl +117 -0
- data/vendor/tracemonkey/jsprvtd.h +366 -0
- data/vendor/tracemonkey/jspubtd.h +585 -0
- data/vendor/tracemonkey/jsregexp.cpp +5051 -0
- data/vendor/tracemonkey/jsregexp.h +199 -0
- data/vendor/tracemonkey/jsreops.tbl +145 -0
- data/vendor/tracemonkey/jsscan.cpp +2040 -0
- data/vendor/tracemonkey/jsscan.h +467 -0
- data/vendor/tracemonkey/jsscope.cpp +1966 -0
- data/vendor/tracemonkey/jsscope.h +487 -0
- data/vendor/tracemonkey/jsscript.cpp +1932 -0
- data/vendor/tracemonkey/jsscript.h +345 -0
- data/vendor/tracemonkey/jsshell.msg +54 -0
- data/vendor/tracemonkey/jsstack.js +167 -0
- data/vendor/tracemonkey/jsstaticcheck.h +69 -0
- data/vendor/tracemonkey/jsstddef.h +87 -0
- data/vendor/tracemonkey/jsstdint.h +96 -0
- data/vendor/tracemonkey/jsstr.cpp +5277 -0
- data/vendor/tracemonkey/jsstr.h +702 -0
- data/vendor/tracemonkey/jstracer.cpp +10991 -0
- data/vendor/tracemonkey/jstracer.h +794 -0
- data/vendor/tracemonkey/jstypes.h +481 -0
- data/vendor/tracemonkey/jsutil.cpp +361 -0
- data/vendor/tracemonkey/jsutil.h +178 -0
- data/vendor/tracemonkey/jsversion.h +243 -0
- data/vendor/tracemonkey/jswince.asm +44 -0
- data/vendor/tracemonkey/jsxdrapi.cpp +800 -0
- data/vendor/tracemonkey/jsxdrapi.h +220 -0
- data/vendor/tracemonkey/jsxml.cpp +8327 -0
- data/vendor/tracemonkey/jsxml.h +305 -0
- data/vendor/tracemonkey/liveconnect/LiveConnect.dsp +157 -0
- data/vendor/tracemonkey/liveconnect/LiveConnectShell.dsp +120 -0
- data/vendor/tracemonkey/liveconnect/LiveConnectShell.dsw +44 -0
- data/vendor/tracemonkey/liveconnect/Makefile.in +105 -0
- data/vendor/tracemonkey/liveconnect/Makefile.ref +169 -0
- data/vendor/tracemonkey/liveconnect/README.html +712 -0
- data/vendor/tracemonkey/liveconnect/_jni/netscape_javascript_JSException.h +14 -0
- data/vendor/tracemonkey/liveconnect/_jni/netscape_javascript_JSObject.h +155 -0
- data/vendor/tracemonkey/liveconnect/classes/Makefile.in +89 -0
- data/vendor/tracemonkey/liveconnect/classes/Makefile.ref +57 -0
- data/vendor/tracemonkey/liveconnect/classes/netscape/Makefile.ref +47 -0
- data/vendor/tracemonkey/liveconnect/classes/netscape/javascript/JSException.java +140 -0
- data/vendor/tracemonkey/liveconnect/classes/netscape/javascript/JSObject.java +183 -0
- data/vendor/tracemonkey/liveconnect/classes/netscape/javascript/JSProxy.java +58 -0
- data/vendor/tracemonkey/liveconnect/classes/netscape/javascript/JSRunnable.java +70 -0
- data/vendor/tracemonkey/liveconnect/classes/netscape/javascript/JSUtil.java +59 -0
- data/vendor/tracemonkey/liveconnect/classes/netscape/javascript/Makefile.ref +53 -0
- data/vendor/tracemonkey/liveconnect/config/AIX4.1.mk +45 -0
- data/vendor/tracemonkey/liveconnect/config/AIX4.2.mk +45 -0
- data/vendor/tracemonkey/liveconnect/config/AIX4.3.mk +50 -0
- data/vendor/tracemonkey/liveconnect/config/HP-UXB.10.10.mk +43 -0
- data/vendor/tracemonkey/liveconnect/config/HP-UXB.10.20.mk +43 -0
- data/vendor/tracemonkey/liveconnect/config/HP-UXB.11.00.mk +43 -0
- data/vendor/tracemonkey/liveconnect/config/IRIX6.2.mk +43 -0
- data/vendor/tracemonkey/liveconnect/config/IRIX6.3.mk +43 -0
- data/vendor/tracemonkey/liveconnect/config/IRIX6.5.mk +43 -0
- data/vendor/tracemonkey/liveconnect/config/Linux_All.mk +73 -0
- data/vendor/tracemonkey/liveconnect/config/OSF1V4.0.mk +65 -0
- data/vendor/tracemonkey/liveconnect/config/OSF1V5.0.mk +62 -0
- data/vendor/tracemonkey/liveconnect/config/SunOS5.5.1.mk +55 -0
- data/vendor/tracemonkey/liveconnect/config/SunOS5.6.mk +39 -0
- data/vendor/tracemonkey/liveconnect/config/SunOS5.7.mk +39 -0
- data/vendor/tracemonkey/liveconnect/config/SunOS5.8.mk +39 -0
- data/vendor/tracemonkey/liveconnect/config/WINNT4.0.mk +53 -0
- data/vendor/tracemonkey/liveconnect/jsj.c +886 -0
- data/vendor/tracemonkey/liveconnect/jsj.msg +98 -0
- data/vendor/tracemonkey/liveconnect/jsj_JSObject.c +1377 -0
- data/vendor/tracemonkey/liveconnect/jsj_JavaArray.c +474 -0
- data/vendor/tracemonkey/liveconnect/jsj_JavaClass.c +737 -0
- data/vendor/tracemonkey/liveconnect/jsj_JavaMember.c +191 -0
- data/vendor/tracemonkey/liveconnect/jsj_JavaObject.c +1079 -0
- data/vendor/tracemonkey/liveconnect/jsj_JavaPackage.c +569 -0
- data/vendor/tracemonkey/liveconnect/jsj_array.c +207 -0
- data/vendor/tracemonkey/liveconnect/jsj_class.c +770 -0
- data/vendor/tracemonkey/liveconnect/jsj_convert.c +902 -0
- data/vendor/tracemonkey/liveconnect/jsj_field.c +421 -0
- data/vendor/tracemonkey/liveconnect/jsj_hash.c +488 -0
- data/vendor/tracemonkey/liveconnect/jsj_hash.h +161 -0
- data/vendor/tracemonkey/liveconnect/jsj_method.c +1825 -0
- data/vendor/tracemonkey/liveconnect/jsj_nodl.c +1 -0
- data/vendor/tracemonkey/liveconnect/jsj_private.h +677 -0
- data/vendor/tracemonkey/liveconnect/jsj_simpleapi.c +219 -0
- data/vendor/tracemonkey/liveconnect/jsj_utils.c +513 -0
- data/vendor/tracemonkey/liveconnect/jsjava.h +316 -0
- data/vendor/tracemonkey/liveconnect/netscape_javascript_JSObject.h +155 -0
- data/vendor/tracemonkey/liveconnect/nsCLiveconnect.cpp +785 -0
- data/vendor/tracemonkey/liveconnect/nsCLiveconnect.h +197 -0
- data/vendor/tracemonkey/liveconnect/nsCLiveconnectFactory.cpp +118 -0
- data/vendor/tracemonkey/liveconnect/nsCLiveconnectFactory.h +76 -0
- data/vendor/tracemonkey/liveconnect/nsILiveconnect.h +197 -0
- data/vendor/tracemonkey/liveconnect/nsISecureLiveconnect.h +94 -0
- data/vendor/tracemonkey/liveconnect/nsISecurityContext.h +136 -0
- data/vendor/tracemonkey/lock_SunOS.s +119 -0
- data/vendor/tracemonkey/mandelbrot-results.js +3 -0
- data/vendor/tracemonkey/math-partial-sums.js +32 -0
- data/vendor/tracemonkey/math-trace-tests.js +507 -0
- data/vendor/tracemonkey/md5.js +289 -0
- data/vendor/tracemonkey/nanojit/Assembler.cpp +1984 -0
- data/vendor/tracemonkey/nanojit/Assembler.h +375 -0
- data/vendor/tracemonkey/nanojit/Fragmento.cpp +651 -0
- data/vendor/tracemonkey/nanojit/Fragmento.h +237 -0
- data/vendor/tracemonkey/nanojit/LIR.cpp +2314 -0
- data/vendor/tracemonkey/nanojit/LIR.h +879 -0
- data/vendor/tracemonkey/nanojit/LIRopcode.tbl +252 -0
- data/vendor/tracemonkey/nanojit/Native.h +127 -0
- data/vendor/tracemonkey/nanojit/NativeARM.cpp +1742 -0
- data/vendor/tracemonkey/nanojit/NativeARM.h +844 -0
- data/vendor/tracemonkey/nanojit/NativeSparc.cpp +1130 -0
- data/vendor/tracemonkey/nanojit/NativeSparc.h +948 -0
- data/vendor/tracemonkey/nanojit/NativeThumb.cpp +1322 -0
- data/vendor/tracemonkey/nanojit/NativeThumb.h +525 -0
- data/vendor/tracemonkey/nanojit/Nativei386.cpp +1748 -0
- data/vendor/tracemonkey/nanojit/Nativei386.h +857 -0
- data/vendor/tracemonkey/nanojit/RegAlloc.cpp +183 -0
- data/vendor/tracemonkey/nanojit/RegAlloc.h +95 -0
- data/vendor/tracemonkey/nanojit/TraceTreeDrawer.cpp +306 -0
- data/vendor/tracemonkey/nanojit/TraceTreeDrawer.h +88 -0
- data/vendor/tracemonkey/nanojit/avmplus.cpp +56 -0
- data/vendor/tracemonkey/nanojit/avmplus.h +1016 -0
- data/vendor/tracemonkey/nanojit/nanojit.h +253 -0
- data/vendor/tracemonkey/perfect.js +39 -0
- data/vendor/tracemonkey/plify_jsdhash.sed +35 -0
- data/vendor/tracemonkey/prmjtime.cpp +869 -0
- data/vendor/tracemonkey/prmjtime.h +103 -0
- data/vendor/tracemonkey/ref-config/AIX4.1.mk +65 -0
- data/vendor/tracemonkey/ref-config/AIX4.2.mk +64 -0
- data/vendor/tracemonkey/ref-config/AIX4.3.mk +65 -0
- data/vendor/tracemonkey/ref-config/Darwin.mk +85 -0
- data/vendor/tracemonkey/ref-config/Darwin1.3.mk +81 -0
- data/vendor/tracemonkey/ref-config/Darwin1.4.mk +41 -0
- data/vendor/tracemonkey/ref-config/Darwin5.2.mk +81 -0
- data/vendor/tracemonkey/ref-config/Darwin5.3.mk +81 -0
- data/vendor/tracemonkey/ref-config/Darwin64.mk +72 -0
- data/vendor/tracemonkey/ref-config/HP-UXB.10.10.mk +77 -0
- data/vendor/tracemonkey/ref-config/HP-UXB.10.20.mk +77 -0
- data/vendor/tracemonkey/ref-config/HP-UXB.11.00.mk +80 -0
- data/vendor/tracemonkey/ref-config/IRIX.mk +87 -0
- data/vendor/tracemonkey/ref-config/IRIX5.3.mk +44 -0
- data/vendor/tracemonkey/ref-config/IRIX6.1.mk +44 -0
- data/vendor/tracemonkey/ref-config/IRIX6.2.mk +44 -0
- data/vendor/tracemonkey/ref-config/IRIX6.3.mk +44 -0
- data/vendor/tracemonkey/ref-config/IRIX6.5.mk +44 -0
- data/vendor/tracemonkey/ref-config/Linux_All.mk +105 -0
- data/vendor/tracemonkey/ref-config/Mac_OS10.0.mk +82 -0
- data/vendor/tracemonkey/ref-config/OSF1V4.0.mk +72 -0
- data/vendor/tracemonkey/ref-config/OSF1V5.0.mk +69 -0
- data/vendor/tracemonkey/ref-config/SunOS4.1.4.mk +101 -0
- data/vendor/tracemonkey/ref-config/SunOS5.10.mk +50 -0
- data/vendor/tracemonkey/ref-config/SunOS5.3.mk +91 -0
- data/vendor/tracemonkey/ref-config/SunOS5.4.mk +92 -0
- data/vendor/tracemonkey/ref-config/SunOS5.5.1.mk +44 -0
- data/vendor/tracemonkey/ref-config/SunOS5.5.mk +87 -0
- data/vendor/tracemonkey/ref-config/SunOS5.6.mk +89 -0
- data/vendor/tracemonkey/ref-config/SunOS5.7.mk +44 -0
- data/vendor/tracemonkey/ref-config/SunOS5.8.mk +44 -0
- data/vendor/tracemonkey/ref-config/SunOS5.9.mk +44 -0
- data/vendor/tracemonkey/ref-config/WINNT4.0.mk +118 -0
- data/vendor/tracemonkey/ref-config/WINNT5.0.mk +118 -0
- data/vendor/tracemonkey/ref-config/WINNT5.1.mk +118 -0
- data/vendor/tracemonkey/ref-config/WINNT5.2.mk +118 -0
- data/vendor/tracemonkey/ref-config/WINNT6.0.mk +118 -0
- data/vendor/tracemonkey/ref-config/dgux.mk +64 -0
- data/vendor/tracemonkey/resource.h +15 -0
- data/vendor/tracemonkey/rules.mk +206 -0
- data/vendor/tracemonkey/shell/Makefile.in +72 -0
- data/vendor/tracemonkey/shell/js.cpp +4719 -0
- data/vendor/tracemonkey/t/3d-cube.js +337 -0
- data/vendor/tracemonkey/t/3d-morph.js +54 -0
- data/vendor/tracemonkey/t/3d-raytrace.js +441 -0
- data/vendor/tracemonkey/t/access-binary-trees.js +50 -0
- data/vendor/tracemonkey/t/access-fannkuch.js +66 -0
- data/vendor/tracemonkey/t/access-nbody.js +169 -0
- data/vendor/tracemonkey/t/access-nsieve.js +38 -0
- data/vendor/tracemonkey/t/bitops-3bit-bits-in-byte.js +32 -0
- data/vendor/tracemonkey/t/bitops-bits-in-byte.js +21 -0
- data/vendor/tracemonkey/t/bitops-bitwise-and.js +28 -0
- data/vendor/tracemonkey/t/bitops-nsieve-bits.js +32 -0
- data/vendor/tracemonkey/t/controlflow-recursive.js +25 -0
- data/vendor/tracemonkey/t/crypto-aes.js +422 -0
- data/vendor/tracemonkey/t/crypto-md5.js +286 -0
- data/vendor/tracemonkey/t/crypto-sha1.js +224 -0
- data/vendor/tracemonkey/t/date-format-tofte.js +299 -0
- data/vendor/tracemonkey/t/date-format-xparb.js +417 -0
- data/vendor/tracemonkey/t/math-cordic.js +95 -0
- data/vendor/tracemonkey/t/math-partial-sums.js +33 -0
- data/vendor/tracemonkey/t/math-spectral-norm.js +51 -0
- data/vendor/tracemonkey/t/regexp-dna.js +1712 -0
- data/vendor/tracemonkey/t/string-base64.js +135 -0
- data/vendor/tracemonkey/t/string-fasta.js +85 -0
- data/vendor/tracemonkey/t/string-tagcloud.js +265 -0
- data/vendor/tracemonkey/t/string-unpack-code.js +68 -0
- data/vendor/tracemonkey/t/string-validate-input.js +89 -0
- data/vendor/tracemonkey/time.sh +13 -0
- data/vendor/tracemonkey/trace-test.js +5564 -0
- data/vendor/tracemonkey/v8/base.js +187 -0
- data/vendor/tracemonkey/v8/crypto.js +1689 -0
- data/vendor/tracemonkey/v8/deltablue.js +880 -0
- data/vendor/tracemonkey/v8/earley-boyer.js +4682 -0
- data/vendor/tracemonkey/v8/raytrace.js +3418 -0
- data/vendor/tracemonkey/v8/richards.js +539 -0
- data/vendor/tracemonkey/v8/run-crypto.js +44 -0
- data/vendor/tracemonkey/v8/run-deltablue.js +44 -0
- data/vendor/tracemonkey/v8/run-earley-boyer.js +44 -0
- data/vendor/tracemonkey/v8/run-raytrace.js +44 -0
- data/vendor/tracemonkey/v8/run-richards.js +44 -0
- data/vendor/tracemonkey/v8/run.js +49 -0
- data/vendor/tracemonkey/vprof/readme.txt +93 -0
- data/vendor/tracemonkey/vprof/vprof.cpp +360 -0
- data/vendor/tracemonkey/vprof/vprof.h +245 -0
- data/vendor/tracemonkey/xpconnect/Makefile.in +67 -0
- data/vendor/tracemonkey/xpconnect/crashtests/117307-1.html +20 -0
- data/vendor/tracemonkey/xpconnect/crashtests/193710.html +11 -0
- data/vendor/tracemonkey/xpconnect/crashtests/290162-1.html +5 -0
- data/vendor/tracemonkey/xpconnect/crashtests/326615-1.html +16 -0
- data/vendor/tracemonkey/xpconnect/crashtests/328553-1.html +13 -0
- data/vendor/tracemonkey/xpconnect/crashtests/346258-1.html +12 -0
- data/vendor/tracemonkey/xpconnect/crashtests/346512-1-frame1.xhtml +16 -0
- data/vendor/tracemonkey/xpconnect/crashtests/346512-1-frame2.xhtml +15 -0
- data/vendor/tracemonkey/xpconnect/crashtests/346512-1.xhtml +30 -0
- data/vendor/tracemonkey/xpconnect/crashtests/382133-1.html +3 -0
- data/vendor/tracemonkey/xpconnect/crashtests/386680-1.html +22 -0
- data/vendor/tracemonkey/xpconnect/crashtests/394810-1.html +4 -0
- data/vendor/tracemonkey/xpconnect/crashtests/400349-1.html +20 -0
- data/vendor/tracemonkey/xpconnect/crashtests/403356-1.html +13 -0
- data/vendor/tracemonkey/xpconnect/crashtests/418139-1.svg +22 -0
- data/vendor/tracemonkey/xpconnect/crashtests/420513-1.html +11 -0
- data/vendor/tracemonkey/xpconnect/crashtests/453935-1.html +37 -0
- data/vendor/tracemonkey/xpconnect/crashtests/462926.html +12 -0
- data/vendor/tracemonkey/xpconnect/crashtests/468552-1.html +18 -0
- data/vendor/tracemonkey/xpconnect/crashtests/471366-1.html +12 -0
- data/vendor/tracemonkey/xpconnect/crashtests/475185-1.html +13 -0
- data/vendor/tracemonkey/xpconnect/crashtests/475291-1.html +14 -0
- data/vendor/tracemonkey/xpconnect/crashtests/503286-1.html +23 -0
- data/vendor/tracemonkey/xpconnect/crashtests/crashtests.list +21 -0
- data/vendor/tracemonkey/xpconnect/idl/Makefile.in +78 -0
- data/vendor/tracemonkey/xpconnect/idl/XPCIDispatch.idl +51 -0
- data/vendor/tracemonkey/xpconnect/idl/mozIJSSubScriptLoader.idl +64 -0
- data/vendor/tracemonkey/xpconnect/idl/nsIActiveXSecurityPolicy.idl +67 -0
- data/vendor/tracemonkey/xpconnect/idl/nsIDispatchSupport.idl +119 -0
- data/vendor/tracemonkey/xpconnect/idl/nsIJSContextStack.idl +85 -0
- data/vendor/tracemonkey/xpconnect/idl/nsIJSRuntimeService.idl +51 -0
- data/vendor/tracemonkey/xpconnect/idl/nsIScriptError.idl +102 -0
- data/vendor/tracemonkey/xpconnect/idl/nsIScriptableInterfaces.idl +67 -0
- data/vendor/tracemonkey/xpconnect/idl/nsIXPCScriptNotify.idl +66 -0
- data/vendor/tracemonkey/xpconnect/idl/nsIXPCScriptable.idl +183 -0
- data/vendor/tracemonkey/xpconnect/idl/nsIXPCSecurityManager.idl +114 -0
- data/vendor/tracemonkey/xpconnect/idl/nsIXPConnect.idl +819 -0
- data/vendor/tracemonkey/xpconnect/idl/xpcIJSModuleLoader.idl +95 -0
- data/vendor/tracemonkey/xpconnect/idl/xpcIJSWeakReference.idl +49 -0
- data/vendor/tracemonkey/xpconnect/idl/xpccomponents.idl +254 -0
- data/vendor/tracemonkey/xpconnect/idl/xpcexception.idl +66 -0
- data/vendor/tracemonkey/xpconnect/idl/xpcjsid.idl +83 -0
- data/vendor/tracemonkey/xpconnect/loader/ISO8601DateUtils.jsm +176 -0
- data/vendor/tracemonkey/xpconnect/loader/Makefile.in +63 -0
- data/vendor/tracemonkey/xpconnect/loader/XPCOMUtils.jsm +267 -0
- data/vendor/tracemonkey/xpconnect/loader/mozJSComponentLoader.cpp +1717 -0
- data/vendor/tracemonkey/xpconnect/loader/mozJSComponentLoader.h +172 -0
- data/vendor/tracemonkey/xpconnect/loader/mozJSLoaderConstructors.h +101 -0
- data/vendor/tracemonkey/xpconnect/loader/mozJSSubScriptLoader.cpp +360 -0
- data/vendor/tracemonkey/xpconnect/loader/mozJSSubScriptLoader.h +66 -0
- data/vendor/tracemonkey/xpconnect/public/Makefile.in +54 -0
- data/vendor/tracemonkey/xpconnect/public/nsAXPCNativeCallContext.h +89 -0
- data/vendor/tracemonkey/xpconnect/public/nsAutoJSValHolder.h +168 -0
- data/vendor/tracemonkey/xpconnect/public/xpc_map_end.h +327 -0
- data/vendor/tracemonkey/xpconnect/sample/Makefile.in +71 -0
- data/vendor/tracemonkey/xpconnect/sample/README +39 -0
- data/vendor/tracemonkey/xpconnect/sample/xpcsample1.cpp +337 -0
- data/vendor/tracemonkey/xpconnect/sample/xpcsample1.idl +82 -0
- data/vendor/tracemonkey/xpconnect/sample/xpcsample1.js +21 -0
- data/vendor/tracemonkey/xpconnect/shell/Makefile.in +106 -0
- data/vendor/tracemonkey/xpconnect/shell/jsshell.msg +50 -0
- data/vendor/tracemonkey/xpconnect/shell/xpcshell.cpp +1817 -0
- data/vendor/tracemonkey/xpconnect/shell/xpcshellMacUtils.h +43 -0
- data/vendor/tracemonkey/xpconnect/shell/xpcshellMacUtils.mm +54 -0
- data/vendor/tracemonkey/xpconnect/src/Makefile.in +228 -0
- data/vendor/tracemonkey/xpconnect/src/README +3 -0
- data/vendor/tracemonkey/xpconnect/src/XPCCrossOriginWrapper.cpp +1186 -0
- data/vendor/tracemonkey/xpconnect/src/XPCDispConvert.cpp +593 -0
- data/vendor/tracemonkey/xpconnect/src/XPCDispInlines.h +667 -0
- data/vendor/tracemonkey/xpconnect/src/XPCDispInterface.cpp +383 -0
- data/vendor/tracemonkey/xpconnect/src/XPCDispObject.cpp +516 -0
- data/vendor/tracemonkey/xpconnect/src/XPCDispParamPropJSClass.cpp +223 -0
- data/vendor/tracemonkey/xpconnect/src/XPCDispParams.cpp +103 -0
- data/vendor/tracemonkey/xpconnect/src/XPCDispPrivate.h +1401 -0
- data/vendor/tracemonkey/xpconnect/src/XPCDispTearOff.cpp +547 -0
- data/vendor/tracemonkey/xpconnect/src/XPCDispTypeInfo.cpp +471 -0
- data/vendor/tracemonkey/xpconnect/src/XPCIDispatchClassInfo.cpp +139 -0
- data/vendor/tracemonkey/xpconnect/src/XPCIDispatchExtension.cpp +362 -0
- data/vendor/tracemonkey/xpconnect/src/XPCNativeWrapper.cpp +1350 -0
- data/vendor/tracemonkey/xpconnect/src/XPCNativeWrapper.h +88 -0
- data/vendor/tracemonkey/xpconnect/src/XPCSafeJSObjectWrapper.cpp +1148 -0
- data/vendor/tracemonkey/xpconnect/src/XPCSystemOnlyWrapper.cpp +718 -0
- data/vendor/tracemonkey/xpconnect/src/XPCWrapper.cpp +850 -0
- data/vendor/tracemonkey/xpconnect/src/XPCWrapper.h +394 -0
- data/vendor/tracemonkey/xpconnect/src/dom_quickstubs.qsconf +568 -0
- data/vendor/tracemonkey/xpconnect/src/nsDispatchSupport.cpp +348 -0
- data/vendor/tracemonkey/xpconnect/src/nsScriptError.cpp +201 -0
- data/vendor/tracemonkey/xpconnect/src/nsXPConnect.cpp +2609 -0
- data/vendor/tracemonkey/xpconnect/src/qsgen.py +1487 -0
- data/vendor/tracemonkey/xpconnect/src/xpc.msg +217 -0
- data/vendor/tracemonkey/xpconnect/src/xpcJSWeakReference.cpp +148 -0
- data/vendor/tracemonkey/xpconnect/src/xpcJSWeakReference.h +56 -0
- data/vendor/tracemonkey/xpconnect/src/xpccallcontext.cpp +579 -0
- data/vendor/tracemonkey/xpconnect/src/xpccomponents.cpp +4144 -0
- data/vendor/tracemonkey/xpconnect/src/xpccontext.cpp +115 -0
- data/vendor/tracemonkey/xpconnect/src/xpcconvert.cpp +2298 -0
- data/vendor/tracemonkey/xpconnect/src/xpcdebug.cpp +481 -0
- data/vendor/tracemonkey/xpconnect/src/xpcexception.cpp +502 -0
- data/vendor/tracemonkey/xpconnect/src/xpcforwards.h +114 -0
- data/vendor/tracemonkey/xpconnect/src/xpcinlines.h +772 -0
- data/vendor/tracemonkey/xpconnect/src/xpcjsid.cpp +1025 -0
- data/vendor/tracemonkey/xpconnect/src/xpcjsruntime.cpp +1342 -0
- data/vendor/tracemonkey/xpconnect/src/xpclog.cpp +128 -0
- data/vendor/tracemonkey/xpconnect/src/xpclog.h +101 -0
- data/vendor/tracemonkey/xpconnect/src/xpcmaps.cpp +761 -0
- data/vendor/tracemonkey/xpconnect/src/xpcmaps.h +713 -0
- data/vendor/tracemonkey/xpconnect/src/xpcmodule.cpp +136 -0
- data/vendor/tracemonkey/xpconnect/src/xpcprivate.h +4138 -0
- data/vendor/tracemonkey/xpconnect/src/xpcquickstubs.cpp +1128 -0
- data/vendor/tracemonkey/xpconnect/src/xpcquickstubs.h +480 -0
- data/vendor/tracemonkey/xpconnect/src/xpcruntimesvc.cpp +179 -0
- data/vendor/tracemonkey/xpconnect/src/xpcstack.cpp +342 -0
- data/vendor/tracemonkey/xpconnect/src/xpcstring.cpp +139 -0
- data/vendor/tracemonkey/xpconnect/src/xpcthreadcontext.cpp +599 -0
- data/vendor/tracemonkey/xpconnect/src/xpcthrower.cpp +399 -0
- data/vendor/tracemonkey/xpconnect/src/xpcvariant.cpp +850 -0
- data/vendor/tracemonkey/xpconnect/src/xpcwrappedjs.cpp +670 -0
- data/vendor/tracemonkey/xpconnect/src/xpcwrappedjsclass.cpp +2015 -0
- data/vendor/tracemonkey/xpconnect/src/xpcwrappednative.cpp +3482 -0
- data/vendor/tracemonkey/xpconnect/src/xpcwrappednativeinfo.cpp +945 -0
- data/vendor/tracemonkey/xpconnect/src/xpcwrappednativejsops.cpp +2003 -0
- data/vendor/tracemonkey/xpconnect/src/xpcwrappednativeproto.cpp +302 -0
- data/vendor/tracemonkey/xpconnect/src/xpcwrappednativescope.cpp +991 -0
- data/vendor/tracemonkey/xpconnect/tests/Makefile.in +75 -0
- data/vendor/tracemonkey/xpconnect/tests/TestXPC.cpp +785 -0
- data/vendor/tracemonkey/xpconnect/tests/chrome/Makefile.in +51 -0
- data/vendor/tracemonkey/xpconnect/tests/chrome/test_bug500931.xul +43 -0
- data/vendor/tracemonkey/xpconnect/tests/components/Makefile.in +85 -0
- data/vendor/tracemonkey/xpconnect/tests/components/xpctest_array.cpp +388 -0
- data/vendor/tracemonkey/xpconnect/tests/components/xpctest_attributes.cpp +305 -0
- data/vendor/tracemonkey/xpconnect/tests/components/xpctest_calljs.cpp +135 -0
- data/vendor/tracemonkey/xpconnect/tests/components/xpctest_child.cpp +225 -0
- data/vendor/tracemonkey/xpconnect/tests/components/xpctest_const.cpp +76 -0
- data/vendor/tracemonkey/xpconnect/tests/components/xpctest_domstring.cpp +118 -0
- data/vendor/tracemonkey/xpconnect/tests/components/xpctest_echo.cpp +616 -0
- data/vendor/tracemonkey/xpconnect/tests/components/xpctest_in.cpp +204 -0
- data/vendor/tracemonkey/xpconnect/tests/components/xpctest_inout.cpp +171 -0
- data/vendor/tracemonkey/xpconnect/tests/components/xpctest_module.cpp +77 -0
- data/vendor/tracemonkey/xpconnect/tests/components/xpctest_multiple.cpp +554 -0
- data/vendor/tracemonkey/xpconnect/tests/components/xpctest_noisy.cpp +154 -0
- data/vendor/tracemonkey/xpconnect/tests/components/xpctest_out.cpp +335 -0
- data/vendor/tracemonkey/xpconnect/tests/components/xpctest_overloaded.cpp +250 -0
- data/vendor/tracemonkey/xpconnect/tests/components/xpctest_private.h +192 -0
- data/vendor/tracemonkey/xpconnect/tests/components/xpctest_string.cpp +185 -0
- data/vendor/tracemonkey/xpconnect/tests/components/xpctest_variant.cpp +355 -0
- data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/StdAfx.cpp +12 -0
- data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/StdAfx.h +28 -0
- data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/XPCDispUtilities.h +28 -0
- data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/XPCIDispatchTest.cpp +86 -0
- data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/XPCIDispatchTest.def +9 -0
- data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/XPCIDispatchTest.dsp +318 -0
- data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/XPCIDispatchTest.dsw +29 -0
- data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/XPCIDispatchTest.idl +454 -0
- data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/XPCIDispatchTest.rc +145 -0
- data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispSimple.cpp +44 -0
- data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispSimple.h +56 -0
- data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispSimple.rgs +23 -0
- data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestArrays.cpp +221 -0
- data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestArrays.h +53 -0
- data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestArrays.rgs +23 -0
- data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestMethods.cpp +699 -0
- data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestMethods.h +138 -0
- data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestMethods.rgs +23 -0
- data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestNoIDispatch.cpp +23 -0
- data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestNoIDispatch.h +41 -0
- data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestNoIDispatch.rgs +23 -0
- data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestProperties.cpp +256 -0
- data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestProperties.h +88 -0
- data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestProperties.rgs +23 -0
- data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestScriptOff.cpp +23 -0
- data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestScriptOff.h +43 -0
- data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestScriptOff.rgs +23 -0
- data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestScriptOn.cpp +29 -0
- data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestScriptOn.h +45 -0
- data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestScriptOn.rgs +23 -0
- data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestWrappedJS.cpp +177 -0
- data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestWrappedJS.h +50 -0
- data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/nsXPCDispTestWrappedJS.rgs +23 -0
- data/vendor/tracemonkey/xpconnect/tests/idispatch/COM/resource.h +36 -0
- data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedCOM/Arrays/XPCIDispatchArrayTests.js +54 -0
- data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedCOM/Attributes/XPCIDispatchAttributeTests.js +150 -0
- data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedCOM/General/XPCIDispatchInstantiations.js +122 -0
- data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedCOM/General/XPCStress.js +58 -0
- data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedCOM/Methods/XPCIDispatchMethodTests.js +376 -0
- data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedCOM/shell.js +377 -0
- data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedJS/General/XPCIDispatchTestWrappedJS.js +76 -0
- data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/WrappedJS/shell.js +377 -0
- data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/exectests.cmd +1 -0
- data/vendor/tracemonkey/xpconnect/tests/idispatch/Tests/jsDriver.pl +1288 -0
- data/vendor/tracemonkey/xpconnect/tests/idl/Makefile.in +61 -0
- data/vendor/tracemonkey/xpconnect/tests/idl/xpctest.idl +312 -0
- data/vendor/tracemonkey/xpconnect/tests/idl/xpctest2.idl +51 -0
- data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_attributes.idl +67 -0
- data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_calljs.idl +59 -0
- data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_const.idl +61 -0
- data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_domstring.idl +59 -0
- data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_in.idl +88 -0
- data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_inout.idl +86 -0
- data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_multiple.idl +77 -0
- data/vendor/tracemonkey/xpconnect/tests/idl/xpctest_out.idl +142 -0
- data/vendor/tracemonkey/xpconnect/tests/js/checkid.js +82 -0
- data/vendor/tracemonkey/xpconnect/tests/js/evaluate.js +311 -0
- data/vendor/tracemonkey/xpconnect/tests/js/exceptions-2.js +153 -0
- data/vendor/tracemonkey/xpconnect/tests/js/exceptions-3.js +194 -0
- data/vendor/tracemonkey/xpconnect/tests/js/exceptions-4.js +297 -0
- data/vendor/tracemonkey/xpconnect/tests/js/exceptions-5.js +343 -0
- data/vendor/tracemonkey/xpconnect/tests/js/exceptions.js +230 -0
- data/vendor/tracemonkey/xpconnect/tests/js/javascript.js +96 -0
- data/vendor/tracemonkey/xpconnect/tests/js/multiple-2.js +151 -0
- data/vendor/tracemonkey/xpconnect/tests/js/multiple-3.js +148 -0
- data/vendor/tracemonkey/xpconnect/tests/js/multiple-4.js +152 -0
- data/vendor/tracemonkey/xpconnect/tests/js/multiple.js +137 -0
- data/vendor/tracemonkey/xpconnect/tests/js/notscriptable.js +104 -0
- data/vendor/tracemonkey/xpconnect/tests/js/old/simpletest.js +36 -0
- data/vendor/tracemonkey/xpconnect/tests/js/old/speed.js +60 -0
- data/vendor/tracemonkey/xpconnect/tests/js/old/testxpc.js +464 -0
- data/vendor/tracemonkey/xpconnect/tests/js/old/threads.js +74 -0
- data/vendor/tracemonkey/xpconnect/tests/js/old/try.js +27 -0
- data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_array.js +308 -0
- data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_callcontext.js +68 -0
- data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_echo.js +636 -0
- data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_enum_and_sort.js +28 -0
- data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_enum_constants.js +15 -0
- data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_enum_create.js +200 -0
- data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_exceptions.js +167 -0
- data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_ids.js +135 -0
- data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_observer.js +36 -0
- data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_overloaded.js +14 -0
- data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_primitives.js +141 -0
- data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_propertybag.js +36 -0
- data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_variant.js +339 -0
- data/vendor/tracemonkey/xpconnect/tests/js/old/xpctest_variant_array.js +30 -0
- data/vendor/tracemonkey/xpconnect/tests/js/readonlyattributes.js +74 -0
- data/vendor/tracemonkey/xpconnect/tests/js/readwriteattributes.js +101 -0
- data/vendor/tracemonkey/xpconnect/tests/js/scriptable.js +120 -0
- data/vendor/tracemonkey/xpconnect/tests/js/testin.js +203 -0
- data/vendor/tracemonkey/xpconnect/tests/js/xpcfun.js +234 -0
- data/vendor/tracemonkey/xpconnect/tests/js/xpctest_primitives.js +200 -0
- data/vendor/tracemonkey/xpconnect/tests/mochitest/Makefile.in +66 -0
- data/vendor/tracemonkey/xpconnect/tests/mochitest/bug500931_helper.html +7 -0
- data/vendor/tracemonkey/xpconnect/tests/mochitest/inner.html +7 -0
- data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug361111.xul +29 -0
- data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug384632.html +32 -0
- data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug390488.html +65 -0
- data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug393269.html +46 -0
- data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug396851.html +43 -0
- data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug428021.html +41 -0
- data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug446584.html +49 -0
- data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug448587.html +31 -0
- data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug462428.html +42 -0
- data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug478438.html +66 -0
- data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug484107.html +100 -0
- data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug484459.html +36 -0
- data/vendor/tracemonkey/xpconnect/tests/mochitest/test_bug500691.html +28 -0
- data/vendor/tracemonkey/xpconnect/tests/mochitest/test_wrappers.html +116 -0
- data/vendor/tracemonkey/xpconnect/tests/unit/bogus_element_type.jsm +1 -0
- data/vendor/tracemonkey/xpconnect/tests/unit/bogus_exports_type.jsm +1 -0
- data/vendor/tracemonkey/xpconnect/tests/unit/bug451678_subscript.js +2 -0
- data/vendor/tracemonkey/xpconnect/tests/unit/component_import.js +144 -0
- data/vendor/tracemonkey/xpconnect/tests/unit/recursive_importA.jsm +44 -0
- data/vendor/tracemonkey/xpconnect/tests/unit/recursive_importB.jsm +45 -0
- data/vendor/tracemonkey/xpconnect/tests/unit/syntax_error.jsm +1 -0
- data/vendor/tracemonkey/xpconnect/tests/unit/test_bogus_files.js +88 -0
- data/vendor/tracemonkey/xpconnect/tests/unit/test_bug408412.js +51 -0
- data/vendor/tracemonkey/xpconnect/tests/unit/test_bug451678.js +52 -0
- data/vendor/tracemonkey/xpconnect/tests/unit/test_bug_442086.js +68 -0
- data/vendor/tracemonkey/xpconnect/tests/unit/test_import.js +127 -0
- data/vendor/tracemonkey/xpconnect/tests/unit/test_js_weak_references.js +63 -0
- data/vendor/tracemonkey/xpconnect/tests/unit/test_recursive_import.js +62 -0
- data/vendor/tracemonkey/xpconnect/tools/Makefile.in +49 -0
- data/vendor/tracemonkey/xpconnect/tools/idl/Makefile.in +53 -0
- data/vendor/tracemonkey/xpconnect/tools/idl/nsIXPCToolsCompiler.idl +60 -0
- data/vendor/tracemonkey/xpconnect/tools/idl/nsIXPCToolsProfiler.idl +57 -0
- data/vendor/tracemonkey/xpconnect/tools/js/CompileJSFiles.js +28 -0
- data/vendor/tracemonkey/xpconnect/tools/js/ListJSFiles.js +18 -0
- data/vendor/tracemonkey/xpconnect/tools/src/Makefile.in +76 -0
- data/vendor/tracemonkey/xpconnect/tools/src/nsXPCToolsCompiler.cpp +161 -0
- data/vendor/tracemonkey/xpconnect/tools/src/nsXPCToolsModule.cpp +65 -0
- data/vendor/tracemonkey/xpconnect/tools/src/nsXPCToolsProfiler.cpp +370 -0
- data/vendor/tracemonkey/xpconnect/tools/src/xpctools_private.h +236 -0
- metadata +782 -107
- data/test/johnson/nodes/export_test.rb +0 -9
- data/test/johnson/nodes/import_test.rb +0 -13
- 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, ®Map);
|
|
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
|
+
|