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:
parent
ddb4fb4c60
commit
cd67176bb2
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue