Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement RETURN_FIELD_* bytecodes and port more of the tests #48

Merged
merged 3 commits into from
Aug 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion src/compiler/BytecodeGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -254,13 +254,34 @@ void EmitRETURNSELF(MethodGenerationContext& mgenc) {
}

void EmitRETURNLOCAL(MethodGenerationContext& mgenc) {
Emit1(mgenc, BC_RETURN_LOCAL, 0);
if (!mgenc.OptimizeReturnField()) {
Emit1(mgenc, BC_RETURN_LOCAL, 0);
}
}

void EmitRETURNNONLOCAL(MethodGenerationContext& mgenc) {
Emit1(mgenc, BC_RETURN_NON_LOCAL, 0);
}

void EmitRETURNFIELD(MethodGenerationContext& mgenc, size_t index) {
assert(index <= 2);
uint8_t bc = 0;
switch (index) {
case 0:
bc = BC_RETURN_FIELD_0;
break;

case 1:
bc = BC_RETURN_FIELD_1;
break;

case 2:
bc = BC_RETURN_FIELD_2;
break;
}
Emit1(mgenc, bc, 0);
}

void EmitINC(MethodGenerationContext& mgenc) {
Emit1(mgenc, BC_INC, 0);
}
Expand Down
1 change: 1 addition & 0 deletions src/compiler/BytecodeGenerator.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ void EmitSUPERSEND(MethodGenerationContext& mgenc, VMSymbol* msg);
void EmitRETURNSELF(MethodGenerationContext& mgenc);
void EmitRETURNLOCAL(MethodGenerationContext& mgenc);
void EmitRETURNNONLOCAL(MethodGenerationContext& mgenc);
void EmitRETURNFIELD(MethodGenerationContext& mgenc, size_t index);

void EmitINC(MethodGenerationContext& mgenc);
void EmitDupSecond(MethodGenerationContext& mgenc);
Expand Down
65 changes: 65 additions & 0 deletions src/compiler/MethodGenerationContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,34 @@ VMTrivialMethod* MethodGenerationContext::assembleFieldGetter(
return MakeGetter(signature, arguments, fieldIndex);
}

VMTrivialMethod* MethodGenerationContext::assembleFieldGetterFromReturn(
uint8_t returnCandidate) {
if (bytecode.size() != Bytecode::GetBytecodeLength(returnCandidate)) {
return nullptr;
}

size_t index = 0;
switch (returnCandidate) {
case BC_RETURN_FIELD_0:
index = 0;
break;

case BC_RETURN_FIELD_1:
index = 1;
break;

case BC_RETURN_FIELD_2:
index = 2;
break;

default:
ErrorExit("Unsupported bytecode in assembleFieldGetterFromReturn");
break;
}

return MakeGetter(signature, arguments, index);
}

VMTrivialMethod* MethodGenerationContext::assembleFieldSetter() {
uint8_t popCandidate = lastBytecodeIsOneOf(1, IsPopFieldBytecode);
if (popCandidate == BC_INVALID) {
Expand Down Expand Up @@ -878,3 +906,40 @@ bool MethodGenerationContext::OptimizeDupPopPopSequence() {

return true;
}

bool MethodGenerationContext::OptimizeReturnField() {
if (isCurrentlyInliningABlock) {
return false;
}

uint8_t bc = lastBytecodeAt(0);
uint8_t index = 0;

switch (bc) {
case BC_PUSH_FIELD_0:
index = 0;
break;

case BC_PUSH_FIELD_1:
index = 1;
break;

case BC_PUSH_FIELD:
index = bytecode.at(bytecode.size() - 1);
assert(index > 1);
break;

default:
return false;
}

if (index > 2) {
// don't have a special bytecode for this
return false;
}

removeLastBytecodes(1);
resetLastBytecodeBuffer();
EmitRETURNFIELD(*this, index);
return true;
}
5 changes: 2 additions & 3 deletions src/compiler/MethodGenerationContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ class MethodGenerationContext {
void PatchJumpOffsetToPointToNextInstruction(size_t indexOfOffset);

bool OptimizeDupPopPopSequence();
bool OptimizeReturnField();

bool LastBytecodeIs(size_t indexFromEnd, uint8_t bytecode);

Expand All @@ -124,9 +125,7 @@ class MethodGenerationContext {
VMTrivialMethod* assembleGlobalReturn();
VMTrivialMethod* assembleFieldGetter(uint8_t pushCandidate);
VMTrivialMethod* assembleFieldSetter();
VMTrivialMethod* assembleFieldGetterFromReturn(uint8_t pushCandidate) {
return nullptr;
}
VMTrivialMethod* assembleFieldGetterFromReturn(uint8_t returnCandidate);

bool optimizeIncFieldPush() {
// TODO: implement
Expand Down
14 changes: 14 additions & 0 deletions src/interpreter/Interpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,20 @@ void Interpreter::doPushFieldWithIndex(uint8_t fieldIndex) {
GetFrame()->Push(o);
}

void Interpreter::doReturnFieldWithIndex(uint8_t fieldIndex) {
vm_oop_t self = GetSelf();
vm_oop_t o;

if (unlikely(IS_TAGGED(self))) {
o = nullptr;
ErrorExit("Integers do not have fields!");
} else {
o = ((VMObject*)self)->GetField(fieldIndex);
}

popFrameAndPushResult(o);
}

void Interpreter::doPushBlock(long bytecodeIndex) {
vm_oop_t block = method->GetConstant(bytecodeIndex);
VMInvokable* blockMethod = static_cast<VMInvokable*>(block);
Expand Down
1 change: 1 addition & 0 deletions src/interpreter/Interpreter.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ class Interpreter {
void doDup();
void doPushLocal(long bytecodeIndex);
void doPushLocalWithIndex(uint8_t localIndex);
void doReturnFieldWithIndex(uint8_t fieldIndex);
void doPushArgument(long bytecodeIndex);
void doPushField(long bytecodeIndex);
void doPushFieldWithIndex(uint8_t fieldIndex);
Expand Down
18 changes: 18 additions & 0 deletions src/interpreter/InterpreterLoop.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ vm_oop_t Start() {
&&LABEL_BC_RETURN_LOCAL,
&&LABEL_BC_RETURN_NON_LOCAL,
&&LABEL_BC_RETURN_SELF,
&&LABEL_BC_RETURN_FIELD_0,
&&LABEL_BC_RETURN_FIELD_1,
&&LABEL_BC_RETURN_FIELD_2,
&&LABEL_BC_INC,
&&LABEL_BC_JUMP,
&&LABEL_BC_JUMP_ON_FALSE_POP,
Expand Down Expand Up @@ -270,6 +273,21 @@ LABEL_BC_RETURN_SELF: {
DISPATCH_NOGC();
}

LABEL_BC_RETURN_FIELD_0:
PROLOGUE(1);
doReturnFieldWithIndex(0);
DISPATCH_NOGC();

LABEL_BC_RETURN_FIELD_1:
PROLOGUE(1);
doReturnFieldWithIndex(1);
DISPATCH_NOGC();

LABEL_BC_RETURN_FIELD_2:
PROLOGUE(1);
doReturnFieldWithIndex(2);
DISPATCH_NOGC();

LABEL_BC_INC:
PROLOGUE(1);
doInc();
Expand Down
36 changes: 21 additions & 15 deletions src/interpreter/bytecodes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ const uint8_t Bytecode::bytecodeLengths[] = {
1, // BC_RETURN_LOCAL
1, // BC_RETURN_NON_LOCAL
1, // BC_RETURN_SELF
1, // BC_RETURN_FIELD_0
1, // BC_RETURN_FIELD_1
1, // BC_RETURN_FIELD_2
1, // BC_INC

3, // BC_JUMP
Expand Down Expand Up @@ -124,21 +127,24 @@ const char* Bytecode::bytecodeNames[] = {
"RETURN_LOCAL ", // 34
"RETURN_NON_LOCAL", // 35
"RETURN_SELF ", // 36
"INC ", // 37
"JUMP ", // 38
"JUMP_ON_FALSE_POP", // 39
"JUMP_ON_TRUE_POP", // 40
"JUMP_ON_FALSE_TOP_NIL", // 41
"JUMP_ON_TRUE_TOP_NIL", // 42
"JUMP_IF_GREATER ", // 43
"JUMP_BACKWARD ", // 44
"JUMP2 ", // 45
"JUMP2_ON_FALSE_POP", // 46
"JUMP2_ON_TRUE_POP", // 47
"JUMP2_ON_FALSE_TOP_NIL", // 48
"JUMP2_ON_TRUE_TOP_NIL", // 49
"JUMP2_IF_GREATER", // 50
"JUMP2_BACKWARD ", // 51
"RETURN_FIELD_0 ", // 37
"RETURN_FIELD_1 ", // 38
"RETURN_FIELD_2 ", // 39
"INC ", // 40
"JUMP ", // 41
"JUMP_ON_FALSE_POP", // 42
"JUMP_ON_TRUE_POP", // 43
"JUMP_ON_FALSE_TOP_NIL", // 44
"JUMP_ON_TRUE_TOP_NIL", // 45
"JUMP_IF_GREATER ", // 46
"JUMP_BACKWARD ", // 47
"JUMP2 ", // 48
"JUMP2_ON_FALSE_POP", // 49
"JUMP2_ON_TRUE_POP", // 50
"JUMP2_ON_FALSE_TOP_NIL", // 51
"JUMP2_ON_TRUE_TOP_NIL", // 52
"JUMP2_IF_GREATER", // 53
"JUMP2_BACKWARD ", // 54
};

bool IsJumpBytecode(uint8_t bc) {
Expand Down
36 changes: 18 additions & 18 deletions src/interpreter/bytecodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,21 +70,24 @@
#define BC_RETURN_LOCAL 34
#define BC_RETURN_NON_LOCAL 35
#define BC_RETURN_SELF 36
#define BC_INC 37
#define BC_JUMP 38
#define BC_JUMP_ON_FALSE_POP 39
#define BC_JUMP_ON_TRUE_POP 40
#define BC_JUMP_ON_FALSE_TOP_NIL 41
#define BC_JUMP_ON_TRUE_TOP_NIL 42
#define BC_JUMP_IF_GREATER 43
#define BC_JUMP_BACKWARD 44
#define BC_JUMP2 45
#define BC_JUMP2_ON_FALSE_POP 46
#define BC_JUMP2_ON_TRUE_POP 47
#define BC_JUMP2_ON_FALSE_TOP_NIL 48
#define BC_JUMP2_ON_TRUE_TOP_NIL 49
#define BC_JUMP2_IF_GREATER 50
#define BC_JUMP2_BACKWARD 51
#define BC_RETURN_FIELD_0 37
#define BC_RETURN_FIELD_1 38
#define BC_RETURN_FIELD_2 39
#define BC_INC 40
#define BC_JUMP 41
#define BC_JUMP_ON_FALSE_POP 42
#define BC_JUMP_ON_TRUE_POP 43
#define BC_JUMP_ON_FALSE_TOP_NIL 44
#define BC_JUMP_ON_TRUE_TOP_NIL 45
#define BC_JUMP_IF_GREATER 46
#define BC_JUMP_BACKWARD 47
#define BC_JUMP2 48
#define BC_JUMP2_ON_FALSE_POP 49
#define BC_JUMP2_ON_TRUE_POP 50
#define BC_JUMP2_ON_FALSE_TOP_NIL 51
#define BC_JUMP2_ON_TRUE_TOP_NIL 52
#define BC_JUMP2_IF_GREATER 53
#define BC_JUMP2_BACKWARD 54

#define _LAST_BYTECODE BC_JUMP2_BACKWARD

Expand All @@ -102,9 +105,6 @@
#define BC_SEND_3 249
#define BC_SEND_2 248
#define BC_SEND_1 247
#define BC_RETURN_FIELD_0 246
#define BC_RETURN_FIELD_1 245
#define BC_RETURN_FIELD_2 244
// clang-format on

// properties of the bytecodes
Expand Down
Loading