| 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_X64) | 6 #if defined(TARGET_ARCH_X64) |
| 7 | 7 |
| 8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
| 9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 25 matching lines...) Expand all Loading... |
| 36 // RSP + 8*R10 + 8 : address of return value. | 36 // RSP + 8*R10 + 8 : address of return value. |
| 37 // RBX : address of the runtime function to call. | 37 // RBX : address of the runtime function to call. |
| 38 // R10 : number of arguments to the call. | 38 // R10 : number of arguments to the call. |
| 39 // Must preserve callee saved registers R12 and R13. | 39 // Must preserve callee saved registers R12 and R13. |
| 40 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) { | 40 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) { |
| 41 const intptr_t thread_offset = NativeArguments::thread_offset(); | 41 const intptr_t thread_offset = NativeArguments::thread_offset(); |
| 42 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); | 42 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); |
| 43 const intptr_t argv_offset = NativeArguments::argv_offset(); | 43 const intptr_t argv_offset = NativeArguments::argv_offset(); |
| 44 const intptr_t retval_offset = NativeArguments::retval_offset(); | 44 const intptr_t retval_offset = NativeArguments::retval_offset(); |
| 45 | 45 |
| 46 __ EnterFrame(0); | 46 __ EnterStubFrame(); |
| 47 | 47 |
| 48 COMPILE_ASSERT( | 48 COMPILE_ASSERT( |
| 49 (CallingConventions::kCalleeSaveCpuRegisters & (1 << R12)) != 0); | 49 (CallingConventions::kCalleeSaveCpuRegisters & (1 << R12)) != 0); |
| 50 __ LoadIsolate(R12); | 50 __ LoadIsolate(R12); |
| 51 | 51 |
| 52 // Save exit frame information to enable stack walking as we are about | 52 // Save exit frame information to enable stack walking as we are about |
| 53 // to transition to Dart VM C++ code. | 53 // to transition to Dart VM C++ code. |
| 54 __ movq(Address(R12, Isolate::top_exit_frame_info_offset()), RBP); | 54 __ movq(Address(R12, Isolate::top_exit_frame_info_offset()), RBP); |
| 55 | 55 |
| 56 #if defined(DEBUG) | 56 #if defined(DEBUG) |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 88 #endif | 88 #endif |
| 89 __ CallCFunction(RBX); | 89 __ CallCFunction(RBX); |
| 90 | 90 |
| 91 // Mark that the isolate is executing Dart code. | 91 // Mark that the isolate is executing Dart code. |
| 92 __ movq(Address(R12, Isolate::vm_tag_offset()), | 92 __ movq(Address(R12, Isolate::vm_tag_offset()), |
| 93 Immediate(VMTag::kDartTagId)); | 93 Immediate(VMTag::kDartTagId)); |
| 94 | 94 |
| 95 // Reset exit frame information in Isolate structure. | 95 // Reset exit frame information in Isolate structure. |
| 96 __ movq(Address(R12, Isolate::top_exit_frame_info_offset()), Immediate(0)); | 96 __ movq(Address(R12, Isolate::top_exit_frame_info_offset()), Immediate(0)); |
| 97 | 97 |
| 98 __ LeaveFrame(); | 98 __ LeaveStubFrame(); |
| 99 __ ret(); | 99 __ ret(); |
| 100 } | 100 } |
| 101 | 101 |
| 102 | 102 |
| 103 // Print the stop message. | 103 // Print the stop message. |
| 104 DEFINE_LEAF_RUNTIME_ENTRY(void, PrintStopMessage, 1, const char* message) { | 104 DEFINE_LEAF_RUNTIME_ENTRY(void, PrintStopMessage, 1, const char* message) { |
| 105 OS::Print("Stop message: %s\n", message); | 105 OS::Print("Stop message: %s\n", message); |
| 106 } | 106 } |
| 107 END_LEAF_RUNTIME_ENTRY | 107 END_LEAF_RUNTIME_ENTRY |
| 108 | 108 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 133 const intptr_t native_args_struct_offset = 0; | 133 const intptr_t native_args_struct_offset = 0; |
| 134 const intptr_t thread_offset = | 134 const intptr_t thread_offset = |
| 135 NativeArguments::thread_offset() + native_args_struct_offset; | 135 NativeArguments::thread_offset() + native_args_struct_offset; |
| 136 const intptr_t argc_tag_offset = | 136 const intptr_t argc_tag_offset = |
| 137 NativeArguments::argc_tag_offset() + native_args_struct_offset; | 137 NativeArguments::argc_tag_offset() + native_args_struct_offset; |
| 138 const intptr_t argv_offset = | 138 const intptr_t argv_offset = |
| 139 NativeArguments::argv_offset() + native_args_struct_offset; | 139 NativeArguments::argv_offset() + native_args_struct_offset; |
| 140 const intptr_t retval_offset = | 140 const intptr_t retval_offset = |
| 141 NativeArguments::retval_offset() + native_args_struct_offset; | 141 NativeArguments::retval_offset() + native_args_struct_offset; |
| 142 | 142 |
| 143 __ EnterFrame(0); | 143 __ EnterStubFrame(); |
| 144 | 144 |
| 145 COMPILE_ASSERT( | 145 COMPILE_ASSERT( |
| 146 (CallingConventions::kCalleeSaveCpuRegisters & (1 << R12)) != 0); | 146 (CallingConventions::kCalleeSaveCpuRegisters & (1 << R12)) != 0); |
| 147 __ LoadIsolate(R12); | 147 __ LoadIsolate(R12); |
| 148 | 148 |
| 149 // Save exit frame information to enable stack walking as we are about | 149 // Save exit frame information to enable stack walking as we are about |
| 150 // to transition to native code. | 150 // to transition to native code. |
| 151 __ movq(Address(R12, Isolate::top_exit_frame_info_offset()), RBP); | 151 __ movq(Address(R12, Isolate::top_exit_frame_info_offset()), RBP); |
| 152 | 152 |
| 153 #if defined(DEBUG) | 153 #if defined(DEBUG) |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 185 __ movq(CallingConventions::kArg2Reg, RBX); | 185 __ movq(CallingConventions::kArg2Reg, RBX); |
| 186 __ CallCFunction(&NativeEntry::NativeCallWrapperLabel()); | 186 __ CallCFunction(&NativeEntry::NativeCallWrapperLabel()); |
| 187 | 187 |
| 188 // Mark that the isolate is executing Dart code. | 188 // Mark that the isolate is executing Dart code. |
| 189 __ movq(Address(R12, Isolate::vm_tag_offset()), | 189 __ movq(Address(R12, Isolate::vm_tag_offset()), |
| 190 Immediate(VMTag::kDartTagId)); | 190 Immediate(VMTag::kDartTagId)); |
| 191 | 191 |
| 192 // Reset exit frame information in Isolate structure. | 192 // Reset exit frame information in Isolate structure. |
| 193 __ movq(Address(R12, Isolate::top_exit_frame_info_offset()), Immediate(0)); | 193 __ movq(Address(R12, Isolate::top_exit_frame_info_offset()), Immediate(0)); |
| 194 | 194 |
| 195 __ LeaveFrame(); | 195 __ LeaveStubFrame(); |
| 196 __ ret(); | 196 __ ret(); |
| 197 } | 197 } |
| 198 | 198 |
| 199 | 199 |
| 200 // Input parameters: | 200 // Input parameters: |
| 201 // RSP : points to return address. | 201 // RSP : points to return address. |
| 202 // RSP + 8 : address of return value. | 202 // RSP + 8 : address of return value. |
| 203 // RAX : address of first argument in argument array. | 203 // RAX : address of first argument in argument array. |
| 204 // RBX : address of the native function to call. | 204 // RBX : address of the native function to call. |
| 205 // R10 : argc_tag including number of arguments and function kind. | 205 // R10 : argc_tag including number of arguments and function kind. |
| 206 void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) { | 206 void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) { |
| 207 const intptr_t native_args_struct_offset = 0; | 207 const intptr_t native_args_struct_offset = 0; |
| 208 const intptr_t thread_offset = | 208 const intptr_t thread_offset = |
| 209 NativeArguments::thread_offset() + native_args_struct_offset; | 209 NativeArguments::thread_offset() + native_args_struct_offset; |
| 210 const intptr_t argc_tag_offset = | 210 const intptr_t argc_tag_offset = |
| 211 NativeArguments::argc_tag_offset() + native_args_struct_offset; | 211 NativeArguments::argc_tag_offset() + native_args_struct_offset; |
| 212 const intptr_t argv_offset = | 212 const intptr_t argv_offset = |
| 213 NativeArguments::argv_offset() + native_args_struct_offset; | 213 NativeArguments::argv_offset() + native_args_struct_offset; |
| 214 const intptr_t retval_offset = | 214 const intptr_t retval_offset = |
| 215 NativeArguments::retval_offset() + native_args_struct_offset; | 215 NativeArguments::retval_offset() + native_args_struct_offset; |
| 216 | 216 |
| 217 __ EnterFrame(0); | 217 __ EnterStubFrame(); |
| 218 | 218 |
| 219 COMPILE_ASSERT( | 219 COMPILE_ASSERT( |
| 220 (CallingConventions::kCalleeSaveCpuRegisters & (1 << R12)) != 0); | 220 (CallingConventions::kCalleeSaveCpuRegisters & (1 << R12)) != 0); |
| 221 __ LoadIsolate(R12); | 221 __ LoadIsolate(R12); |
| 222 | 222 |
| 223 // Save exit frame information to enable stack walking as we are about | 223 // Save exit frame information to enable stack walking as we are about |
| 224 // to transition to native code. | 224 // to transition to native code. |
| 225 __ movq(Address(R12, Isolate::top_exit_frame_info_offset()), RBP); | 225 __ movq(Address(R12, Isolate::top_exit_frame_info_offset()), RBP); |
| 226 | 226 |
| 227 #if defined(DEBUG) | 227 #if defined(DEBUG) |
| (...skipping 29 matching lines...) Expand all Loading... |
| 257 __ movq(CallingConventions::kArg1Reg, RSP); | 257 __ movq(CallingConventions::kArg1Reg, RSP); |
| 258 __ CallCFunction(RBX); | 258 __ CallCFunction(RBX); |
| 259 | 259 |
| 260 // Mark that the isolate is executing Dart code. | 260 // Mark that the isolate is executing Dart code. |
| 261 __ movq(Address(R12, Isolate::vm_tag_offset()), | 261 __ movq(Address(R12, Isolate::vm_tag_offset()), |
| 262 Immediate(VMTag::kDartTagId)); | 262 Immediate(VMTag::kDartTagId)); |
| 263 | 263 |
| 264 // Reset exit frame information in Isolate structure. | 264 // Reset exit frame information in Isolate structure. |
| 265 __ movq(Address(R12, Isolate::top_exit_frame_info_offset()), Immediate(0)); | 265 __ movq(Address(R12, Isolate::top_exit_frame_info_offset()), Immediate(0)); |
| 266 | 266 |
| 267 __ LeaveFrame(); | 267 __ LeaveStubFrame(); |
| 268 __ ret(); | 268 __ ret(); |
| 269 } | 269 } |
| 270 | 270 |
| 271 | 271 |
| 272 // Input parameters: | 272 // Input parameters: |
| 273 // R10: arguments descriptor array. | 273 // R10: arguments descriptor array. |
| 274 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { | 274 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { |
| 275 __ EnterStubFrame(); | 275 __ EnterStubFrame(); |
| 276 __ pushq(R10); // Preserve arguments descriptor array. | 276 __ pushq(R10); // Preserve arguments descriptor array. |
| 277 // Setup space on stack for return value. | 277 // Setup space on stack for return value. |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 479 __ movq(RBX, Address(RBP, kFirstLocalSlotFromFp * kWordSize)); | 479 __ movq(RBX, Address(RBP, kFirstLocalSlotFromFp * kWordSize)); |
| 480 } | 480 } |
| 481 // Code above cannot cause GC. | 481 // Code above cannot cause GC. |
| 482 // There is a Dart Frame on the stack. We must restore PP and leave frame. | 482 // There is a Dart Frame on the stack. We must restore PP and leave frame. |
| 483 __ LeaveDartFrame(); | 483 __ LeaveDartFrame(); |
| 484 | 484 |
| 485 // Frame is fully rewritten at this point and it is safe to perform a GC. | 485 // Frame is fully rewritten at this point and it is safe to perform a GC. |
| 486 // Materialize any objects that were deferred by FillFrame because they | 486 // Materialize any objects that were deferred by FillFrame because they |
| 487 // require allocation. | 487 // require allocation. |
| 488 // Enter stub frame with loading PP. The caller's PP is not materialized yet. | 488 // Enter stub frame with loading PP. The caller's PP is not materialized yet. |
| 489 __ EnterStubFrame(true); | 489 __ EnterStubFrame(); |
| 490 if (preserve_result) { | 490 if (preserve_result) { |
| 491 __ pushq(Immediate(0)); // Workaround for dropped stack slot during GC. | 491 __ pushq(Immediate(0)); // Workaround for dropped stack slot during GC. |
| 492 __ pushq(RBX); // Preserve result, it will be GC-d here. | 492 __ pushq(RBX); // Preserve result, it will be GC-d here. |
| 493 } | 493 } |
| 494 __ pushq(Immediate(Smi::RawValue(0))); // Space for the result. | 494 __ pushq(Immediate(Smi::RawValue(0))); // Space for the result. |
| 495 __ CallRuntime(kDeoptimizeMaterializeRuntimeEntry, 0); | 495 __ CallRuntime(kDeoptimizeMaterializeRuntimeEntry, 0); |
| 496 // Result tells stub how many bytes to remove from the expression stack | 496 // Result tells stub how many bytes to remove from the expression stack |
| 497 // of the bottom-most frame. They were used as materialization arguments. | 497 // of the bottom-most frame. They were used as materialization arguments. |
| 498 __ popq(RBX); | 498 __ popq(RBX); |
| 499 __ SmiUntag(RBX); | 499 __ SmiUntag(RBX); |
| (...skipping 633 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1133 } | 1133 } |
| 1134 // Done allocating and initializing the instance. | 1134 // Done allocating and initializing the instance. |
| 1135 // RAX: new object (tagged). | 1135 // RAX: new object (tagged). |
| 1136 __ ret(); | 1136 __ ret(); |
| 1137 | 1137 |
| 1138 __ Bind(&slow_case); | 1138 __ Bind(&slow_case); |
| 1139 } | 1139 } |
| 1140 // If is_cls_parameterized: | 1140 // If is_cls_parameterized: |
| 1141 // RDX: new object type arguments. | 1141 // RDX: new object type arguments. |
| 1142 // Create a stub frame. | 1142 // Create a stub frame. |
| 1143 __ EnterStubFrame(true); // Uses PP to access class object. | 1143 __ EnterStubFrame(); // Uses PP to access class object. |
| 1144 __ pushq(R12); // Setup space on stack for return value. | 1144 __ pushq(R12); // Setup space on stack for return value. |
| 1145 __ PushObject(cls, PP); // Push class of object to be allocated. | 1145 __ PushObject(cls, PP); // Push class of object to be allocated. |
| 1146 if (is_cls_parameterized) { | 1146 if (is_cls_parameterized) { |
| 1147 __ pushq(RDX); // Push type arguments of object to be allocated. | 1147 __ pushq(RDX); // Push type arguments of object to be allocated. |
| 1148 } else { | 1148 } else { |
| 1149 __ pushq(R12); // Push null type arguments. | 1149 __ pushq(R12); // Push null type arguments. |
| 1150 } | 1150 } |
| 1151 __ CallRuntime(kAllocateObjectRuntimeEntry, 2); // Allocate object. | 1151 __ CallRuntime(kAllocateObjectRuntimeEntry, 2); // Allocate object. |
| 1152 __ popq(RAX); // Pop argument (type arguments of object). | 1152 __ popq(RAX); // Pop argument (type arguments of object). |
| 1153 __ popq(RAX); // Pop argument (class of object). | 1153 __ popq(RAX); // Pop argument (class of object). |
| (...skipping 858 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2012 __ j(NOT_EQUAL, &done, Assembler::kNearJump); | 2012 __ j(NOT_EQUAL, &done, Assembler::kNearJump); |
| 2013 __ movq(left, FieldAddress(left, Mint::value_offset())); | 2013 __ movq(left, FieldAddress(left, Mint::value_offset())); |
| 2014 __ cmpq(left, FieldAddress(right, Mint::value_offset())); | 2014 __ cmpq(left, FieldAddress(right, Mint::value_offset())); |
| 2015 __ jmp(&done, Assembler::kNearJump); | 2015 __ jmp(&done, Assembler::kNearJump); |
| 2016 | 2016 |
| 2017 __ Bind(&check_bigint); | 2017 __ Bind(&check_bigint); |
| 2018 __ CompareClassId(left, kBigintCid); | 2018 __ CompareClassId(left, kBigintCid); |
| 2019 __ j(NOT_EQUAL, &reference_compare, Assembler::kNearJump); | 2019 __ j(NOT_EQUAL, &reference_compare, Assembler::kNearJump); |
| 2020 __ CompareClassId(right, kBigintCid); | 2020 __ CompareClassId(right, kBigintCid); |
| 2021 __ j(NOT_EQUAL, &done, Assembler::kNearJump); | 2021 __ j(NOT_EQUAL, &done, Assembler::kNearJump); |
| 2022 __ EnterFrame(0); | 2022 __ EnterStubFrame(); |
| 2023 __ ReserveAlignedFrameSpace(0); | 2023 __ ReserveAlignedFrameSpace(0); |
| 2024 __ movq(CallingConventions::kArg1Reg, left); | 2024 __ movq(CallingConventions::kArg1Reg, left); |
| 2025 __ movq(CallingConventions::kArg2Reg, right); | 2025 __ movq(CallingConventions::kArg2Reg, right); |
| 2026 __ CallRuntime(kBigintCompareRuntimeEntry, 2); | 2026 __ CallRuntime(kBigintCompareRuntimeEntry, 2); |
| 2027 // Result in RAX, 0 means equal. | 2027 // Result in RAX, 0 means equal. |
| 2028 __ LeaveFrame(); | 2028 __ LeaveStubFrame(); |
| 2029 __ cmpq(RAX, Immediate(0)); | 2029 __ cmpq(RAX, Immediate(0)); |
| 2030 __ jmp(&done); | 2030 __ jmp(&done); |
| 2031 | 2031 |
| 2032 __ Bind(&reference_compare); | 2032 __ Bind(&reference_compare); |
| 2033 __ cmpq(left, right); | 2033 __ cmpq(left, right); |
| 2034 __ Bind(&done); | 2034 __ Bind(&done); |
| 2035 } | 2035 } |
| 2036 | 2036 |
| 2037 | 2037 |
| 2038 // Called only from unoptimized code. All relevant registers have been saved. | 2038 // Called only from unoptimized code. All relevant registers have been saved. |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2135 // Result: | 2135 // Result: |
| 2136 // RCX: entry point. | 2136 // RCX: entry point. |
| 2137 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { | 2137 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { |
| 2138 EmitMegamorphicLookup(assembler, RDI, RBX, RCX); | 2138 EmitMegamorphicLookup(assembler, RDI, RBX, RCX); |
| 2139 __ ret(); | 2139 __ ret(); |
| 2140 } | 2140 } |
| 2141 | 2141 |
| 2142 } // namespace dart | 2142 } // namespace dart |
| 2143 | 2143 |
| 2144 #endif // defined TARGET_ARCH_X64 | 2144 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |