| 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 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 217 __ movq(RAX, FieldAddress(RAX, Code::instructions_offset())); | 217 __ movq(RAX, FieldAddress(RAX, Code::instructions_offset())); |
| 218 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | 218 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
| 219 __ LeaveFrame(); | 219 __ LeaveFrame(); |
| 220 __ jmp(RAX); | 220 __ jmp(RAX); |
| 221 __ int3(); | 221 __ int3(); |
| 222 } | 222 } |
| 223 | 223 |
| 224 | 224 |
| 225 // Input parameters: | 225 // Input parameters: |
| 226 // R10: smi-tagged argument count, may be zero. | 226 // R10: smi-tagged argument count, may be zero. |
| 227 static void PushArgumentsArray(Assembler* assembler, intptr_t arg_offset) { | 227 // RBP[kParamEndSlotFromFp + 1]: last argument. |
| 228 static void PushArgumentsArray(Assembler* assembler) { |
| 228 const Immediate& raw_null = | 229 const Immediate& raw_null = |
| 229 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 230 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 230 | 231 |
| 231 // Allocate array to store arguments of caller. | 232 // Allocate array to store arguments of caller. |
| 232 __ movq(RBX, raw_null); // Null element type for raw Array. | 233 __ movq(RBX, raw_null); // Null element type for raw Array. |
| 233 __ call(&StubCode::AllocateArrayLabel()); | 234 __ call(&StubCode::AllocateArrayLabel()); |
| 234 __ SmiUntag(R10); | 235 __ SmiUntag(R10); |
| 235 // RAX: newly allocated array. | 236 // RAX: newly allocated array. |
| 236 // R10: length of the array (was preserved by the stub). | 237 // R10: length of the array (was preserved by the stub). |
| 237 __ pushq(RAX); // Array is in RAX and on top of stack. | 238 __ pushq(RAX); // Array is in RAX and on top of stack. |
| 238 __ leaq(R12, Address(RSP, R10, TIMES_8, arg_offset)); // Addr of first arg. | 239 __ leaq(R12, Address(RBP, R10, TIMES_8, kParamEndSlotFromFp * kWordSize)); |
| 239 __ leaq(RBX, FieldAddress(RAX, Array::data_offset())); | 240 __ leaq(RBX, FieldAddress(RAX, Array::data_offset())); |
| 241 // R12: address of first argument on stack. |
| 242 // RBX: address of first argument in array. |
| 240 Label loop, loop_condition; | 243 Label loop, loop_condition; |
| 241 __ jmp(&loop_condition, Assembler::kNearJump); | 244 __ jmp(&loop_condition, Assembler::kNearJump); |
| 242 __ Bind(&loop); | 245 __ Bind(&loop); |
| 243 __ movq(RAX, Address(R12, 0)); | 246 __ movq(RAX, Address(R12, 0)); |
| 244 __ movq(Address(RBX, 0), RAX); | 247 __ movq(Address(RBX, 0), RAX); |
| 245 __ AddImmediate(RBX, Immediate(kWordSize)); | 248 __ AddImmediate(RBX, Immediate(kWordSize)); |
| 246 __ AddImmediate(R12, Immediate(-kWordSize)); | 249 __ AddImmediate(R12, Immediate(-kWordSize)); |
| 247 __ Bind(&loop_condition); | 250 __ Bind(&loop_condition); |
| 248 __ decq(R10); | 251 __ decq(R10); |
| 249 __ j(POSITIVE, &loop, Assembler::kNearJump); | 252 __ j(POSITIVE, &loop, Assembler::kNearJump); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 268 // three words (null, stub's pc marker, saved fp) above the return | 271 // three words (null, stub's pc marker, saved fp) above the return |
| 269 // address. | 272 // address. |
| 270 __ movq(R13, FieldAddress(R10, ArgumentsDescriptor::count_offset())); | 273 __ movq(R13, FieldAddress(R10, ArgumentsDescriptor::count_offset())); |
| 271 __ pushq(Address(RSP, R13, TIMES_4, (3 * kWordSize))); | 274 __ pushq(Address(RSP, R13, TIMES_4, (3 * kWordSize))); |
| 272 | 275 |
| 273 __ pushq(RBX); // Pass IC data object. | 276 __ pushq(RBX); // Pass IC data object. |
| 274 __ pushq(R10); // Pass arguments descriptor array. | 277 __ pushq(R10); // Pass arguments descriptor array. |
| 275 | 278 |
| 276 // Pass the call's arguments array. | 279 // Pass the call's arguments array. |
| 277 __ movq(R10, R13); // Smi-tagged arguments array length. | 280 __ movq(R10, R13); // Smi-tagged arguments array length. |
| 278 PushArgumentsArray(assembler, (7 * kWordSize)); | 281 PushArgumentsArray(assembler); |
| 279 // Stack layout explaining "(7 * kWordSize)" offset. | |
| 280 // TOS + 0: Arguments array. | |
| 281 // TOS + 1: Arguments descriptor array. | |
| 282 // TOS + 2: IC data object. | |
| 283 // TOS + 3: Receiver. | |
| 284 // TOS + 4: Space for the result of the runtime call. | |
| 285 // TOS + 5: Stub's PC marker (0) | |
| 286 // TOS + 6: Saved FP | |
| 287 // TOS + 7: Dart code return address | |
| 288 // TOS + 8: Last argument of caller. | |
| 289 // .... | |
| 290 | 282 |
| 291 __ CallRuntime(kInstanceFunctionLookupRuntimeEntry); | 283 __ CallRuntime(kInstanceFunctionLookupRuntimeEntry); |
| 284 |
| 292 // Remove arguments. | 285 // Remove arguments. |
| 293 __ popq(RAX); | 286 __ Drop(4); |
| 294 __ popq(RAX); | |
| 295 __ popq(RAX); | |
| 296 __ popq(RAX); | |
| 297 __ popq(RAX); // Get result into RAX. | 287 __ popq(RAX); // Get result into RAX. |
| 298 __ LeaveFrame(); | 288 __ LeaveFrame(); |
| 299 __ ret(); | 289 __ ret(); |
| 300 } | 290 } |
| 301 | 291 |
| 302 | 292 |
| 303 DECLARE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame, | 293 DECLARE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame, |
| 304 intptr_t deopt_reason, | 294 intptr_t deopt_reason, |
| 305 uword saved_registers_address); | 295 uword saved_registers_address); |
| 306 | 296 |
| (...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 671 // R10: arguments descriptor array. | 661 // R10: arguments descriptor array. |
| 672 | 662 |
| 673 // Create a stub frame as we are pushing some objects on the stack before | 663 // Create a stub frame as we are pushing some objects on the stack before |
| 674 // calling into the runtime. | 664 // calling into the runtime. |
| 675 __ EnterStubFrame(); | 665 __ EnterStubFrame(); |
| 676 | 666 |
| 677 __ pushq(raw_null); // Setup space on stack for result from call. | 667 __ pushq(raw_null); // Setup space on stack for result from call. |
| 678 __ pushq(R10); // Arguments descriptor. | 668 __ pushq(R10); // Arguments descriptor. |
| 679 // Load smi-tagged arguments array length, including the non-closure. | 669 // Load smi-tagged arguments array length, including the non-closure. |
| 680 __ movq(R10, FieldAddress(R10, ArgumentsDescriptor::count_offset())); | 670 __ movq(R10, FieldAddress(R10, ArgumentsDescriptor::count_offset())); |
| 681 // See stack layout below explaining "wordSize * 5" offset. | 671 PushArgumentsArray(assembler); |
| 682 PushArgumentsArray(assembler, (kWordSize * 5)); | |
| 683 | 672 |
| 684 // Stack: | |
| 685 // TOS + 0: Argument array. | |
| 686 // TOS + 1: Arguments descriptor array. | |
| 687 // TOS + 2: Place for result from the call. | |
| 688 // TOS + 3: PC marker => RawInstruction object. | |
| 689 // TOS + 4: Saved RBP of previous frame. <== RBP | |
| 690 // TOS + 5: Dart code return address | |
| 691 // TOS + 6: Last argument of caller. | |
| 692 // .... | |
| 693 __ CallRuntime(kInvokeNonClosureRuntimeEntry); | 673 __ CallRuntime(kInvokeNonClosureRuntimeEntry); |
| 674 |
| 694 // Remove arguments. | 675 // Remove arguments. |
| 695 __ popq(RAX); | 676 __ Drop(2); |
| 696 __ popq(RAX); | |
| 697 __ popq(RAX); // Get result into RAX. | 677 __ popq(RAX); // Get result into RAX. |
| 698 | 678 |
| 699 // Remove the stub frame as we are about to return. | 679 // Remove the stub frame as we are about to return. |
| 700 __ LeaveFrame(); | 680 __ LeaveFrame(); |
| 701 __ ret(); | 681 __ ret(); |
| 702 } | 682 } |
| 703 | 683 |
| 704 | 684 |
| 705 // Called when invoking Dart code from C++ (VM code). | 685 // Called when invoking Dart code from C++ (VM code). |
| 706 // Input parameters: | 686 // Input parameters: |
| (...skipping 627 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1334 } | 1314 } |
| 1335 __ popq(RAX); // Pop the function object. | 1315 __ popq(RAX); // Pop the function object. |
| 1336 __ popq(RAX); // Pop the result. | 1316 __ popq(RAX); // Pop the result. |
| 1337 // RAX: New closure object. | 1317 // RAX: New closure object. |
| 1338 // Restore the calling frame. | 1318 // Restore the calling frame. |
| 1339 __ LeaveFrame(); | 1319 __ LeaveFrame(); |
| 1340 __ ret(); | 1320 __ ret(); |
| 1341 } | 1321 } |
| 1342 | 1322 |
| 1343 | 1323 |
| 1344 // Called for invoking noSuchMethod function from the entry code of a dart | 1324 // Called for invoking "dynamic noSuchMethod(Invocation invocation)" function |
| 1345 // function after an error in passed named arguments is detected. | 1325 // from the entry code of a dart function after an error in passed argument |
| 1326 // name or number is detected. |
| 1346 // Input parameters: | 1327 // Input parameters: |
| 1347 // RBP - 8 : PC marker => RawInstruction object. | 1328 // RSP : points to return address. |
| 1348 // RBP : points to previous frame pointer. | 1329 // RSP + 8 : address of last argument. |
| 1349 // RBP + 8 : points to return address. | |
| 1350 // RBP + 16 : address of last argument (arg n-1). | |
| 1351 // RBP + 16 + 8*(n-1) : address of first argument (arg 0). | |
| 1352 // RBX : ic-data. | 1330 // RBX : ic-data. |
| 1353 // R10 : arguments descriptor array. | 1331 // R10 : arguments descriptor array. |
| 1354 void StubCode::GenerateCallNoSuchMethodFunctionStub(Assembler* assembler) { | 1332 void StubCode::GenerateCallNoSuchMethodFunctionStub(Assembler* assembler) { |
| 1355 // The target function was not found, so invoke method | 1333 __ EnterStubFrame(); |
| 1356 // "dynamic noSuchMethod(Invocation invocation)". | 1334 |
| 1335 // Load the receiver. |
| 1336 __ movq(R13, FieldAddress(R10, ArgumentsDescriptor::count_offset())); |
| 1337 __ movq(RAX, Address(RBP, R13, TIMES_4, kParamEndSlotFromFp * kWordSize)); |
| 1338 |
| 1357 const Immediate& raw_null = | 1339 const Immediate& raw_null = |
| 1358 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 1340 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 1359 __ movq(R13, FieldAddress(R10, ArgumentsDescriptor::count_offset())); | |
| 1360 __ movq(RAX, Address(RBP, R13, TIMES_4, kWordSize)); // Get receiver. | |
| 1361 | |
| 1362 // Create a stub frame. | |
| 1363 __ EnterStubFrame(); | |
| 1364 | |
| 1365 __ pushq(raw_null); // Setup space on stack for result from noSuchMethod. | 1341 __ pushq(raw_null); // Setup space on stack for result from noSuchMethod. |
| 1366 __ pushq(RAX); // Receiver. | 1342 __ pushq(RAX); // Receiver. |
| 1367 __ pushq(RBX); // IC data array. | 1343 __ pushq(RBX); // IC data array. |
| 1368 __ pushq(R10); // Arguments descriptor array. | 1344 __ pushq(R10); // Arguments descriptor array. |
| 1369 | 1345 |
| 1370 __ movq(R10, R13); // Smi-tagged arguments array length. | 1346 __ movq(R10, R13); // Smi-tagged arguments array length. |
| 1371 // See stack layout below explaining "wordSize * 10" offset. | 1347 PushArgumentsArray(assembler); |
| 1372 PushArgumentsArray(assembler, (kWordSize * 10)); | |
| 1373 | 1348 |
| 1374 // Stack: | |
| 1375 // TOS + 0: Argument array. | |
| 1376 // TOS + 1: Arguments descriptor array. | |
| 1377 // TOS + 2: Ic-data array. | |
| 1378 // TOS + 3: Receiver. | |
| 1379 // TOS + 4: Place for result from noSuchMethod. | |
| 1380 // TOS + 5: PC marker => RawInstruction object. | |
| 1381 // TOS + 6: Saved RBP of previous frame. <== RBP | |
| 1382 // TOS + 7: Dart callee (or stub) code return address | |
| 1383 // TOS + 8: PC marker => RawInstruction object of dart caller frame. | |
| 1384 // TOS + 9: Saved RBP of dart caller frame. | |
| 1385 // TOS + 10: Dart caller code return address | |
| 1386 // TOS + 11: Last argument of caller. | |
| 1387 // .... | |
| 1388 __ CallRuntime(kInvokeNoSuchMethodFunctionRuntimeEntry); | 1349 __ CallRuntime(kInvokeNoSuchMethodFunctionRuntimeEntry); |
| 1350 |
| 1389 // Remove arguments. | 1351 // Remove arguments. |
| 1390 __ popq(RAX); | 1352 __ Drop(4); |
| 1391 __ popq(RAX); | |
| 1392 __ popq(RAX); | |
| 1393 __ popq(RAX); | |
| 1394 __ popq(RAX); // Get result into RAX. | 1353 __ popq(RAX); // Get result into RAX. |
| 1395 | 1354 |
| 1396 // Remove the stub frame as we are about to return. | 1355 // Remove the stub frame as we are about to return. |
| 1397 __ LeaveFrame(); | 1356 __ LeaveFrame(); |
| 1398 __ ret(); | 1357 __ ret(); |
| 1399 } | 1358 } |
| 1400 | 1359 |
| 1401 | 1360 |
| 1402 // Cannot use function object from ICData as it may be the inlined | 1361 // Cannot use function object from ICData as it may be the inlined |
| 1403 // function and not the top-scope function. | 1362 // function and not the top-scope function. |
| (...skipping 734 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2138 __ cmpq(left, right); | 2097 __ cmpq(left, right); |
| 2139 __ Bind(&done); | 2098 __ Bind(&done); |
| 2140 __ popq(right); | 2099 __ popq(right); |
| 2141 __ popq(left); | 2100 __ popq(left); |
| 2142 __ ret(); | 2101 __ ret(); |
| 2143 } | 2102 } |
| 2144 | 2103 |
| 2145 } // namespace dart | 2104 } // namespace dart |
| 2146 | 2105 |
| 2147 #endif // defined TARGET_ARCH_X64 | 2106 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |