V4: Difference between revisions

From Qt Wiki
Jump to navigation Jump to search
No edit summary
 
(7 intermediate revisions by 4 users not shown)
Line 1: Line 1:
{{Cleanup | reason=Auto-imported from ExpressionEngine.}}
== V4 Javascript Engine ==
== V4 Javascript Engine ==
[http://qt.io/groups/qt-contributors-summit-2013/wiki/QML-engine Why it was created?]
[http://wiki.qt.io/Qt-contributors-summit-2013-QML-engine Why it was created?]


=== Environment Variables ===
=== Environment Variables ===
Line 8: Line 6:
You need to set specific environment variables to debug this engine. In this wiki only few of them are described. To get full list of them you can try to open '''qtdeclarative.pro''' and search for text '''"QV4_'''.
You need to set specific environment variables to debug this engine. In this wiki only few of them are described. To get full list of them you can try to open '''qtdeclarative.pro''' and search for text '''"QV4_'''.


* '''QV4_SHOW_IR''' - prints intermediate representation of code. It's rather long output because many optimisation techniques are applied.
* '''QV4_SHOW_IR''' - prints intermediate representation of code. It's rather long output because the IR is printed after each of the many optimization passes. Make sure to enable the corresponding debug area, too. (TODO which one is it? I just changed qDebug() to qWarning() in showMeTheCode(IR::Function *function, const char *marker) ...)
* '''QV4_SHOW_ASM''' prints dissassembly output. If it prints message ''disassembly not available for range'' additional macros will have to be added which currently requires significant effort; so start your hacking from qtdeclarative/src/3rdparty/masm/disassembler/Disassembler.cpp
* '''QV4_SHOW_ASM''' prints dissassembly output. If it prints message ''disassembly not available for range,'' you need to recompile qtdeclarative with CONFIG+=disassembler.
* '''QV4_FORCE_INTERPRETER''' - disables just-in-time compilation. This usually significantly degrades performance and therefore only should be used for debugging purposes.
* '''QV4_FORCE_INTERPRETER''' - disables just-in-time compilation. This usually significantly degrades performance and therefore only should be used for debugging purposes.


=== Platforms without JIT ===
=== Platforms without JIT ===


Having JIT enabled is important to get fluent animations in QML. Still there are platforms that don't support just-in-time compilation for QML. In the better case this simply is because nobody came around to implement this feature for the platform yet. Trouble only occurs if the platform itself restricts usage of JIT, be it App Store policies as for iOS, be it missing sandbox API as for Windows RT.
Having JIT enabled is important to get fluid animations in QML. Still there are platforms that don't support just-in-time compilation for QML. In the better case this simply is because nobody came around to implement this feature for the platform yet. Trouble only occurs if the platform itself restricts usage of JIT, be it App Store policies as for iOS, be it missing sandbox API as for Windows RT.


So what can you do, if it turns out, that JIT is not enabled for your platform?
So what can you do, if it turns out, that JIT is not enabled for your platform?
Line 38: Line 36:
It's reasonable to verify new features by running the EcmaScript 262 test suite.
It's reasonable to verify new features by running the EcmaScript 262 test suite.


# Check out the test suite submodule repository:
* Check out the test suite submodule repository:
 
  git submodule update --init tests/auto/qml/ecmascripttests/test262
 
or


   git submodule update --init --checkout tests/manual/v4/test262
   git submodule update --init --checkout tests/manual/v4/test262


# Run the wrapper script in the tests/manual/v4 sub-directory:
if you're on a Qt version before 5.9
 
* Run the tests via the qmake target in the directory above test262:
 
    qmake
    make check  # Runs with the JIT or interpreter, depending on platform
    make check-interpreter  # Force a run with the interpreter
 
==== qjstest ====
 
If you're using Qt 5.12 or later, then after running make in the auto-test
directory you should find a qjstest program in your bin directory. That can
be used during development to run for example sub-sets of the tests like so:
 
    cd tests/auto/qml/ecmascripttests
    qjstest --with-test-expectations --parallel language/expressions
 
This would run only the tests that related to expressions, run them in parallel on
all cores and compare the results against the expected failures recorded in the
TestExpectations file.
 
You can also run an individual test like so:
 
    qjstest language/function-code/block-decl-strict.js
 
If you want to debug a test case, it's advisable to fetch the test together with the harness:
 
    qjstest --cat language/function-code/block-decl-strict.js > /tmp/test.js
 
The resulting file is self-contained and can be run with qmljs.
 
If you are trying to run any of the module tests this way, then you need to make sure instruct
qmljs to load the file as a module:
 
    qjstest --cat language/module-code/parse-export-empty.js > /tmp/test.mjs
    qmljs --module /tmp/test.mjs


    python ./test262.py
If the module test case imports other files (typically with a fixture infix), then you need to
copy those files out of the test262 directory manually and adjust the import statements in test.mjs
accordingly.

Latest revision as of 12:30, 7 September 2018

V4 Javascript Engine

Why it was created?

Environment Variables

You need to set specific environment variables to debug this engine. In this wiki only few of them are described. To get full list of them you can try to open qtdeclarative.pro and search for text "QV4_.

  • QV4_SHOW_IR - prints intermediate representation of code. It's rather long output because the IR is printed after each of the many optimization passes. Make sure to enable the corresponding debug area, too. (TODO which one is it? I just changed qDebug() to qWarning() in showMeTheCode(IR::Function *function, const char *marker) ...)
  • QV4_SHOW_ASM prints dissassembly output. If it prints message disassembly not available for range, you need to recompile qtdeclarative with CONFIG+=disassembler.
  • QV4_FORCE_INTERPRETER - disables just-in-time compilation. This usually significantly degrades performance and therefore only should be used for debugging purposes.

Platforms without JIT

Having JIT enabled is important to get fluid animations in QML. Still there are platforms that don't support just-in-time compilation for QML. In the better case this simply is because nobody came around to implement this feature for the platform yet. Trouble only occurs if the platform itself restricts usage of JIT, be it App Store policies as for iOS, be it missing sandbox API as for Windows RT.

So what can you do, if it turns out, that JIT is not enabled for your platform?

In-house application for iOS

Easy: Open src/qml/jsruntime/qv4global_p.h, search for references to the Q_OS_IOS macro, and remove the one that explicitly disables JIT support by undefining V4_ENABLE_JIT. Just make sure to comply with all legal requirements when doing so (Apple Enterprise Developer account, proper Qt license,...).

iOS App Store, Windows RT

On this platforms your only hope is to use ahead-of-time compilation (AOT). The QML compiler that's part of Qt Commerical should help you there.

Bad compiler switches, missing platform support

If nothing above applies search src/qml/jsruntime/qv4global_p.h for instances of V4_ENABLE_JIT to understand why JIT is disabled for your platform. With some luck it turns out you are use bad compiler flags. GCC on ARM for instance must support Thumb instructions to make JIT work; check documentation for -mthumb, and -mthunmb-interwork to learn more. In other cases your target CPU simply might not be supported yet. You'll figure out and easily find someone who can remove this limitation.

Hacking

TODO: maybe explain main purprose of some subprojects (where parsing, where optimisations, where jitter is executed..)

Running the EcmaScript 262 Test suite

It's reasonable to verify new features by running the EcmaScript 262 test suite.

  • Check out the test suite submodule repository:
 git submodule update --init tests/auto/qml/ecmascripttests/test262

or

 git submodule update --init --checkout tests/manual/v4/test262

if you're on a Qt version before 5.9

  • Run the tests via the qmake target in the directory above test262:
   qmake
   make check  # Runs with the JIT or interpreter, depending on platform
   make check-interpreter  # Force a run with the interpreter

qjstest

If you're using Qt 5.12 or later, then after running make in the auto-test directory you should find a qjstest program in your bin directory. That can be used during development to run for example sub-sets of the tests like so:

   cd tests/auto/qml/ecmascripttests
   qjstest --with-test-expectations --parallel language/expressions

This would run only the tests that related to expressions, run them in parallel on all cores and compare the results against the expected failures recorded in the TestExpectations file.

You can also run an individual test like so:

   qjstest language/function-code/block-decl-strict.js

If you want to debug a test case, it's advisable to fetch the test together with the harness:

   qjstest --cat language/function-code/block-decl-strict.js > /tmp/test.js

The resulting file is self-contained and can be run with qmljs.

If you are trying to run any of the module tests this way, then you need to make sure instruct qmljs to load the file as a module:

   qjstest --cat language/module-code/parse-export-empty.js > /tmp/test.mjs
   qmljs --module /tmp/test.mjs

If the module test case imports other files (typically with a fixture infix), then you need to copy those files out of the test262 directory manually and adjust the import statements in test.mjs accordingly.