| 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 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 360 __ CallRuntime(kFixAllocationStubTargetRuntimeEntry, 0); | 360 __ CallRuntime(kFixAllocationStubTargetRuntimeEntry, 0); |
| 361 __ popq(RAX); // Get Code object. | 361 __ popq(RAX); // Get Code object. |
| 362 __ movq(RAX, FieldAddress(RAX, Code::instructions_offset())); | 362 __ movq(RAX, FieldAddress(RAX, Code::instructions_offset())); |
| 363 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | 363 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
| 364 __ LeaveStubFrame(); | 364 __ LeaveStubFrame(); |
| 365 __ jmp(RAX); | 365 __ jmp(RAX); |
| 366 __ int3(); | 366 __ int3(); |
| 367 } | 367 } |
| 368 | 368 |
| 369 | 369 |
| 370 // Called from array allocate instruction when the allocation stub has been |
| 371 // disabled. |
| 372 // R10: length (preserved). |
| 373 // RBX: element type (preserved). |
| 374 void StubCode::GenerateFixAllocateArrayStubTargetStub(Assembler* assembler) { |
| 375 __ EnterStubFrame(); |
| 376 __ pushq(R10); // Preserve length. |
| 377 __ pushq(RBX); // Preserve element type. |
| 378 // Setup space on stack for return value. |
| 379 __ PushObject(Object::null_object(), PP); |
| 380 __ CallRuntime(kFixAllocationStubTargetRuntimeEntry, 0); |
| 381 __ popq(RAX); // Get Code object. |
| 382 __ popq(RBX); // Restore element type. |
| 383 __ popq(R10); // Restore length. |
| 384 __ movq(RAX, FieldAddress(RAX, Code::instructions_offset())); |
| 385 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
| 386 __ LeaveStubFrame(); |
| 387 __ jmp(RAX); |
| 388 __ int3(); |
| 389 } |
| 390 |
| 391 |
| 370 // Input parameters: | 392 // Input parameters: |
| 371 // R10: smi-tagged argument count, may be zero. | 393 // R10: smi-tagged argument count, may be zero. |
| 372 // RBP[kParamEndSlotFromFp + 1]: last argument. | 394 // RBP[kParamEndSlotFromFp + 1]: last argument. |
| 373 static void PushArgumentsArray(Assembler* assembler) { | 395 static void PushArgumentsArray(Assembler* assembler) { |
| 374 StubCode* stub_code = Isolate::Current()->stub_code(); | 396 StubCode* stub_code = Isolate::Current()->stub_code(); |
| 375 | 397 |
| 376 __ LoadObject(R12, Object::null_object(), PP); | 398 __ LoadObject(R12, Object::null_object(), PP); |
| 377 // Allocate array to store arguments of caller. | 399 // Allocate array to store arguments of caller. |
| 378 __ movq(RBX, R12); // Null element type for raw Array. | 400 __ movq(RBX, R12); // Null element type for raw Array. |
| 379 __ call(&stub_code->AllocateArrayLabel()); | 401 const Code& array_stub = Code::Handle(stub_code->GetAllocateArrayStub()); |
| 402 const ExternalLabel array_label(array_stub.EntryPoint()); |
| 403 __ call(&array_label); |
| 380 __ SmiUntag(R10); | 404 __ SmiUntag(R10); |
| 381 // RAX: newly allocated array. | 405 // RAX: newly allocated array. |
| 382 // R10: length of the array (was preserved by the stub). | 406 // R10: length of the array (was preserved by the stub). |
| 383 __ pushq(RAX); // Array is in RAX and on top of stack. | 407 __ pushq(RAX); // Array is in RAX and on top of stack. |
| 384 __ leaq(R12, Address(RBP, R10, TIMES_8, kParamEndSlotFromFp * kWordSize)); | 408 __ leaq(R12, Address(RBP, R10, TIMES_8, kParamEndSlotFromFp * kWordSize)); |
| 385 __ leaq(RBX, FieldAddress(RAX, Array::data_offset())); | 409 __ leaq(RBX, FieldAddress(RAX, Array::data_offset())); |
| 386 // R12: address of first argument on stack. | 410 // R12: address of first argument on stack. |
| 387 // RBX: address of first argument in array. | 411 // RBX: address of first argument in array. |
| 388 Label loop, loop_condition; | 412 Label loop, loop_condition; |
| 389 __ jmp(&loop_condition, Assembler::kNearJump); | 413 __ jmp(&loop_condition, Assembler::kNearJump); |
| (...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 573 __ jmp(RCX); | 597 __ jmp(RCX); |
| 574 } | 598 } |
| 575 | 599 |
| 576 | 600 |
| 577 // Called for inline allocation of arrays. | 601 // Called for inline allocation of arrays. |
| 578 // Input parameters: | 602 // Input parameters: |
| 579 // R10 : Array length as Smi. | 603 // R10 : Array length as Smi. |
| 580 // RBX : array element type (either NULL or an instantiated type). | 604 // RBX : array element type (either NULL or an instantiated type). |
| 581 // NOTE: R10 cannot be clobbered here as the caller relies on it being saved. | 605 // NOTE: R10 cannot be clobbered here as the caller relies on it being saved. |
| 582 // The newly allocated object is returned in RAX. | 606 // The newly allocated object is returned in RAX. |
| 583 void StubCode::GenerateAllocateArrayStub(Assembler* assembler) { | 607 void StubCode::GeneratePatchableAllocateArrayStub(Assembler* assembler, |
| 608 uword* entry_patch_offset, uword* patch_code_pc_offset) { |
| 609 // Must load pool pointer before being able to patch. |
| 610 Register new_pp = R13; |
| 611 __ LoadPoolPointer(new_pp); |
| 612 *entry_patch_offset = assembler->CodeSize(); |
| 584 Label slow_case; | 613 Label slow_case; |
| 585 // Compute the size to be allocated, it is based on the array length | 614 // Compute the size to be allocated, it is based on the array length |
| 586 // and is computed as: | 615 // and is computed as: |
| 587 // RoundedAllocationSize((array_length * kwordSize) + sizeof(RawArray)). | 616 // RoundedAllocationSize((array_length * kwordSize) + sizeof(RawArray)). |
| 588 __ movq(RDI, R10); // Array Length. | 617 __ movq(RDI, R10); // Array Length. |
| 589 // Check that length is a positive Smi. | 618 // Check that length is a positive Smi. |
| 590 __ testq(RDI, Immediate(kSmiTagMask)); | 619 __ testq(RDI, Immediate(kSmiTagMask)); |
| 591 __ j(NOT_ZERO, &slow_case); | 620 __ j(NOT_ZERO, &slow_case); |
| 592 __ cmpq(RDI, Immediate(0)); | 621 __ cmpq(RDI, Immediate(0)); |
| 593 __ j(LESS, &slow_case); | 622 __ j(LESS, &slow_case); |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 684 // Setup space on stack for return value. | 713 // Setup space on stack for return value. |
| 685 __ PushObject(Object::null_object(), PP); | 714 __ PushObject(Object::null_object(), PP); |
| 686 __ pushq(R10); // Array length as Smi. | 715 __ pushq(R10); // Array length as Smi. |
| 687 __ pushq(RBX); // Element type. | 716 __ pushq(RBX); // Element type. |
| 688 __ CallRuntime(kAllocateArrayRuntimeEntry, 2); | 717 __ CallRuntime(kAllocateArrayRuntimeEntry, 2); |
| 689 __ popq(RAX); // Pop element type argument. | 718 __ popq(RAX); // Pop element type argument. |
| 690 __ popq(R10); // Pop array length argument. | 719 __ popq(R10); // Pop array length argument. |
| 691 __ popq(RAX); // Pop return value from return slot. | 720 __ popq(RAX); // Pop return value from return slot. |
| 692 __ LeaveStubFrame(); | 721 __ LeaveStubFrame(); |
| 693 __ ret(); | 722 __ ret(); |
| 723 *patch_code_pc_offset = assembler->CodeSize(); |
| 724 StubCode* stub_code = Isolate::Current()->stub_code(); |
| 725 __ JmpPatchable(&stub_code->FixAllocateArrayStubTargetLabel(), new_pp); |
| 694 } | 726 } |
| 695 | 727 |
| 696 | 728 |
| 697 // Called when invoking Dart code from C++ (VM code). | 729 // Called when invoking Dart code from C++ (VM code). |
| 698 // Input parameters: | 730 // Input parameters: |
| 699 // RSP : points to return address. | 731 // RSP : points to return address. |
| 700 // RDI : entrypoint of the Dart function to call. | 732 // RDI : entrypoint of the Dart function to call. |
| 701 // RSI : arguments descriptor array. | 733 // RSI : arguments descriptor array. |
| 702 // RDX : arguments array. | 734 // RDX : arguments array. |
| 703 // RCX : new context containing the current isolate pointer. | 735 // RCX : new context containing the current isolate pointer. |
| (...skipping 1319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2023 | 2055 |
| 2024 __ movq(left, Address(RSP, 2 * kWordSize)); | 2056 __ movq(left, Address(RSP, 2 * kWordSize)); |
| 2025 __ movq(right, Address(RSP, 1 * kWordSize)); | 2057 __ movq(right, Address(RSP, 1 * kWordSize)); |
| 2026 GenerateIdenticalWithNumberCheckStub(assembler, left, right); | 2058 GenerateIdenticalWithNumberCheckStub(assembler, left, right); |
| 2027 __ ret(); | 2059 __ ret(); |
| 2028 } | 2060 } |
| 2029 | 2061 |
| 2030 } // namespace dart | 2062 } // namespace dart |
| 2031 | 2063 |
| 2032 #endif // defined TARGET_ARCH_X64 | 2064 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |