Warning, /graphics/krita/3rdparty/ext_qt/0134-V4-Generate-function-tables-on-64bit-windows.patch is written in an unsupported language. File is not indexed.

0001 From 67bb77d22b7a5a3452b2c36da8ec2154d24489e6 Mon Sep 17 00:00:00 2001
0002 From: Ulf Hermann <ulf.hermann@qt.io>
0003 Date: Thu, 8 Nov 2018 18:09:21 +0100
0004 Subject: [PATCH 134/139] V4: Generate function tables on 64bit windows
0005 
0006 In order for global exception handlers to be called reliably, the runtime
0007 needs to unwind through JIT-generated code. This can be facilitated by
0008 installing a "function table" for each JITed function that specifies "use
0009 the frame pointer".
0010 
0011 Also make sure to generate a function table for JIT'ed regular
0012 expressions. Those were forgotten also in the linux case.
0013 
0014 Fixes: QTBUG-50061
0015 Change-Id: Ib0b8ae9356ed80afe1cab017e36efa4ccbe73f90
0016 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
0017 (cherry picked from commit 74d23ca548b47c85c4b8cdde5fd5a9026e4eb08c)
0018 Signed-off-by: L. E. Segovia <amy@amyspark.me>
0019 ---
0020  .../QtQml/private/qv4functiontable_p.h        |   1 +
0021  include/QtQml/headers.pri                     |   2 +-
0022  src/3rdparty/masm/assembler/LinkBuffer.h      |  13 ++
0023  src/3rdparty/masm/stubs/ExecutableAllocator.h |   1 +
0024  src/3rdparty/masm/yarr/YarrJIT.cpp            |  40 ++++-
0025  src/3rdparty/masm/yarr/YarrJIT.h              |  25 ++-
0026  src/qml/jit/qv4assemblercommon.cpp            |  44 +----
0027  src/qml/jsruntime/jsruntime.pri               |  18 +++
0028  src/qml/jsruntime/qv4executableallocator.cpp  |  10 +-
0029  src/qml/jsruntime/qv4executableallocator_p.h  |   1 +
0030  src/qml/jsruntime/qv4function.cpp             |  17 +-
0031  src/qml/jsruntime/qv4function_p.h             |   5 +-
0032  src/qml/jsruntime/qv4functiontable_noop.cpp   |  65 ++++++++
0033  src/qml/jsruntime/qv4functiontable_p.h        |  75 +++++++++
0034  src/qml/jsruntime/qv4functiontable_unix.cpp   |  99 ++++++++++++
0035  src/qml/jsruntime/qv4functiontable_win64.cpp  | 153 ++++++++++++++++++
0036  tests/auto/qml/qv4assembler/data/crash.qml    |  53 ++++++
0037  tests/auto/qml/qv4assembler/qv4assembler.pro  |   5 +
0038  .../qml/qv4assembler/tst_qv4assembler.cpp     |  55 ++++++-
0039  19 files changed, 623 insertions(+), 59 deletions(-)
0040  create mode 100644 include/QtQml/5.12.12/QtQml/private/qv4functiontable_p.h
0041  create mode 100644 src/qml/jsruntime/qv4functiontable_noop.cpp
0042  create mode 100644 src/qml/jsruntime/qv4functiontable_p.h
0043  create mode 100644 src/qml/jsruntime/qv4functiontable_unix.cpp
0044  create mode 100644 src/qml/jsruntime/qv4functiontable_win64.cpp
0045  create mode 100644 tests/auto/qml/qv4assembler/data/crash.qml
0046 
0047 diff --git a/include/QtQml/5.12.12/QtQml/private/qv4functiontable_p.h b/include/QtQml/5.12.12/QtQml/private/qv4functiontable_p.h
0048 new file mode 100644
0049 index 00000000..55a639eb
0050 --- /dev/null
0051 +++ b/include/QtQml/5.12.12/QtQml/private/qv4functiontable_p.h
0052 @@ -0,0 +1 @@
0053 +#include "../../../../../src/qml/jsruntime/qv4functiontable_p.h"
0054 diff --git a/include/QtQml/headers.pri b/include/QtQml/headers.pri
0055 index 08811981..634a8a24 100644
0056 --- a/include/QtQml/headers.pri
0057 +++ b/include/QtQml/headers.pri
0058 @@ -1,6 +1,6 @@
0059  SYNCQT.HEADER_FILES = qtqmlglobal.h debugger/qqmldebug.h jsapi/qjsengine.h jsapi/qjsvalue.h jsapi/qjsvalueiterator.h qml/qqml.h qml/qqmlabstracturlinterceptor.h qml/qqmlapplicationengine.h qml/qqmlcomponent.h qml/qqmlcontext.h qml/qqmlengine.h qml/qqmlerror.h qml/qqmlexpression.h qml/qqmlextensioninterface.h qml/qqmlextensionplugin.h qml/qqmlfile.h qml/qqmlfileselector.h qml/qqmlincubator.h qml/qqmlinfo.h qml/qqmllist.h qml/qqmlnetworkaccessmanagerfactory.h qml/qqmlparserstatus.h qml/qqmlprivate.h qml/qqmlproperty.h qml/qqmlpropertyvaluesource.h qml/qqmlscriptstring.h util/qqmlpropertymap.h 
0060  SYNCQT.GENERATED_HEADER_FILES = QQmlDebuggingEnabler QJSEngine QJSValueList QJSValue QJSValueIterator QQmlAbstractUrlInterceptor QQmlApplicationEngine QQmlComponent QQmlContext QQmlImageProviderBase QQmlEngine QQmlError QQmlExpression QQmlTypesExtensionInterface QQmlExtensionInterface QQmlExtensionPlugin QQmlFile QQmlFileSelector QQmlIncubator QQmlIncubationController QQmlInfo QQmlListProperty QQmlListReference QQmlNetworkAccessManagerFactory QQmlParserStatus QQmlAttachedPropertiesFunc QQmlTypeInfo QQmlProperty QQmlProperties QQmlPropertyValueSource QQmlScriptString QQmlPropertyMap qtqmlversion.h QtQmlVersion QtQml 
0061 -SYNCQT.PRIVATE_HEADER_FILES = qtqmlglobal_p.h animations/qabstractanimationjob_p.h animations/qanimationgroupjob_p.h animations/qanimationjobutil_p.h animations/qcontinuinganimationgroupjob_p.h animations/qparallelanimationgroupjob_p.h animations/qpauseanimationjob_p.h animations/qsequentialanimationgroupjob_p.h compiler/qqmlirbuilder_p.h compiler/qqmlpropertycachecreator_p.h compiler/qqmlpropertyvalidator_p.h compiler/qqmltypecompiler_p.h compiler/qv4bytecodegenerator_p.h compiler/qv4bytecodehandler_p.h compiler/qv4codegen_p.h compiler/qv4compilationunitmapper_p.h compiler/qv4compileddata_p.h compiler/qv4compiler_p.h compiler/qv4compilercontext_p.h compiler/qv4compilercontrolflow_p.h compiler/qv4compilerscanfunctions_p.h compiler/qv4instr_moth_p.h debugger/qqmlabstractprofileradapter_p.h debugger/qqmlconfigurabledebugservice_p.h debugger/qqmldebugconnector_p.h debugger/qqmldebugpluginmanager_p.h debugger/qqmldebugserver_p.h debugger/qqmldebugserverconnection_p.h debugger/qqmldebugservice_p.h debugger/qqmldebugservicefactory_p.h debugger/qqmldebugserviceinterfaces_p.h debugger/qqmldebugstatesdelegate_p.h debugger/qqmlmemoryprofiler_p.h debugger/qqmlprofiler_p.h debugger/qqmlprofilerdefinitions_p.h jit/qv4assemblercommon_p.h jit/qv4baselineassembler_p.h jit/qv4baselinejit_p.h jit/qv4jithelpers_p.h jsapi/qjsengine_p.h jsapi/qjsvalue_p.h jsapi/qjsvalueiterator_p.h jsruntime/qv4alloca_p.h jsruntime/qv4argumentsobject_p.h jsruntime/qv4arraybuffer_p.h jsruntime/qv4arraydata_p.h jsruntime/qv4arrayiterator_p.h jsruntime/qv4arrayobject_p.h jsruntime/qv4atomics_p.h jsruntime/qv4booleanobject_p.h jsruntime/qv4context_p.h jsruntime/qv4dataview_p.h jsruntime/qv4dateobject_p.h jsruntime/qv4debugging_p.h jsruntime/qv4engine_p.h jsruntime/qv4enginebase_p.h jsruntime/qv4errorobject_p.h jsruntime/qv4estable_p.h jsruntime/qv4executableallocator_p.h jsruntime/qv4function_p.h jsruntime/qv4functionobject_p.h jsruntime/qv4generatorobject_p.h jsruntime/qv4global_p.h jsruntime/qv4globalobject_p.h jsruntime/qv4identifier_p.h jsruntime/qv4identifiertable_p.h jsruntime/qv4include_p.h jsruntime/qv4internalclass_p.h jsruntime/qv4iterator_p.h jsruntime/qv4jscall_p.h jsruntime/qv4jsonobject_p.h jsruntime/qv4lookup_p.h jsruntime/qv4managed_p.h jsruntime/qv4mapiterator_p.h jsruntime/qv4mapobject_p.h jsruntime/qv4math_p.h jsruntime/qv4mathobject_p.h jsruntime/qv4memberdata_p.h jsruntime/qv4module_p.h jsruntime/qv4numberobject_p.h jsruntime/qv4object_p.h jsruntime/qv4objectiterator_p.h jsruntime/qv4objectproto_p.h jsruntime/qv4persistent_p.h jsruntime/qv4profiling_p.h jsruntime/qv4promiseobject_p.h jsruntime/qv4property_p.h jsruntime/qv4propertykey_p.h jsruntime/qv4proxy_p.h jsruntime/qv4qmlcontext_p.h jsruntime/qv4qobjectwrapper_p.h jsruntime/qv4reflect_p.h jsruntime/qv4regexp_p.h jsruntime/qv4regexpobject_p.h jsruntime/qv4runtime_p.h jsruntime/qv4runtimeapi_p.h jsruntime/qv4runtimecodegen_p.h jsruntime/qv4scopedvalue_p.h jsruntime/qv4script_p.h jsruntime/qv4sequenceobject_p.h jsruntime/qv4serialize_p.h jsruntime/qv4setiterator_p.h jsruntime/qv4setobject_p.h jsruntime/qv4sparsearray_p.h jsruntime/qv4stackframe_p.h jsruntime/qv4string_p.h jsruntime/qv4stringiterator_p.h jsruntime/qv4stringobject_p.h jsruntime/qv4symbol_p.h jsruntime/qv4typedarray_p.h jsruntime/qv4util_p.h jsruntime/qv4value_p.h jsruntime/qv4variantobject_p.h jsruntime/qv4vme_moth_p.h jsruntime/qv4vtable_p.h memory/qv4heap_p.h memory/qv4mm_p.h memory/qv4mmdefs_p.h memory/qv4writebarrier_p.h parser/qqmljsast_p.h parser/qqmljsastfwd_p.h parser/qqmljsastvisitor_p.h parser/qqmljsengine_p.h parser/qqmljsglobal_p.h parser/qqmljskeywords_p.h parser/qqmljslexer_p.h parser/qqmljsmemorypool_p.h qml/qqmlabstractbinding_p.h qml/qqmlapplicationengine_p.h qml/qqmlbinding_p.h qml/qqmlboundsignal_p.h qml/qqmlboundsignalexpressionpointer_p.h qml/qqmlcleanup_p.h qml/qqmlcomponent_p.h qml/qqmlcomponentattached_p.h qml/qqmlcontext_p.h qml/qqmlcustomparser_p.h qml/qqmldata_p.h qml/qqmldelayedcallqueue_p.h qml/qqmldirparser_p.h qml/qqmlengine_p.h qml/qqmlexpression_p.h qml/qqmlextensionplugin_p.h qml/qqmlfileselector_p.h qml/qqmlglobal_p.h qml/qqmlguard_p.h qml/qqmlimport_p.h qml/qqmlincubator_p.h qml/qqmljavascriptexpression_p.h qml/qqmllist_p.h qml/qqmllistwrapper_p.h qml/qqmllocale_p.h qml/qqmlloggingcategory_p.h qml/qqmlmetatype_p.h qml/qqmlnotifier_p.h qml/qqmlobjectcreator_p.h qml/qqmlopenmetaobject_p.h qml/qqmlplatform_p.h qml/qqmlproperty_p.h qml/qqmlpropertycache_p.h qml/qqmlpropertyindex_p.h qml/qqmlpropertyvalueinterceptor_p.h qml/qqmlproxymetaobject_p.h qml/qqmlscriptstring_p.h qml/qqmlstringconverters_p.h qml/qqmltypeloader_p.h qml/qqmltypenamecache_p.h qml/qqmltypenotavailable_p.h qml/qqmltypewrapper_p.h qml/qqmlvaluetype_p.h qml/qqmlvaluetypeproxybinding_p.h qml/qqmlvaluetypewrapper_p.h qml/qqmlvme_p.h qml/qqmlvmemetaobject_p.h qml/qqmlxmlhttprequest_p.h types/qqmlbind_p.h types/qqmlconnections_p.h types/qqmldelegatecomponent_p.h types/qqmldelegatemodel_p.h types/qqmldelegatemodel_p_p.h types/qqmlinstantiator_p.h types/qqmlinstantiator_p_p.h types/qqmllistmodel_p.h types/qqmllistmodel_p_p.h types/qqmllistmodelworkeragent_p.h types/qqmlmodelindexvaluetype_p.h types/qqmlmodelsmodule_p.h types/qqmlobjectmodel_p.h types/qqmltableinstancemodel_p.h types/qqmltimer_p.h types/qquickpackage_p.h types/qquickworkerscript_p.h util/qqmladaptormodel_p.h util/qqmlchangeset_p.h util/qqmllistaccessor_p.h util/qqmllistcompositor_p.h qml/ftw/qbitfield_p.h qml/ftw/qfieldlist_p.h qml/ftw/qfinitestack_p.h qml/ftw/qflagpointer_p.h qml/ftw/qhashedstring_p.h qml/ftw/qintrusivelist_p.h qml/ftw/qlazilyallocated_p.h qml/ftw/qpodvector_p.h qml/ftw/qqmlnullablevalue_p.h qml/ftw/qqmlrefcount_p.h qml/ftw/qqmlthread_p.h qml/ftw/qrecursionwatcher_p.h qml/ftw/qrecyclepool_p.h qml/v8/qqmlbuiltinfunctions_p.h qml/v8/qv4domerrors_p.h qml/v8/qv4sqlerrors_p.h qml/v8/qv8engine_p.h 
0062 +SYNCQT.PRIVATE_HEADER_FILES = qtqmlglobal_p.h animations/qabstractanimationjob_p.h animations/qanimationgroupjob_p.h animations/qanimationjobutil_p.h animations/qcontinuinganimationgroupjob_p.h animations/qparallelanimationgroupjob_p.h animations/qpauseanimationjob_p.h animations/qsequentialanimationgroupjob_p.h compiler/qqmlirbuilder_p.h compiler/qqmlpropertycachecreator_p.h compiler/qqmlpropertyvalidator_p.h compiler/qqmltypecompiler_p.h compiler/qv4bytecodegenerator_p.h compiler/qv4bytecodehandler_p.h compiler/qv4codegen_p.h compiler/qv4compilationunitmapper_p.h compiler/qv4compileddata_p.h compiler/qv4compiler_p.h compiler/qv4compilercontext_p.h compiler/qv4compilercontrolflow_p.h compiler/qv4compilerscanfunctions_p.h compiler/qv4instr_moth_p.h debugger/qqmlabstractprofileradapter_p.h debugger/qqmlconfigurabledebugservice_p.h debugger/qqmldebugconnector_p.h debugger/qqmldebugpluginmanager_p.h debugger/qqmldebugserver_p.h debugger/qqmldebugserverconnection_p.h debugger/qqmldebugservice_p.h debugger/qqmldebugservicefactory_p.h debugger/qqmldebugserviceinterfaces_p.h debugger/qqmldebugstatesdelegate_p.h debugger/qqmlmemoryprofiler_p.h debugger/qqmlprofiler_p.h debugger/qqmlprofilerdefinitions_p.h jit/qv4assemblercommon_p.h jit/qv4baselineassembler_p.h jit/qv4baselinejit_p.h jit/qv4jithelpers_p.h jsapi/qjsengine_p.h jsapi/qjsvalue_p.h jsapi/qjsvalueiterator_p.h jsruntime/qv4alloca_p.h jsruntime/qv4argumentsobject_p.h jsruntime/qv4arraybuffer_p.h jsruntime/qv4arraydata_p.h jsruntime/qv4arrayiterator_p.h jsruntime/qv4arrayobject_p.h jsruntime/qv4atomics_p.h jsruntime/qv4booleanobject_p.h jsruntime/qv4context_p.h jsruntime/qv4dataview_p.h jsruntime/qv4dateobject_p.h jsruntime/qv4debugging_p.h jsruntime/qv4engine_p.h jsruntime/qv4enginebase_p.h jsruntime/qv4errorobject_p.h jsruntime/qv4estable_p.h jsruntime/qv4executableallocator_p.h jsruntime/qv4function_p.h jsruntime/qv4functionobject_p.h jsruntime/qv4functiontable_p.h jsruntime/qv4generatorobject_p.h jsruntime/qv4global_p.h jsruntime/qv4globalobject_p.h jsruntime/qv4identifier_p.h jsruntime/qv4identifiertable_p.h jsruntime/qv4include_p.h jsruntime/qv4internalclass_p.h jsruntime/qv4iterator_p.h jsruntime/qv4jscall_p.h jsruntime/qv4jsonobject_p.h jsruntime/qv4lookup_p.h jsruntime/qv4managed_p.h jsruntime/qv4mapiterator_p.h jsruntime/qv4mapobject_p.h jsruntime/qv4math_p.h jsruntime/qv4mathobject_p.h jsruntime/qv4memberdata_p.h jsruntime/qv4module_p.h jsruntime/qv4numberobject_p.h jsruntime/qv4object_p.h jsruntime/qv4objectiterator_p.h jsruntime/qv4objectproto_p.h jsruntime/qv4persistent_p.h jsruntime/qv4profiling_p.h jsruntime/qv4promiseobject_p.h jsruntime/qv4property_p.h jsruntime/qv4propertykey_p.h jsruntime/qv4proxy_p.h jsruntime/qv4qmlcontext_p.h jsruntime/qv4qobjectwrapper_p.h jsruntime/qv4reflect_p.h jsruntime/qv4regexp_p.h jsruntime/qv4regexpobject_p.h jsruntime/qv4runtime_p.h jsruntime/qv4runtimeapi_p.h jsruntime/qv4runtimecodegen_p.h jsruntime/qv4scopedvalue_p.h jsruntime/qv4script_p.h jsruntime/qv4sequenceobject_p.h jsruntime/qv4serialize_p.h jsruntime/qv4setiterator_p.h jsruntime/qv4setobject_p.h jsruntime/qv4sparsearray_p.h jsruntime/qv4stackframe_p.h jsruntime/qv4string_p.h jsruntime/qv4stringiterator_p.h jsruntime/qv4stringobject_p.h jsruntime/qv4symbol_p.h jsruntime/qv4typedarray_p.h jsruntime/qv4util_p.h jsruntime/qv4value_p.h jsruntime/qv4variantobject_p.h jsruntime/qv4vme_moth_p.h jsruntime/qv4vtable_p.h memory/qv4heap_p.h memory/qv4mm_p.h memory/qv4mmdefs_p.h memory/qv4writebarrier_p.h parser/qqmljsast_p.h parser/qqmljsastfwd_p.h parser/qqmljsastvisitor_p.h parser/qqmljsengine_p.h parser/qqmljsglobal_p.h parser/qqmljskeywords_p.h parser/qqmljslexer_p.h parser/qqmljsmemorypool_p.h qml/qqmlabstractbinding_p.h qml/qqmlapplicationengine_p.h qml/qqmlbinding_p.h qml/qqmlboundsignal_p.h qml/qqmlboundsignalexpressionpointer_p.h qml/qqmlcleanup_p.h qml/qqmlcomponent_p.h qml/qqmlcomponentattached_p.h qml/qqmlcontext_p.h qml/qqmlcustomparser_p.h qml/qqmldata_p.h qml/qqmldelayedcallqueue_p.h qml/qqmldirparser_p.h qml/qqmlengine_p.h qml/qqmlexpression_p.h qml/qqmlextensionplugin_p.h qml/qqmlfileselector_p.h qml/qqmlglobal_p.h qml/qqmlguard_p.h qml/qqmlimport_p.h qml/qqmlincubator_p.h qml/qqmljavascriptexpression_p.h qml/qqmllist_p.h qml/qqmllistwrapper_p.h qml/qqmllocale_p.h qml/qqmlloggingcategory_p.h qml/qqmlmetatype_p.h qml/qqmlnotifier_p.h qml/qqmlobjectcreator_p.h qml/qqmlopenmetaobject_p.h qml/qqmlplatform_p.h qml/qqmlproperty_p.h qml/qqmlpropertycache_p.h qml/qqmlpropertyindex_p.h qml/qqmlpropertyvalueinterceptor_p.h qml/qqmlproxymetaobject_p.h qml/qqmlscriptstring_p.h qml/qqmlstringconverters_p.h qml/qqmltypeloader_p.h qml/qqmltypenamecache_p.h qml/qqmltypenotavailable_p.h qml/qqmltypewrapper_p.h qml/qqmlvaluetype_p.h qml/qqmlvaluetypeproxybinding_p.h qml/qqmlvaluetypewrapper_p.h qml/qqmlvme_p.h qml/qqmlvmemetaobject_p.h qml/qqmlxmlhttprequest_p.h types/qqmlbind_p.h types/qqmlconnections_p.h types/qqmldelegatecomponent_p.h types/qqmldelegatemodel_p.h types/qqmldelegatemodel_p_p.h types/qqmlinstantiator_p.h types/qqmlinstantiator_p_p.h types/qqmllistmodel_p.h types/qqmllistmodel_p_p.h types/qqmllistmodelworkeragent_p.h types/qqmlmodelindexvaluetype_p.h types/qqmlmodelsmodule_p.h types/qqmlobjectmodel_p.h types/qqmltableinstancemodel_p.h types/qqmltimer_p.h types/qquickpackage_p.h types/qquickworkerscript_p.h util/qqmladaptormodel_p.h util/qqmlchangeset_p.h util/qqmllistaccessor_p.h util/qqmllistcompositor_p.h qml/ftw/qbitfield_p.h qml/ftw/qfieldlist_p.h qml/ftw/qfinitestack_p.h qml/ftw/qflagpointer_p.h qml/ftw/qhashedstring_p.h qml/ftw/qintrusivelist_p.h qml/ftw/qlazilyallocated_p.h qml/ftw/qpodvector_p.h qml/ftw/qqmlnullablevalue_p.h qml/ftw/qqmlrefcount_p.h qml/ftw/qqmlthread_p.h qml/ftw/qrecursionwatcher_p.h qml/ftw/qrecyclepool_p.h qml/v8/qqmlbuiltinfunctions_p.h qml/v8/qv4domerrors_p.h qml/v8/qv4sqlerrors_p.h qml/v8/qv8engine_p.h 
0063  SYNCQT.QPA_HEADER_FILES = 
0064  SYNCQT.CLEAN_HEADER_FILES = qtqmlglobal.h debugger/qqmldebug.h jsapi/qjsengine.h jsapi/qjsvalue.h jsapi/qjsvalueiterator.h qml/qqml.h qml/qqmlabstracturlinterceptor.h qml/qqmlapplicationengine.h qml/qqmlcomponent.h qml/qqmlcontext.h qml/qqmlengine.h qml/qqmlerror.h qml/qqmlexpression.h qml/qqmlextensioninterface.h qml/qqmlextensionplugin.h qml/qqmlfile.h qml/qqmlfileselector.h qml/qqmlincubator.h qml/qqmlinfo.h qml/qqmllist.h qml/qqmlnetworkaccessmanagerfactory.h qml/qqmlparserstatus.h qml/qqmlprivate.h qml/qqmlproperty.h qml/qqmlpropertyvaluesource.h qml/qqmlscriptstring.h util/qqmlpropertymap.h 
0065  SYNCQT.INJECTIONS = src/qml/qqmljsgrammar_p.h:^5.12.12/QtQml/private/qqmljsgrammar_p.h src/qml/qqmljsparser_p.h:^5.12.12/QtQml/private/qqmljsparser_p.h 
0066 diff --git a/src/3rdparty/masm/assembler/LinkBuffer.h b/src/3rdparty/masm/assembler/LinkBuffer.h
0067 index 7f997930..a1bb046d 100644
0068 --- a/src/3rdparty/masm/assembler/LinkBuffer.h
0069 +++ b/src/3rdparty/masm/assembler/LinkBuffer.h
0070 @@ -228,6 +228,8 @@ public:
0071          return m_size;
0072      }
0073  
0074 +    inline void makeExecutable();
0075 +
0076  private:
0077      template <typename T> T applyOffset(T src)
0078      {
0079 @@ -353,6 +355,11 @@ void LinkBufferBase<MacroAssembler, ExecutableOffsetCalculator>::performFinaliza
0080  
0081      ASSERT(m_size <= INT_MAX);
0082      MacroAssembler::cacheFlush(code(), m_size);
0083 +}
0084 +
0085 +template <typename MacroAssembler, template <typename T> class ExecutableOffsetCalculator>
0086 +inline void LinkBufferBase<MacroAssembler, ExecutableOffsetCalculator>::makeExecutable()
0087 +{
0088      ExecutableAllocator::makeExecutable(code(), static_cast<int>(m_size));
0089  }
0090  
0091 @@ -389,6 +396,7 @@ public:
0092      }
0093  
0094      virtual void performFinalization() override final;
0095 +    inline void makeExecutable();
0096  
0097      inline void linkCode(void* ownerUID, JITCompilationEffort);
0098  
0099 @@ -421,6 +429,11 @@ void BranchCompactingLinkBuffer<MacroAssembler>::performFinalization()
0100  #endif
0101  
0102      MacroAssembler::cacheFlush(code(), m_size);
0103 +}
0104 +
0105 +template <typename MacroAssembler>
0106 +inline void BranchCompactingLinkBuffer<MacroAssembler>::makeExecutable()
0107 +{
0108      ExecutableAllocator::makeExecutable(code(), m_initialSize);
0109  }
0110  
0111 diff --git a/src/3rdparty/masm/stubs/ExecutableAllocator.h b/src/3rdparty/masm/stubs/ExecutableAllocator.h
0112 index 156b24b4..a439c538 100644
0113 --- a/src/3rdparty/masm/stubs/ExecutableAllocator.h
0114 +++ b/src/3rdparty/masm/stubs/ExecutableAllocator.h
0115 @@ -82,6 +82,7 @@ struct ExecutableMemoryHandle : public RefCounted<ExecutableMemoryHandle> {
0116  
0117      inline bool isManaged() const { return true; }
0118  
0119 +    void *exceptionHandler() { return m_allocation->exceptionHandler(); }
0120      void *start() { return m_allocation->start(); }
0121      size_t sizeInBytes() { return m_size; }
0122  
0123 diff --git a/src/3rdparty/masm/yarr/YarrJIT.cpp b/src/3rdparty/masm/yarr/YarrJIT.cpp
0124 index dee2ade4..98e4ade5 100644
0125 --- a/src/3rdparty/masm/yarr/YarrJIT.cpp
0126 +++ b/src/3rdparty/masm/yarr/YarrJIT.cpp
0127 @@ -33,6 +33,8 @@
0128  #include "Yarr.h"
0129  #include "YarrCanonicalize.h"
0130  
0131 +#include <private/qv4functiontable_p.h>
0132 +
0133  #if ENABLE(YARR_JIT)
0134  
0135  using namespace WTF;
0136 @@ -3529,17 +3531,30 @@ public:
0137  
0138          m_backtrackingState.linkDataLabels(linkBuffer);
0139  
0140 +        CodeRef codeRef;
0141          if (compileMode == MatchOnly) {
0142 -            if (m_charSize == Char8)
0143 -                codeBlock.set8BitCodeMatchOnly(FINALIZE_CODE(linkBuffer, "YarrJIT", "Match-only 8-bit regular expression"));
0144 -            else
0145 -                codeBlock.set16BitCodeMatchOnly(FINALIZE_CODE(linkBuffer, "YarrJIT", "Match-only 16-bit regular expression"));
0146 +            if (m_charSize == Char8) {
0147 +                codeRef = FINALIZE_CODE(linkBuffer, "YarJIT",
0148 +                                        "Match-only 8-bit regular expression");
0149 +                codeBlock.set8BitCodeMatchOnly(codeRef);
0150 +            } else {
0151 +                codeRef = FINALIZE_CODE(linkBuffer, "YarJIT",
0152 +                                        "Match-only 16-bit regular expression");
0153 +                codeBlock.set16BitCodeMatchOnly(codeRef);
0154 +            }
0155          } else {
0156 -            if (m_charSize == Char8)
0157 -                codeBlock.set8BitCode(FINALIZE_CODE(linkBuffer, "YarrJIT", "8-bit regular expression"));
0158 -            else
0159 -                codeBlock.set16BitCode(FINALIZE_CODE(linkBuffer, "YarrJIT", "16-bit regular expression"));
0160 +            if (m_charSize == Char8) {
0161 +                codeRef = FINALIZE_CODE(linkBuffer, "YarJIT", "8-bit regular expression");
0162 +                codeBlock.set8BitCode(codeRef);
0163 +            } else {
0164 +                codeRef = FINALIZE_CODE(linkBuffer, "YarJIT", "16-bit regular expression");
0165 +                codeBlock.set16BitCode(codeRef);
0166 +            }
0167          }
0168 +        QV4::generateFunctionTable(nullptr, &codeRef);
0169 +
0170 +        linkBuffer.makeExecutable();
0171 +
0172          if (m_failureReason)
0173              codeBlock.setFallBackWithFailureReason(*m_failureReason);
0174      }
0175 @@ -3587,6 +3602,15 @@ private:
0176      BacktrackingState m_backtrackingState;
0177  };
0178  
0179 +void YarrCodeBlock::replaceCodeRef(MacroAssemblerCodeRef &target,
0180 +                                   const MacroAssemblerCodeRef &source)
0181 +{
0182 +    if (!!target && target.code().executableAddress() != source.code().executableAddress())
0183 +        QV4::destroyFunctionTable(nullptr, &target);
0184 +
0185 +    target = source;
0186 +}
0187 +
0188  static void dumpCompileFailure(JITFailureReason failure)
0189  {
0190      switch (failure) {
0191 diff --git a/src/3rdparty/masm/yarr/YarrJIT.h b/src/3rdparty/masm/yarr/YarrJIT.h
0192 index 8b6b3a75..35a0690f 100644
0193 --- a/src/3rdparty/masm/yarr/YarrJIT.h
0194 +++ b/src/3rdparty/masm/yarr/YarrJIT.h
0195 @@ -82,19 +82,28 @@ class YarrCodeBlock {
0196  
0197  public:
0198      YarrCodeBlock() = default;
0199 +    ~YarrCodeBlock() { clear(); }
0200 +
0201 +    static void replaceCodeRef(MacroAssemblerCodeRef &target, const MacroAssemblerCodeRef &source);
0202  
0203      void setFallBackWithFailureReason(JITFailureReason failureReason) { m_failureReason = failureReason; }
0204      std::optional<JITFailureReason> failureReason() { return m_failureReason; }
0205  
0206      bool has8BitCode() { return m_ref8.size(); }
0207      bool has16BitCode() { return m_ref16.size(); }
0208 -    void set8BitCode(MacroAssemblerCodeRef ref) { m_ref8 = ref; }
0209 -    void set16BitCode(MacroAssemblerCodeRef ref) { m_ref16 = ref; }
0210 +    void set8BitCode(MacroAssemblerCodeRef ref) { replaceCodeRef(m_ref8, ref); }
0211 +    void set16BitCode(MacroAssemblerCodeRef ref) { replaceCodeRef(m_ref16, ref); }
0212  
0213      bool has8BitCodeMatchOnly() { return m_matchOnly8.size(); }
0214      bool has16BitCodeMatchOnly() { return m_matchOnly16.size(); }
0215 -    void set8BitCodeMatchOnly(MacroAssemblerCodeRef matchOnly) { m_matchOnly8 = matchOnly; }
0216 -    void set16BitCodeMatchOnly(MacroAssemblerCodeRef matchOnly) { m_matchOnly16 = matchOnly; }
0217 +    void set8BitCodeMatchOnly(MacroAssemblerCodeRef matchOnly)
0218 +    {
0219 +        replaceCodeRef(m_matchOnly8, matchOnly);
0220 +    }
0221 +    void set16BitCodeMatchOnly(MacroAssemblerCodeRef matchOnly)
0222 +    {
0223 +        replaceCodeRef(m_matchOnly16, matchOnly);
0224 +    }
0225  
0226  #if ENABLE(YARR_JIT_ALL_PARENS_EXPRESSIONS)
0227      bool usesPatternContextBuffer() { return m_usesPatternContextBuffer; }
0228 @@ -190,10 +199,10 @@ public:
0229  
0230      void clear()
0231      {
0232 -        m_ref8 = MacroAssemblerCodeRef();
0233 -        m_ref16 = MacroAssemblerCodeRef();
0234 -        m_matchOnly8 = MacroAssemblerCodeRef();
0235 -        m_matchOnly16 = MacroAssemblerCodeRef();
0236 +        replaceCodeRef(m_ref8, MacroAssemblerCodeRef());
0237 +        replaceCodeRef(m_ref16, MacroAssemblerCodeRef());
0238 +        replaceCodeRef(m_matchOnly8, MacroAssemblerCodeRef());
0239 +        replaceCodeRef(m_matchOnly16, MacroAssemblerCodeRef());
0240          m_failureReason = std::nullopt;
0241      }
0242  
0243 diff --git a/src/qml/jit/qv4assemblercommon.cpp b/src/qml/jit/qv4assemblercommon.cpp
0244 index 831496a6..6dc40ad8 100644
0245 --- a/src/qml/jit/qv4assemblercommon.cpp
0246 +++ b/src/qml/jit/qv4assemblercommon.cpp
0247 @@ -43,6 +43,7 @@
0248  #include "qv4engine_p.h"
0249  #include "qv4assemblercommon_p.h"
0250  #include <private/qv4function_p.h>
0251 +#include <private/qv4functiontable_p.h>
0252  #include <private/qv4runtime_p.h>
0253  
0254  #include <assembler/MacroAssemblerCodeRef.h>
0255 @@ -112,17 +113,6 @@ static void printDisassembledOutputWithCalls(QByteArray processedOutput,
0256      qDebug("%s", processedOutput.constData());
0257  }
0258  
0259 -static QByteArray functionName(Function *function)
0260 -{
0261 -    QByteArray name = function->name()->toQString().toUtf8();
0262 -    if (name.isEmpty()) {
0263 -        name = QByteArray::number(reinterpret_cast<quintptr>(function), 16);
0264 -        name.prepend("QV4::Function(0x");
0265 -        name.append(')');
0266 -    }
0267 -    return name;
0268 -}
0269 -
0270  JIT::PlatformAssemblerCommon::~PlatformAssemblerCommon()
0271  {}
0272  
0273 @@ -147,7 +137,9 @@ void PlatformAssemblerCommon::link(Function *function, const char *jitKind)
0274          buf.open(QIODevice::WriteOnly);
0275          WTF::setDataFile(new QIODevicePrintStream(&buf));
0276  
0277 -        QByteArray name = functionName(function);
0278 +        // We use debugAddress here because it's actually for debugging and hidden behind an
0279 +        // environment variable.
0280 +        const QByteArray name = Function::prettyName(function, linkBuffer.debugAddress()).toUtf8();
0281          codeRef = linkBuffer.finalizeCodeWithDisassembly(jitKind, "function %s", name.constData());
0282  
0283          WTF::setDataFile(stderr);
0284 @@ -159,31 +151,9 @@ void PlatformAssemblerCommon::link(Function *function, const char *jitKind)
0285      function->codeRef = new JSC::MacroAssemblerCodeRef(codeRef);
0286      function->jittedCode = reinterpret_cast<Function::JittedCode>(function->codeRef->code().executableAddress());
0287  
0288 -    // This implements writing of JIT'd addresses so that perf can find the
0289 -    // symbol names.
0290 -    //
0291 -    // Perf expects the mapping to be in a certain place and have certain
0292 -    // content, for more information, see:
0293 -    // https://github.com/torvalds/linux/blob/master/tools/perf/Documentation/jit-interface.txt
0294 -    static bool doProfile = !qEnvironmentVariableIsEmpty("QV4_PROFILE_WRITE_PERF_MAP");
0295 -    if (Q_UNLIKELY(doProfile)) {
0296 -        static QFile perfMapFile(QString::fromLatin1("/tmp/perf-%1.map")
0297 -                                 .arg(QCoreApplication::applicationPid()));
0298 -        static const bool isOpen = perfMapFile.open(QIODevice::WriteOnly);
0299 -        if (!isOpen) {
0300 -            qWarning("QV4::JIT::Assembler: Cannot write perf map file.");
0301 -            doProfile = false;
0302 -        } else {
0303 -            perfMapFile.write(QByteArray::number(reinterpret_cast<quintptr>(
0304 -                                                     codeRef.code().executableAddress()), 16));
0305 -            perfMapFile.putChar(' ');
0306 -            perfMapFile.write(QByteArray::number(static_cast<qsizetype>(codeRef.size()), 16));
0307 -            perfMapFile.putChar(' ');
0308 -            perfMapFile.write(functionName(function));
0309 -            perfMapFile.putChar('\n');
0310 -            perfMapFile.flush();
0311 -        }
0312 -    }
0313 +    generateFunctionTable(function, &codeRef);
0314 +
0315 +    linkBuffer.makeExecutable();
0316  }
0317  
0318  void PlatformAssemblerCommon::prepareCallWithArgCount(int argc)
0319 diff --git a/src/qml/jsruntime/jsruntime.pri b/src/qml/jsruntime/jsruntime.pri
0320 index 5ec55b96..b0562ef8 100644
0321 --- a/src/qml/jsruntime/jsruntime.pri
0322 +++ b/src/qml/jsruntime/jsruntime.pri
0323 @@ -142,6 +142,7 @@ qtConfig(qml-sequence-object) {
0324  
0325  
0326  HEADERS += \
0327 +    $$PWD/qv4functiontable_p.h \
0328      $$PWD/qv4runtime_p.h \
0329      $$PWD/qv4runtimeapi_p.h \
0330      $$PWD/qv4value_p.h \
0331 @@ -156,6 +157,23 @@ SOURCES += \
0332      $$PWD/qv4value.cpp \
0333      $$PWD/qv4executableallocator.cpp
0334  
0335 +qmldevtools_build {
0336 +    SOURCES += \
0337 +        $$PWD/qv4functiontable_noop.cpp
0338 +} else:win32 {
0339 +    equals(QT_ARCH, x86_64){
0340 +        SOURCES += \
0341 +            $$PWD/qv4functiontable_win64.cpp
0342 +    } else {
0343 +        SOURCES += \
0344 +            $$PWD/qv4functiontable_noop.cpp
0345 +    }
0346 +} else {
0347 +    SOURCES += \
0348 +        $$PWD/qv4functiontable_unix.cpp
0349 +}
0350 +
0351 +
0352  valgrind {
0353      DEFINES += V4_USE_VALGRIND
0354  }
0355 diff --git a/src/qml/jsruntime/qv4executableallocator.cpp b/src/qml/jsruntime/qv4executableallocator.cpp
0356 index 6f04a712..c836d121 100644
0357 --- a/src/qml/jsruntime/qv4executableallocator.cpp
0358 +++ b/src/qml/jsruntime/qv4executableallocator.cpp
0359 @@ -38,17 +38,23 @@
0360  ****************************************************************************/
0361  
0362  #include "qv4executableallocator_p.h"
0363 +#include "qv4functiontable_p.h"
0364  
0365  #include <wtf/StdLibExtras.h>
0366  #include <wtf/PageAllocation.h>
0367  
0368  using namespace QV4;
0369  
0370 -void *ExecutableAllocator::Allocation::start() const
0371 +void *ExecutableAllocator::Allocation::exceptionHandler() const
0372  {
0373      return reinterpret_cast<void*>(addr);
0374  }
0375  
0376 +void *ExecutableAllocator::Allocation::start() const
0377 +{
0378 +    return reinterpret_cast<void*>(addr + exceptionHandlerSize());
0379 +}
0380 +
0381  void ExecutableAllocator::Allocation::deallocate(ExecutableAllocator *allocator)
0382  {
0383      if (isValid())
0384 @@ -162,7 +168,7 @@ ExecutableAllocator::Allocation *ExecutableAllocator::allocate(size_t size)
0385      Allocation *allocation = nullptr;
0386  
0387      // Code is best aligned to 16-byte boundaries.
0388 -    size = WTF::roundUpToMultipleOf(16, size);
0389 +    size = WTF::roundUpToMultipleOf(16, size + exceptionHandlerSize());
0390  
0391      QMultiMap<size_t, Allocation*>::Iterator it = freeAllocations.lowerBound(size);
0392      if (it != freeAllocations.end()) {
0393 diff --git a/src/qml/jsruntime/qv4executableallocator_p.h b/src/qml/jsruntime/qv4executableallocator_p.h
0394 index 375c9a36..013c6d71 100644
0395 --- a/src/qml/jsruntime/qv4executableallocator_p.h
0396 +++ b/src/qml/jsruntime/qv4executableallocator_p.h
0397 @@ -86,6 +86,7 @@ public:
0398              , free(true)
0399          {}
0400  
0401 +        void *exceptionHandler() const;
0402          void *start() const;
0403          void invalidate() { addr = 0; }
0404          bool isValid() const { return addr != 0; }
0405 diff --git a/src/qml/jsruntime/qv4function.cpp b/src/qml/jsruntime/qv4function.cpp
0406 index 51a9b929..55fca618 100644
0407 --- a/src/qml/jsruntime/qv4function.cpp
0408 +++ b/src/qml/jsruntime/qv4function.cpp
0409 @@ -46,6 +46,7 @@
0410  #include "qv4lookup_p.h"
0411  #include <private/qv4mm_p.h>
0412  #include <private/qv4identifiertable_p.h>
0413 +#include "qv4functiontable_p.h"
0414  #include <assembler/MacroAssemblerCodeRef.h>
0415  #include <private/qv4vme_moth_p.h>
0416  #include <private/qqmlglobal_p.h>
0417 @@ -97,7 +98,10 @@ Function::Function(ExecutionEngine *engine, CompiledData::CompilationUnit *unit,
0418  
0419  Function::~Function()
0420  {
0421 -    delete codeRef;
0422 +    if (codeRef) {
0423 +        destroyFunctionTable(this, codeRef);
0424 +        delete codeRef;
0425 +    }
0426  }
0427  
0428  void Function::updateInternalClass(ExecutionEngine *engine, const QList<QByteArray> &parameters)
0429 @@ -144,6 +148,17 @@ void Function::updateInternalClass(ExecutionEngine *engine, const QList<QByteArr
0430      nFormals = parameters.size();
0431  }
0432  
0433 +QString Function::prettyName(const Function *function, const void *code)
0434 +{
0435 +    QString prettyName = function ? function->name()->toQString() : QString();
0436 +    if (prettyName.isEmpty()) {
0437 +        prettyName = QString::number(reinterpret_cast<quintptr>(code), 16);
0438 +        prettyName.prepend(QLatin1String("QV4::Function(0x"));
0439 +        prettyName.append(QLatin1Char(')'));
0440 +    }
0441 +    return prettyName;
0442 +}
0443 +
0444  QQmlSourceLocation Function::sourceLocation() const
0445  {
0446      return QQmlSourceLocation(sourceFile(), compiledFunction->location.line, compiledFunction->location.column);
0447 diff --git a/src/qml/jsruntime/qv4function_p.h b/src/qml/jsruntime/qv4function_p.h
0448 index 62c5d24f..859b6a87 100644
0449 --- a/src/qml/jsruntime/qv4function_p.h
0450 +++ b/src/qml/jsruntime/qv4function_p.h
0451 @@ -88,9 +88,12 @@ struct Q_QML_EXPORT Function {
0452      // used when dynamically assigning signal handlers (QQmlConnection)
0453      void updateInternalClass(ExecutionEngine *engine, const QList<QByteArray> &parameters);
0454  
0455 -    inline Heap::String *name() {
0456 +    inline Heap::String *name() const {
0457          return compilationUnit->runtimeStrings[compiledFunction->nameIndex];
0458      }
0459 +
0460 +    static QString prettyName(const Function *function, const void *address);
0461 +
0462      inline QString sourceFile() const { return compilationUnit->fileName(); }
0463      inline QUrl finalUrl() const { return compilationUnit->finalUrl(); }
0464  
0465 diff --git a/src/qml/jsruntime/qv4functiontable_noop.cpp b/src/qml/jsruntime/qv4functiontable_noop.cpp
0466 new file mode 100644
0467 index 00000000..31c198eb
0468 --- /dev/null
0469 +++ b/src/qml/jsruntime/qv4functiontable_noop.cpp
0470 @@ -0,0 +1,65 @@
0471 +/****************************************************************************
0472 +**
0473 +** Copyright (C) 2017 The Qt Company Ltd.
0474 +** Contact: https://www.qt.io/licensing/
0475 +**
0476 +** This file is part of the QtQml module of the Qt Toolkit.
0477 +**
0478 +** $QT_BEGIN_LICENSE:LGPL$
0479 +** Commercial License Usage
0480 +** Licensees holding valid commercial Qt licenses may use this file in
0481 +** accordance with the commercial license agreement provided with the
0482 +** Software or, alternatively, in accordance with the terms contained in
0483 +** a written agreement between you and The Qt Company. For licensing terms
0484 +** and conditions see https://www.qt.io/terms-conditions. For further
0485 +** information use the contact form at https://www.qt.io/contact-us.
0486 +**
0487 +** GNU Lesser General Public License Usage
0488 +** Alternatively, this file may be used under the terms of the GNU Lesser
0489 +** General Public License version 3 as published by the Free Software
0490 +** Foundation and appearing in the file LICENSE.LGPL3 included in the
0491 +** packaging of this file. Please review the following information to
0492 +** ensure the GNU Lesser General Public License version 3 requirements
0493 +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
0494 +**
0495 +** GNU General Public License Usage
0496 +** Alternatively, this file may be used under the terms of the GNU
0497 +** General Public License version 2.0 or (at your option) the GNU General
0498 +** Public license version 3 or any later version approved by the KDE Free
0499 +** Qt Foundation. The licenses are as published by the Free Software
0500 +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
0501 +** included in the packaging of this file. Please review the following
0502 +** information to ensure the GNU General Public License requirements will
0503 +** be met: https://www.gnu.org/licenses/gpl-2.0.html and
0504 +** https://www.gnu.org/licenses/gpl-3.0.html.
0505 +**
0506 +** $QT_END_LICENSE$
0507 +**
0508 +****************************************************************************/
0509 +
0510 +#include "qv4functiontable_p.h"
0511 +
0512 +QT_BEGIN_NAMESPACE
0513 +
0514 +namespace QV4 {
0515 +
0516 +void generateFunctionTable(Function *function, JSC::MacroAssemblerCodeRef *codeRef)
0517 +{
0518 +    Q_UNUSED(function);
0519 +    Q_UNUSED(codeRef);
0520 +}
0521 +
0522 +void destroyFunctionTable(Function *function, JSC::MacroAssemblerCodeRef *codeRef)
0523 +{
0524 +    Q_UNUSED(function);
0525 +    Q_UNUSED(codeRef);
0526 +}
0527 +
0528 +size_t exceptionHandlerSize()
0529 +{
0530 +    return 0;
0531 +}
0532 +
0533 +} // QV4
0534 +
0535 +QT_END_NAMESPACE
0536 diff --git a/src/qml/jsruntime/qv4functiontable_p.h b/src/qml/jsruntime/qv4functiontable_p.h
0537 new file mode 100644
0538 index 00000000..69e3d2bd
0539 --- /dev/null
0540 +++ b/src/qml/jsruntime/qv4functiontable_p.h
0541 @@ -0,0 +1,75 @@
0542 +/****************************************************************************
0543 +**
0544 +** Copyright (C) 2018 The Qt Company Ltd.
0545 +** Contact: https://www.qt.io/licensing/
0546 +**
0547 +** This file is part of the QtQml module of the Qt Toolkit.
0548 +**
0549 +** $QT_BEGIN_LICENSE:LGPL$
0550 +** Commercial License Usage
0551 +** Licensees holding valid commercial Qt licenses may use this file in
0552 +** accordance with the commercial license agreement provided with the
0553 +** Software or, alternatively, in accordance with the terms contained in
0554 +** a written agreement between you and The Qt Company. For licensing terms
0555 +** and conditions see https://www.qt.io/terms-conditions. For further
0556 +** information use the contact form at https://www.qt.io/contact-us.
0557 +**
0558 +** GNU Lesser General Public License Usage
0559 +** Alternatively, this file may be used under the terms of the GNU Lesser
0560 +** General Public License version 3 as published by the Free Software
0561 +** Foundation and appearing in the file LICENSE.LGPL3 included in the
0562 +** packaging of this file. Please review the following information to
0563 +** ensure the GNU Lesser General Public License version 3 requirements
0564 +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
0565 +**
0566 +** GNU General Public License Usage
0567 +** Alternatively, this file may be used under the terms of the GNU
0568 +** General Public License version 2.0 or (at your option) the GNU General
0569 +** Public license version 3 or any later version approved by the KDE Free
0570 +** Qt Foundation. The licenses are as published by the Free Software
0571 +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
0572 +** included in the packaging of this file. Please review the following
0573 +** information to ensure the GNU General Public License requirements will
0574 +** be met: https://www.gnu.org/licenses/gpl-2.0.html and
0575 +** https://www.gnu.org/licenses/gpl-3.0.html.
0576 +**
0577 +** $QT_END_LICENSE$
0578 +**
0579 +****************************************************************************/
0580 +
0581 +#ifndef QV4FUNCTIONTABLE_P_H
0582 +#define QV4FUNCTIONTABLE_P_H
0583 +
0584 +//
0585 +//  W A R N I N G
0586 +//  -------------
0587 +//
0588 +// This file is not part of the Qt API.  It exists purely as an
0589 +// implementation detail.  This header file may change from version to
0590 +// version without notice, or even be removed.
0591 +//
0592 +// We mean it.
0593 +//
0594 +
0595 +#include "qv4global_p.h"
0596 +
0597 +namespace JSC {
0598 +class MacroAssemblerCodeRef;
0599 +}
0600 +
0601 +QT_BEGIN_NAMESPACE
0602 +
0603 +namespace QV4 {
0604 +
0605 +struct Function;
0606 +
0607 +void generateFunctionTable(Function *function, JSC::MacroAssemblerCodeRef *codeRef);
0608 +void destroyFunctionTable(Function *function, JSC::MacroAssemblerCodeRef *codeRef);
0609 +
0610 +size_t exceptionHandlerSize();
0611 +
0612 +}
0613 +
0614 +QT_END_NAMESPACE
0615 +
0616 +#endif // QV4FUNCTIONTABLE_P_H
0617 diff --git a/src/qml/jsruntime/qv4functiontable_unix.cpp b/src/qml/jsruntime/qv4functiontable_unix.cpp
0618 new file mode 100644
0619 index 00000000..25b5c271
0620 --- /dev/null
0621 +++ b/src/qml/jsruntime/qv4functiontable_unix.cpp
0622 @@ -0,0 +1,99 @@
0623 +/****************************************************************************
0624 +**
0625 +** Copyright (C) 2017 The Qt Company Ltd.
0626 +** Contact: https://www.qt.io/licensing/
0627 +**
0628 +** This file is part of the QtQml module of the Qt Toolkit.
0629 +**
0630 +** $QT_BEGIN_LICENSE:LGPL$
0631 +** Commercial License Usage
0632 +** Licensees holding valid commercial Qt licenses may use this file in
0633 +** accordance with the commercial license agreement provided with the
0634 +** Software or, alternatively, in accordance with the terms contained in
0635 +** a written agreement between you and The Qt Company. For licensing terms
0636 +** and conditions see https://www.qt.io/terms-conditions. For further
0637 +** information use the contact form at https://www.qt.io/contact-us.
0638 +**
0639 +** GNU Lesser General Public License Usage
0640 +** Alternatively, this file may be used under the terms of the GNU Lesser
0641 +** General Public License version 3 as published by the Free Software
0642 +** Foundation and appearing in the file LICENSE.LGPL3 included in the
0643 +** packaging of this file. Please review the following information to
0644 +** ensure the GNU Lesser General Public License version 3 requirements
0645 +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
0646 +**
0647 +** GNU General Public License Usage
0648 +** Alternatively, this file may be used under the terms of the GNU
0649 +** General Public License version 2.0 or (at your option) the GNU General
0650 +** Public license version 3 or any later version approved by the KDE Free
0651 +** Qt Foundation. The licenses are as published by the Free Software
0652 +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
0653 +** included in the packaging of this file. Please review the following
0654 +** information to ensure the GNU General Public License requirements will
0655 +** be met: https://www.gnu.org/licenses/gpl-2.0.html and
0656 +** https://www.gnu.org/licenses/gpl-3.0.html.
0657 +**
0658 +** $QT_END_LICENSE$
0659 +**
0660 +****************************************************************************/
0661 +
0662 +#include "qv4functiontable_p.h"
0663 +#include "qv4function_p.h"
0664 +
0665 +#include <assembler/MacroAssemblerCodeRef.h>
0666 +
0667 +#include <QtCore/qfile.h>
0668 +#include <QtCore/qcoreapplication.h>
0669 +
0670 +QT_BEGIN_NAMESPACE
0671 +
0672 +namespace QV4 {
0673 +
0674 +void generateFunctionTable(Function *function, JSC::MacroAssemblerCodeRef *codeRef)
0675 +{
0676 +    // This implements writing of JIT'd addresses so that perf can find the
0677 +    // symbol names.
0678 +    //
0679 +    // Perf expects the mapping to be in a certain place and have certain
0680 +    // content, for more information, see:
0681 +    // https://github.com/torvalds/linux/blob/master/tools/perf/Documentation/jit-interface.txt
0682 +    static bool doProfile = !qEnvironmentVariableIsEmpty("QV4_PROFILE_WRITE_PERF_MAP");
0683 +    if (Q_UNLIKELY(doProfile)) {
0684 +        static QFile perfMapFile(QString::fromLatin1("/tmp/perf-%1.map")
0685 +                                 .arg(QCoreApplication::applicationPid()));
0686 +        static const bool isOpen = perfMapFile.open(QIODevice::WriteOnly);
0687 +        if (!isOpen) {
0688 +            qWarning("QV4::JIT::Assembler: Cannot write perf map file.");
0689 +            doProfile = false;
0690 +        } else {
0691 +            const void *address = codeRef->code().executableAddress();
0692 +            perfMapFile.write(QByteArray::number(reinterpret_cast<quintptr>(address), 16));
0693 +            perfMapFile.putChar(' ');
0694 +            perfMapFile.write(QByteArray::number(static_cast<qsizetype>(codeRef->size()), 16));
0695 +            perfMapFile.putChar(' ');
0696 +            perfMapFile.write(Function::prettyName(function, address).toUtf8());
0697 +            perfMapFile.putChar('\n');
0698 +            perfMapFile.flush();
0699 +        }
0700 +    }
0701 +}
0702 +
0703 +void destroyFunctionTable(Function *function, JSC::MacroAssemblerCodeRef *codeRef)
0704 +{
0705 +    Q_UNUSED(function);
0706 +    Q_UNUSED(codeRef);
0707 +
0708 +    // It's not advisable to remove things from the perf map file, as it's primarily used to analyze
0709 +    // a trace after the application has terminated. We want to know about all functions that were
0710 +    // ever jitted then. If the memory ranges overlap, we will have a problem when analyzing the
0711 +    // trace. The JIT should try to avoid this.
0712 +}
0713 +
0714 +size_t exceptionHandlerSize()
0715 +{
0716 +    return 0;
0717 +}
0718 +
0719 +} // QV4
0720 +
0721 +QT_END_NAMESPACE
0722 diff --git a/src/qml/jsruntime/qv4functiontable_win64.cpp b/src/qml/jsruntime/qv4functiontable_win64.cpp
0723 new file mode 100644
0724 index 00000000..bc5b24f6
0725 --- /dev/null
0726 +++ b/src/qml/jsruntime/qv4functiontable_win64.cpp
0727 @@ -0,0 +1,153 @@
0728 +/****************************************************************************
0729 +**
0730 +** Copyright (C) 2018 The Qt Company Ltd.
0731 +** Contact: https://www.qt.io/licensing/
0732 +**
0733 +** This file is part of the QtQml module of the Qt Toolkit.
0734 +**
0735 +** $QT_BEGIN_LICENSE:LGPL$
0736 +** Commercial License Usage
0737 +** Licensees holding valid commercial Qt licenses may use this file in
0738 +** accordance with the commercial license agreement provided with the
0739 +** Software or, alternatively, in accordance with the terms contained in
0740 +** a written agreement between you and The Qt Company. For licensing terms
0741 +** and conditions see https://www.qt.io/terms-conditions. For further
0742 +** information use the contact form at https://www.qt.io/contact-us.
0743 +**
0744 +** GNU Lesser General Public License Usage
0745 +** Alternatively, this file may be used under the terms of the GNU Lesser
0746 +** General Public License version 3 as published by the Free Software
0747 +** Foundation and appearing in the file LICENSE.LGPL3 included in the
0748 +** packaging of this file. Please review the following information to
0749 +** ensure the GNU Lesser General Public License version 3 requirements
0750 +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
0751 +**
0752 +** GNU General Public License Usage
0753 +** Alternatively, this file may be used under the terms of the GNU
0754 +** General Public License version 2.0 or (at your option) the GNU General
0755 +** Public license version 3 or any later version approved by the KDE Free
0756 +** Qt Foundation. The licenses are as published by the Free Software
0757 +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
0758 +** included in the packaging of this file. Please review the following
0759 +** information to ensure the GNU General Public License requirements will
0760 +** be met: https://www.gnu.org/licenses/gpl-2.0.html and
0761 +** https://www.gnu.org/licenses/gpl-3.0.html.
0762 +**
0763 +** $QT_END_LICENSE$
0764 +**
0765 +****************************************************************************/
0766 +
0767 +#include "qv4functiontable_p.h"
0768 +
0769 +#include <assembler/MacroAssemblerCodeRef.h>
0770 +
0771 +#include <QtCore/qdebug.h>
0772 +
0773 +#include <Windows.h>
0774 +
0775 +QT_BEGIN_NAMESPACE
0776 +
0777 +namespace QV4 {
0778 +
0779 +enum UnwindOpcode: UINT8
0780 +{
0781 +    UWOP_PUSH_NONVOL = 0, /* info == register number */
0782 +    UWOP_ALLOC_LARGE,     /* no info, alloc size in next 2 slots */
0783 +    UWOP_ALLOC_SMALL,     /* info == size of allocation / 8 - 1 */
0784 +    UWOP_SET_FPREG,       /* no info, FP = RSP + UNWIND_INFO.FPRegOffset*16 */
0785 +    UWOP_SAVE_NONVOL,     /* info == register number, offset in next slot */
0786 +    UWOP_SAVE_NONVOL_FAR, /* info == register number, offset in next 2 slots */
0787 +    UWOP_SAVE_XMM128 = 8, /* info == XMM reg number, offset in next slot */
0788 +    UWOP_SAVE_XMM128_FAR, /* info == XMM reg number, offset in next 2 slots */
0789 +    UWOP_PUSH_MACHFRAME   /* info == 0: no error-code, 1: error-code */
0790 +};
0791 +
0792 +enum Register : UINT8
0793 +{
0794 +    RAX = 0,
0795 +    RCX,
0796 +    RDX,
0797 +    RBX,
0798 +    RSP,
0799 +    RBP,
0800 +    RSI,
0801 +    RDI,
0802 +    NONE = 15
0803 +};
0804 +
0805 +struct UnwindCode
0806 +{
0807 +    UnwindCode(UINT8 offset, UnwindOpcode operation, Register info)
0808 +        : offset(offset), operation(operation), info(info)
0809 +    {}
0810 +
0811 +    UINT8 offset;
0812 +    UINT8 operation: 4;
0813 +    UINT8 info:      4;
0814 +};
0815 +
0816 +struct UnwindInfo
0817 +{
0818 +    UINT8 Version : 3;
0819 +    UINT8 Flags : 5;
0820 +    UINT8 SizeOfProlog;
0821 +    UINT8 CountOfUnwindCodes;
0822 +    UINT8 FrameRegister : 4;
0823 +    UINT8 FrameRegisterOffset : 4;
0824 +    UnwindCode UnwindCodes[2];
0825 +};
0826 +
0827 +struct ExceptionHandlerRecord
0828 +{
0829 +    RUNTIME_FUNCTION handler;
0830 +    UnwindInfo info;
0831 +};
0832 +
0833 +void generateFunctionTable(Function *, JSC::MacroAssemblerCodeRef *codeRef)
0834 +{
0835 +    ExceptionHandlerRecord *record = reinterpret_cast<ExceptionHandlerRecord *>(
0836 +                codeRef->executableMemory()->exceptionHandler());
0837 +
0838 +    record->info.Version             = 1;
0839 +    record->info.Flags               = 0;
0840 +    record->info.SizeOfProlog        = 4;
0841 +    record->info.CountOfUnwindCodes  = 2;
0842 +    record->info.FrameRegister       = RBP;
0843 +    record->info.FrameRegisterOffset = 0;
0844 +
0845 +    // Push frame pointer
0846 +    record->info.UnwindCodes[1] = UnwindCode(1, UWOP_PUSH_NONVOL,  RBP);
0847 +    // Set frame pointer from stack pointer
0848 +    record->info.UnwindCodes[0] = UnwindCode(4,   UWOP_SET_FPREG, NONE);
0849 +
0850 +    const quintptr codeStart = quintptr(codeRef->code().executableAddress());
0851 +    const quintptr codeSize = codeRef->size();
0852 +
0853 +    record->handler.BeginAddress = DWORD(codeStart - quintptr(record));
0854 +    record->handler.EndAddress   = DWORD(codeStart + codeSize - quintptr(record));
0855 +    record->handler.UnwindData   = offsetof(ExceptionHandlerRecord, info);
0856 +
0857 +    if (!RtlAddFunctionTable(&record->handler, 1, DWORD64(record))) {
0858 +        const unsigned int errorCode = GetLastError();
0859 +        qWarning() << "Failed to install win64 unwind hook. Error code:" << errorCode;
0860 +    }
0861 +}
0862 +
0863 +void destroyFunctionTable(Function *, JSC::MacroAssemblerCodeRef *codeRef)
0864 +{
0865 +    ExceptionHandlerRecord *record = reinterpret_cast<ExceptionHandlerRecord *>(
0866 +                codeRef->executableMemory()->exceptionHandler());
0867 +    if (!RtlDeleteFunctionTable(&record->handler)) {
0868 +        const unsigned int errorCode = GetLastError();
0869 +        qWarning() << "Failed to remove win64 unwind hook. Error code:" << errorCode;
0870 +    }
0871 +}
0872 +
0873 +size_t exceptionHandlerSize()
0874 +{
0875 +    return sizeof(ExceptionHandlerRecord);
0876 +}
0877 +
0878 +} // QV4
0879 +
0880 +QT_END_NAMESPACE
0881 diff --git a/tests/auto/qml/qv4assembler/data/crash.qml b/tests/auto/qml/qv4assembler/data/crash.qml
0882 new file mode 100644
0883 index 00000000..dfdb9ceb
0884 --- /dev/null
0885 +++ b/tests/auto/qml/qv4assembler/data/crash.qml
0886 @@ -0,0 +1,53 @@
0887 +/****************************************************************************
0888 +**
0889 +** Copyright (C) 2018 The Qt Company Ltd.
0890 +** Contact: https://www.qt.io/licensing/
0891 +**
0892 +** This file is part of the test suite of the Qt Toolkit.
0893 +**
0894 +** $QT_BEGIN_LICENSE:GPL-EXCEPT$
0895 +** Commercial License Usage
0896 +** Licensees holding valid commercial Qt licenses may use this file in
0897 +** accordance with the commercial license agreement provided with the
0898 +** Software or, alternatively, in accordance with the terms contained in
0899 +** a written agreement between you and The Qt Company. For licensing terms
0900 +** and conditions see https://www.qt.io/terms-conditions. For further
0901 +** information use the contact form at https://www.qt.io/contact-us.
0902 +**
0903 +** GNU General Public License Usage
0904 +** Alternatively, this file may be used under the terms of the GNU
0905 +** General Public License version 3 as published by the Free Software
0906 +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
0907 +** included in the packaging of this file. Please review the following
0908 +** information to ensure the GNU General Public License requirements will
0909 +** be met: https://www.gnu.org/licenses/gpl-3.0.html.
0910 +**
0911 +** $QT_END_LICENSE$
0912 +**
0913 +****************************************************************************/
0914 +
0915 +import QtQml 2.2
0916 +import Crash 1.0
0917 +
0918 +QtObject {
0919 +    property Crash crash: Crash {
0920 +        id: crash
0921 +    }
0922 +
0923 +    // Recursion makes the crash more reliable
0924 +    // With a single frame the unwinder might guess
0925 +    // the next frame by chance.
0926 +    function recurse(x) {
0927 +        if (x > 32)
0928 +            crash.crash();
0929 +        else
0930 +            recurse(x + 1);
0931 +    }
0932 +
0933 +    property Timer timer: Timer {
0934 +        interval: 10
0935 +        running: true
0936 +        onTriggered: recurse(0)
0937 +    }
0938 +}
0939 +
0940 diff --git a/tests/auto/qml/qv4assembler/qv4assembler.pro b/tests/auto/qml/qv4assembler/qv4assembler.pro
0941 index afd7586a..895e241c 100644
0942 --- a/tests/auto/qml/qv4assembler/qv4assembler.pro
0943 +++ b/tests/auto/qml/qv4assembler/qv4assembler.pro
0944 @@ -1,7 +1,12 @@
0945  CONFIG += testcase
0946  TARGET = tst_qv4assembler
0947 +
0948 +include (../../shared/util.pri)
0949 +
0950  macos:CONFIG -= app_bundle
0951  
0952 +TESTDATA = data/*
0953 +
0954  SOURCES += tst_qv4assembler.cpp
0955  
0956  QT += qml-private testlib
0957 diff --git a/tests/auto/qml/qv4assembler/tst_qv4assembler.cpp b/tests/auto/qml/qv4assembler/tst_qv4assembler.cpp
0958 index afc00ec7..61a3e778 100644
0959 --- a/tests/auto/qml/qv4assembler/tst_qv4assembler.cpp
0960 +++ b/tests/auto/qml/qv4assembler/tst_qv4assembler.cpp
0961 @@ -26,20 +26,37 @@
0962  **
0963  ****************************************************************************/
0964  
0965 +#include <util.h>
0966 +
0967  #include <QtTest/QtTest>
0968  #include <QtCore/qprocess.h>
0969  #include <QtCore/qtemporaryfile.h>
0970 +#include <QtQml/qqml.h>
0971 +#include <QtQml/qqmlapplicationengine.h>
0972 +
0973  #include <private/qv4global_p.h>
0974  
0975 -class tst_QV4Assembler : public QObject
0976 +#ifdef Q_OS_WIN
0977 +#include <Windows.h>
0978 +#endif
0979 +
0980 +class tst_QV4Assembler : public QQmlDataTest
0981  {
0982      Q_OBJECT
0983  
0984  private slots:
0985 +    void initTestCase() override;
0986      void perfMapFile();
0987 +    void functionTable();
0988      void jitEnabled();
0989  };
0990  
0991 +void tst_QV4Assembler::initTestCase()
0992 +{
0993 +    qputenv("QV4_JIT_CALL_THRESHOLD", "0");
0994 +    QQmlDataTest::initTestCase();
0995 +}
0996 +
0997  void tst_QV4Assembler::perfMapFile()
0998  {
0999  #if !defined(Q_OS_LINUX)
1000 @@ -87,6 +104,42 @@ void tst_QV4Assembler::perfMapFile()
1001  #endif
1002  }
1003  
1004 +#ifdef Q_OS_WIN
1005 +class Crash : public QObject
1006 +{
1007 +    Q_OBJECT
1008 +public:
1009 +    explicit Crash(QObject *parent = nullptr) : QObject(parent) { }
1010 +    Q_INVOKABLE static void crash();
1011 +};
1012 +
1013 +static bool crashHandlerHit = false;
1014 +
1015 +static LONG WINAPI crashHandler(EXCEPTION_POINTERS*)
1016 +{
1017 +    crashHandlerHit = true;
1018 +    return EXCEPTION_CONTINUE_EXECUTION;
1019 +}
1020 +
1021 +void Crash::crash()
1022 +{
1023 +    SetUnhandledExceptionFilter(crashHandler);
1024 +    RaiseException(EXCEPTION_ACCESS_VIOLATION, 0, 0, nullptr);
1025 +}
1026 +#endif
1027 +
1028 +void tst_QV4Assembler::functionTable()
1029 +{
1030 +#ifndef Q_OS_WIN
1031 +    QSKIP("Function tables only exist on windows.");
1032 +#else
1033 +    QQmlApplicationEngine engine;
1034 +    qmlRegisterType<Crash>("Crash", 1, 0, "Crash");
1035 +    engine.load(testFileUrl("crash.qml"));
1036 +    QTRY_VERIFY(crashHandlerHit);
1037 +#endif
1038 +}
1039 +
1040  #ifdef V4_ENABLE_JIT
1041  #define JIT_ENABLED 1
1042  #else
1043 -- 
1044 2.37.3
1045