OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart 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 file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/globals.h" | 5 #include "vm/globals.h" |
6 #if defined(TARGET_ARCH_ARM) | 6 #if defined(TARGET_ARCH_ARM) |
7 | 7 |
8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
9 #include "vm/code_generator.h" | 9 #include "vm/code_generator.h" |
10 #include "vm/cpu.h" | 10 #include "vm/cpu.h" |
(...skipping 748 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
759 // The new Context structure contains a pointer to the current Isolate | 759 // The new Context structure contains a pointer to the current Isolate |
760 // structure. Cache the Context pointer in the CTX register so that it is | 760 // structure. Cache the Context pointer in the CTX register so that it is |
761 // available in generated code and calls to Isolate::Current() need not be | 761 // available in generated code and calls to Isolate::Current() need not be |
762 // done. The assumption is that this register will never be clobbered by | 762 // done. The assumption is that this register will never be clobbered by |
763 // compiled or runtime stub code. | 763 // compiled or runtime stub code. |
764 | 764 |
765 // Cache the new Context pointer into CTX while executing Dart code. | 765 // Cache the new Context pointer into CTX while executing Dart code. |
766 __ ldr(CTX, Address(R3, VMHandles::kOffsetOfRawPtrInHandle)); | 766 __ ldr(CTX, Address(R3, VMHandles::kOffsetOfRawPtrInHandle)); |
767 | 767 |
768 // Load Isolate pointer into temporary register R8. | 768 // Load Isolate pointer into temporary register R8. |
769 __ LoadImmediate(R8, Isolate::CurrentAddress()); | 769 __ LoadIsolate(R8); |
770 | 770 |
771 // Save the current VMTag on the stack. | 771 // Save the current VMTag on the stack. |
772 ASSERT(kSavedVMTagSlotFromEntryFp == -25); | 772 ASSERT(kSavedVMTagSlotFromEntryFp == -25); |
773 __ LoadFromOffset(kWord, R5, R8, Isolate::vm_tag_offset()); | 773 __ LoadFromOffset(kWord, R5, R8, Isolate::vm_tag_offset()); |
774 __ Push(R5); | 774 __ Push(R5); |
775 | 775 |
776 // Mark that the isolate is executing Dart code. | 776 // Mark that the isolate is executing Dart code. |
777 __ LoadImmediate(R5, VMTag::kDartTagId); | 777 __ LoadImmediate(R5, VMTag::kDartTagId); |
778 __ StoreToOffset(kWord, R5, R8, Isolate::vm_tag_offset()); | 778 __ StoreToOffset(kWord, R5, R8, Isolate::vm_tag_offset()); |
779 | 779 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
826 __ blx(R0); // R4 is the arguments descriptor array. | 826 __ blx(R0); // R4 is the arguments descriptor array. |
827 | 827 |
828 // Read the saved new Context pointer. | 828 // Read the saved new Context pointer. |
829 __ ldr(CTX, Address(FP, kNewContextOffsetFromFp)); | 829 __ ldr(CTX, Address(FP, kNewContextOffsetFromFp)); |
830 __ ldr(CTX, Address(CTX, VMHandles::kOffsetOfRawPtrInHandle)); | 830 __ ldr(CTX, Address(CTX, VMHandles::kOffsetOfRawPtrInHandle)); |
831 | 831 |
832 // Get rid of arguments pushed on the stack. | 832 // Get rid of arguments pushed on the stack. |
833 __ AddImmediate(SP, FP, kSavedContextSlotFromEntryFp * kWordSize); | 833 __ AddImmediate(SP, FP, kSavedContextSlotFromEntryFp * kWordSize); |
834 | 834 |
835 // Load Isolate pointer into CTX. Drop Context. | 835 // Load Isolate pointer into CTX. Drop Context. |
836 __ LoadImmediate(CTX, Isolate::CurrentAddress()); | 836 __ LoadIsolate(CTX); |
837 | 837 |
838 // Restore the saved Context pointer into the Isolate structure. | 838 // Restore the saved Context pointer into the Isolate structure. |
839 // Uses R4 as a temporary register for this. | 839 // Uses R4 as a temporary register for this. |
840 // Restore the saved top exit frame info back into the Isolate structure. | 840 // Restore the saved top exit frame info back into the Isolate structure. |
841 // Uses R5 as a temporary register for this. | 841 // Uses R5 as a temporary register for this. |
842 __ PopList((1 << R4) | (1 << R5)); | 842 __ PopList((1 << R4) | (1 << R5)); |
843 __ StoreToOffset(kWord, R4, CTX, Isolate::top_context_offset()); | 843 __ StoreToOffset(kWord, R4, CTX, Isolate::top_context_offset()); |
844 __ StoreToOffset(kWord, R5, CTX, Isolate::top_exit_frame_info_offset()); | 844 __ StoreToOffset(kWord, R5, CTX, Isolate::top_exit_frame_info_offset()); |
845 | 845 |
846 // Restore the current VMTag from the stack. | 846 // Restore the current VMTag from the stack. |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
930 | 930 |
931 // Setup up number of context variables field. | 931 // Setup up number of context variables field. |
932 // R0: new object. | 932 // R0: new object. |
933 // R1: number of context variables as integer value (not object). | 933 // R1: number of context variables as integer value (not object). |
934 __ str(R1, FieldAddress(R0, Context::num_variables_offset())); | 934 __ str(R1, FieldAddress(R0, Context::num_variables_offset())); |
935 | 935 |
936 // Setup isolate field. | 936 // Setup isolate field. |
937 // Load Isolate pointer into R2. | 937 // Load Isolate pointer into R2. |
938 // R0: new object. | 938 // R0: new object. |
939 // R1: number of context variables. | 939 // R1: number of context variables. |
940 __ LoadImmediate(R2, Isolate::CurrentAddress()); | 940 __ LoadIsolate(R2); |
941 // R2: isolate, not an object. | 941 // R2: isolate, not an object. |
942 __ str(R2, FieldAddress(R0, Context::isolate_offset())); | 942 __ str(R2, FieldAddress(R0, Context::isolate_offset())); |
943 | 943 |
944 // Setup the parent field. | 944 // Setup the parent field. |
945 // R0: new object. | 945 // R0: new object. |
946 // R1: number of context variables. | 946 // R1: number of context variables. |
947 __ LoadImmediate(R2, reinterpret_cast<intptr_t>(Object::null())); | 947 __ LoadImmediate(R2, reinterpret_cast<intptr_t>(Object::null())); |
948 __ str(R2, FieldAddress(R0, Context::parent_offset())); | 948 __ str(R2, FieldAddress(R0, Context::parent_offset())); |
949 | 949 |
950 // Initialize the context variables. | 950 // Initialize the context variables. |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1001 __ PopList((1 << R1) | (1 << R2) | (1 << R3)); | 1001 __ PopList((1 << R1) | (1 << R2) | (1 << R3)); |
1002 __ Ret(); | 1002 __ Ret(); |
1003 | 1003 |
1004 __ Bind(&add_to_buffer); | 1004 __ Bind(&add_to_buffer); |
1005 __ orr(R2, R2, Operand(1 << RawObject::kRememberedBit)); | 1005 __ orr(R2, R2, Operand(1 << RawObject::kRememberedBit)); |
1006 __ str(R2, FieldAddress(R0, Object::tags_offset())); | 1006 __ str(R2, FieldAddress(R0, Object::tags_offset())); |
1007 | 1007 |
1008 // Load the isolate. | 1008 // Load the isolate. |
1009 // Spilled: R1, R2, R3. | 1009 // Spilled: R1, R2, R3. |
1010 // R0: address being stored. | 1010 // R0: address being stored. |
1011 __ LoadImmediate(R1, Isolate::CurrentAddress()); | 1011 __ LoadIsolate(R1); |
1012 | 1012 |
1013 // Load the StoreBuffer block out of the isolate. Then load top_ out of the | 1013 // Load the StoreBuffer block out of the isolate. Then load top_ out of the |
1014 // StoreBufferBlock and add the address to the pointers_. | 1014 // StoreBufferBlock and add the address to the pointers_. |
1015 // R1: isolate. | 1015 // R1: isolate. |
1016 __ ldr(R1, Address(R1, Isolate::store_buffer_offset())); | 1016 __ ldr(R1, Address(R1, Isolate::store_buffer_offset())); |
1017 __ ldr(R2, Address(R1, StoreBufferBlock::top_offset())); | 1017 __ ldr(R2, Address(R1, StoreBufferBlock::top_offset())); |
1018 __ add(R3, R1, Operand(R2, LSL, 2)); | 1018 __ add(R3, R1, Operand(R2, LSL, 2)); |
1019 __ str(R0, Address(R3, StoreBufferBlock::pointers_offset())); | 1019 __ str(R0, Address(R3, StoreBufferBlock::pointers_offset())); |
1020 | 1020 |
1021 // Increment top_ and check for overflow. | 1021 // Increment top_ and check for overflow. |
1022 // R2: top_. | 1022 // R2: top_. |
1023 // R1: StoreBufferBlock. | 1023 // R1: StoreBufferBlock. |
1024 Label L; | 1024 Label L; |
1025 __ add(R2, R2, Operand(1)); | 1025 __ add(R2, R2, Operand(1)); |
1026 __ str(R2, Address(R1, StoreBufferBlock::top_offset())); | 1026 __ str(R2, Address(R1, StoreBufferBlock::top_offset())); |
1027 __ CompareImmediate(R2, StoreBufferBlock::kSize); | 1027 __ CompareImmediate(R2, StoreBufferBlock::kSize); |
1028 // Restore values. | 1028 // Restore values. |
1029 __ PopList((1 << R1) | (1 << R2) | (1 << R3)); | 1029 __ PopList((1 << R1) | (1 << R2) | (1 << R3)); |
1030 __ b(&L, EQ); | 1030 __ b(&L, EQ); |
1031 __ Ret(); | 1031 __ Ret(); |
1032 | 1032 |
1033 // Handle overflow: Call the runtime leaf function. | 1033 // Handle overflow: Call the runtime leaf function. |
1034 __ Bind(&L); | 1034 __ Bind(&L); |
1035 // Setup frame, push callee-saved registers. | 1035 // Setup frame, push callee-saved registers. |
1036 | 1036 |
1037 __ EnterCallRuntimeFrame(0 * kWordSize); | 1037 __ EnterCallRuntimeFrame(0 * kWordSize); |
1038 __ LoadImmediate(R0, Isolate::CurrentAddress()); | 1038 __ LoadIsolate(R0); |
1039 __ CallRuntime(kStoreBufferBlockProcessRuntimeEntry, 1); | 1039 __ CallRuntime(kStoreBufferBlockProcessRuntimeEntry, 1); |
1040 // Restore callee-saved registers, tear down frame. | 1040 // Restore callee-saved registers, tear down frame. |
1041 __ LeaveCallRuntimeFrame(); | 1041 __ LeaveCallRuntimeFrame(); |
1042 __ Ret(); | 1042 __ Ret(); |
1043 } | 1043 } |
1044 | 1044 |
1045 | 1045 |
1046 // Called for inline allocation of objects. | 1046 // Called for inline allocation of objects. |
1047 // Input parameters: | 1047 // Input parameters: |
1048 // LR : return address. | 1048 // LR : return address. |
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1331 __ CompareImmediate(R6, num_args); | 1331 __ CompareImmediate(R6, num_args); |
1332 __ b(&ok, EQ); | 1332 __ b(&ok, EQ); |
1333 __ Stop("Incorrect stub for IC data"); | 1333 __ Stop("Incorrect stub for IC data"); |
1334 __ Bind(&ok); | 1334 __ Bind(&ok); |
1335 } | 1335 } |
1336 #endif // DEBUG | 1336 #endif // DEBUG |
1337 | 1337 |
1338 | 1338 |
1339 // Check single stepping. | 1339 // Check single stepping. |
1340 Label stepping, done_stepping; | 1340 Label stepping, done_stepping; |
1341 __ LoadImmediate(R6, Isolate::CurrentAddress()); | 1341 __ LoadIsolate(R6); |
1342 __ ldrb(R6, Address(R6, Isolate::single_step_offset())); | 1342 __ ldrb(R6, Address(R6, Isolate::single_step_offset())); |
1343 __ CompareImmediate(R6, 0); | 1343 __ CompareImmediate(R6, 0); |
1344 __ b(&stepping, NE); | 1344 __ b(&stepping, NE); |
1345 __ Bind(&done_stepping); | 1345 __ Bind(&done_stepping); |
1346 | 1346 |
1347 if (kind != Token::kILLEGAL) { | 1347 if (kind != Token::kILLEGAL) { |
1348 Label not_smi_or_overflow; | 1348 Label not_smi_or_overflow; |
1349 EmitFastSmiOp(assembler, kind, num_args, ¬_smi_or_overflow); | 1349 EmitFastSmiOp(assembler, kind, num_args, ¬_smi_or_overflow); |
1350 __ Bind(¬_smi_or_overflow); | 1350 __ Bind(¬_smi_or_overflow); |
1351 } | 1351 } |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1552 __ and_(R6, R6, Operand(ICData::NumArgsTestedMask())); | 1552 __ and_(R6, R6, Operand(ICData::NumArgsTestedMask())); |
1553 __ CompareImmediate(R6, 0); | 1553 __ CompareImmediate(R6, 0); |
1554 __ b(&ok, EQ); | 1554 __ b(&ok, EQ); |
1555 __ Stop("Incorrect IC data for unoptimized static call"); | 1555 __ Stop("Incorrect IC data for unoptimized static call"); |
1556 __ Bind(&ok); | 1556 __ Bind(&ok); |
1557 } | 1557 } |
1558 #endif // DEBUG | 1558 #endif // DEBUG |
1559 | 1559 |
1560 // Check single stepping. | 1560 // Check single stepping. |
1561 Label stepping, done_stepping; | 1561 Label stepping, done_stepping; |
1562 __ LoadImmediate(R6, Isolate::CurrentAddress()); | 1562 __ LoadIsolate(R6); |
1563 __ ldrb(R6, Address(R6, Isolate::single_step_offset())); | 1563 __ ldrb(R6, Address(R6, Isolate::single_step_offset())); |
1564 __ CompareImmediate(R6, 0); | 1564 __ CompareImmediate(R6, 0); |
1565 __ b(&stepping, NE); | 1565 __ b(&stepping, NE); |
1566 __ Bind(&done_stepping); | 1566 __ Bind(&done_stepping); |
1567 | 1567 |
1568 // R5: IC data object (preserved). | 1568 // R5: IC data object (preserved). |
1569 __ ldr(R6, FieldAddress(R5, ICData::ic_data_offset())); | 1569 __ ldr(R6, FieldAddress(R5, ICData::ic_data_offset())); |
1570 // R6: ic_data_array with entries: target functions and count. | 1570 // R6: ic_data_array with entries: target functions and count. |
1571 __ AddImmediate(R6, R6, Array::data_offset() - kHeapObjectTag); | 1571 __ AddImmediate(R6, R6, Array::data_offset() - kHeapObjectTag); |
1572 // R6: points directly to the first ic data array element. | 1572 // R6: points directly to the first ic data array element. |
(...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1974 const Register right = R0; | 1974 const Register right = R0; |
1975 __ ldr(left, Address(SP, 1 * kWordSize)); | 1975 __ ldr(left, Address(SP, 1 * kWordSize)); |
1976 __ ldr(right, Address(SP, 0 * kWordSize)); | 1976 __ ldr(right, Address(SP, 0 * kWordSize)); |
1977 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); | 1977 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); |
1978 __ Ret(); | 1978 __ Ret(); |
1979 } | 1979 } |
1980 | 1980 |
1981 } // namespace dart | 1981 } // namespace dart |
1982 | 1982 |
1983 #endif // defined TARGET_ARCH_ARM | 1983 #endif // defined TARGET_ARCH_ARM |
OLD | NEW |