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_MIPS) | 6 #if defined(TARGET_ARCH_MIPS) |
| 7 | 7 |
| 8 #include "vm/assembler.h" | |
| 9 #include "vm/code_generator.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 // RA : points to return address. | |
| 77 // A0 : entrypoint of the Dart function to call. | |
| 78 // A1 : arguments descriptor array. | |
| 79 // A2 : arguments array. | |
| 80 // A3 : 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 __ EnterStubFrame(); | |
| 84 | |
| 85 // Save new context and C++ ABI callee-saved registers. | |
| 86 const intptr_t kNewContextOffset = | |
| 87 -(2 + kAbiPreservedCpuRegCount) * kWordSize; | |
| 88 | |
| 89 __ addiu(SP, SP, Immediate(-(1 + kAbiPreservedCpuRegCount) * kWordSize)); | |
| 90 for (int i = S0; i <= S7; i++) { | |
| 91 Register r = static_cast<Register>(i); | |
| 92 __ sw(r, Address(SP, (i - S0 + 1) * kWordSize)); | |
| 93 } | |
| 94 __ sw(A3, Address(SP)); | |
| 95 | |
| 96 // The new Context structure contains a pointer to the current Isolate | |
| 97 // structure. Cache the Context pointer in the CTX register so that it is | |
| 98 // available in generated code and calls to Isolate::Current() need not be | |
| 99 // done. The assumption is that this register will never be clobbered by | |
| 100 // compiled or runtime stub code. | |
| 101 | |
| 102 // Cache the new Context pointer into CTX while executing Dart code. | |
| 103 __ lw(CTX, Address(A3, VMHandles::kOffsetOfRawPtrInHandle)); | |
| 104 | |
| 105 // Load Isolate pointer from Context structure into temporary register R8. | |
| 106 __ lw(T2, FieldAddress(CTX, Context::isolate_offset())); | |
| 107 | |
| 108 // Save the top exit frame info. Use R5 as a temporary register. | |
| 109 // StackFrameIterator reads the top exit frame info saved in this frame. | |
| 110 __ lw(S5, Address(T2, Isolate::top_exit_frame_info_offset())); | |
| 111 __ LoadImmediate(T0, 0); | |
| 112 __ sw(T0, Address(T2, Isolate::top_exit_frame_info_offset())); | |
| 113 | |
| 114 // Save the old Context pointer. Use S4 as a temporary register. | |
| 115 // Note that VisitObjectPointers will find this saved Context pointer during | |
| 116 // GC marking, since it traverses any information between SP and | |
| 117 // FP - kExitLinkOffsetInEntryFrame. | |
| 118 // EntryFrame::SavedContext reads the context saved in this frame. | |
| 119 __ lw(S4, Address(T2, Isolate::top_context_offset())); | |
| 120 | |
| 121 // The constants kSavedContextOffsetInEntryFrame and | |
| 122 // kExitLinkOffsetInEntryFrame must be kept in sync with the code below. | |
| 123 __ addiu(SP, SP, Immediate(-2 * kWordSize)); | |
|
regis
2013/03/29 00:23:32
The SP could be adjusted only once above.
zra
2013/03/29 17:10:44
Done.
| |
| 124 __ sw(S4, Address(SP)); | |
| 125 __ sw(S5, Address(SP, kWordSize)); | |
| 126 | |
| 127 // after the call, The stack pointer is restored to this location. | |
| 128 const intptr_t kSavedContextOffsetInEntryFrame = -12 * kWordSize; | |
| 129 | |
| 130 // Load arguments descriptor array into S4, which is passed to Dart code. | |
| 131 __ lw(S4, Address(A1, VMHandles::kOffsetOfRawPtrInHandle)); | |
| 132 | |
| 133 // Load number of arguments into S5. | |
| 134 __ lw(S5, FieldAddress(S4, ArgumentsDescriptor::count_offset())); | |
| 135 __ SmiUntag(S5); | |
| 136 | |
| 137 // Compute address of 'arguments array' data area into A2. | |
| 138 __ lw(A2, Address(A2, VMHandles::kOffsetOfRawPtrInHandle)); | |
| 139 __ addiu(A2, A2, Immediate(Array::data_offset() - kHeapObjectTag)); | |
| 140 | |
| 141 // Set up arguments for the Dart call. | |
| 142 Label push_arguments; | |
| 143 Label done_push_arguments; | |
| 144 | |
| 145 __ beq(S5, ZR, &done_push_arguments); // check if there are arguments. | |
| 146 __ LoadImmediate(A1, 0); | |
| 147 __ Bind(&push_arguments); | |
| 148 __ lw(A3, Address(A2)); | |
| 149 __ Push(A3); | |
| 150 __ addiu(A2, A2, Immediate(kWordSize)); | |
| 151 __ addiu(A1, A1, Immediate(1)); | |
| 152 __ subu(T0, A1, S5); | |
| 153 __ bltz(T0, &push_arguments); | |
| 154 | |
| 155 __ Bind(&done_push_arguments); | |
| 156 | |
| 157 | |
| 158 // Call the Dart code entrypoint. | |
| 159 __ jalr(A0); // S4 is the arguments descriptor array. | |
| 160 | |
| 161 // Read the saved new Context pointer. | |
| 162 __ lw(CTX, Address(FP, kNewContextOffset)); | |
| 163 __ lw(CTX, Address(CTX, VMHandles::kOffsetOfRawPtrInHandle)); | |
| 164 | |
| 165 // Get rid of arguments pushed on the stack. | |
| 166 __ addiu(SP, FP, Immediate(kSavedContextOffsetInEntryFrame)); | |
| 167 | |
| 168 // Load Isolate pointer from Context structure into CTX. Drop Context. | |
| 169 __ lw(CTX, FieldAddress(CTX, Context::isolate_offset())); | |
| 170 | |
| 171 // Restore the saved Context pointer into the Isolate structure. | |
| 172 // Uses S4 as a temporary register for this. | |
| 173 // Restore the saved top exit frame info back into the Isolate structure. | |
| 174 // Uses S5 as a temporary register for this. | |
| 175 __ lw(S4, Address(SP)); | |
| 176 __ lw(S5, Address(SP, kWordSize)); | |
| 177 __ addiu(SP, SP, Immediate(2 * kWordSize)); | |
|
regis
2013/03/29 00:23:32
ditto
zra
2013/03/29 17:10:44
Done.
| |
| 178 __ sw(S4, Address(CTX, Isolate::top_context_offset())); | |
| 179 __ sw(S5, Address(CTX, Isolate::top_exit_frame_info_offset())); | |
| 180 | |
| 181 // Restore C++ ABI callee-saved registers. | |
| 182 for (int i = S0; i <= S7; i++) { | |
| 183 Register r = static_cast<Register>(i); | |
| 184 __ lw(r, Address(SP, (i - S0 + 1) * kWordSize)); | |
| 185 } | |
| 186 __ lw(A3, Address(SP)); | |
| 187 __ addiu(SP, SP, Immediate((1 + kAbiPreservedCpuRegCount) * kWordSize)); | |
| 188 | |
| 189 // Restore the frame pointer and return. | |
| 190 __ LeaveStubFrame(); | |
| 191 __ Ret(); | |
| 71 } | 192 } |
| 72 | 193 |
| 73 | 194 |
| 74 void StubCode::GenerateAllocateContextStub(Assembler* assembler) { | 195 void StubCode::GenerateAllocateContextStub(Assembler* assembler) { |
| 75 __ Unimplemented("AllocateContext stub"); | 196 __ Unimplemented("AllocateContext stub"); |
| 76 } | 197 } |
| 77 | 198 |
| 78 | 199 |
| 79 void StubCode::GenerateUpdateStoreBufferStub(Assembler* assembler) { | 200 void StubCode::GenerateUpdateStoreBufferStub(Assembler* assembler) { |
| 80 __ Unimplemented("UpdateStoreBuffer stub"); | 201 __ Unimplemented("UpdateStoreBuffer stub"); |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 222 } | 343 } |
| 223 | 344 |
| 224 | 345 |
| 225 void StubCode::GenerateIdenticalWithNumberCheckStub(Assembler* assembler) { | 346 void StubCode::GenerateIdenticalWithNumberCheckStub(Assembler* assembler) { |
| 226 __ Unimplemented("IdenticalWithNumberCheck stub"); | 347 __ Unimplemented("IdenticalWithNumberCheck stub"); |
| 227 } | 348 } |
| 228 | 349 |
| 229 } // namespace dart | 350 } // namespace dart |
| 230 | 351 |
| 231 #endif // defined TARGET_ARCH_MIPS | 352 #endif // defined TARGET_ARCH_MIPS |
| OLD | NEW |