Start compressing the byte code

As a first step, use only one byte for the instruction type.

Change-Id: I762a05233c277a7144472793bc71e41d9e8e82cb
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
This commit is contained in:
Lars Knoll 2017-08-24 15:31:44 +02:00
parent ddb4fb4c60
commit cd67176bb2
3 changed files with 34 additions and 20 deletions

View File

@ -67,10 +67,24 @@ int BytecodeGenerator::newRegisterArray(int n)
return t;
}
void BytecodeGenerator::compressInstructions()
{
for (auto &i : instructions) {
Instr instr = i.instr;
i.packed[0] = static_cast<char>(i.type);
memcpy(i.packed + 1, reinterpret_cast<char *>(&instr), i.size);
++i.size;
if (i.offsetForJump != -1)
++i.offsetForJump;
}
}
void BytecodeGenerator::finalize(Compiler::Context *context)
{
QByteArray code;
compressInstructions();
// content
QVector<int> instructionOffsets;
QVector<int> lineNumbers;
@ -85,7 +99,7 @@ void BytecodeGenerator::finalize(Compiler::Context *context)
}
}
instructionOffsets.append(code.size());
code.append(reinterpret_cast<const char *>(&i.instr), i.size);
code.append(i.packed, i.size);
}
// resolve jumps

View File

@ -148,9 +148,8 @@ public:
void addInstruction(const InstrData<InstrT> &data)
{
Instr genericInstr;
genericInstr.Nop.instructionType = InstrT;
InstrMeta<InstrT>::setDataNoCommon(genericInstr, data);
addInstructionHelper(InstrMeta<InstrT>::Size, genericInstr);
InstrMeta<InstrT>::setData(genericInstr, data);
addInstructionHelper(Moth::Instr::Type(InstrT), InstrMeta<InstrT>::Size, genericInstr);
}
Q_REQUIRED_RESULT Jump jump()
@ -228,9 +227,8 @@ public:
Jump addJumpInstruction(const InstrData<InstrT> &data)
{
Instr genericInstr;
genericInstr.Nop.instructionType = InstrT;
InstrMeta<InstrT>::setDataNoCommon(genericInstr, data);
return Jump(this, addInstructionHelper(InstrMeta<InstrT>::Size, genericInstr, offsetof(InstrData<InstrT>, offset)));
InstrMeta<InstrT>::setData(genericInstr, data);
return Jump(this, addInstructionHelper(Moth::Instr::Type(InstrT), InstrMeta<InstrT>::Size, genericInstr, offsetof(InstrData<InstrT>, offset)));
}
private:
@ -238,18 +236,24 @@ private:
friend struct Label;
friend struct ExceptionHandler;
int addInstructionHelper(uint size, const Instr &i, int offsetOfOffset = -1) {
int addInstructionHelper(Moth::Instr::Type type, uint size, const Instr &i, int offsetOfOffset = -1) {
int pos = instructions.size();
instructions.append({size, currentLine, offsetOfOffset, -1, i});
instructions.append({type, size, 0, currentLine, offsetOfOffset, -1, { i } });
return pos;
}
void compressInstructions();
struct I {
Moth::Instr::Type type;
uint size;
uint position;
int line;
int offsetForJump;
int linkedLabel;
Instr instr;
union {
Instr instr;
char packed[sizeof(Instr) + 2]; // 2 for instruction and prefix
};
};
QVector<I> instructions;

View File

@ -302,8 +302,6 @@ QT_BEGIN_NAMESPACE
#define MOTH_INSTR_ALIGN_MASK (Q_ALIGNOF(QV4::Moth::Instr) - 1)
#define MOTH_INSTR_HEADER int instructionType;
#define MOTH_INSTR_ENUM(I) I,
#define MOTH_INSTR_SIZE(I) ((sizeof(QV4::Moth::Instr::instr_##I) + MOTH_INSTR_ALIGN_MASK) & ~MOTH_INSTR_ALIGN_MASK)
@ -335,7 +333,6 @@ QT_BEGIN_NAMESPACE
INSTR_##instr(MOTH_EMIT_STRUCT)
#define MOTH_EMIT_STRUCT_INSTRUCTION(name, nargs, ...) \
struct instr_##name { \
MOTH_INSTR_HEADER \
MOTH_DEFINE_ARGS(nargs, __VA_ARGS__) \
};
@ -373,8 +370,8 @@ QT_BEGIN_NAMESPACE
MOTH_DECODE_ARG(arg4, type, 3);
#define MOTH_DISPATCH() \
int instr = *reinterpret_cast<const int *>(code); \
code += 4; \
int instr = *code; \
++code; \
goto *jumpTable[instr];
namespace QV4 {
@ -455,11 +452,10 @@ QT_WARNING_DISABLE_GCC("-Wuninitialized")
enum { Size = MOTH_INSTR_SIZE(I) }; \
typedef Instr::instr_##I DataType; \
static const DataType &data(const Instr &instr) { return instr.I; } \
static void setData(Instr &instr, const DataType &v) { instr.I = v; } \
static void setDataNoCommon(Instr &instr, const DataType &v) \
{ memcpy(reinterpret_cast<char *>(&instr.I) + sizeof(Instr::instr_Nop), \
reinterpret_cast<const char *>(&v) + sizeof(Instr::instr_Nop), \
Size - sizeof(Instr::instr_Nop)); } \
static void setData(Instr &instr, const DataType &v) \
{ memcpy(reinterpret_cast<char *>(&instr.I), \
reinterpret_cast<const char *>(&v), \
Size); } \
};
FOR_EACH_MOTH_INSTR(MOTH_INSTR_META_TEMPLATE);
#undef MOTH_INSTR_META_TEMPLATE