diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/3rdparty/masm/assembler/MacroAssemblerX86.h | 5 | ||||
-rw-r--r-- | src/3rdparty/masm/assembler/MacroAssemblerX86_64.h | 5 | ||||
-rw-r--r-- | src/qml/compiler/qv4isel_masm_p.h | 20 | ||||
-rw-r--r-- | src/qml/jsruntime/jsruntime.pri | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4context_p.h | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4engine.cpp | 19 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4stacktrace.cpp | 182 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4stacktrace_p.h | 75 |
8 files changed, 38 insertions, 272 deletions
diff --git a/src/3rdparty/masm/assembler/MacroAssemblerX86.h b/src/3rdparty/masm/assembler/MacroAssemblerX86.h index 7a01e41e11..9a33fe870e 100644 --- a/src/3rdparty/masm/assembler/MacroAssemblerX86.h +++ b/src/3rdparty/masm/assembler/MacroAssemblerX86.h @@ -197,6 +197,11 @@ public: return Call(m_assembler.call(), Call::Linkable); } + void callToRetrieveIP() + { + m_assembler.call(); + } + // Address is a memory location containing the address to jump to void jump(AbsoluteAddress address) { diff --git a/src/3rdparty/masm/assembler/MacroAssemblerX86_64.h b/src/3rdparty/masm/assembler/MacroAssemblerX86_64.h index db0e880cb9..9e74f1c29f 100644 --- a/src/3rdparty/masm/assembler/MacroAssemblerX86_64.h +++ b/src/3rdparty/masm/assembler/MacroAssemblerX86_64.h @@ -136,6 +136,11 @@ public: return result; } + void callToRetrieveIP() + { + m_assembler.call(); + } + // Address is a memory location containing the address to jump to void jump(AbsoluteAddress address) { diff --git a/src/qml/compiler/qv4isel_masm_p.h b/src/qml/compiler/qv4isel_masm_p.h index 4d1114e756..02ddd158a9 100644 --- a/src/qml/compiler/qv4isel_masm_p.h +++ b/src/qml/compiler/qv4isel_masm_p.h @@ -430,7 +430,25 @@ public: V4IR::BasicBlock *block; }; + void saveInstructionPointer(RegisterID freeScratchRegister) { + Address ipAddr(ContextRegister, qOffsetOf(QV4::ExecutionContext, jitInstructionPointer)); + RegisterID sourceRegister = freeScratchRegister; + +#if CPU(X86_64) || CPU(X86) + callToRetrieveIP(); + peek(sourceRegister); + pop(); +#elif CPU(ARM) + move(JSC::ARMRegisters::pc, sourceRegister); +#else +#error "Port me!" +#endif + + storePtr(sourceRegister, ipAddr); + } + void callAbsolute(const char* functionName, FunctionPtr function) { + saveInstructionPointer(ScratchRegister); CallToLink ctl; ctl.call = call(); ctl.externalFunction = function; @@ -439,11 +457,13 @@ public: } void callAbsolute(const char* /*functionName*/, Address addr) { + saveInstructionPointer(ScratchRegister); call(addr); } void callAbsolute(const char* /*functionName*/, const RelativeCall &relativeCall) { + saveInstructionPointer(ScratchRegister); call(relativeCall.addr); } diff --git a/src/qml/jsruntime/jsruntime.pri b/src/qml/jsruntime/jsruntime.pri index 14701feeb5..e2880c0972 100644 --- a/src/qml/jsruntime/jsruntime.pri +++ b/src/qml/jsruntime/jsruntime.pri @@ -45,7 +45,6 @@ SOURCES += \ $$PWD/qv4include.cpp \ $$PWD/qv4qobjectwrapper.cpp \ $$PWD/qv4qmlextensions.cpp \ - $$PWD/qv4stacktrace.cpp \ $$PWD/qv4vme_moth.cpp HEADERS += \ @@ -96,7 +95,6 @@ HEADERS += \ $$PWD/qv4include_p.h \ $$PWD/qv4qobjectwrapper_p.h \ $$PWD/qv4qmlextensions_p.h \ - $$PWD/qv4stacktrace_p.h \ $$PWD/qv4vme_moth_p.h # Use SSE2 floating point math on 32 bit instead of the default diff --git a/src/qml/jsruntime/qv4context_p.h b/src/qml/jsruntime/qv4context_p.h index 2535161713..d44c7d25f9 100644 --- a/src/qml/jsruntime/qv4context_p.h +++ b/src/qml/jsruntime/qv4context_p.h @@ -97,6 +97,7 @@ struct Q_QML_EXPORT ExecutionContext EvalCode *currentEvalCode; const uchar **interpreterInstructionPointer; + char *jitInstructionPointer; void initBaseContext(Type type, ExecutionEngine *engine, ExecutionContext *parentContext) { @@ -110,6 +111,7 @@ struct Q_QML_EXPORT ExecutionContext compilationUnit = 0; currentEvalCode = 0; interpreterInstructionPointer = 0; + jitInstructionPointer = 0; } CallContext *newCallContext(void *stackSpace, SafeValue *locals, FunctionObject *f, CallData *callData); diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index 2ddc07d63c..23faa43ac7 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -66,7 +66,6 @@ #include "qv4sequenceobject_p.h" #include "qv4qobjectwrapper_p.h" #include "qv4qmlextensions_p.h" -#include "qv4stacktrace_p.h" #ifdef V4_ENABLE_JIT #include "qv4isel_masm_p.h" @@ -568,7 +567,6 @@ Returned<Object> *ExecutionEngine::qmlContextObject() const namespace { struct LineNumberResolver { const ExecutionEngine* engine; - QScopedPointer<QV4::NativeStackTrace> nativeTrace; LineNumberResolver(const ExecutionEngine *engine) : engine(engine) @@ -577,17 +575,12 @@ namespace { void resolve(StackFrame *frame, ExecutionContext *context, Function *function) { - if (context->interpreterInstructionPointer) { - qptrdiff offset = *context->interpreterInstructionPointer - 1 - function->codeData; - frame->line = function->lineNumberForProgramCounter(offset); - } else { - if (!nativeTrace) - nativeTrace.reset(new QV4::NativeStackTrace(engine->current)); - - NativeFrame nativeFrame = nativeTrace->nextFrame(); - if (nativeFrame.function == function) - frame->line = nativeFrame.line; - } + qptrdiff offset; + if (context->interpreterInstructionPointer) + offset = *context->interpreterInstructionPointer - 1 - function->codeData; + else + offset = context->jitInstructionPointer - (char*)function->codePtr; + frame->line = function->lineNumberForProgramCounter(offset); } }; } diff --git a/src/qml/jsruntime/qv4stacktrace.cpp b/src/qml/jsruntime/qv4stacktrace.cpp deleted file mode 100644 index 905111a23e..0000000000 --- a/src/qml/jsruntime/qv4stacktrace.cpp +++ /dev/null @@ -1,182 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#if defined(_WIN32) && !(defined(WINCE) || defined(_WIN32_WCE)) -#include <windows.h> -#include <DbgHelp.h> -#endif - -#include "qv4stacktrace_p.h" -#include "qv4function_p.h" -#include "qv4engine_p.h" -#include "qv4unwindhelper_p.h" - -#if defined(V4_CXX_ABI_EXCEPTION) || (defined(Q_OS_DARWIN) && !defined(Q_PROCESSOR_ARM_32)) -#define USE_UNWIND_BACKTRACE -#endif - -#if defined(USE_UNWIND_BACKTRACE) -#include <unwind.h> - -struct BacktraceHelper -{ - void **array; - int maximumSize; - int frameCount; -}; - -static _Unwind_Reason_Code bt_helper(struct _Unwind_Context *ctx, void *data) -{ - BacktraceHelper *helper = reinterpret_cast<BacktraceHelper*>(data); - - if (helper->frameCount != -1) { - helper->array[helper->frameCount] = (void*)_Unwind_GetIP(ctx); - - if (helper->frameCount > 0 && helper->array[helper->frameCount] == helper->array[helper->frameCount - 1]) - return _URC_END_OF_STACK; - } - ++helper->frameCount; - if (helper->frameCount == helper->maximumSize) - return _URC_END_OF_STACK; - return _URC_NO_REASON; -} - -static int get_backtrace_from_libunwind(void **array, int size) -{ - BacktraceHelper helper; - helper.array = array; - helper.maximumSize = size; - helper.frameCount = -1; // To skip this function - _Unwind_Backtrace(&bt_helper, &helper); - return helper.frameCount; -} -#endif - -QT_BEGIN_NAMESPACE - -using namespace QV4; - -NativeStackTrace::NativeStackTrace(ExecutionContext *context) -{ - engine = context->engine; - currentNativeFrame = 0; - -#if defined(USE_UNWIND_BACKTRACE) - UnwindHelper::prepareForUnwind(context); - - nativeFrameCount = get_backtrace_from_libunwind(&trace[0], sizeof(trace) / sizeof(trace[0])); -#elif defined(Q_OS_WIN) && !defined(Q_OS_WINCE) - - int machineType = 0; - - CONTEXT winContext; - memset(&winContext, 0, sizeof(winContext)); - winContext.ContextFlags = CONTEXT_FULL; - RtlCaptureContext(&winContext); - - STACKFRAME64 sf64; - memset(&sf64, 0, sizeof(sf64)); - -#if defined(Q_PROCESSOR_X86_32) - machineType = IMAGE_FILE_MACHINE_I386; - - sf64.AddrFrame.Offset = winContext.Ebp; - sf64.AddrFrame.Mode = AddrModeFlat; - sf64.AddrPC.Offset = winContext.Eip; - sf64.AddrPC.Mode = AddrModeFlat; - sf64.AddrStack.Offset = winContext.Esp; - sf64.AddrStack.Mode = AddrModeFlat; - -#elif defined(Q_PROCESSOR_X86_64) - machineType = IMAGE_FILE_MACHINE_AMD64; - - sf64.AddrFrame.Offset = winContext.Rbp; - sf64.AddrFrame.Mode = AddrModeFlat; - sf64.AddrPC.Offset = winContext.Rip; - sf64.AddrPC.Mode = AddrModeFlat; - sf64.AddrStack.Offset = winContext.Rsp; - sf64.AddrStack.Mode = AddrModeFlat; - -#else -#error "Platform unsupported!" -#endif - - nativeFrameCount = 0; - - while (StackWalk64(machineType, GetCurrentProcess(), GetCurrentThread(), &sf64, &winContext, 0, SymFunctionTableAccess64, SymGetModuleBase64, 0)) { - - if (sf64.AddrReturn.Offset == 0) - break; - - trace[nativeFrameCount] = reinterpret_cast<void*>(sf64.AddrReturn.Offset); - nativeFrameCount++; - if (nativeFrameCount >= sizeof(trace) / sizeof(trace[0])) - break; - } - -#else - nativeFrameCount = 0; -#endif - } - -NativeFrame NativeStackTrace::nextFrame() { - NativeFrame frame; - frame.function = 0; - frame.line = -1; - - for (; currentNativeFrame < nativeFrameCount && !frame.function; ++currentNativeFrame) { - quintptr pc = reinterpret_cast<quintptr>(trace[currentNativeFrame]); - // The pointers from the back trace point to the return address, but we are interested in - // the caller site. - pc = pc - 1; - - Function *f = engine->functionForProgramCounter(pc); - if (!f) - continue; - - frame.function = f; - frame.line = f->lineNumberForProgramCounter(pc - reinterpret_cast<quintptr>(f->codePtr)); - } - - return frame; -} - -QT_END_NAMESPACE diff --git a/src/qml/jsruntime/qv4stacktrace_p.h b/src/qml/jsruntime/qv4stacktrace_p.h deleted file mode 100644 index 79cb4d1813..0000000000 --- a/src/qml/jsruntime/qv4stacktrace_p.h +++ /dev/null @@ -1,75 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef QV4STACKTRACE_P_H -#define QV4STACKTRACE_P_H - -#include <qglobal.h> - -QT_BEGIN_NAMESPACE - -namespace QV4 { - -struct Function; -struct ExecutionEngine; -struct ExecutionContext; - -struct NativeFrame { - Function *function; - int line; -}; - -struct NativeStackTrace -{ - void *trace[100]; - int nativeFrameCount; - int currentNativeFrame; - ExecutionEngine *engine; - - NativeStackTrace(ExecutionContext *context); - - NativeFrame nextFrame(); -}; - -} // namespace QV4 - -QT_END_NAMESPACE - -#endif // QV4STACKTRACE_P_H |