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 363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
374 __ movq(RAX, Address(R12, 0)); | 374 __ movq(RAX, Address(R12, 0)); |
375 __ movq(Address(RBX, 0), RAX); | 375 __ movq(Address(RBX, 0), RAX); |
376 __ addq(RBX, Immediate(kWordSize)); | 376 __ addq(RBX, Immediate(kWordSize)); |
377 __ subq(R12, Immediate(kWordSize)); | 377 __ subq(R12, Immediate(kWordSize)); |
378 __ Bind(&loop_condition); | 378 __ Bind(&loop_condition); |
379 __ decq(R10); | 379 __ decq(R10); |
380 __ j(POSITIVE, &loop, Assembler::kNearJump); | 380 __ j(POSITIVE, &loop, Assembler::kNearJump); |
381 } | 381 } |
382 | 382 |
383 | 383 |
384 // Input parameters: | |
385 // RBX: ic-data. | |
386 // R10: arguments descriptor array. | |
387 // Note: The receiver object is the first argument to the function being | |
388 // called, the stub accesses the receiver from this location directly | |
389 // when trying to resolve the call. | |
390 void StubCode::GenerateInstanceFunctionLookupStub(Assembler* assembler) { | |
391 __ EnterStubFrame(); | |
392 __ PushObject(Object::null_object(), PP); // Space for the return value. | |
393 | |
394 // Push the receiver as an argument. Load the smi-tagged argument | |
395 // count into R13 to index the receiver in the stack. There are | |
396 // four words (null, stub's pc marker, saved pp, saved fp) above the return | |
397 // address. | |
398 __ movq(R13, FieldAddress(R10, ArgumentsDescriptor::count_offset())); | |
399 __ pushq(Address(RSP, R13, TIMES_4, (4 * kWordSize))); | |
400 | |
401 __ pushq(RBX); // Pass IC data object. | |
402 __ pushq(R10); // Pass arguments descriptor array. | |
403 | |
404 // Pass the call's arguments array. | |
405 __ movq(R10, R13); // Smi-tagged arguments array length. | |
406 PushArgumentsArray(assembler); | |
407 | |
408 __ CallRuntime(kInstanceFunctionLookupRuntimeEntry, 4); | |
409 | |
410 // Remove arguments. | |
411 __ Drop(4); | |
412 __ popq(RAX); // Get result into RAX. | |
413 __ LeaveStubFrame(); | |
414 __ ret(); | |
415 } | |
416 | |
417 | |
418 DECLARE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame, | 384 DECLARE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame, |
419 intptr_t deopt_reason, | 385 intptr_t deopt_reason, |
420 uword saved_registers_address); | 386 uword saved_registers_address); |
421 | 387 |
422 DECLARE_LEAF_RUNTIME_ENTRY(void, DeoptimizeFillFrame, uword last_fp); | 388 DECLARE_LEAF_RUNTIME_ENTRY(void, DeoptimizeFillFrame, uword last_fp); |
423 | 389 |
424 | 390 |
425 // Used by eager and lazy deoptimization. Preserve result in RAX if necessary. | 391 // Used by eager and lazy deoptimization. Preserve result in RAX if necessary. |
426 // This stub translates optimized frame into unoptimized frame. The optimized | 392 // This stub translates optimized frame into unoptimized frame. The optimized |
427 // frame can contain values in registers and on stack, the unoptimized | 393 // frame can contain values in registers and on stack, the unoptimized |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
571 // Space for the result of the runtime call. | 537 // Space for the result of the runtime call. |
572 __ PushObject(Object::null_object(), PP); | 538 __ PushObject(Object::null_object(), PP); |
573 __ pushq(RAX); // Receiver. | 539 __ pushq(RAX); // Receiver. |
574 __ pushq(RBX); // IC data. | 540 __ pushq(RBX); // IC data. |
575 __ pushq(R10); // Arguments descriptor. | 541 __ pushq(R10); // Arguments descriptor. |
576 __ CallRuntime(kMegamorphicCacheMissHandlerRuntimeEntry, 3); | 542 __ CallRuntime(kMegamorphicCacheMissHandlerRuntimeEntry, 3); |
577 // Discard arguments. | 543 // Discard arguments. |
578 __ popq(RAX); | 544 __ popq(RAX); |
579 __ popq(RAX); | 545 __ popq(RAX); |
580 __ popq(RAX); | 546 __ popq(RAX); |
581 __ popq(RAX); // Return value from the runtime call (instructions). | 547 __ popq(RAX); // Return value from the runtime call (function). |
582 __ popq(R10); // Restore arguments descriptor. | 548 __ popq(R10); // Restore arguments descriptor. |
583 __ popq(RBX); // Restore IC data. | 549 __ popq(RBX); // Restore IC data. |
584 __ LeaveStubFrame(); | 550 __ LeaveStubFrame(); |
585 | 551 |
586 Label lookup; | 552 __ movq(RCX, FieldAddress(RAX, Function::code_offset())); |
587 __ CompareObject(RAX, Object::null_object(), PP); | 553 __ movq(RCX, FieldAddress(RCX, Code::instructions_offset())); |
588 __ j(EQUAL, &lookup, Assembler::kNearJump); | 554 __ addq(RCX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
589 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | 555 __ jmp(RCX); |
590 __ jmp(RAX); | |
591 | |
592 __ Bind(&lookup); | |
593 __ jmp(&StubCode::InstanceFunctionLookupLabel()); | |
594 } | 556 } |
595 | 557 |
596 | 558 |
597 // Called for inline allocation of arrays. | 559 // Called for inline allocation of arrays. |
598 // Input parameters: | 560 // Input parameters: |
599 // R10 : Array length as Smi. | 561 // R10 : Array length as Smi. |
600 // RBX : array element type (either NULL or an instantiated type). | 562 // RBX : array element type (either NULL or an instantiated type). |
601 // NOTE: R10 cannot be clobbered here as the caller relies on it being saved. | 563 // NOTE: R10 cannot be clobbered here as the caller relies on it being saved. |
602 // The newly allocated object is returned in RAX. | 564 // The newly allocated object is returned in RAX. |
603 void StubCode::GenerateAllocateArrayStub(Assembler* assembler) { | 565 void StubCode::GenerateAllocateArrayStub(Assembler* assembler) { |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
759 // Actual class is not a closure class. | 721 // Actual class is not a closure class. |
760 __ j(EQUAL, ¬_closure, Assembler::kNearJump); | 722 __ j(EQUAL, ¬_closure, Assembler::kNearJump); |
761 | 723 |
762 // RAX is just the signature function. Load the actual closure function. | 724 // RAX is just the signature function. Load the actual closure function. |
763 __ movq(RAX, FieldAddress(R13, Closure::function_offset())); | 725 __ movq(RAX, FieldAddress(R13, Closure::function_offset())); |
764 | 726 |
765 // Load closure context in CTX; note that CTX has already been preserved. | 727 // Load closure context in CTX; note that CTX has already been preserved. |
766 __ movq(CTX, FieldAddress(R13, Closure::context_offset())); | 728 __ movq(CTX, FieldAddress(R13, Closure::context_offset())); |
767 | 729 |
768 // Load closure function code in RAX. | 730 // Load closure function code in RAX. |
769 __ movq(RBX, FieldAddress(RAX, Function::code_offset())); | 731 __ movq(RCX, FieldAddress(RAX, Function::code_offset())); |
770 | 732 |
771 // RAX: Function. | 733 // RAX: Function. |
772 // R10: Arguments descriptor array. | 734 // R10: Arguments descriptor array. |
773 __ movq(RCX, FieldAddress(RBX, Code::instructions_offset())); | 735 __ movq(RCX, FieldAddress(RCX, Code::instructions_offset())); |
774 __ addq(RCX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | 736 __ addq(RCX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
775 __ jmp(RCX); | 737 __ jmp(RCX); |
776 | 738 |
777 __ Bind(¬_closure); | 739 __ Bind(¬_closure); |
778 // Call runtime to attempt to resolve and invoke a call method on a | 740 // Call runtime to attempt to resolve and invoke a call method on a |
779 // non-closure object, passing the non-closure object and its arguments array, | 741 // non-closure object, passing the non-closure object and its arguments array, |
780 // returning here. | 742 // returning here. |
781 // If no call method exists, throw a NoSuchMethodError. | 743 // If no call method exists, throw a NoSuchMethodError. |
782 // R13: non-closure object. | 744 // R13: non-closure object. |
783 // R10: arguments descriptor array. | 745 // R10: arguments descriptor array. |
(...skipping 655 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1439 for (intptr_t i = 0; i < num_args; i++) { | 1401 for (intptr_t i = 0; i < num_args; i++) { |
1440 __ movq(RCX, Address(RAX, -kWordSize * i)); | 1402 __ movq(RCX, Address(RAX, -kWordSize * i)); |
1441 __ pushq(RCX); | 1403 __ pushq(RCX); |
1442 } | 1404 } |
1443 __ pushq(RBX); // Pass IC data object. | 1405 __ pushq(RBX); // Pass IC data object. |
1444 __ CallRuntime(handle_ic_miss, num_args + 1); | 1406 __ CallRuntime(handle_ic_miss, num_args + 1); |
1445 // Remove the call arguments pushed earlier, including the IC data object. | 1407 // Remove the call arguments pushed earlier, including the IC data object. |
1446 for (intptr_t i = 0; i < num_args + 1; i++) { | 1408 for (intptr_t i = 0; i < num_args + 1; i++) { |
1447 __ popq(RAX); | 1409 __ popq(RAX); |
1448 } | 1410 } |
1449 __ popq(RAX); // Pop returned code object into RAX (null if not found). | 1411 __ popq(RAX); // Pop returned function object into RAX. |
1450 __ popq(RBX); // Restore IC data array. | 1412 __ popq(RBX); // Restore IC data array. |
1451 __ popq(R10); // Restore arguments descriptor array. | 1413 __ popq(R10); // Restore arguments descriptor array. |
1452 __ LeaveStubFrame(); | 1414 __ LeaveStubFrame(); |
1453 Label call_target_function; | 1415 Label call_target_function; |
1454 __ cmpq(RAX, R12); | 1416 __ jmp(&call_target_function); |
1455 __ j(NOT_EQUAL, &call_target_function, Assembler::kNearJump); | |
1456 // NoSuchMethod or closure. | |
1457 // Mark IC call that it may be a closure call that does not collect | |
1458 // type feedback. | |
1459 __ movb(FieldAddress(RBX, ICData::is_closure_call_offset()), Immediate(1)); | |
1460 __ jmp(&StubCode::InstanceFunctionLookupLabel()); | |
1461 | 1417 |
1462 __ Bind(&found); | 1418 __ Bind(&found); |
1463 // R12: Pointer to an IC data check group. | 1419 // R12: Pointer to an IC data check group. |
1464 const intptr_t target_offset = ICData::TargetIndexFor(num_args) * kWordSize; | 1420 const intptr_t target_offset = ICData::TargetIndexFor(num_args) * kWordSize; |
1465 const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize; | 1421 const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize; |
1466 __ movq(RAX, Address(R12, target_offset)); | 1422 __ movq(RAX, Address(R12, target_offset)); |
1467 __ addq(Address(R12, count_offset), Immediate(Smi::RawValue(1))); | 1423 __ addq(Address(R12, count_offset), Immediate(Smi::RawValue(1))); |
1468 __ j(NO_OVERFLOW, &call_target_function, Assembler::kNearJump); | 1424 __ j(NO_OVERFLOW, &call_target_function, Assembler::kNearJump); |
1469 __ movq(Address(R12, count_offset), | 1425 __ movq(Address(R12, count_offset), |
1470 Immediate(Smi::RawValue(Smi::kMaxValue))); | 1426 Immediate(Smi::RawValue(Smi::kMaxValue))); |
(...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1960 | 1916 |
1961 __ movq(left, Address(RSP, 2 * kWordSize)); | 1917 __ movq(left, Address(RSP, 2 * kWordSize)); |
1962 __ movq(right, Address(RSP, 1 * kWordSize)); | 1918 __ movq(right, Address(RSP, 1 * kWordSize)); |
1963 GenerateIdenticalWithNumberCheckStub(assembler, left, right); | 1919 GenerateIdenticalWithNumberCheckStub(assembler, left, right); |
1964 __ ret(); | 1920 __ ret(); |
1965 } | 1921 } |
1966 | 1922 |
1967 } // namespace dart | 1923 } // namespace dart |
1968 | 1924 |
1969 #endif // defined TARGET_ARCH_X64 | 1925 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |