| 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" |
| 9 #include "vm/assembler_macros.h" |
| 10 #include "vm/dart_entry.h" |
| 11 #include "vm/instructions.h" |
| 12 #include "vm/stack_frame.h" |
| 8 #include "vm/stub_code.h" | 13 #include "vm/stub_code.h" |
| 9 | 14 |
| 10 #define __ assembler-> | 15 #define __ assembler-> |
| 11 | 16 |
| 12 namespace dart { | 17 namespace dart { |
| 13 | 18 |
| 14 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) { | 19 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) { |
| 15 __ Unimplemented("CallToRuntime stub"); | 20 __ Unimplemented("CallToRuntime stub"); |
| 16 } | 21 } |
| 17 | 22 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 59 void StubCode::GenerateAllocateArrayStub(Assembler* assembler) { | 64 void StubCode::GenerateAllocateArrayStub(Assembler* assembler) { |
| 60 __ Unimplemented("AllocateArray stub"); | 65 __ Unimplemented("AllocateArray stub"); |
| 61 } | 66 } |
| 62 | 67 |
| 63 | 68 |
| 64 void StubCode::GenerateCallClosureFunctionStub(Assembler* assembler) { | 69 void StubCode::GenerateCallClosureFunctionStub(Assembler* assembler) { |
| 65 __ Unimplemented("CallClosureFunction stub"); | 70 __ Unimplemented("CallClosureFunction stub"); |
| 66 } | 71 } |
| 67 | 72 |
| 68 | 73 |
| 74 // Called when invoking Dart code from C++ (VM code). |
| 75 // Input parameters: |
| 76 // LR : points to return address. |
| 77 // R0 : entrypoint of the Dart function to call. |
| 78 // R1 : arguments descriptor array. |
| 79 // R2 : arguments array. |
| 80 // R3 : new context containing the current isolate pointer. |
| 69 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) { | 81 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) { |
| 70 __ Unimplemented("InvokeDartCode stub"); | 82 // Save frame pointer coming in. |
| 83 AssemblerMacros::EnterStubFrame(assembler); |
| 84 |
| 85 // Save new context and C++ ABI callee-saved registers. |
| 86 const intptr_t kNewContextOffset = -(1 + kAbiPreservedRegCount) * kWordSize; |
| 87 __ PushList((1 << R3) | kAbiPreservedRegs); |
| 88 |
| 89 // The new Context structure contains a pointer to the current Isolate |
| 90 // structure. Cache the Context pointer in the CTX register so that it is |
| 91 // available in generated code and calls to Isolate::Current() need not be |
| 92 // done. The assumption is that this register will never be clobbered by |
| 93 // compiled or runtime stub code. |
| 94 |
| 95 // Cache the new Context pointer into CTX while executing Dart code. |
| 96 __ ldr(CTX, Address(R3, VMHandles::kOffsetOfRawPtrInHandle)); |
| 97 |
| 98 // Load Isolate pointer from Context structure into temporary register R8. |
| 99 __ ldr(R8, FieldAddress(CTX, Context::isolate_offset())); |
| 100 |
| 101 // Save the top exit frame info. Use R5 as a temporary register. |
| 102 // StackFrameIterator reads the top exit frame info saved in this frame. |
| 103 { |
| 104 // TODO(regis): Add assembler macro for {Load,Store}BasedOffset with no |
| 105 // restriction on the offset. |
| 106 const intptr_t offset = Isolate::top_exit_frame_info_offset(); |
| 107 const int32_t offset12_hi = offset & ~kOffset12Mask; // signed |
| 108 const uint32_t offset12_lo = offset & kOffset12Mask; // unsigned |
| 109 __ AddImmediate(R7, R8, offset12_hi); |
| 110 __ ldr(R5, Address(R7, offset12_lo)); |
| 111 __ LoadImmediate(R6, 0); |
| 112 __ str(R6, Address(R7, offset12_lo)); |
| 113 } |
| 114 |
| 115 // Save the old Context pointer. Use R4 as a temporary register. |
| 116 // Note that VisitObjectPointers will find this saved Context pointer during |
| 117 // GC marking, since it traverses any information between SP and |
| 118 // FP - kExitLinkOffsetInEntryFrame. |
| 119 // EntryFrame::SavedContext reads the context saved in this frame. |
| 120 { |
| 121 const intptr_t offset = Isolate::top_context_offset(); |
| 122 const int32_t offset12_hi = offset & ~kOffset12Mask; // signed |
| 123 const uint32_t offset12_lo = offset & kOffset12Mask; // unsigned |
| 124 __ AddImmediate(R7, R8, offset12_hi); |
| 125 __ ldr(R4, Address(R7, offset12_lo)); |
| 126 } |
| 127 |
| 128 // The constants kSavedContextOffsetInEntryFrame and |
| 129 // kExitLinkOffsetInEntryFrame must be kept in sync with the code below. |
| 130 __ PushList((1 << R4) | (1 << R5)); |
| 131 |
| 132 // The stack pointer is restore after the call to this location. |
| 133 const intptr_t kSavedContextOffsetInEntryFrame = -10 * kWordSize; |
| 134 |
| 135 // Load arguments descriptor array into R4, which is passed to Dart code. |
| 136 __ ldr(R4, Address(R1, VMHandles::kOffsetOfRawPtrInHandle)); |
| 137 |
| 138 // Load number of arguments into R5. |
| 139 __ ldr(R5, FieldAddress(R4, ArgumentsDescriptor::count_offset())); |
| 140 __ SmiUntag(R5); |
| 141 |
| 142 // Compute address of 'arguments array' data area into R2. |
| 143 __ ldr(R2, Address(R2, VMHandles::kOffsetOfRawPtrInHandle)); |
| 144 __ AddImmediate(R2, R2, Array::data_offset() - kHeapObjectTag); |
| 145 |
| 146 // Set up arguments for the Dart call. |
| 147 Label push_arguments; |
| 148 Label done_push_arguments; |
| 149 __ CompareImmediate(R5, 0); // check if there are arguments. |
| 150 __ b(&done_push_arguments, EQ); |
| 151 __ LoadImmediate(R1, 0); |
| 152 __ Bind(&push_arguments); |
| 153 __ ldr(R3, Address(R2)); |
| 154 __ Push(R3); |
| 155 __ AddImmediate(R2, kWordSize); |
| 156 __ AddImmediate(R1, 1); |
| 157 __ cmp(R1, ShifterOperand(R5)); |
| 158 __ b(&push_arguments, LT); |
| 159 __ Bind(&done_push_arguments); |
| 160 |
| 161 // Call the Dart code entrypoint. |
| 162 __ blx(R0); // R4 is the arguments descriptor array. |
| 163 |
| 164 // Read the saved new Context pointer. |
| 165 __ ldr(CTX, Address(FP, kNewContextOffset)); |
| 166 __ ldr(CTX, Address(CTX, VMHandles::kOffsetOfRawPtrInHandle)); |
| 167 |
| 168 // Get rid of arguments pushed on the stack. |
| 169 __ AddImmediate(SP, FP, kSavedContextOffsetInEntryFrame); |
| 170 |
| 171 // Load Isolate pointer from Context structure into CTX. Drop Context. |
| 172 __ ldr(CTX, FieldAddress(CTX, Context::isolate_offset())); |
| 173 |
| 174 // Restore the saved Context pointer into the Isolate structure. |
| 175 // Uses R4 as a temporary register for this. |
| 176 // Restore the saved top exit frame info back into the Isolate structure. |
| 177 // Uses R5 as a temporary register for this. |
| 178 __ PopList((1 << R4) | (1 << R5)); |
| 179 { |
| 180 const intptr_t offset = Isolate::top_context_offset(); |
| 181 const int32_t offset12_hi = offset & ~kOffset12Mask; // signed |
| 182 const uint32_t offset12_lo = offset & kOffset12Mask; // unsigned |
| 183 __ AddImmediate(R7, CTX, offset12_hi); |
| 184 __ str(R4, Address(R7, offset12_lo)); |
| 185 } |
| 186 { |
| 187 const intptr_t offset = Isolate::top_exit_frame_info_offset(); |
| 188 const int32_t offset12_hi = offset & ~kOffset12Mask; // signed |
| 189 const uint32_t offset12_lo = offset & kOffset12Mask; // unsigned |
| 190 __ AddImmediate(R7, CTX, offset12_hi); |
| 191 __ str(R5, Address(R7, offset12_lo)); |
| 192 } |
| 193 |
| 194 // Restore C++ ABI callee-saved registers. |
| 195 __ PopList((1 << R3) | kAbiPreservedRegs); // Ignore restored R3. |
| 196 |
| 197 // Restore the frame pointer. |
| 198 AssemblerMacros::LeaveStubFrame(assembler); |
| 199 |
| 200 __ Ret(); |
| 71 } | 201 } |
| 72 | 202 |
| 73 | 203 |
| 74 void StubCode::GenerateAllocateContextStub(Assembler* assembler) { | 204 void StubCode::GenerateAllocateContextStub(Assembler* assembler) { |
| 75 __ Unimplemented("AllocateContext stub"); | 205 __ Unimplemented("AllocateContext stub"); |
| 76 } | 206 } |
| 77 | 207 |
| 78 | 208 |
| 79 void StubCode::GenerateUpdateStoreBufferStub(Assembler* assembler) { | 209 void StubCode::GenerateUpdateStoreBufferStub(Assembler* assembler) { |
| 80 __ Unimplemented("UpdateStoreBuffer stub"); | 210 __ Unimplemented("UpdateStoreBuffer stub"); |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 222 } | 352 } |
| 223 | 353 |
| 224 | 354 |
| 225 void StubCode::GenerateIdenticalWithNumberCheckStub(Assembler* assembler) { | 355 void StubCode::GenerateIdenticalWithNumberCheckStub(Assembler* assembler) { |
| 226 __ Unimplemented("IdenticalWithNumberCheck stub"); | 356 __ Unimplemented("IdenticalWithNumberCheck stub"); |
| 227 } | 357 } |
| 228 | 358 |
| 229 } // namespace dart | 359 } // namespace dart |
| 230 | 360 |
| 231 #endif // defined TARGET_ARCH_ARM | 361 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |