summaryrefslogtreecommitdiff
path: root/src/qml/compiler/qv4bytecodegenerator.cpp
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2017-08-26 19:37:39 +0200
committerLars Knoll <lars.knoll@qt.io>2017-08-28 13:19:42 +0000
commitb5ade552b799ded48fbb1700d80de5c499ba0f15 (patch)
tree9f3ec66b3753af68a8a0225ff2063d49330235ab /src/qml/compiler/qv4bytecodegenerator.cpp
parentad77c970281345bc03501cea583125a89637a52c (diff)
downloadqtdeclarative-b5ade552b799ded48fbb1700d80de5c499ba0f15.tar.gz
Remove the distinction between wide and xwide instructions
Only keep 1 byte and 4 byte wide instructions. As this gives less than 256 distinct instructions, those can now again be encoded in 1 byte, dropping the Wide and XWide prefix instructions. This gives us 95% of the size savings that we had before, by being able to encode the full instruction in one byte, while bringing back pretty much all of the speed lost through the compression. Change-Id: I9ec978d43314ed304ca0ee5546035d2b581b6dc3 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/compiler/qv4bytecodegenerator.cpp')
-rw-r--r--src/qml/compiler/qv4bytecodegenerator.cpp46
1 files changed, 15 insertions, 31 deletions
diff --git a/src/qml/compiler/qv4bytecodegenerator.cpp b/src/qml/compiler/qv4bytecodegenerator.cpp
index 401730c275..9feafb8bd4 100644
--- a/src/qml/compiler/qv4bytecodegenerator.cpp
+++ b/src/qml/compiler/qv4bytecodegenerator.cpp
@@ -69,27 +69,26 @@ int BytecodeGenerator::newRegisterArray(int n)
void BytecodeGenerator::packInstruction(I &i)
{
+ uchar type = *reinterpret_cast<uchar *>(i.packed);
+ Q_ASSERT(type >= MOTH_NUM_INSTRUCTIONS());
+ if (type >= MOTH_NUM_INSTRUCTIONS())
+ type -= MOTH_NUM_INSTRUCTIONS();
int instructionsAsInts[sizeof(Instr)/sizeof(int)];
int nMembers = Moth::Instr::argumentCount[static_cast<int>(i.type)];
- char *data = i.packed;
- Q_ASSERT(*data == static_cast<char>(Instr::Type::XWide));
- data += 2;
- memcpy(instructionsAsInts, data, nMembers*sizeof(int));
+ memcpy(instructionsAsInts, i.packed + 1, nMembers*sizeof(int));
enum {
Normal,
- Wide,
- XWide
+ Wide
} 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);
+ *reinterpret_cast<uchar *>(code) = type;
+ ++code;
for (int n = 0; n < nMembers; ++n) {
char v = static_cast<char>(instructionsAsInts[n]);
memcpy(code, &v, 1);
@@ -100,18 +99,6 @@ void BytecodeGenerator::packInstruction(I &i)
i.offsetForJump = i.size - 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;
- }
- i.size = code - i.packed;
- if (i.offsetForJump != -1)
- i.offsetForJump = i.size - 2;
- break;
- case XWide:
// nothing to do
break;
}
@@ -129,14 +116,10 @@ void BytecodeGenerator::adjustJumpOffsets()
int jumpOffset = linkedInstruction.position - (i.position + i.size);
// qDebug() << "adjusting jump offset for instruction" << index << i.position << i.size << "offsetForJump" << i.offsetForJump << "target"
// << labels.at(i.linkedLabel) << linkedInstruction.position << "jumpOffset" << jumpOffset;
- if (*i.packed == static_cast<char>(Instr::Type::XWide)) {
+ uchar type = *reinterpret_cast<const uchar *>(i.packed);
+ if (type >= MOTH_NUM_INSTRUCTIONS()) {
Q_ASSERT(i.offsetForJump == i.size - 4);
memcpy(c, &jumpOffset, sizeof(int));
- } else if (*i.packed == static_cast<char>(Instr::Type::Wide)) {
- Q_ASSERT(i.offsetForJump == i.size - 2);
- short o = jumpOffset;
- Q_ASSERT(o == jumpOffset);
- memcpy(c, &o, sizeof(short));
} else {
Q_ASSERT(i.offsetForJump == i.size - 1);
char o = jumpOffset;
@@ -199,11 +182,12 @@ int BytecodeGenerator::addInstructionHelper(Instr::Type type, const Instr &i, in
int pos = instructions.size();
int s = Moth::Instr::argumentCount[static_cast<int>(type)]*sizeof(int);
if (offsetOfOffset != -1)
- offsetOfOffset += 2;
- I instr{type, static_cast<short>(s + 2), 0, currentLine, offsetOfOffset, -1, "\0\0" };
+ offsetOfOffset += 1;
+ I instr{type, static_cast<short>(s + 1), 0, currentLine, offsetOfOffset, -1, "\0\0" };
char *code = instr.packed;
- *code++ = static_cast<char>(Instr::Type::XWide);
- *code++ = static_cast<char>(type);
+ *reinterpret_cast<uchar *>(code) = static_cast<uchar>(MOTH_NUM_INSTRUCTIONS() + static_cast<int>(type));
+ ++code;
+ Q_ASSERT(MOTH_NUM_INSTRUCTIONS() + static_cast<int>(type) < 256);
memcpy(code, &i, s);
instructions.append(instr);