aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/compiler/qv4bytecodegenerator.cpp
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/qml/compiler/qv4bytecodegenerator.cpp
parent2951f6105ad3851b38fa66348a4edd3fe7cfa47e (diff)
Compress all non jump instructions
Change-Id: I90daee5388f5aba5a5c1cd643379adc9a8e05039 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/compiler/qv4bytecodegenerator.cpp')
-rw-r--r--src/qml/compiler/qv4bytecodegenerator.cpp63
1 files changed, 57 insertions, 6 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;
}
}