Chromium Code Reviews| 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 747 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 758 | 758 |
| 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 from Context structure into temporary register R8. | 768 // Load Isolate pointer into temporary register R8. |
| 769 __ ldr(R8, FieldAddress(CTX, Context::isolate_offset())); | 769 __ LoadImmediate(R8, Isolate::CurrentAddress()); |
|
Ivan Posva
2014/09/18 17:31:12
On second thought I will add a LoadIsolate() to th
| |
| 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 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 825 // Call the Dart code entrypoint. | 825 // Call the Dart code entrypoint. |
| 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 from Context structure into CTX. Drop Context. | 835 // Load Isolate pointer into CTX. Drop Context. |
| 836 __ ldr(CTX, FieldAddress(CTX, Context::isolate_offset())); | 836 __ LoadImmediate(CTX, Isolate::CurrentAddress()); |
| 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 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 926 __ LoadImmediate(IP, RawObject::ClassIdTag::encode(context_class.id())); | 926 __ LoadImmediate(IP, RawObject::ClassIdTag::encode(context_class.id())); |
| 927 __ orr(R2, R2, Operand(IP)); | 927 __ orr(R2, R2, Operand(IP)); |
| 928 __ str(R2, FieldAddress(R0, Context::tags_offset())); | 928 __ str(R2, FieldAddress(R0, Context::tags_offset())); |
| 929 | 929 |
| 930 // Setup up number of context variables field. | 930 // Setup up number of context variables field. |
| 931 // R0: new object. | 931 // R0: new object. |
| 932 // R1: number of context variables as integer value (not object). | 932 // R1: number of context variables as integer value (not object). |
| 933 __ str(R1, FieldAddress(R0, Context::num_variables_offset())); | 933 __ str(R1, FieldAddress(R0, Context::num_variables_offset())); |
| 934 | 934 |
| 935 // Setup isolate field. | 935 // Setup isolate field. |
| 936 // Load Isolate pointer from Context structure into R2. | 936 // Load Isolate pointer into R2. |
| 937 // R0: new object. | 937 // R0: new object. |
| 938 // R1: number of context variables. | 938 // R1: number of context variables. |
| 939 __ ldr(R2, FieldAddress(CTX, Context::isolate_offset())); | 939 __ LoadImmediate(R2, Isolate::CurrentAddress()); |
| 940 // R2: isolate, not an object. | 940 // R2: isolate, not an object. |
| 941 __ str(R2, FieldAddress(R0, Context::isolate_offset())); | 941 __ str(R2, FieldAddress(R0, Context::isolate_offset())); |
| 942 | 942 |
| 943 // Setup the parent field. | 943 // Setup the parent field. |
| 944 // R0: new object. | 944 // R0: new object. |
| 945 // R1: number of context variables. | 945 // R1: number of context variables. |
| 946 __ LoadImmediate(R2, reinterpret_cast<intptr_t>(Object::null())); | 946 __ LoadImmediate(R2, reinterpret_cast<intptr_t>(Object::null())); |
| 947 __ str(R2, FieldAddress(R0, Context::parent_offset())); | 947 __ str(R2, FieldAddress(R0, Context::parent_offset())); |
| 948 | 948 |
| 949 // Initialize the context variables. | 949 // Initialize the context variables. |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 997 __ ldr(R2, FieldAddress(R0, Object::tags_offset())); | 997 __ ldr(R2, FieldAddress(R0, Object::tags_offset())); |
| 998 __ tst(R2, Operand(1 << RawObject::kRememberedBit)); | 998 __ tst(R2, Operand(1 << RawObject::kRememberedBit)); |
| 999 __ b(&add_to_buffer, EQ); | 999 __ b(&add_to_buffer, EQ); |
| 1000 __ PopList((1 << R1) | (1 << R2) | (1 << R3)); | 1000 __ PopList((1 << R1) | (1 << R2) | (1 << R3)); |
| 1001 __ Ret(); | 1001 __ Ret(); |
| 1002 | 1002 |
| 1003 __ Bind(&add_to_buffer); | 1003 __ Bind(&add_to_buffer); |
| 1004 __ orr(R2, R2, Operand(1 << RawObject::kRememberedBit)); | 1004 __ orr(R2, R2, Operand(1 << RawObject::kRememberedBit)); |
| 1005 __ str(R2, FieldAddress(R0, Object::tags_offset())); | 1005 __ str(R2, FieldAddress(R0, Object::tags_offset())); |
| 1006 | 1006 |
| 1007 // Load the isolate out of the context. | 1007 // Load the isolate. |
| 1008 // Spilled: R1, R2, R3. | 1008 // Spilled: R1, R2, R3. |
| 1009 // R0: address being stored. | 1009 // R0: address being stored. |
| 1010 __ ldr(R1, FieldAddress(CTX, Context::isolate_offset())); | 1010 __ LoadImmediate(R1, Isolate::CurrentAddress()); |
| 1011 | 1011 |
| 1012 // Load the StoreBuffer block out of the isolate. Then load top_ out of the | 1012 // Load the StoreBuffer block out of the isolate. Then load top_ out of the |
| 1013 // StoreBufferBlock and add the address to the pointers_. | 1013 // StoreBufferBlock and add the address to the pointers_. |
| 1014 // R1: isolate. | 1014 // R1: isolate. |
| 1015 __ ldr(R1, Address(R1, Isolate::store_buffer_offset())); | 1015 __ ldr(R1, Address(R1, Isolate::store_buffer_offset())); |
| 1016 __ ldr(R2, Address(R1, StoreBufferBlock::top_offset())); | 1016 __ ldr(R2, Address(R1, StoreBufferBlock::top_offset())); |
| 1017 __ add(R3, R1, Operand(R2, LSL, 2)); | 1017 __ add(R3, R1, Operand(R2, LSL, 2)); |
| 1018 __ str(R0, Address(R3, StoreBufferBlock::pointers_offset())); | 1018 __ str(R0, Address(R3, StoreBufferBlock::pointers_offset())); |
| 1019 | 1019 |
| 1020 // Increment top_ and check for overflow. | 1020 // Increment top_ and check for overflow. |
| 1021 // R2: top_. | 1021 // R2: top_. |
| 1022 // R1: StoreBufferBlock. | 1022 // R1: StoreBufferBlock. |
| 1023 Label L; | 1023 Label L; |
| 1024 __ add(R2, R2, Operand(1)); | 1024 __ add(R2, R2, Operand(1)); |
| 1025 __ str(R2, Address(R1, StoreBufferBlock::top_offset())); | 1025 __ str(R2, Address(R1, StoreBufferBlock::top_offset())); |
| 1026 __ CompareImmediate(R2, StoreBufferBlock::kSize); | 1026 __ CompareImmediate(R2, StoreBufferBlock::kSize); |
| 1027 // Restore values. | 1027 // Restore values. |
| 1028 __ PopList((1 << R1) | (1 << R2) | (1 << R3)); | 1028 __ PopList((1 << R1) | (1 << R2) | (1 << R3)); |
| 1029 __ b(&L, EQ); | 1029 __ b(&L, EQ); |
| 1030 __ Ret(); | 1030 __ Ret(); |
| 1031 | 1031 |
| 1032 // Handle overflow: Call the runtime leaf function. | 1032 // Handle overflow: Call the runtime leaf function. |
| 1033 __ Bind(&L); | 1033 __ Bind(&L); |
| 1034 // Setup frame, push callee-saved registers. | 1034 // Setup frame, push callee-saved registers. |
| 1035 | 1035 |
| 1036 __ EnterCallRuntimeFrame(0 * kWordSize); | 1036 __ EnterCallRuntimeFrame(0 * kWordSize); |
| 1037 __ ldr(R0, FieldAddress(CTX, Context::isolate_offset())); | 1037 __ LoadImmediate(R0, Isolate::CurrentAddress()); |
| 1038 __ CallRuntime(kStoreBufferBlockProcessRuntimeEntry, 1); | 1038 __ CallRuntime(kStoreBufferBlockProcessRuntimeEntry, 1); |
| 1039 // Restore callee-saved registers, tear down frame. | 1039 // Restore callee-saved registers, tear down frame. |
| 1040 __ LeaveCallRuntimeFrame(); | 1040 __ LeaveCallRuntimeFrame(); |
| 1041 __ Ret(); | 1041 __ Ret(); |
| 1042 } | 1042 } |
| 1043 | 1043 |
| 1044 | 1044 |
| 1045 // Called for inline allocation of objects. | 1045 // Called for inline allocation of objects. |
| 1046 // Input parameters: | 1046 // Input parameters: |
| 1047 // LR : return address. | 1047 // LR : return address. |
| (...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1326 __ ldr(R6, FieldAddress(R5, ICData::state_bits_offset())); | 1326 __ ldr(R6, FieldAddress(R5, ICData::state_bits_offset())); |
| 1327 ASSERT(ICData::NumArgsTestedShift() == 0); // No shift needed. | 1327 ASSERT(ICData::NumArgsTestedShift() == 0); // No shift needed. |
| 1328 __ and_(R6, R6, Operand(ICData::NumArgsTestedMask())); | 1328 __ and_(R6, R6, Operand(ICData::NumArgsTestedMask())); |
| 1329 __ CompareImmediate(R6, num_args); | 1329 __ CompareImmediate(R6, num_args); |
| 1330 __ b(&ok, EQ); | 1330 __ b(&ok, EQ); |
| 1331 __ Stop("Incorrect stub for IC data"); | 1331 __ Stop("Incorrect stub for IC data"); |
| 1332 __ Bind(&ok); | 1332 __ Bind(&ok); |
| 1333 } | 1333 } |
| 1334 #endif // DEBUG | 1334 #endif // DEBUG |
| 1335 | 1335 |
| 1336 Label stepping, done_stepping; | |
| 1337 | 1336 |
| 1338 // Check single stepping. | 1337 // Check single stepping. |
| 1339 __ ldr(R6, FieldAddress(CTX, Context::isolate_offset())); | 1338 Label stepping, done_stepping; |
| 1339 __ LoadImmediate(R6, Isolate::CurrentAddress()); | |
| 1340 __ ldrb(R6, Address(R6, Isolate::single_step_offset())); | 1340 __ ldrb(R6, Address(R6, Isolate::single_step_offset())); |
| 1341 __ CompareImmediate(R6, 0); | 1341 __ CompareImmediate(R6, 0); |
| 1342 __ b(&stepping, NE); | 1342 __ b(&stepping, NE); |
| 1343 __ Bind(&done_stepping); | 1343 __ Bind(&done_stepping); |
| 1344 | 1344 |
| 1345 if (kind != Token::kILLEGAL) { | 1345 if (kind != Token::kILLEGAL) { |
| 1346 Label not_smi_or_overflow; | 1346 Label not_smi_or_overflow; |
| 1347 EmitFastSmiOp(assembler, kind, num_args, ¬_smi_or_overflow); | 1347 EmitFastSmiOp(assembler, kind, num_args, ¬_smi_or_overflow); |
| 1348 __ Bind(¬_smi_or_overflow); | 1348 __ Bind(¬_smi_or_overflow); |
| 1349 } | 1349 } |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1550 __ and_(R6, R6, Operand(ICData::NumArgsTestedMask())); | 1550 __ and_(R6, R6, Operand(ICData::NumArgsTestedMask())); |
| 1551 __ CompareImmediate(R6, 0); | 1551 __ CompareImmediate(R6, 0); |
| 1552 __ b(&ok, EQ); | 1552 __ b(&ok, EQ); |
| 1553 __ Stop("Incorrect IC data for unoptimized static call"); | 1553 __ Stop("Incorrect IC data for unoptimized static call"); |
| 1554 __ Bind(&ok); | 1554 __ Bind(&ok); |
| 1555 } | 1555 } |
| 1556 #endif // DEBUG | 1556 #endif // DEBUG |
| 1557 | 1557 |
| 1558 // Check single stepping. | 1558 // Check single stepping. |
| 1559 Label stepping, done_stepping; | 1559 Label stepping, done_stepping; |
| 1560 __ ldr(R6, FieldAddress(CTX, Context::isolate_offset())); | 1560 __ LoadImmediate(R6, Isolate::CurrentAddress()); |
| 1561 __ ldrb(R6, Address(R6, Isolate::single_step_offset())); | 1561 __ ldrb(R6, Address(R6, Isolate::single_step_offset())); |
| 1562 __ CompareImmediate(R6, 0); | 1562 __ CompareImmediate(R6, 0); |
| 1563 __ b(&stepping, NE); | 1563 __ b(&stepping, NE); |
| 1564 __ Bind(&done_stepping); | 1564 __ Bind(&done_stepping); |
| 1565 | 1565 |
| 1566 // R5: IC data object (preserved). | 1566 // R5: IC data object (preserved). |
| 1567 __ ldr(R6, FieldAddress(R5, ICData::ic_data_offset())); | 1567 __ ldr(R6, FieldAddress(R5, ICData::ic_data_offset())); |
| 1568 // R6: ic_data_array with entries: target functions and count. | 1568 // R6: ic_data_array with entries: target functions and count. |
| 1569 __ AddImmediate(R6, R6, Array::data_offset() - kHeapObjectTag); | 1569 __ AddImmediate(R6, R6, Array::data_offset() - kHeapObjectTag); |
| 1570 // R6: points directly to the first ic data array element. | 1570 // R6: points directly to the first ic data array element. |
| (...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1972 const Register right = R0; | 1972 const Register right = R0; |
| 1973 __ ldr(left, Address(SP, 1 * kWordSize)); | 1973 __ ldr(left, Address(SP, 1 * kWordSize)); |
| 1974 __ ldr(right, Address(SP, 0 * kWordSize)); | 1974 __ ldr(right, Address(SP, 0 * kWordSize)); |
| 1975 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); | 1975 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); |
| 1976 __ Ret(); | 1976 __ Ret(); |
| 1977 } | 1977 } |
| 1978 | 1978 |
| 1979 } // namespace dart | 1979 } // namespace dart |
| 1980 | 1980 |
| 1981 #endif // defined TARGET_ARCH_ARM | 1981 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |