| 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 25 matching lines...) Expand all Loading... |
| 36 // SP + 4*R4 : address of return value. | 36 // SP + 4*R4 : address of return value. |
| 37 // R5 : address of the runtime function to call. | 37 // R5 : address of the runtime function to call. |
| 38 // R4 : number of arguments to the call. | 38 // R4 : number of arguments to the call. |
| 39 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) { | 39 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) { |
| 40 const intptr_t thread_offset = NativeArguments::thread_offset(); | 40 const intptr_t thread_offset = NativeArguments::thread_offset(); |
| 41 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); | 41 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); |
| 42 const intptr_t argv_offset = NativeArguments::argv_offset(); | 42 const intptr_t argv_offset = NativeArguments::argv_offset(); |
| 43 const intptr_t retval_offset = NativeArguments::retval_offset(); | 43 const intptr_t retval_offset = NativeArguments::retval_offset(); |
| 44 const intptr_t exitframe_last_param_slot_from_fp = 2; | 44 const intptr_t exitframe_last_param_slot_from_fp = 2; |
| 45 | 45 |
| 46 __ mov(IP, Operand(0)); | 46 __ EnterStubFrame(); |
| 47 __ Push(IP); // Push 0 for the PC marker. | |
| 48 __ EnterFrame((1 << FP) | (1 << LR), 0); | |
| 49 | 47 |
| 50 COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << R9)) != 0); | 48 COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << R9)) != 0); |
| 51 __ LoadIsolate(R9); | 49 __ LoadIsolate(R9); |
| 52 | 50 |
| 53 // Save exit frame information to enable stack walking as we are about | 51 // Save exit frame information to enable stack walking as we are about |
| 54 // to transition to Dart VM C++ code. | 52 // to transition to Dart VM C++ code. |
| 55 __ StoreToOffset(kWord, FP, R9, Isolate::top_exit_frame_info_offset()); | 53 __ StoreToOffset(kWord, FP, R9, Isolate::top_exit_frame_info_offset()); |
| 56 | 54 |
| 57 #if defined(DEBUG) | 55 #if defined(DEBUG) |
| 58 { Label ok; | 56 { Label ok; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 97 __ blx(R5); | 95 __ blx(R5); |
| 98 | 96 |
| 99 // Mark that the isolate is executing Dart code. | 97 // Mark that the isolate is executing Dart code. |
| 100 __ LoadImmediate(R2, VMTag::kDartTagId); | 98 __ LoadImmediate(R2, VMTag::kDartTagId); |
| 101 __ StoreToOffset(kWord, R2, R9, Isolate::vm_tag_offset()); | 99 __ StoreToOffset(kWord, R2, R9, Isolate::vm_tag_offset()); |
| 102 | 100 |
| 103 // Reset exit frame information in Isolate structure. | 101 // Reset exit frame information in Isolate structure. |
| 104 __ LoadImmediate(R2, 0); | 102 __ LoadImmediate(R2, 0); |
| 105 __ StoreToOffset(kWord, R2, R9, Isolate::top_exit_frame_info_offset()); | 103 __ StoreToOffset(kWord, R2, R9, Isolate::top_exit_frame_info_offset()); |
| 106 | 104 |
| 107 __ LeaveFrame((1 << FP) | (1 << LR)); | 105 __ LeaveStubFrame(); |
| 108 // Adjust SP for the empty PC marker. | |
| 109 __ AddImmediate(SP, kWordSize); | |
| 110 __ Ret(); | 106 __ Ret(); |
| 111 } | 107 } |
| 112 | 108 |
| 113 | 109 |
| 114 // Print the stop message. | 110 // Print the stop message. |
| 115 DEFINE_LEAF_RUNTIME_ENTRY(void, PrintStopMessage, 1, const char* message) { | 111 DEFINE_LEAF_RUNTIME_ENTRY(void, PrintStopMessage, 1, const char* message) { |
| 116 OS::Print("Stop message: %s\n", message); | 112 OS::Print("Stop message: %s\n", message); |
| 117 } | 113 } |
| 118 END_LEAF_RUNTIME_ENTRY | 114 END_LEAF_RUNTIME_ENTRY |
| 119 | 115 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 135 // SP : address of return value. | 131 // SP : address of return value. |
| 136 // R5 : address of the native function to call. | 132 // R5 : address of the native function to call. |
| 137 // R2 : address of first argument in argument array. | 133 // R2 : address of first argument in argument array. |
| 138 // R1 : argc_tag including number of arguments and function kind. | 134 // R1 : argc_tag including number of arguments and function kind. |
| 139 void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) { | 135 void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) { |
| 140 const intptr_t thread_offset = NativeArguments::thread_offset(); | 136 const intptr_t thread_offset = NativeArguments::thread_offset(); |
| 141 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); | 137 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); |
| 142 const intptr_t argv_offset = NativeArguments::argv_offset(); | 138 const intptr_t argv_offset = NativeArguments::argv_offset(); |
| 143 const intptr_t retval_offset = NativeArguments::retval_offset(); | 139 const intptr_t retval_offset = NativeArguments::retval_offset(); |
| 144 | 140 |
| 145 __ mov(IP, Operand(0)); | 141 __ EnterStubFrame(); |
| 146 __ Push(IP); // Push 0 for the PC marker. | |
| 147 __ EnterFrame((1 << FP) | (1 << LR), 0); | |
| 148 | 142 |
| 149 COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << R9)) != 0); | 143 COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << R9)) != 0); |
| 150 __ LoadIsolate(R9); | 144 __ LoadIsolate(R9); |
| 151 | 145 |
| 152 // Save exit frame information to enable stack walking as we are about | 146 // Save exit frame information to enable stack walking as we are about |
| 153 // to transition to native code. | 147 // to transition to native code. |
| 154 __ StoreToOffset(kWord, FP, R9, Isolate::top_exit_frame_info_offset()); | 148 __ StoreToOffset(kWord, FP, R9, Isolate::top_exit_frame_info_offset()); |
| 155 | 149 |
| 156 #if defined(DEBUG) | 150 #if defined(DEBUG) |
| 157 { Label ok; | 151 { Label ok; |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 209 #endif | 203 #endif |
| 210 | 204 |
| 211 // Mark that the isolate is executing Dart code. | 205 // Mark that the isolate is executing Dart code. |
| 212 __ LoadImmediate(R2, VMTag::kDartTagId); | 206 __ LoadImmediate(R2, VMTag::kDartTagId); |
| 213 __ StoreToOffset(kWord, R2, R9, Isolate::vm_tag_offset()); | 207 __ StoreToOffset(kWord, R2, R9, Isolate::vm_tag_offset()); |
| 214 | 208 |
| 215 // Reset exit frame information in Isolate structure. | 209 // Reset exit frame information in Isolate structure. |
| 216 __ LoadImmediate(R2, 0); | 210 __ LoadImmediate(R2, 0); |
| 217 __ StoreToOffset(kWord, R2, R9, Isolate::top_exit_frame_info_offset()); | 211 __ StoreToOffset(kWord, R2, R9, Isolate::top_exit_frame_info_offset()); |
| 218 | 212 |
| 219 __ LeaveFrame((1 << FP) | (1 << LR)); | 213 __ LeaveStubFrame(); |
| 220 // Adjust SP for the empty PC marker. | |
| 221 __ AddImmediate(SP, kWordSize); | |
| 222 __ Ret(); | 214 __ Ret(); |
| 223 } | 215 } |
| 224 | 216 |
| 225 | 217 |
| 226 // Input parameters: | 218 // Input parameters: |
| 227 // LR : return address. | 219 // LR : return address. |
| 228 // SP : address of return value. | 220 // SP : address of return value. |
| 229 // R5 : address of the native function to call. | 221 // R5 : address of the native function to call. |
| 230 // R2 : address of first argument in argument array. | 222 // R2 : address of first argument in argument array. |
| 231 // R1 : argc_tag including number of arguments and function kind. | 223 // R1 : argc_tag including number of arguments and function kind. |
| 232 void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) { | 224 void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) { |
| 233 const intptr_t thread_offset = NativeArguments::thread_offset(); | 225 const intptr_t thread_offset = NativeArguments::thread_offset(); |
| 234 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); | 226 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); |
| 235 const intptr_t argv_offset = NativeArguments::argv_offset(); | 227 const intptr_t argv_offset = NativeArguments::argv_offset(); |
| 236 const intptr_t retval_offset = NativeArguments::retval_offset(); | 228 const intptr_t retval_offset = NativeArguments::retval_offset(); |
| 237 | 229 |
| 238 __ mov(IP, Operand(0)); | 230 __ EnterStubFrame(); |
| 239 __ Push(IP); // Push 0 for the PC marker. | |
| 240 __ EnterFrame((1 << FP) | (1 << LR), 0); | |
| 241 | 231 |
| 242 COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << R9)) != 0); | 232 COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << R9)) != 0); |
| 243 __ LoadIsolate(R9); | 233 __ LoadIsolate(R9); |
| 244 | 234 |
| 245 // Save exit frame information to enable stack walking as we are about | 235 // Save exit frame information to enable stack walking as we are about |
| 246 // to transition to native code. | 236 // to transition to native code. |
| 247 __ StoreToOffset(kWord, FP, R9, Isolate::top_exit_frame_info_offset()); | 237 __ StoreToOffset(kWord, FP, R9, Isolate::top_exit_frame_info_offset()); |
| 248 | 238 |
| 249 #if defined(DEBUG) | 239 #if defined(DEBUG) |
| 250 { Label ok; | 240 { Label ok; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 293 __ blx(R5); | 283 __ blx(R5); |
| 294 | 284 |
| 295 // Mark that the isolate is executing Dart code. | 285 // Mark that the isolate is executing Dart code. |
| 296 __ LoadImmediate(R2, VMTag::kDartTagId); | 286 __ LoadImmediate(R2, VMTag::kDartTagId); |
| 297 __ StoreToOffset(kWord, R2, R9, Isolate::vm_tag_offset()); | 287 __ StoreToOffset(kWord, R2, R9, Isolate::vm_tag_offset()); |
| 298 | 288 |
| 299 // Reset exit frame information in Isolate structure. | 289 // Reset exit frame information in Isolate structure. |
| 300 __ LoadImmediate(R2, 0); | 290 __ LoadImmediate(R2, 0); |
| 301 __ StoreToOffset(kWord, R2, R9, Isolate::top_exit_frame_info_offset()); | 291 __ StoreToOffset(kWord, R2, R9, Isolate::top_exit_frame_info_offset()); |
| 302 | 292 |
| 303 __ LeaveFrame((1 << FP) | (1 << LR)); | 293 __ LeaveStubFrame(); |
| 304 // Adjust SP for the empty PC marker. | |
| 305 __ AddImmediate(SP, kWordSize); | |
| 306 __ Ret(); | 294 __ Ret(); |
| 307 } | 295 } |
| 308 | 296 |
| 309 | 297 |
| 310 // Input parameters: | 298 // Input parameters: |
| 311 // R4: arguments descriptor array. | 299 // R4: arguments descriptor array. |
| 312 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { | 300 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { |
| 313 // Create a stub frame as we are pushing some objects on the stack before | 301 // Create a stub frame as we are pushing some objects on the stack before |
| 314 // calling into the runtime. | 302 // calling into the runtime. |
| 315 __ EnterStubFrame(); | 303 __ EnterStubFrame(); |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 527 // Restore result into R1. | 515 // Restore result into R1. |
| 528 __ ldr(R1, Address(FP, kFirstLocalSlotFromFp * kWordSize)); | 516 __ ldr(R1, Address(FP, kFirstLocalSlotFromFp * kWordSize)); |
| 529 } | 517 } |
| 530 // Code above cannot cause GC. | 518 // Code above cannot cause GC. |
| 531 __ LeaveDartFrame(); | 519 __ LeaveDartFrame(); |
| 532 | 520 |
| 533 // Frame is fully rewritten at this point and it is safe to perform a GC. | 521 // Frame is fully rewritten at this point and it is safe to perform a GC. |
| 534 // Materialize any objects that were deferred by FillFrame because they | 522 // Materialize any objects that were deferred by FillFrame because they |
| 535 // require allocation. | 523 // require allocation. |
| 536 // Enter stub frame with loading PP. The caller's PP is not materialized yet. | 524 // Enter stub frame with loading PP. The caller's PP is not materialized yet. |
| 537 __ EnterStubFrame(true); | 525 __ EnterStubFrame(); |
| 538 if (preserve_result) { | 526 if (preserve_result) { |
| 539 __ Push(R1); // Preserve result, it will be GC-d here. | 527 __ Push(R1); // Preserve result, it will be GC-d here. |
| 540 } | 528 } |
| 541 __ PushObject(Smi::ZoneHandle()); // Space for the result. | 529 __ PushObject(Smi::ZoneHandle()); // Space for the result. |
| 542 __ CallRuntime(kDeoptimizeMaterializeRuntimeEntry, 0); | 530 __ CallRuntime(kDeoptimizeMaterializeRuntimeEntry, 0); |
| 543 // Result tells stub how many bytes to remove from the expression stack | 531 // Result tells stub how many bytes to remove from the expression stack |
| 544 // of the bottom-most frame. They were used as materialization arguments. | 532 // of the bottom-most frame. They were used as materialization arguments. |
| 545 __ Pop(R1); | 533 __ Pop(R1); |
| 546 if (preserve_result) { | 534 if (preserve_result) { |
| 547 __ Pop(R0); // Restore result. | 535 __ Pop(R0); // Restore result. |
| (...skipping 602 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1150 __ Bind(&slow_case); | 1138 __ Bind(&slow_case); |
| 1151 } | 1139 } |
| 1152 if (is_cls_parameterized) { | 1140 if (is_cls_parameterized) { |
| 1153 // Load the type arguments. | 1141 // Load the type arguments. |
| 1154 __ ldr(R4, Address(SP, 0)); | 1142 __ ldr(R4, Address(SP, 0)); |
| 1155 } | 1143 } |
| 1156 // If is_cls_parameterized: | 1144 // If is_cls_parameterized: |
| 1157 // R4: new object type arguments. | 1145 // R4: new object type arguments. |
| 1158 // Create a stub frame as we are pushing some objects on the stack before | 1146 // Create a stub frame as we are pushing some objects on the stack before |
| 1159 // calling into the runtime. | 1147 // calling into the runtime. |
| 1160 __ EnterStubFrame(true); // Uses pool pointer to pass cls to runtime. | 1148 __ EnterStubFrame(); // Uses pool pointer to pass cls to runtime. |
| 1161 __ LoadImmediate(R2, reinterpret_cast<intptr_t>(Object::null())); | 1149 __ LoadImmediate(R2, reinterpret_cast<intptr_t>(Object::null())); |
| 1162 __ Push(R2); // Setup space on stack for return value. | 1150 __ Push(R2); // Setup space on stack for return value. |
| 1163 __ PushObject(cls); // Push class of object to be allocated. | 1151 __ PushObject(cls); // Push class of object to be allocated. |
| 1164 if (is_cls_parameterized) { | 1152 if (is_cls_parameterized) { |
| 1165 // Push type arguments. | 1153 // Push type arguments. |
| 1166 __ Push(R4); | 1154 __ Push(R4); |
| 1167 } else { | 1155 } else { |
| 1168 // Push null type arguments. | 1156 // Push null type arguments. |
| 1169 __ Push(R2); | 1157 __ Push(R2); |
| 1170 } | 1158 } |
| (...skipping 925 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2096 // Result: | 2084 // Result: |
| 2097 // R1: entry point. | 2085 // R1: entry point. |
| 2098 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { | 2086 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { |
| 2099 EmitMegamorphicLookup(assembler, R0, R1, R1); | 2087 EmitMegamorphicLookup(assembler, R0, R1, R1); |
| 2100 __ Ret(); | 2088 __ Ret(); |
| 2101 } | 2089 } |
| 2102 | 2090 |
| 2103 } // namespace dart | 2091 } // namespace dart |
| 2104 | 2092 |
| 2105 #endif // defined TARGET_ARCH_ARM | 2093 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |