diff options
author | Lars Knoll <lars.knoll@qt.io> | 2017-08-24 16:33:27 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2017-08-28 13:19:09 +0000 |
commit | 41a4e387222a117e1cb47c119858c69e0d193e4f (patch) | |
tree | e905125c51543fd10608a088e56dc17a61ed1eb5 /src | |
parent | 2951f6105ad3851b38fa66348a4edd3fe7cfa47e (diff) |
Compress all non jump instructions
Change-Id: I90daee5388f5aba5a5c1cd643379adc9a8e05039
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/qml/compiler/qv4bytecodegenerator.cpp | 63 | ||||
-rw-r--r-- | src/qml/compiler/qv4bytecodegenerator_p.h | 12 | ||||
-rw-r--r-- | src/qml/compiler/qv4instr_moth.cpp | 5 | ||||
-rw-r--r-- | src/qml/compiler/qv4instr_moth_p.h | 7 |
4 files changed, 76 insertions, 11 deletions
diff --git a/src/qml/compiler/qv4bytecodegenerator.cpp b/src/qml/compiler/qv4bytecodegenerator.cpp index 3ce3acdb86..aa459a7556 100644 --- a/src/qml/compiler/qv4bytecodegenerator.cpp +++ b/src/qml/compiler/qv4bytecodegenerator.cpp @@ -67,16 +67,67 @@ int BytecodeGenerator::newRegisterArray(int n) return t; } +void BytecodeGenerator::packInstruction(I &i) +{ + int instructionsAsInts[sizeof(Instr)/sizeof(int)]; + int nMembers = Moth::Instr::argumentCount[static_cast<int>(i.type)]; + memcpy(instructionsAsInts, &i.instr, nMembers*sizeof(int)); + enum { + Normal, + Wide, + XWide + } width = Normal; + for (int n = 0; n < nMembers; ++n) { + if (width == Normal && (static_cast<char>(instructionsAsInts[n]) != instructionsAsInts[n])) + width = Wide; + if (width == Wide && (static_cast<short>(instructionsAsInts[n]) != instructionsAsInts[n])) + width = XWide; + } + char *code = i.packed; + switch (width) { + case Normal: + *code++ = static_cast<char>(i.type); + for (int n = 0; n < nMembers; ++n) { + char v = static_cast<char>(instructionsAsInts[n]); + memcpy(code, &v, 1); + code += 1; + } + break; + case Wide: + *code++ = static_cast<char>(Instr::Type::Wide); + *code++ = static_cast<char>(i.type); + for (int n = 0; n < nMembers; ++n) { + short v = static_cast<short>(instructionsAsInts[n]); + memcpy(code, &v, 2); + code += 2; + } + break; + case XWide: + *code++ = static_cast<char>(Instr::Type::XWide); + *code++ = static_cast<char>(i.type); + for (int n = 0; n < nMembers; ++n) { + int v = instructionsAsInts[n]; + memcpy(code, &v, 4); + code += 4; + } + break; + } + i.size = code - i.packed; +} + void BytecodeGenerator::compressInstructions() { + // first round: compress all non jump instructions + int position = 0; for (auto &i : instructions) { - Instr instr = i.instr; - i.packed[0] = static_cast<char>(Instr::Type::XWide); - i.packed[1] = static_cast<char>(i.type); - memcpy(i.packed + 2, reinterpret_cast<char *>(&instr), i.size); - i.size += 2; - if (i.offsetForJump != -1) + if (i.offsetForJump != -1) { + int dummy = INT_MAX; + memcpy(reinterpret_cast<char *>(&i.instr) + i.offsetForJump, &dummy, 4); i.offsetForJump += 2; + } + i.position = position; + packInstruction(i); + position += i.size; } } diff --git a/src/qml/compiler/qv4bytecodegenerator_p.h b/src/qml/compiler/qv4bytecodegenerator_p.h index 3483565fb0..d6b4d1b06e 100644 --- a/src/qml/compiler/qv4bytecodegenerator_p.h +++ b/src/qml/compiler/qv4bytecodegenerator_p.h @@ -149,7 +149,7 @@ public: { Instr genericInstr; InstrMeta<InstrT>::setData(genericInstr, data); - addInstructionHelper(Moth::Instr::Type(InstrT), InstrMeta<InstrT>::Size, genericInstr); + addInstructionHelper(Moth::Instr::Type(InstrT), genericInstr); } Q_REQUIRED_RESULT Jump jump() @@ -228,7 +228,7 @@ public: { Instr genericInstr; InstrMeta<InstrT>::setData(genericInstr, data); - return Jump(this, addInstructionHelper(Moth::Instr::Type(InstrT), InstrMeta<InstrT>::Size, genericInstr, offsetof(InstrData<InstrT>, offset))); + return Jump(this, addInstructionHelper(Moth::Instr::Type(InstrT), genericInstr, offsetof(InstrData<InstrT>, offset))); } private: @@ -236,12 +236,11 @@ private: friend struct Label; friend struct ExceptionHandler; - int addInstructionHelper(Moth::Instr::Type type, uint size, const Instr &i, int offsetOfOffset = -1) { + int addInstructionHelper(Moth::Instr::Type type, const Instr &i, int offsetOfOffset = -1) { int pos = instructions.size(); - instructions.append({type, size, 0, currentLine, offsetOfOffset, -1, { i } }); + instructions.append({type, 0, 0, currentLine, offsetOfOffset, -1, { i } }); return pos; } - void compressInstructions(); struct I { Moth::Instr::Type type; @@ -256,6 +255,9 @@ private: }; }; + void compressInstructions(); + void packInstruction(I &i); + QVector<I> instructions; QVector<int> labels; ExceptionHandler *currentExceptionHandler; diff --git a/src/qml/compiler/qv4instr_moth.cpp b/src/qml/compiler/qv4instr_moth.cpp index 2716bed5ad..8f639453bd 100644 --- a/src/qml/compiler/qv4instr_moth.cpp +++ b/src/qml/compiler/qv4instr_moth.cpp @@ -107,6 +107,11 @@ QT_BEGIN_NAMESPACE namespace QV4 { namespace Moth { +const int Instr::argumentCount[] = { + FOR_EACH_MOTH_INSTR(MOTH_COLLECT_NARGS) +}; + + void dumpConstantTable(const Value *constants, uint count) { QDebug d = qDebug(); diff --git a/src/qml/compiler/qv4instr_moth_p.h b/src/qml/compiler/qv4instr_moth_p.h index c10d48ff8e..f134591d1c 100644 --- a/src/qml/compiler/qv4instr_moth_p.h +++ b/src/qml/compiler/qv4instr_moth_p.h @@ -341,6 +341,11 @@ QT_BEGIN_NAMESPACE #define MOTH_EMIT_INSTR_MEMBER_INSTRUCTION(name, nargs, ...) \ instr_##name name; +#define MOTH_COLLECT_NARGS(instr) \ + INSTR_##instr(MOTH_COLLECT_ARG_COUNT) +#define MOTH_COLLECT_ARG_COUNT_INSTRUCTION(name, nargs, ...) \ + nargs, + /* collect jump labels */ #define COLLECT_LABELS(instr) \ INSTR_##instr(GET_LABEL) @@ -475,6 +480,8 @@ union Instr FOR_EACH_MOTH_INSTR(MOTH_INSTR_ENUM) }; + static const int argumentCount[]; + FOR_EACH_MOTH_INSTR(MOTH_EMIT_STRUCTS) FOR_EACH_MOTH_INSTR(MOTH_EMIT_INSTR_MEMBERS) |