From: Simon Hausmann Date: Mon, 4 Mar 2013 14:30:40 +0000 (+0100) Subject: Cleanup unwind handler X-Git-Tag: upstream/5.2.1~669^2~659^2~170 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=03b0e23ccec7b040709c9cf52cbd3efe224982b5;p=platform%2Fupstream%2Fqtdeclarative.git Cleanup unwind handler Store the platform specific unwind info (CIE/FDE on Linux/Mac x86/x86-64) directly inside the VM::Function and therefore make all the functions of UnwindHelper static. Also calculate the function size correctly. Change-Id: If6a6b92a250044c6799218ef3506f34d630674c7 Reviewed-by: Lars Knoll --- diff --git a/src/v4/qmljs_engine.cpp b/src/v4/qmljs_engine.cpp index 6df44ef..126162e 100644 --- a/src/v4/qmljs_engine.cpp +++ b/src/v4/qmljs_engine.cpp @@ -71,7 +71,6 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory) , exception(Value::nullValue()) { MemoryManager::GCBlocker gcBlocker(memoryManager); - unwindHelper = UnwindHelper::create(); memoryManager->setExecutionEngine(this); @@ -236,9 +235,7 @@ ExecutionEngine::~ExecutionEngine() delete globalObject.asObject(); rootContext->destroy(); delete rootContext; - if (unwindHelper) - unwindHelper->deregisterFunctions(functions); - delete unwindHelper; + UnwindHelper::deregisterFunctions(functions); qDeleteAll(functions); delete memoryManager; } diff --git a/src/v4/qmljs_engine.h b/src/v4/qmljs_engine.h index 2289e73..0d8dd05 100644 --- a/src/v4/qmljs_engine.h +++ b/src/v4/qmljs_engine.h @@ -102,7 +102,6 @@ class RegExp; struct Q_V4_EXPORT ExecutionEngine { MemoryManager *memoryManager; - UnwindHelper *unwindHelper; EvalISelFactory *iselFactory; ExecutionContext *current; ExecutionContext *rootContext; diff --git a/src/v4/qv4functionobject.h b/src/v4/qv4functionobject.h index bbe6306..2cfb66f 100644 --- a/src/v4/qv4functionobject.h +++ b/src/v4/qv4functionobject.h @@ -115,6 +115,7 @@ struct Function { VM::Value (*code)(VM::ExecutionContext *, const uchar *); const uchar *codeData; JSC::MacroAssemblerCodeRef codeRef; + QByteArray unwindInfo; // CIE+FDE on x86/x86-64 QVector formals; QVector locals; diff --git a/src/v4/qv4isel_masm.cpp b/src/v4/qv4isel_masm.cpp index 35bd638..fc39f4c 100644 --- a/src/v4/qv4isel_masm.cpp +++ b/src/v4/qv4isel_masm.cpp @@ -422,6 +422,8 @@ void Assembler::link(VM::Function *vmFunc) JSC::JSGlobalData dummy; JSC::LinkBuffer linkBuffer(dummy, this, 0); + uint32_t codeSize = linkBuffer.offsetOf(label()); + QHash functions; foreach (CallToLink ctl, _callsToLink) { linkBuffer.link(ctl.call, ctl.externalFunction); @@ -456,6 +458,7 @@ void Assembler::link(VM::Function *vmFunc) } vmFunc->code = (Value (*)(VM::ExecutionContext *, const uchar *)) vmFunc->codeRef.code().executableAddress(); + vmFunc->unwindInfo = UnwindHelper::createUnwindInfo(vmFunc, codeSize); } InstructionSelection::InstructionSelection(VM::ExecutionEngine *engine, IR::Module *module) @@ -517,7 +520,6 @@ void InstructionSelection::run(VM::Function *vmFunction, IR::Function *function) _as->poke(Assembler::ScratchRegister); #endif _as->ret(); - // TODO: add a label and a nop, so we can determine the exact function length _as->link(_vmFunction); @@ -526,8 +528,7 @@ void InstructionSelection::run(VM::Function *vmFunction, IR::Function *function) memcpy(_vmFunction->lookups, _lookups.constData(), _lookups.size()*sizeof(Lookup)); } - if (engine()->unwindHelper) - engine()->unwindHelper->registerFunction(_vmFunction); + UnwindHelper::registerFunction(_vmFunction); qSwap(_vmFunction, vmFunction); qSwap(_function, function); diff --git a/src/v4/qv4unwindhelper.cpp b/src/v4/qv4unwindhelper.cpp index 31d9d68..a376b33 100644 --- a/src/v4/qv4unwindhelper.cpp +++ b/src/v4/qv4unwindhelper.cpp @@ -26,12 +26,10 @@ #ifdef USE_NULL_HELPER using namespace QQmlJS::VM; -UnwindHelper *UnwindHelper::create() { return 0; } -UnwindHelper::UnwindHelper() {} -UnwindHelper::~UnwindHelper() {} void UnwindHelper::registerFunction(Function *function) {Q_UNUSED(function);} void UnwindHelper::registerFunctions(QVector functions) {Q_UNUSED(functions);} void UnwindHelper::deregisterFunction(Function *function) {Q_UNUSED(function);} void UnwindHelper::deregisterFunctions(QVector functions) {Q_UNUSED(functions);} +QByteArray UnwindHelper::createUnwindInfo(Function*, size_t) { return QByteArray(); } #endif // USE_NULL_HELPER diff --git a/src/v4/qv4unwindhelper.h b/src/v4/qv4unwindhelper.h index bf70a01..19d33bb 100644 --- a/src/v4/qv4unwindhelper.h +++ b/src/v4/qv4unwindhelper.h @@ -10,24 +10,13 @@ struct Function; class UnwindHelper { - Q_DISABLE_COPY(UnwindHelper) - -private: - UnwindHelper(); - public: - ~UnwindHelper(); - - static UnwindHelper *create(); - - void registerFunction(Function *function); - void registerFunctions(QVector functions); - void deregisterFunction(Function *function); - void deregisterFunctions(QVector functions); + static QByteArray createUnwindInfo(Function*f, size_t functionSize); -private: - struct Private; - Private *p; + static void registerFunction(Function *function); + static void registerFunctions(QVector functions); + static void deregisterFunction(Function *function); + static void deregisterFunctions(QVector functions); }; } // VM namespace diff --git a/src/v4/qv4unwindhelper_p-dw2.h b/src/v4/qv4unwindhelper_p-dw2.h index 302e173..4d60812 100644 --- a/src/v4/qv4unwindhelper_p-dw2.h +++ b/src/v4/qv4unwindhelper_p-dw2.h @@ -46,55 +46,6 @@ static const int address_range_offset = 32; #endif } // anonymous namespace -namespace { -struct EHInfo { - unsigned char *cie_and_fde; - unsigned char *fde; - - EHInfo(unsigned char *cie_and_fde, unsigned char *fde) - : cie_and_fde(cie_and_fde), fde(fde) - { - Q_ASSERT(cie_and_fde); - Q_ASSERT(fde); - - __register_frame(fde); - } - - ~EHInfo() - { - Q_ASSERT(cie_and_fde); - Q_ASSERT(fde); - - __deregister_frame(fde); - - delete[] cie_and_fde; - } -}; -} // anonymous namespace - -struct Function; - -struct UnwindHelper::Private -{ - QHash ehInfoForFunction; -}; - -UnwindHelper *UnwindHelper::create() -{ - return new UnwindHelper; -} - -UnwindHelper::UnwindHelper() - : p(new Private) -{} - -UnwindHelper::~UnwindHelper() -{ - foreach (Function *f, p->ehInfoForFunction.keys()) - deregisterFunction(f); - delete p; -} - void UnwindHelper::registerFunctions(QVector functions) { foreach (Function *f, functions) registerFunction(f); @@ -102,12 +53,9 @@ void UnwindHelper::registerFunctions(QVector functions) void UnwindHelper::deregisterFunction(Function *function) { - QHash::iterator i = p->ehInfoForFunction.find(function); - if (i == p->ehInfoForFunction.end()) + if (function->unwindInfo.isEmpty()) return; - - delete i.value(); - p->ehInfoForFunction.erase(i); + __deregister_frame(function->unwindInfo.data() + fde_offset); } void UnwindHelper::deregisterFunctions(QVector functions) @@ -133,17 +81,25 @@ void writeIntPtrValue(unsigned char *addr, intptr_t val) void UnwindHelper::registerFunction(Function *function) { - unsigned char *cie_and_fde = new unsigned char[sizeof(cie_fde_data)]; + if (function->unwindInfo.isEmpty()) + return; + __register_frame(function->unwindInfo.data() + fde_offset); +} + +QByteArray UnwindHelper::createUnwindInfo(Function *f, size_t functionSize) +{ + QByteArray info; + info.resize(sizeof(cie_fde_data)); + + unsigned char *cie_and_fde = reinterpret_cast(info.data()); memcpy(cie_and_fde, cie_fde_data, sizeof(cie_fde_data)); - intptr_t ptr = static_cast(function->codeRef.code().executableAddress()) - static_cast(0); + intptr_t ptr = static_cast(f->codeRef.code().executableAddress()) - static_cast(0); writeIntPtrValue(cie_and_fde + initial_location_offset, ptr); - size_t len = function->codeRef.size(); - writeIntPtrValue(cie_and_fde + address_range_offset, len); + writeIntPtrValue(cie_and_fde + address_range_offset, functionSize); - p->ehInfoForFunction.insert(function, new EHInfo(cie_and_fde, - cie_and_fde + fde_offset)); + return info; } } // VM namespace