aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2017-08-24 16:33:27 +0200
committerLars Knoll <lars.knoll@qt.io>2017-08-28 13:19:09 +0000
commit41a4e387222a117e1cb47c119858c69e0d193e4f (patch)
treee905125c51543fd10608a088e56dc17a61ed1eb5 /src
parent2951f6105ad3851b38fa66348a4edd3fe7cfa47e (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.cpp63
-rw-r--r--src/qml/compiler/qv4bytecodegenerator_p.h12
-rw-r--r--src/qml/compiler/qv4instr_moth.cpp5
-rw-r--r--src/qml/compiler/qv4instr_moth_p.h7
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)