| OLD | NEW |
| 1 // Copyright (c) 2015, the Dartino project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, the Dartino project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE.md file. | 3 // BSD-style license that can be found in the LICENSE.md file. |
| 4 | 4 |
| 5 #if defined(DARTINO_TARGET_ARM) | 5 #if defined(DARTINO_TARGET_ARM) |
| 6 | 6 |
| 7 #include "src/shared/bytecodes.h" | 7 #include "src/shared/bytecodes.h" |
| 8 #include "src/shared/names.h" | 8 #include "src/shared/names.h" |
| 9 #include "src/shared/selectors.h" | 9 #include "src/shared/selectors.h" |
| 10 | 10 |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 79 #undef V | 79 #undef V |
| 80 } | 80 } |
| 81 | 81 |
| 82 class InterpreterGeneratorARM : public InterpreterGenerator { | 82 class InterpreterGeneratorARM : public InterpreterGenerator { |
| 83 public: | 83 public: |
| 84 explicit InterpreterGeneratorARM(Assembler* assembler) | 84 explicit InterpreterGeneratorARM(Assembler* assembler) |
| 85 : InterpreterGenerator(assembler), spill_size_(-1) {} | 85 : InterpreterGenerator(assembler), spill_size_(-1) {} |
| 86 | 86 |
| 87 // Registers | 87 // Registers |
| 88 // --------- | 88 // --------- |
| 89 // r4: current process | 89 // R4: current process |
| 90 // r5: bytecode pointer | 90 // R5: bytecode pointer |
| 91 // r6: stack pointer (top) | 91 // R6: stack pointer (top) |
| 92 // r8: null | 92 // R8: null |
| 93 // r10: true | 93 // R10: program |
| 94 // r11: false | 94 // R11: dispatch table |
| 95 | 95 |
| 96 virtual void GeneratePrologue(); | 96 virtual void GeneratePrologue(); |
| 97 virtual void GenerateEpilogue(); | 97 virtual void GenerateEpilogue(); |
| 98 | 98 |
| 99 virtual void GenerateMethodEntry(); | 99 virtual void GenerateMethodEntry(); |
| 100 | 100 |
| 101 virtual void GenerateBytecodePrologue(const char* name); | 101 virtual void GenerateBytecodePrologue(const char* name); |
| 102 virtual void GenerateDebugAtBytecode(); | 102 virtual void GenerateDebugAtBytecode(); |
| 103 | 103 |
| 104 virtual void DoLoadLocal0(); | 104 virtual void DoLoadLocal0(); |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 232 private: | 232 private: |
| 233 Label done_; | 233 Label done_; |
| 234 Label done_state_saved_; | 234 Label done_state_saved_; |
| 235 Label check_stack_overflow_; | 235 Label check_stack_overflow_; |
| 236 Label check_stack_overflow_0_; | 236 Label check_stack_overflow_0_; |
| 237 Label gc_; | 237 Label gc_; |
| 238 Label intrinsic_failure_; | 238 Label intrinsic_failure_; |
| 239 Label interpreter_entry_; | 239 Label interpreter_entry_; |
| 240 int spill_size_; | 240 int spill_size_; |
| 241 | 241 |
| 242 static const int kFalseOffset = 8; |
| 243 static const int kTrueOffset = 16; |
| 244 |
| 242 void LoadLocal(Register reg, int index); | 245 void LoadLocal(Register reg, int index); |
| 243 void StoreLocal(Register reg, int index); | 246 void StoreLocal(Register reg, int index); |
| 244 | 247 |
| 245 void Push(Register reg); | 248 void Push(Register reg); |
| 246 void Pop(Register reg); | 249 void Pop(Register reg); |
| 247 void Drop(int n); | 250 void Drop(int n); |
| 248 void Drop(Register reg); | 251 void Drop(Register reg); |
| 249 void DropNAndSetTop(int dropping_slots, Register reg); | 252 void DropNAndSetTop(int dropping_slots, Register reg); |
| 250 | 253 |
| 251 void LoadFramePointer(Register reg); | 254 void LoadFramePointer(Register reg); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 283 void InvokeBitXor(const char* fallback); | 286 void InvokeBitXor(const char* fallback); |
| 284 void InvokeBitShr(const char* fallback); | 287 void InvokeBitShr(const char* fallback); |
| 285 void InvokeBitShl(const char* fallback); | 288 void InvokeBitShl(const char* fallback); |
| 286 | 289 |
| 287 void InvokeMethodUnfold(bool test); | 290 void InvokeMethodUnfold(bool test); |
| 288 void InvokeMethod(bool test); | 291 void InvokeMethod(bool test); |
| 289 | 292 |
| 290 void InvokeNative(bool yield, bool safepoint); | 293 void InvokeNative(bool yield, bool safepoint); |
| 291 void InvokeStatic(); | 294 void InvokeStatic(); |
| 292 | 295 |
| 293 void ConditionalStore(Register reg_if_eq, Register reg_if_ne, | 296 void AddIf(Condition cond, Register reg, int immediate); |
| 294 const Address& address); | 297 void ToBoolean(Condition cond, Register reg); |
| 298 void LoadFalse(Register reg); |
| 299 void LoadTrue(Register reg); |
| 295 | 300 |
| 296 void CheckStackOverflow(int size); | 301 void CheckStackOverflow(int size); |
| 297 | 302 |
| 298 void Dispatch(int size); | 303 void Dispatch(int size); |
| 299 | 304 |
| 300 void SaveState(Label* resume); | 305 void SaveState(Label* resume); |
| 301 void RestoreState(); | 306 void RestoreState(); |
| 302 | 307 |
| 303 static int ComputeStackPadding(int reserved, int extra) { | 308 static int ComputeStackPadding(int reserved, int extra) { |
| 304 const int kAlignment = 8; | 309 const int kAlignment = 8; |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 396 __ b(NE, &overflow); | 401 __ b(NE, &overflow); |
| 397 __ mov(R0, Immediate(Interpreter::kBreakpoint)); | 402 __ mov(R0, Immediate(Interpreter::kBreakpoint)); |
| 398 __ b(&done_); | 403 __ b(&done_); |
| 399 | 404 |
| 400 __ Bind(&stay_fast); | 405 __ Bind(&stay_fast); |
| 401 Dispatch(0); | 406 Dispatch(0); |
| 402 | 407 |
| 403 __ Bind(&overflow); | 408 __ Bind(&overflow); |
| 404 Label throw_resume; | 409 Label throw_resume; |
| 405 SaveState(&throw_resume); | 410 SaveState(&throw_resume); |
| 406 __ ldr(R7, Address(R4, Process::kProgramOffset)); | 411 __ ldr(R7, Address(R10, Program::kStackOverflowErrorOffset)); |
| 407 __ ldr(R7, Address(R7, Program::kStackOverflowErrorOffset)); | |
| 408 DoThrowAfterSaveState(&throw_resume); | 412 DoThrowAfterSaveState(&throw_resume); |
| 409 | 413 |
| 410 // Intrinsic failure: Just invoke the method. | 414 // Intrinsic failure: Just invoke the method. |
| 411 __ Bind(&intrinsic_failure_); | 415 __ Bind(&intrinsic_failure_); |
| 412 __ b("InterpreterMethodEntry"); | 416 __ b("InterpreterMethodEntry"); |
| 413 } | 417 } |
| 414 | 418 |
| 415 void InterpreterGeneratorARM::GenerateMethodEntry() { | 419 void InterpreterGeneratorARM::GenerateMethodEntry() { |
| 416 __ SwitchToText(); | 420 __ SwitchToText(); |
| 417 __ AlignToPowerOfTwo(3); | 421 __ AlignToPowerOfTwo(3); |
| (...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 633 | 637 |
| 634 Dispatch(kStoreFieldWideLength); | 638 Dispatch(kStoreFieldWideLength); |
| 635 } | 639 } |
| 636 | 640 |
| 637 void InterpreterGeneratorARM::DoLoadLiteralNull() { | 641 void InterpreterGeneratorARM::DoLoadLiteralNull() { |
| 638 Push(R8); | 642 Push(R8); |
| 639 Dispatch(kLoadLiteralNullLength); | 643 Dispatch(kLoadLiteralNullLength); |
| 640 } | 644 } |
| 641 | 645 |
| 642 void InterpreterGeneratorARM::DoLoadLiteralTrue() { | 646 void InterpreterGeneratorARM::DoLoadLiteralTrue() { |
| 643 Push(R10); | 647 LoadTrue(R2); |
| 648 Push(R2); |
| 644 Dispatch(kLoadLiteralTrueLength); | 649 Dispatch(kLoadLiteralTrueLength); |
| 645 } | 650 } |
| 646 | 651 |
| 647 void InterpreterGeneratorARM::DoLoadLiteralFalse() { | 652 void InterpreterGeneratorARM::DoLoadLiteralFalse() { |
| 648 Push(R11); | 653 LoadFalse(R2); |
| 654 Push(R2); |
| 649 Dispatch(kLoadLiteralFalseLength); | 655 Dispatch(kLoadLiteralFalseLength); |
| 650 } | 656 } |
| 651 | 657 |
| 652 void InterpreterGeneratorARM::DoLoadLiteral0() { | 658 void InterpreterGeneratorARM::DoLoadLiteral0() { |
| 653 __ mov(R0, Immediate(reinterpret_cast<int32_t>(Smi::FromWord(0)))); | 659 __ mov(R0, Immediate(reinterpret_cast<int32_t>(Smi::FromWord(0)))); |
| 654 Push(R0); | 660 Push(R0); |
| 655 Dispatch(kLoadLiteral0Length); | 661 Dispatch(kLoadLiteral0Length); |
| 656 } | 662 } |
| 657 | 663 |
| 658 void InterpreterGeneratorARM::DoLoadLiteral1() { | 664 void InterpreterGeneratorARM::DoLoadLiteral1() { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 678 } | 684 } |
| 679 | 685 |
| 680 void InterpreterGeneratorARM::DoInvokeMethodUnfold() { | 686 void InterpreterGeneratorARM::DoInvokeMethodUnfold() { |
| 681 InvokeMethodUnfold(false); | 687 InvokeMethodUnfold(false); |
| 682 } | 688 } |
| 683 | 689 |
| 684 void InterpreterGeneratorARM::DoInvokeMethod() { InvokeMethod(false); } | 690 void InterpreterGeneratorARM::DoInvokeMethod() { InvokeMethod(false); } |
| 685 | 691 |
| 686 void InterpreterGeneratorARM::DoInvokeNoSuchMethod() { | 692 void InterpreterGeneratorARM::DoInvokeNoSuchMethod() { |
| 687 // Use the noSuchMethod entry from entry zero of the virtual table. | 693 // Use the noSuchMethod entry from entry zero of the virtual table. |
| 688 __ ldr(R1, Address(R4, Process::kProgramOffset)); | 694 __ ldr(R1, Address(R10, Program::kDispatchTableOffset)); |
| 689 __ ldr(R1, Address(R1, Program::kDispatchTableOffset)); | |
| 690 __ ldr(R1, Address(R1, Array::kSize - HeapObject::kTag)); | 695 __ ldr(R1, Address(R1, Array::kSize - HeapObject::kTag)); |
| 691 | 696 |
| 692 // Load the function. | 697 // Load the function. |
| 693 __ ldr(R0, | 698 __ ldr(R0, |
| 694 Address(R1, DispatchTableEntry::kTargetOffset - HeapObject::kTag)); | 699 Address(R1, DispatchTableEntry::kTargetOffset - HeapObject::kTag)); |
| 695 | 700 |
| 696 SaveByteCodePointer(R2); | 701 SaveByteCodePointer(R2); |
| 697 __ bl("InterpreterMethodEntry"); | 702 __ bl("InterpreterMethodEntry"); |
| 698 RestoreByteCodePointer(R2); | 703 RestoreByteCodePointer(R2); |
| 699 | 704 |
| 700 __ ldr(R7, Address(R5, 1)); | 705 __ ldr(R7, Address(R5, 1)); |
| 701 // Compute the arity from the selector. | 706 // Compute the arity from the selector. |
| 702 ASSERT(Selector::ArityField::shift() == 0); | 707 ASSERT(Selector::ArityField::shift() == 0); |
| 703 __ and_(R2, R7, Immediate(Selector::ArityField::mask())); | 708 __ and_(R2, R7, Immediate(Selector::ArityField::mask())); |
| 704 | 709 |
| 705 Drop(R2); | 710 Drop(R2); |
| 706 | 711 |
| 707 StoreLocal(R0, 0); | 712 StoreLocal(R0, 0); |
| 708 Dispatch(kInvokeNoSuchMethodLength); | 713 Dispatch(kInvokeNoSuchMethodLength); |
| 709 } | 714 } |
| 710 | 715 |
| 711 void InterpreterGeneratorARM::DoInvokeTestNoSuchMethod() { | 716 void InterpreterGeneratorARM::DoInvokeTestNoSuchMethod() { |
| 712 StoreLocal(R11, 0); | 717 LoadFalse(R2); |
| 718 StoreLocal(R2, 0); |
| 713 Dispatch(kInvokeTestNoSuchMethodLength); | 719 Dispatch(kInvokeTestNoSuchMethodLength); |
| 714 } | 720 } |
| 715 | 721 |
| 716 void InterpreterGeneratorARM::DoInvokeTestUnfold() { InvokeMethodUnfold(true); } | 722 void InterpreterGeneratorARM::DoInvokeTestUnfold() { InvokeMethodUnfold(true); } |
| 717 | 723 |
| 718 void InterpreterGeneratorARM::DoInvokeTest() { InvokeMethod(true); } | 724 void InterpreterGeneratorARM::DoInvokeTest() { InvokeMethod(true); } |
| 719 | 725 |
| 720 void InterpreterGeneratorARM::DoInvokeStatic() { InvokeStatic(); } | 726 void InterpreterGeneratorARM::DoInvokeStatic() { InvokeStatic(); } |
| 721 | 727 |
| 722 void InterpreterGeneratorARM::DoInvokeFactory() { InvokeStatic(); } | 728 void InterpreterGeneratorARM::DoInvokeFactory() { InvokeStatic(); } |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 962 | 968 |
| 963 void InterpreterGeneratorARM::DoBranchWide() { | 969 void InterpreterGeneratorARM::DoBranchWide() { |
| 964 __ ldr(R0, Address(R5, 1)); | 970 __ ldr(R0, Address(R5, 1)); |
| 965 __ adds(R5, R5, R0); | 971 __ adds(R5, R5, R0); |
| 966 Dispatch(0); | 972 Dispatch(0); |
| 967 } | 973 } |
| 968 | 974 |
| 969 void InterpreterGeneratorARM::DoBranchIfTrueWide() { | 975 void InterpreterGeneratorARM::DoBranchIfTrueWide() { |
| 970 Label branch; | 976 Label branch; |
| 971 Pop(R7); | 977 Pop(R7); |
| 972 __ cmp(R7, R10); | 978 LoadTrue(R2); |
| 979 __ cmp(R7, R2); |
| 973 __ b(EQ, &branch); | 980 __ b(EQ, &branch); |
| 974 Dispatch(kBranchIfTrueWideLength); | 981 Dispatch(kBranchIfTrueWideLength); |
| 975 | 982 |
| 976 __ Bind(&branch); | 983 __ Bind(&branch); |
| 977 __ ldr(R0, Address(R5, 1)); | 984 __ ldr(R0, Address(R5, 1)); |
| 978 __ adds(R5, R5, R0); | 985 __ adds(R5, R5, R0); |
| 979 Dispatch(0); | 986 Dispatch(0); |
| 980 } | 987 } |
| 981 | 988 |
| 982 void InterpreterGeneratorARM::DoBranchIfFalseWide() { | 989 void InterpreterGeneratorARM::DoBranchIfFalseWide() { |
| 983 Label branch; | 990 Label branch; |
| 984 Pop(R7); | 991 Pop(R7); |
| 985 __ cmp(R7, R10); | 992 LoadTrue(R2); |
| 993 __ cmp(R7, R2); |
| 986 __ b(NE, &branch); | 994 __ b(NE, &branch); |
| 987 Dispatch(kBranchIfFalseWideLength); | 995 Dispatch(kBranchIfFalseWideLength); |
| 988 | 996 |
| 989 __ Bind(&branch); | 997 __ Bind(&branch); |
| 990 __ ldr(R0, Address(R5, 1)); | 998 __ ldr(R0, Address(R5, 1)); |
| 991 __ adds(R5, R5, R0); | 999 __ adds(R5, R5, R0); |
| 992 Dispatch(0); | 1000 Dispatch(0); |
| 993 } | 1001 } |
| 994 | 1002 |
| 995 void InterpreterGeneratorARM::DoBranchBack() { | 1003 void InterpreterGeneratorARM::DoBranchBack() { |
| 996 CheckStackOverflow(0); | 1004 CheckStackOverflow(0); |
| 997 __ ldrb(R0, Address(R5, 1)); | 1005 __ ldrb(R0, Address(R5, 1)); |
| 998 __ subs(R5, R5, R0); | 1006 __ subs(R5, R5, R0); |
| 999 Dispatch(0); | 1007 Dispatch(0); |
| 1000 } | 1008 } |
| 1001 | 1009 |
| 1002 void InterpreterGeneratorARM::DoBranchBackIfTrue() { | 1010 void InterpreterGeneratorARM::DoBranchBackIfTrue() { |
| 1003 CheckStackOverflow(0); | 1011 CheckStackOverflow(0); |
| 1004 | 1012 |
| 1005 Label branch; | 1013 Label branch; |
| 1006 Pop(R1); | 1014 Pop(R1); |
| 1007 __ cmp(R1, R10); | 1015 LoadTrue(R2); |
| 1016 __ cmp(R1, R2); |
| 1008 __ b(EQ, &branch); | 1017 __ b(EQ, &branch); |
| 1009 Dispatch(kBranchBackIfTrueLength); | 1018 Dispatch(kBranchBackIfTrueLength); |
| 1010 | 1019 |
| 1011 __ Bind(&branch); | 1020 __ Bind(&branch); |
| 1012 __ ldrb(R0, Address(R5, 1)); | 1021 __ ldrb(R0, Address(R5, 1)); |
| 1013 __ subs(R5, R5, R0); | 1022 __ subs(R5, R5, R0); |
| 1014 Dispatch(0); | 1023 Dispatch(0); |
| 1015 } | 1024 } |
| 1016 | 1025 |
| 1017 void InterpreterGeneratorARM::DoBranchBackIfFalse() { | 1026 void InterpreterGeneratorARM::DoBranchBackIfFalse() { |
| 1018 CheckStackOverflow(0); | 1027 CheckStackOverflow(0); |
| 1019 | 1028 |
| 1020 Label branch; | 1029 Label branch; |
| 1021 Pop(R1); | 1030 Pop(R1); |
| 1022 __ cmp(R1, R10); | 1031 LoadTrue(R2); |
| 1032 __ cmp(R1, R2); |
| 1023 __ b(NE, &branch); | 1033 __ b(NE, &branch); |
| 1024 Dispatch(kBranchBackIfFalseLength); | 1034 Dispatch(kBranchBackIfFalseLength); |
| 1025 | 1035 |
| 1026 __ Bind(&branch); | 1036 __ Bind(&branch); |
| 1027 __ ldrb(R0, Address(R5, 1)); | 1037 __ ldrb(R0, Address(R5, 1)); |
| 1028 __ subs(R5, R5, R0); | 1038 __ subs(R5, R5, R0); |
| 1029 Dispatch(0); | 1039 Dispatch(0); |
| 1030 } | 1040 } |
| 1031 | 1041 |
| 1032 void InterpreterGeneratorARM::DoBranchBackWide() { | 1042 void InterpreterGeneratorARM::DoBranchBackWide() { |
| 1033 CheckStackOverflow(0); | 1043 CheckStackOverflow(0); |
| 1034 __ ldr(R0, Address(R5, 1)); | 1044 __ ldr(R0, Address(R5, 1)); |
| 1035 __ subs(R5, R5, R0); | 1045 __ subs(R5, R5, R0); |
| 1036 Dispatch(0); | 1046 Dispatch(0); |
| 1037 } | 1047 } |
| 1038 | 1048 |
| 1039 void InterpreterGeneratorARM::DoBranchBackIfTrueWide() { | 1049 void InterpreterGeneratorARM::DoBranchBackIfTrueWide() { |
| 1040 CheckStackOverflow(0); | 1050 CheckStackOverflow(0); |
| 1041 | 1051 |
| 1042 Label branch; | 1052 Label branch; |
| 1043 Pop(R1); | 1053 Pop(R1); |
| 1044 __ cmp(R10, R1); | 1054 LoadTrue(R2); |
| 1055 __ cmp(R2, R1); |
| 1045 __ b(EQ, &branch); | 1056 __ b(EQ, &branch); |
| 1046 Dispatch(kBranchBackIfTrueWideLength); | 1057 Dispatch(kBranchBackIfTrueWideLength); |
| 1047 | 1058 |
| 1048 __ Bind(&branch); | 1059 __ Bind(&branch); |
| 1049 __ ldr(R0, Address(R5, 1)); | 1060 __ ldr(R0, Address(R5, 1)); |
| 1050 __ subs(R5, R5, R0); | 1061 __ subs(R5, R5, R0); |
| 1051 Dispatch(0); | 1062 Dispatch(0); |
| 1052 } | 1063 } |
| 1053 | 1064 |
| 1054 void InterpreterGeneratorARM::DoBranchBackIfFalseWide() { | 1065 void InterpreterGeneratorARM::DoBranchBackIfFalseWide() { |
| 1055 CheckStackOverflow(0); | 1066 CheckStackOverflow(0); |
| 1056 | 1067 |
| 1057 Label branch; | 1068 Label branch; |
| 1058 Pop(R1); | 1069 Pop(R1); |
| 1059 __ cmp(R10, R1); | 1070 LoadTrue(R2); |
| 1071 __ cmp(R2, R1); |
| 1060 __ b(NE, &branch); | 1072 __ b(NE, &branch); |
| 1061 Dispatch(kBranchBackIfTrueWideLength); | 1073 Dispatch(kBranchBackIfTrueWideLength); |
| 1062 | 1074 |
| 1063 __ Bind(&branch); | 1075 __ Bind(&branch); |
| 1064 __ ldr(R0, Address(R5, 1)); | 1076 __ ldr(R0, Address(R5, 1)); |
| 1065 __ subs(R5, R5, R0); | 1077 __ subs(R5, R5, R0); |
| 1066 Dispatch(0); | 1078 Dispatch(0); |
| 1067 } | 1079 } |
| 1068 | 1080 |
| 1069 void InterpreterGeneratorARM::DoPopAndBranchWide() { | 1081 void InterpreterGeneratorARM::DoPopAndBranchWide() { |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1096 __ bl("HandleAllocateBoxed"); | 1108 __ bl("HandleAllocateBoxed"); |
| 1097 __ and_(R1, R0, Immediate(Failure::kTagMask | Failure::kTypeMask)); | 1109 __ and_(R1, R0, Immediate(Failure::kTagMask | Failure::kTypeMask)); |
| 1098 __ cmp(R1, Immediate(Failure::kTag)); | 1110 __ cmp(R1, Immediate(Failure::kTag)); |
| 1099 __ b(EQ, &gc_); | 1111 __ b(EQ, &gc_); |
| 1100 StoreLocal(R0, 0); | 1112 StoreLocal(R0, 0); |
| 1101 Dispatch(kAllocateBoxedLength); | 1113 Dispatch(kAllocateBoxedLength); |
| 1102 } | 1114 } |
| 1103 | 1115 |
| 1104 void InterpreterGeneratorARM::DoNegate() { | 1116 void InterpreterGeneratorARM::DoNegate() { |
| 1105 LoadLocal(R1, 0); | 1117 LoadLocal(R1, 0); |
| 1106 __ cmp(R1, R10); | 1118 LoadTrue(R2); |
| 1107 ConditionalStore(R11, R10, Address(R6, 0)); | 1119 __ cmp(R1, R2); |
| 1120 AddIf(EQ, R2, kFalseOffset - kTrueOffset); |
| 1121 StoreLocal(R2, 0); |
| 1108 Dispatch(kNegateLength); | 1122 Dispatch(kNegateLength); |
| 1109 } | 1123 } |
| 1110 | 1124 |
| 1111 void InterpreterGeneratorARM::DoStackOverflowCheck() { | 1125 void InterpreterGeneratorARM::DoStackOverflowCheck() { |
| 1112 __ ldr(R0, Address(R5, 1)); | 1126 __ ldr(R0, Address(R5, 1)); |
| 1113 __ ldr(R1, Address(R4, Process::kStackLimitOffset)); | 1127 __ ldr(R1, Address(R4, Process::kStackLimitOffset)); |
| 1114 __ sub(R3, R6, Operand(R0, TIMES_WORD_SIZE)); | 1128 __ sub(R3, R6, Operand(R0, TIMES_WORD_SIZE)); |
| 1115 __ cmp(R3, R1); | 1129 __ cmp(R3, R1); |
| 1116 __ b(LS, &check_stack_overflow_); | 1130 __ b(LS, &check_stack_overflow_); |
| 1117 Dispatch(kStackOverflowCheckLength); | 1131 Dispatch(kStackOverflowCheckLength); |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1246 int type_field_shift = InstanceFormat::TypeField::shift(); | 1260 int type_field_shift = InstanceFormat::TypeField::shift(); |
| 1247 | 1261 |
| 1248 __ and_(R2, R2, Immediate(InstanceFormat::TypeField::mask())); | 1262 __ and_(R2, R2, Immediate(InstanceFormat::TypeField::mask())); |
| 1249 __ cmp(R2, Immediate(double_type << type_field_shift)); | 1263 __ cmp(R2, Immediate(double_type << type_field_shift)); |
| 1250 __ b(EQ, &bail_out); | 1264 __ b(EQ, &bail_out); |
| 1251 __ cmp(R2, Immediate(large_integer_type << type_field_shift)); | 1265 __ cmp(R2, Immediate(large_integer_type << type_field_shift)); |
| 1252 __ b(EQ, &bail_out); | 1266 __ b(EQ, &bail_out); |
| 1253 | 1267 |
| 1254 __ Bind(&fast_case); | 1268 __ Bind(&fast_case); |
| 1255 __ cmp(R1, R0); | 1269 __ cmp(R1, R0); |
| 1256 ConditionalStore(R10, R11, Address(R6, kWordSize)); | 1270 ToBoolean(EQ, R2); |
| 1271 StoreLocal(R2, 1); |
| 1257 Drop(1); | 1272 Drop(1); |
| 1258 Dispatch(kIdenticalLength); | 1273 Dispatch(kIdenticalLength); |
| 1259 | 1274 |
| 1260 __ Bind(&bail_out); | 1275 __ Bind(&bail_out); |
| 1261 __ mov(R2, R0); | 1276 __ mov(R2, R0); |
| 1262 __ mov(R0, R4); | 1277 __ mov(R0, R4); |
| 1263 __ bl("HandleIdentical"); | 1278 __ bl("HandleIdentical"); |
| 1264 DropNAndSetTop(1, R0); | 1279 DropNAndSetTop(1, R0); |
| 1265 Dispatch(kIdenticalLength); | 1280 Dispatch(kIdenticalLength); |
| 1266 } | 1281 } |
| 1267 | 1282 |
| 1268 void InterpreterGeneratorARM::DoIdenticalNonNumeric() { | 1283 void InterpreterGeneratorARM::DoIdenticalNonNumeric() { |
| 1269 LoadLocal(R0, 0); | 1284 LoadLocal(R0, 0); |
| 1270 LoadLocal(R1, 1); | 1285 LoadLocal(R1, 1); |
| 1271 __ cmp(R0, R1); | 1286 __ cmp(R0, R1); |
| 1272 ConditionalStore(R10, R11, Address(R6, kWordSize)); | 1287 ToBoolean(EQ, R2); |
| 1288 StoreLocal(R2, 1); |
| 1273 Drop(1); | 1289 Drop(1); |
| 1274 Dispatch(kIdenticalNonNumericLength); | 1290 Dispatch(kIdenticalNonNumericLength); |
| 1275 } | 1291 } |
| 1276 | 1292 |
| 1277 void InterpreterGeneratorARM::DoEnterNoSuchMethod() { | 1293 void InterpreterGeneratorARM::DoEnterNoSuchMethod() { |
| 1278 SaveState(&interpreter_entry_); | 1294 SaveState(&interpreter_entry_); |
| 1279 __ mov(R0, R4); | 1295 __ mov(R0, R4); |
| 1280 __ bl("HandleEnterNoSuchMethod"); | 1296 __ bl("HandleEnterNoSuchMethod"); |
| 1281 RestoreState(); | 1297 RestoreState(); |
| 1282 } | 1298 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1304 Pop(LR); | 1320 Pop(LR); |
| 1305 __ mov(PC, LR); | 1321 __ mov(PC, LR); |
| 1306 } | 1322 } |
| 1307 | 1323 |
| 1308 void InterpreterGeneratorARM::DoMethodEnd() { __ bkpt(); } | 1324 void InterpreterGeneratorARM::DoMethodEnd() { __ bkpt(); } |
| 1309 | 1325 |
| 1310 void InterpreterGeneratorARM::DoIntrinsicObjectEquals() { | 1326 void InterpreterGeneratorARM::DoIntrinsicObjectEquals() { |
| 1311 LoadLocal(R0, 0); | 1327 LoadLocal(R0, 0); |
| 1312 LoadLocal(R1, 1); | 1328 LoadLocal(R1, 1); |
| 1313 __ cmp(R0, R1); | 1329 __ cmp(R0, R1); |
| 1314 ConditionalStore(R10, R11, Address(R6, -kWordSize)); | 1330 ToBoolean(EQ, R2); |
| 1331 StoreLocal(R2, -1); |
| 1315 Drop(1); | 1332 Drop(1); |
| 1316 Dispatch(kInvokeMethodLength); | 1333 Dispatch(kInvokeMethodLength); |
| 1317 } | 1334 } |
| 1318 | 1335 |
| 1319 void InterpreterGeneratorARM::DoIntrinsicGetField() { | 1336 void InterpreterGeneratorARM::DoIntrinsicGetField() { |
| 1320 __ ldrb(R1, Address(R0, 2 + Function::kSize - HeapObject::kTag)); | 1337 __ ldrb(R1, Address(R0, 2 + Function::kSize - HeapObject::kTag)); |
| 1321 LoadLocal(R0, 0); | 1338 LoadLocal(R0, 0); |
| 1322 __ adds(R0, R0, Immediate(Instance::kSize - HeapObject::kTag)); | 1339 __ adds(R0, R0, Immediate(Instance::kSize - HeapObject::kTag)); |
| 1323 __ ldr(R0, Address(R0, Operand(R1, TIMES_WORD_SIZE))); | 1340 __ ldr(R0, Address(R0, Operand(R1, TIMES_WORD_SIZE))); |
| 1324 | 1341 |
| (...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1570 __ b(NE, &hit); | 1587 __ b(NE, &hit); |
| 1571 __ ldr(R0, "InterpreterMethodEntry"); | 1588 __ ldr(R0, "InterpreterMethodEntry"); |
| 1572 __ Bind(&hit); | 1589 __ Bind(&hit); |
| 1573 } | 1590 } |
| 1574 | 1591 |
| 1575 if (test) { | 1592 if (test) { |
| 1576 // Materialize either true or false depending on whether or not | 1593 // Materialize either true or false depending on whether or not |
| 1577 // we've found a target method. | 1594 // we've found a target method. |
| 1578 Label found; | 1595 Label found; |
| 1579 __ tst(R0, R0); | 1596 __ tst(R0, R0); |
| 1580 ConditionalStore(R11, R10, Address(R6, 0)); | 1597 ToBoolean(EQ, R2); |
| 1598 StoreLocal(R2, 0); |
| 1581 Dispatch(kInvokeTestUnfoldLength); | 1599 Dispatch(kInvokeTestUnfoldLength); |
| 1582 } else { | 1600 } else { |
| 1583 SaveByteCodePointer(R2); | 1601 SaveByteCodePointer(R2); |
| 1584 __ bl("InterpreterMethodEntry"); | 1602 __ bl("InterpreterMethodEntry"); |
| 1585 RestoreByteCodePointer(R2); | 1603 RestoreByteCodePointer(R2); |
| 1586 | 1604 |
| 1587 __ ldr(R7, Address(R5, 1)); | 1605 __ ldr(R7, Address(R5, 1)); |
| 1588 // Compute the arity from the selector. | 1606 // Compute the arity from the selector. |
| 1589 ASSERT(Selector::ArityField::shift() == 0); | 1607 ASSERT(Selector::ArityField::shift() == 0); |
| 1590 __ and_(R2, R7, Immediate(Selector::ArityField::mask())); | 1608 __ and_(R2, R7, Immediate(Selector::ArityField::mask())); |
| 1591 | 1609 |
| 1592 Drop(R2); | 1610 Drop(R2); |
| 1593 | 1611 |
| 1594 StoreLocal(R0, 0); | 1612 StoreLocal(R0, 0); |
| 1595 Dispatch(kInvokeMethodUnfoldLength); | 1613 Dispatch(kInvokeMethodUnfoldLength); |
| 1596 } | 1614 } |
| 1597 | 1615 |
| 1598 __ Bind(&smi); | 1616 __ Bind(&smi); |
| 1599 __ ldr(R3, Address(R4, Process::kProgramOffset)); | 1617 __ ldr(R2, Address(R10, Program::kSmiClassOffset)); |
| 1600 __ ldr(R2, Address(R3, Program::kSmiClassOffset)); | |
| 1601 __ b(&probe); | 1618 __ b(&probe); |
| 1602 | 1619 |
| 1603 // We didn't find a valid entry in primary lookup cache. | 1620 // We didn't find a valid entry in primary lookup cache. |
| 1604 __ Bind(&miss); | 1621 __ Bind(&miss); |
| 1605 // Arguments: | 1622 // Arguments: |
| 1606 // - r0: process | 1623 // - r0: process |
| 1607 // - r1: primary cache entry | 1624 // - r1: primary cache entry |
| 1608 // - r2: class (already in r2) | 1625 // - r2: class (already in r2) |
| 1609 // - r3: selector | 1626 // - r3: selector |
| 1610 __ mov(R1, R0); | 1627 __ mov(R1, R0); |
| 1611 __ mov(R0, R4); | 1628 __ mov(R0, R4); |
| 1612 __ mov(R3, R7); | 1629 __ mov(R3, R7); |
| 1613 __ bl("HandleLookupEntry"); | 1630 __ bl("HandleLookupEntry"); |
| 1614 __ b(&finish); | 1631 __ b(&finish); |
| 1615 } | 1632 } |
| 1616 | 1633 |
| 1617 void InterpreterGeneratorARM::InvokeMethod(bool test) { | 1634 void InterpreterGeneratorARM::InvokeMethod(bool test) { |
| 1618 // Get the selector from the bytecodes. | 1635 // Get the selector from the bytecodes. |
| 1619 __ ldr(R7, Address(R5, 1)); | 1636 __ ldr(R7, Address(R5, 1)); |
| 1620 | 1637 |
| 1621 // Fetch the virtual table from the program. | 1638 // Fetch the virtual table from the program. |
| 1622 __ ldr(R1, Address(R4, Process::kProgramOffset)); | 1639 __ ldr(R1, Address(R10, Program::kDispatchTableOffset)); |
| 1623 __ ldr(R1, Address(R1, Program::kDispatchTableOffset)); | |
| 1624 | 1640 |
| 1625 if (!test) { | 1641 if (!test) { |
| 1626 // Compute the arity from the selector. | 1642 // Compute the arity from the selector. |
| 1627 ASSERT(Selector::ArityField::shift() == 0); | 1643 ASSERT(Selector::ArityField::shift() == 0); |
| 1628 __ and_(R2, R7, Immediate(Selector::ArityField::mask())); | 1644 __ and_(R2, R7, Immediate(Selector::ArityField::mask())); |
| 1629 } | 1645 } |
| 1630 | 1646 |
| 1631 // Compute the selector offset (smi tagged) from the selector. | 1647 // Compute the selector offset (smi tagged) from the selector. |
| 1632 __ LoadInt(R9, Selector::IdField::mask()); | 1648 __ LoadInt(R9, Selector::IdField::mask()); |
| 1633 __ and_(R7, R7, R9); | 1649 __ and_(R7, R7, R9); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1663 // we used to find it. | 1679 // we used to find it. |
| 1664 Label invalid; | 1680 Label invalid; |
| 1665 __ ldr(R3, Address(R1, DispatchTableEntry::kOffsetOffset - HeapObject::kTag)); | 1681 __ ldr(R3, Address(R1, DispatchTableEntry::kOffsetOffset - HeapObject::kTag)); |
| 1666 __ cmp(R7, R3); | 1682 __ cmp(R7, R3); |
| 1667 __ b(NE, &invalid); | 1683 __ b(NE, &invalid); |
| 1668 | 1684 |
| 1669 // Load the target and the intrinsic from the entry. | 1685 // Load the target and the intrinsic from the entry. |
| 1670 Label validated, intrinsified; | 1686 Label validated, intrinsified; |
| 1671 if (test) { | 1687 if (test) { |
| 1672 // Valid entry: The answer is true. | 1688 // Valid entry: The answer is true. |
| 1673 StoreLocal(R10, 0); | 1689 LoadTrue(R2); |
| 1690 StoreLocal(R2, 0); |
| 1674 Dispatch(kInvokeTestLength); | 1691 Dispatch(kInvokeTestLength); |
| 1675 } else { | 1692 } else { |
| 1676 __ Bind(&validated); | 1693 __ Bind(&validated); |
| 1677 | 1694 |
| 1678 __ ldr(R0, | 1695 __ ldr(R0, |
| 1679 Address(R1, DispatchTableEntry::kTargetOffset - HeapObject::kTag)); | 1696 Address(R1, DispatchTableEntry::kTargetOffset - HeapObject::kTag)); |
| 1680 | 1697 |
| 1681 SaveByteCodePointer(R2); | 1698 SaveByteCodePointer(R2); |
| 1682 __ ldr(R1, | 1699 __ ldr(R1, |
| 1683 Address(R1, DispatchTableEntry::kCodeOffset - HeapObject::kTag)); | 1700 Address(R1, DispatchTableEntry::kCodeOffset - HeapObject::kTag)); |
| 1684 __ blx(R1); | 1701 __ blx(R1); |
| 1685 RestoreByteCodePointer(R2); | 1702 RestoreByteCodePointer(R2); |
| 1686 | 1703 |
| 1687 __ ldr(R7, Address(R5, 1)); | 1704 __ ldr(R7, Address(R5, 1)); |
| 1688 // Compute the arity from the selector. | 1705 // Compute the arity from the selector. |
| 1689 ASSERT(Selector::ArityField::shift() == 0); | 1706 ASSERT(Selector::ArityField::shift() == 0); |
| 1690 __ and_(R2, R7, Immediate(Selector::ArityField::mask())); | 1707 __ and_(R2, R7, Immediate(Selector::ArityField::mask())); |
| 1691 | 1708 |
| 1692 Drop(R2); | 1709 Drop(R2); |
| 1693 | 1710 |
| 1694 StoreLocal(R0, 0); | 1711 StoreLocal(R0, 0); |
| 1695 Dispatch(kInvokeMethodLength); | 1712 Dispatch(kInvokeMethodLength); |
| 1696 } | 1713 } |
| 1697 | 1714 |
| 1698 __ Bind(&smi); | 1715 __ Bind(&smi); |
| 1699 __ ldr(R2, Address(R4, Process::kProgramOffset)); | 1716 __ ldr(R2, Address(R10, Program::kSmiClassOffset)); |
| 1700 __ ldr(R2, Address(R2, Program::kSmiClassOffset)); | |
| 1701 __ b(&dispatch); | 1717 __ b(&dispatch); |
| 1702 | 1718 |
| 1703 if (test) { | 1719 if (test) { |
| 1704 // Invalid entry: The answer is false. | 1720 // Invalid entry: The answer is false. |
| 1705 __ Bind(&invalid); | 1721 __ Bind(&invalid); |
| 1706 StoreLocal(R11, 0); | 1722 LoadFalse(R2); |
| 1723 StoreLocal(R2, 0); |
| 1707 Dispatch(kInvokeTestLength); | 1724 Dispatch(kInvokeTestLength); |
| 1708 } else { | 1725 } else { |
| 1709 __ Bind(&intrinsified); | 1726 __ Bind(&intrinsified); |
| 1710 __ mov(PC, R2); | 1727 __ mov(PC, R2); |
| 1711 | 1728 |
| 1712 // Invalid entry: Use the noSuchMethod entry from entry zero of | 1729 // Invalid entry: Use the noSuchMethod entry from entry zero of |
| 1713 // the virtual table. | 1730 // the virtual table. |
| 1714 __ Bind(&invalid); | 1731 __ Bind(&invalid); |
| 1715 __ ldr(R1, Address(R4, Process::kProgramOffset)); | 1732 __ ldr(R1, Address(R10, Program::kDispatchTableOffset)); |
| 1716 __ ldr(R1, Address(R1, Program::kDispatchTableOffset)); | |
| 1717 __ ldr(R1, Address(R1, Array::kSize - HeapObject::kTag)); | 1733 __ ldr(R1, Address(R1, Array::kSize - HeapObject::kTag)); |
| 1718 __ b(&validated); | 1734 __ b(&validated); |
| 1719 } | 1735 } |
| 1720 } | 1736 } |
| 1721 | 1737 |
| 1722 void InterpreterGeneratorARM::InvokeNative(bool yield, bool safepoint) { | 1738 void InterpreterGeneratorARM::InvokeNative(bool yield, bool safepoint) { |
| 1723 __ ldrb(R1, Address(R5, 1)); | 1739 __ ldrb(R1, Address(R5, 1)); |
| 1724 // Also skip two empty slots. | 1740 // Also skip two empty slots. |
| 1725 __ adds(R1, R1, Immediate(2)); | 1741 __ adds(R1, R1, Immediate(2)); |
| 1726 __ ldrb(R0, Address(R5, 2)); | 1742 __ ldrb(R0, Address(R5, 2)); |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1959 Condition cond) { | 1975 Condition cond) { |
| 1960 LoadLocal(R0, 0); | 1976 LoadLocal(R0, 0); |
| 1961 __ tst(R0, Immediate(Smi::kTagMask)); | 1977 __ tst(R0, Immediate(Smi::kTagMask)); |
| 1962 __ b(NE, fallback); | 1978 __ b(NE, fallback); |
| 1963 LoadLocal(R1, 1); | 1979 LoadLocal(R1, 1); |
| 1964 __ tst(R1, Immediate(Smi::kTagMask)); | 1980 __ tst(R1, Immediate(Smi::kTagMask)); |
| 1965 __ b(NE, fallback); | 1981 __ b(NE, fallback); |
| 1966 | 1982 |
| 1967 Label true_case; | 1983 Label true_case; |
| 1968 __ cmp(R1, R0); | 1984 __ cmp(R1, R0); |
| 1969 __ b(cond, &true_case); | 1985 ToBoolean(cond, R2); |
| 1970 | 1986 DropNAndSetTop(1, R2); |
| 1971 DropNAndSetTop(1, R11); | |
| 1972 Dispatch(5); | |
| 1973 | |
| 1974 __ Bind(&true_case); | |
| 1975 DropNAndSetTop(1, R10); | |
| 1976 Dispatch(5); | 1987 Dispatch(5); |
| 1977 } | 1988 } |
| 1978 | 1989 |
| 1979 void InterpreterGeneratorARM::ConditionalStore(Register reg_if_eq, | 1990 void InterpreterGeneratorARM::AddIf(Condition cond, Register reg, |
| 1980 Register reg_if_ne, | 1991 int add_if_eq) { |
| 1981 const Address& address) { | 1992 __ it(cond); |
| 1982 Label if_ne, done; | 1993 __ add(cond, reg, reg, Immediate(add_if_eq)); |
| 1983 __ b(NE, &if_ne); | 1994 } |
| 1984 __ str(reg_if_eq, address); | 1995 |
| 1985 __ b(&done); | 1996 void InterpreterGeneratorARM::LoadTrue(Register reg) { |
| 1986 __ Bind(&if_ne); | 1997 __ add(reg, R8, Immediate(kTrueOffset)); |
| 1987 __ str(reg_if_ne, address); | 1998 } |
| 1988 __ Bind(&done); | 1999 |
| 2000 void InterpreterGeneratorARM::LoadFalse(Register reg) { |
| 2001 __ add(reg, R8, Immediate(kFalseOffset)); |
| 2002 } |
| 2003 |
| 2004 void InterpreterGeneratorARM::ToBoolean(Condition cond, Register reg) { |
| 2005 LoadFalse(reg); |
| 2006 AddIf(cond, reg, kTrueOffset - kFalseOffset); |
| 1989 } | 2007 } |
| 1990 | 2008 |
| 1991 void InterpreterGeneratorARM::CheckStackOverflow(int size) { | 2009 void InterpreterGeneratorARM::CheckStackOverflow(int size) { |
| 1992 __ ldr(R1, Address(R4, Process::kStackLimitOffset)); | 2010 __ ldr(R1, Address(R4, Process::kStackLimitOffset)); |
| 1993 __ cmp(R6, R1); | 2011 __ cmp(R6, R1); |
| 1994 if (size == 0) { | 2012 if (size == 0) { |
| 1995 __ b(LS, &check_stack_overflow_0_); | 2013 __ b(LS, &check_stack_overflow_0_); |
| 1996 } else { | 2014 } else { |
| 1997 Label done; | 2015 Label done; |
| 1998 __ b(HI, &done); | 2016 __ b(HI, &done); |
| 1999 __ mov(R0, Immediate(size)); | 2017 __ mov(R0, Immediate(size)); |
| 2000 __ b(&check_stack_overflow_); | 2018 __ b(&check_stack_overflow_); |
| 2001 __ Bind(&done); | 2019 __ Bind(&done); |
| 2002 } | 2020 } |
| 2003 } | 2021 } |
| 2004 | 2022 |
| 2005 void InterpreterGeneratorARM::Dispatch(int size) { | 2023 void InterpreterGeneratorARM::Dispatch(int size) { |
| 2006 // Load the next bytecode through R5 and dispatch to it. | 2024 // Load the next bytecode through R5 and dispatch to it. |
| 2007 #ifdef DARTINO_THUMB_ONLY | 2025 #ifdef DARTINO_THUMB_ONLY |
| 2008 __ ldrb(R7, Address(R5, size)); | 2026 __ ldrb(R7, Address(R5, size)); |
| 2009 if (size > 0) { | 2027 if (size > 0) { |
| 2010 __ adds(R5, R5, Immediate(size)); | 2028 __ adds(R5, R5, Immediate(size)); |
| 2011 } | 2029 } |
| 2012 #else | 2030 #else |
| 2013 __ ldrb(R7, Address(R5, size), WRITE_BACK); | 2031 __ ldrb(R7, Address(R5, size), WRITE_BACK); |
| 2014 #endif | 2032 #endif |
| 2015 __ ldr(R9, "Interpret_DispatchTable"); | 2033 __ ldr(PC, Address(R11, Operand(R7, TIMES_WORD_SIZE))); |
| 2016 __ ldr(PC, Address(R9, Operand(R7, TIMES_WORD_SIZE))); | |
| 2017 __ GenerateConstantPool(); | 2034 __ GenerateConstantPool(); |
| 2018 } | 2035 } |
| 2019 | 2036 |
| 2020 void InterpreterGeneratorARM::SaveState(Label* resume) { | 2037 void InterpreterGeneratorARM::SaveState(Label* resume) { |
| 2021 // Save the bytecode pointer at the return-address slot. | 2038 // Save the bytecode pointer at the return-address slot. |
| 2022 LoadFramePointer(R3); | 2039 LoadFramePointer(R3); |
| 2023 __ str(R5, Address(R3, -kWordSize)); | 2040 __ str(R5, Address(R3, -kWordSize)); |
| 2024 | 2041 |
| 2025 // Push resume address. | 2042 // Push resume address. |
| 2026 __ ldr(R5, resume); | 2043 __ ldr(R5, resume); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 2041 void InterpreterGeneratorARM::RestoreState() { | 2058 void InterpreterGeneratorARM::RestoreState() { |
| 2042 // Load the current stack pointer into R6. | 2059 // Load the current stack pointer into R6. |
| 2043 __ ldr(R6, Address(R4, Process::kCoroutineOffset)); | 2060 __ ldr(R6, Address(R4, Process::kCoroutineOffset)); |
| 2044 __ ldr(R6, Address(R6, Coroutine::kStackOffset - HeapObject::kTag)); | 2061 __ ldr(R6, Address(R6, Coroutine::kStackOffset - HeapObject::kTag)); |
| 2045 __ ldr(R5, Address(R6, Stack::kTopOffset - HeapObject::kTag)); | 2062 __ ldr(R5, Address(R6, Stack::kTopOffset - HeapObject::kTag)); |
| 2046 __ adds(R6, R6, Immediate(Stack::kSize - HeapObject::kTag)); | 2063 __ adds(R6, R6, Immediate(Stack::kSize - HeapObject::kTag)); |
| 2047 __ add(R6, R6, Operand(R5, TIMES_2)); | 2064 __ add(R6, R6, Operand(R5, TIMES_2)); |
| 2048 | 2065 |
| 2049 // Load constants into registers. | 2066 // Load constants into registers. |
| 2050 __ ldr(R10, Address(R4, Process::kProgramOffset)); | 2067 __ ldr(R10, Address(R4, Process::kProgramOffset)); |
| 2051 __ ldr(R11, Address(R10, Program::kFalseObjectOffset)); | |
| 2052 __ ldr(R8, Address(R10, Program::kNullObjectOffset)); | 2068 __ ldr(R8, Address(R10, Program::kNullObjectOffset)); |
| 2053 __ ldr(R10, Address(R10, Program::kTrueObjectOffset)); | 2069 __ ldr(R11, "Interpret_DispatchTable"); |
| 2054 | 2070 |
| 2055 // Pop and store frame pointer. | 2071 // Pop and store frame pointer. |
| 2056 Pop(R5); | 2072 Pop(R5); |
| 2057 StoreFramePointer(R5); | 2073 StoreFramePointer(R5); |
| 2058 | 2074 |
| 2059 // Set the bytecode pointer from the stack. | 2075 // Set the bytecode pointer from the stack. |
| 2060 __ ldr(R5, Address(R5, -kWordSize)); | 2076 __ ldr(R5, Address(R5, -kWordSize)); |
| 2061 | 2077 |
| 2062 // Pop and branch to resume address. | 2078 // Pop and branch to resume address. |
| 2063 Pop(LR); | 2079 Pop(LR); |
| 2064 __ mov(PC, LR); | 2080 __ mov(PC, LR); |
| 2065 } | 2081 } |
| 2066 | 2082 |
| 2067 } // namespace dartino | 2083 } // namespace dartino |
| 2068 | 2084 |
| 2069 #endif // defined(DARTINO_TARGET_ARM) | 2085 #endif // defined(DARTINO_TARGET_ARM) |
| OLD | NEW |