Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(75)

Side by Side Diff: src/vm/interpreter_arm.cc

Issue 2067483002: More compact snapshots. (Closed) Base URL: git@github.com:dartino/sdk.git@master
Patch Set: Feedback Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/vm/heap.cc ('k') | src/vm/program.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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)
OLDNEW
« no previous file with comments | « src/vm/heap.cc ('k') | src/vm/program.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698