| 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 |