| Index: src/vm/interpreter_arm.cc
|
| diff --git a/src/vm/interpreter_arm.cc b/src/vm/interpreter_arm.cc
|
| index a67de7a259eb054e105fcb5dd3c2b6b9c1e14987..8352c80acdbd41b7d08dd5d1f7cba08525446ae6 100644
|
| --- a/src/vm/interpreter_arm.cc
|
| +++ b/src/vm/interpreter_arm.cc
|
| @@ -86,12 +86,12 @@ class InterpreterGeneratorARM : public InterpreterGenerator {
|
|
|
| // Registers
|
| // ---------
|
| - // r4: current process
|
| - // r5: bytecode pointer
|
| - // r6: stack pointer (top)
|
| - // r8: null
|
| - // r10: true
|
| - // r11: false
|
| + // R4: current process
|
| + // R5: bytecode pointer
|
| + // R6: stack pointer (top)
|
| + // R8: null
|
| + // R10: program
|
| + // R11: dispatch table
|
|
|
| virtual void GeneratePrologue();
|
| virtual void GenerateEpilogue();
|
| @@ -239,6 +239,9 @@ class InterpreterGeneratorARM : public InterpreterGenerator {
|
| Label interpreter_entry_;
|
| int spill_size_;
|
|
|
| + static const int kFalseOffset = 8;
|
| + static const int kTrueOffset = 16;
|
| +
|
| void LoadLocal(Register reg, int index);
|
| void StoreLocal(Register reg, int index);
|
|
|
| @@ -290,8 +293,10 @@ class InterpreterGeneratorARM : public InterpreterGenerator {
|
| void InvokeNative(bool yield, bool safepoint);
|
| void InvokeStatic();
|
|
|
| - void ConditionalStore(Register reg_if_eq, Register reg_if_ne,
|
| - const Address& address);
|
| + void AddIf(Condition cond, Register reg, int immediate);
|
| + void ToBoolean(Condition cond, Register reg);
|
| + void LoadFalse(Register reg);
|
| + void LoadTrue(Register reg);
|
|
|
| void CheckStackOverflow(int size);
|
|
|
| @@ -403,8 +408,7 @@ void InterpreterGeneratorARM::GenerateEpilogue() {
|
| __ Bind(&overflow);
|
| Label throw_resume;
|
| SaveState(&throw_resume);
|
| - __ ldr(R7, Address(R4, Process::kProgramOffset));
|
| - __ ldr(R7, Address(R7, Program::kStackOverflowErrorOffset));
|
| + __ ldr(R7, Address(R10, Program::kStackOverflowErrorOffset));
|
| DoThrowAfterSaveState(&throw_resume);
|
|
|
| // Intrinsic failure: Just invoke the method.
|
| @@ -640,12 +644,14 @@ void InterpreterGeneratorARM::DoLoadLiteralNull() {
|
| }
|
|
|
| void InterpreterGeneratorARM::DoLoadLiteralTrue() {
|
| - Push(R10);
|
| + LoadTrue(R2);
|
| + Push(R2);
|
| Dispatch(kLoadLiteralTrueLength);
|
| }
|
|
|
| void InterpreterGeneratorARM::DoLoadLiteralFalse() {
|
| - Push(R11);
|
| + LoadFalse(R2);
|
| + Push(R2);
|
| Dispatch(kLoadLiteralFalseLength);
|
| }
|
|
|
| @@ -685,8 +691,7 @@ void InterpreterGeneratorARM::DoInvokeMethod() { InvokeMethod(false); }
|
|
|
| void InterpreterGeneratorARM::DoInvokeNoSuchMethod() {
|
| // Use the noSuchMethod entry from entry zero of the virtual table.
|
| - __ ldr(R1, Address(R4, Process::kProgramOffset));
|
| - __ ldr(R1, Address(R1, Program::kDispatchTableOffset));
|
| + __ ldr(R1, Address(R10, Program::kDispatchTableOffset));
|
| __ ldr(R1, Address(R1, Array::kSize - HeapObject::kTag));
|
|
|
| // Load the function.
|
| @@ -709,7 +714,8 @@ void InterpreterGeneratorARM::DoInvokeNoSuchMethod() {
|
| }
|
|
|
| void InterpreterGeneratorARM::DoInvokeTestNoSuchMethod() {
|
| - StoreLocal(R11, 0);
|
| + LoadFalse(R2);
|
| + StoreLocal(R2, 0);
|
| Dispatch(kInvokeTestNoSuchMethodLength);
|
| }
|
|
|
| @@ -969,7 +975,8 @@ void InterpreterGeneratorARM::DoBranchWide() {
|
| void InterpreterGeneratorARM::DoBranchIfTrueWide() {
|
| Label branch;
|
| Pop(R7);
|
| - __ cmp(R7, R10);
|
| + LoadTrue(R2);
|
| + __ cmp(R7, R2);
|
| __ b(EQ, &branch);
|
| Dispatch(kBranchIfTrueWideLength);
|
|
|
| @@ -982,7 +989,8 @@ void InterpreterGeneratorARM::DoBranchIfTrueWide() {
|
| void InterpreterGeneratorARM::DoBranchIfFalseWide() {
|
| Label branch;
|
| Pop(R7);
|
| - __ cmp(R7, R10);
|
| + LoadTrue(R2);
|
| + __ cmp(R7, R2);
|
| __ b(NE, &branch);
|
| Dispatch(kBranchIfFalseWideLength);
|
|
|
| @@ -1004,7 +1012,8 @@ void InterpreterGeneratorARM::DoBranchBackIfTrue() {
|
|
|
| Label branch;
|
| Pop(R1);
|
| - __ cmp(R1, R10);
|
| + LoadTrue(R2);
|
| + __ cmp(R1, R2);
|
| __ b(EQ, &branch);
|
| Dispatch(kBranchBackIfTrueLength);
|
|
|
| @@ -1019,7 +1028,8 @@ void InterpreterGeneratorARM::DoBranchBackIfFalse() {
|
|
|
| Label branch;
|
| Pop(R1);
|
| - __ cmp(R1, R10);
|
| + LoadTrue(R2);
|
| + __ cmp(R1, R2);
|
| __ b(NE, &branch);
|
| Dispatch(kBranchBackIfFalseLength);
|
|
|
| @@ -1041,7 +1051,8 @@ void InterpreterGeneratorARM::DoBranchBackIfTrueWide() {
|
|
|
| Label branch;
|
| Pop(R1);
|
| - __ cmp(R10, R1);
|
| + LoadTrue(R2);
|
| + __ cmp(R2, R1);
|
| __ b(EQ, &branch);
|
| Dispatch(kBranchBackIfTrueWideLength);
|
|
|
| @@ -1056,7 +1067,8 @@ void InterpreterGeneratorARM::DoBranchBackIfFalseWide() {
|
|
|
| Label branch;
|
| Pop(R1);
|
| - __ cmp(R10, R1);
|
| + LoadTrue(R2);
|
| + __ cmp(R2, R1);
|
| __ b(NE, &branch);
|
| Dispatch(kBranchBackIfTrueWideLength);
|
|
|
| @@ -1103,8 +1115,10 @@ void InterpreterGeneratorARM::DoAllocateBoxed() {
|
|
|
| void InterpreterGeneratorARM::DoNegate() {
|
| LoadLocal(R1, 0);
|
| - __ cmp(R1, R10);
|
| - ConditionalStore(R11, R10, Address(R6, 0));
|
| + LoadTrue(R2);
|
| + __ cmp(R1, R2);
|
| + AddIf(EQ, R2, kFalseOffset - kTrueOffset);
|
| + StoreLocal(R2, 0);
|
| Dispatch(kNegateLength);
|
| }
|
|
|
| @@ -1253,7 +1267,8 @@ void InterpreterGeneratorARM::DoIdentical() {
|
|
|
| __ Bind(&fast_case);
|
| __ cmp(R1, R0);
|
| - ConditionalStore(R10, R11, Address(R6, kWordSize));
|
| + ToBoolean(EQ, R2);
|
| + StoreLocal(R2, 1);
|
| Drop(1);
|
| Dispatch(kIdenticalLength);
|
|
|
| @@ -1269,7 +1284,8 @@ void InterpreterGeneratorARM::DoIdenticalNonNumeric() {
|
| LoadLocal(R0, 0);
|
| LoadLocal(R1, 1);
|
| __ cmp(R0, R1);
|
| - ConditionalStore(R10, R11, Address(R6, kWordSize));
|
| + ToBoolean(EQ, R2);
|
| + StoreLocal(R2, 1);
|
| Drop(1);
|
| Dispatch(kIdenticalNonNumericLength);
|
| }
|
| @@ -1311,7 +1327,8 @@ void InterpreterGeneratorARM::DoIntrinsicObjectEquals() {
|
| LoadLocal(R0, 0);
|
| LoadLocal(R1, 1);
|
| __ cmp(R0, R1);
|
| - ConditionalStore(R10, R11, Address(R6, -kWordSize));
|
| + ToBoolean(EQ, R2);
|
| + StoreLocal(R2, -1);
|
| Drop(1);
|
| Dispatch(kInvokeMethodLength);
|
| }
|
| @@ -1577,7 +1594,8 @@ void InterpreterGeneratorARM::InvokeMethodUnfold(bool test) {
|
| // we've found a target method.
|
| Label found;
|
| __ tst(R0, R0);
|
| - ConditionalStore(R11, R10, Address(R6, 0));
|
| + ToBoolean(EQ, R2);
|
| + StoreLocal(R2, 0);
|
| Dispatch(kInvokeTestUnfoldLength);
|
| } else {
|
| SaveByteCodePointer(R2);
|
| @@ -1596,8 +1614,7 @@ void InterpreterGeneratorARM::InvokeMethodUnfold(bool test) {
|
| }
|
|
|
| __ Bind(&smi);
|
| - __ ldr(R3, Address(R4, Process::kProgramOffset));
|
| - __ ldr(R2, Address(R3, Program::kSmiClassOffset));
|
| + __ ldr(R2, Address(R10, Program::kSmiClassOffset));
|
| __ b(&probe);
|
|
|
| // We didn't find a valid entry in primary lookup cache.
|
| @@ -1619,8 +1636,7 @@ void InterpreterGeneratorARM::InvokeMethod(bool test) {
|
| __ ldr(R7, Address(R5, 1));
|
|
|
| // Fetch the virtual table from the program.
|
| - __ ldr(R1, Address(R4, Process::kProgramOffset));
|
| - __ ldr(R1, Address(R1, Program::kDispatchTableOffset));
|
| + __ ldr(R1, Address(R10, Program::kDispatchTableOffset));
|
|
|
| if (!test) {
|
| // Compute the arity from the selector.
|
| @@ -1670,7 +1686,8 @@ void InterpreterGeneratorARM::InvokeMethod(bool test) {
|
| Label validated, intrinsified;
|
| if (test) {
|
| // Valid entry: The answer is true.
|
| - StoreLocal(R10, 0);
|
| + LoadTrue(R2);
|
| + StoreLocal(R2, 0);
|
| Dispatch(kInvokeTestLength);
|
| } else {
|
| __ Bind(&validated);
|
| @@ -1696,14 +1713,14 @@ void InterpreterGeneratorARM::InvokeMethod(bool test) {
|
| }
|
|
|
| __ Bind(&smi);
|
| - __ ldr(R2, Address(R4, Process::kProgramOffset));
|
| - __ ldr(R2, Address(R2, Program::kSmiClassOffset));
|
| + __ ldr(R2, Address(R10, Program::kSmiClassOffset));
|
| __ b(&dispatch);
|
|
|
| if (test) {
|
| // Invalid entry: The answer is false.
|
| __ Bind(&invalid);
|
| - StoreLocal(R11, 0);
|
| + LoadFalse(R2);
|
| + StoreLocal(R2, 0);
|
| Dispatch(kInvokeTestLength);
|
| } else {
|
| __ Bind(&intrinsified);
|
| @@ -1712,8 +1729,7 @@ void InterpreterGeneratorARM::InvokeMethod(bool test) {
|
| // Invalid entry: Use the noSuchMethod entry from entry zero of
|
| // the virtual table.
|
| __ Bind(&invalid);
|
| - __ ldr(R1, Address(R4, Process::kProgramOffset));
|
| - __ ldr(R1, Address(R1, Program::kDispatchTableOffset));
|
| + __ ldr(R1, Address(R10, Program::kDispatchTableOffset));
|
| __ ldr(R1, Address(R1, Array::kSize - HeapObject::kTag));
|
| __ b(&validated);
|
| }
|
| @@ -1966,26 +1982,28 @@ void InterpreterGeneratorARM::InvokeCompare(const char* fallback,
|
|
|
| Label true_case;
|
| __ cmp(R1, R0);
|
| - __ b(cond, &true_case);
|
| -
|
| - DropNAndSetTop(1, R11);
|
| + ToBoolean(cond, R2);
|
| + DropNAndSetTop(1, R2);
|
| Dispatch(5);
|
| +}
|
|
|
| - __ Bind(&true_case);
|
| - DropNAndSetTop(1, R10);
|
| - Dispatch(5);
|
| +void InterpreterGeneratorARM::AddIf(Condition cond, Register reg,
|
| + int add_if_eq) {
|
| + __ it(cond);
|
| + __ add(cond, reg, reg, Immediate(add_if_eq));
|
| }
|
|
|
| -void InterpreterGeneratorARM::ConditionalStore(Register reg_if_eq,
|
| - Register reg_if_ne,
|
| - const Address& address) {
|
| - Label if_ne, done;
|
| - __ b(NE, &if_ne);
|
| - __ str(reg_if_eq, address);
|
| - __ b(&done);
|
| - __ Bind(&if_ne);
|
| - __ str(reg_if_ne, address);
|
| - __ Bind(&done);
|
| +void InterpreterGeneratorARM::LoadTrue(Register reg) {
|
| + __ add(reg, R8, Immediate(kTrueOffset));
|
| +}
|
| +
|
| +void InterpreterGeneratorARM::LoadFalse(Register reg) {
|
| + __ add(reg, R8, Immediate(kFalseOffset));
|
| +}
|
| +
|
| +void InterpreterGeneratorARM::ToBoolean(Condition cond, Register reg) {
|
| + LoadFalse(reg);
|
| + AddIf(cond, reg, kTrueOffset - kFalseOffset);
|
| }
|
|
|
| void InterpreterGeneratorARM::CheckStackOverflow(int size) {
|
| @@ -2012,8 +2030,7 @@ void InterpreterGeneratorARM::Dispatch(int size) {
|
| #else
|
| __ ldrb(R7, Address(R5, size), WRITE_BACK);
|
| #endif
|
| - __ ldr(R9, "Interpret_DispatchTable");
|
| - __ ldr(PC, Address(R9, Operand(R7, TIMES_WORD_SIZE)));
|
| + __ ldr(PC, Address(R11, Operand(R7, TIMES_WORD_SIZE)));
|
| __ GenerateConstantPool();
|
| }
|
|
|
| @@ -2048,9 +2065,8 @@ void InterpreterGeneratorARM::RestoreState() {
|
|
|
| // Load constants into registers.
|
| __ ldr(R10, Address(R4, Process::kProgramOffset));
|
| - __ ldr(R11, Address(R10, Program::kFalseObjectOffset));
|
| __ ldr(R8, Address(R10, Program::kNullObjectOffset));
|
| - __ ldr(R10, Address(R10, Program::kTrueObjectOffset));
|
| + __ ldr(R11, "Interpret_DispatchTable");
|
|
|
| // Pop and store frame pointer.
|
| Pop(R5);
|
|
|