| 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_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
| 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 682 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 693 __ pushl(ECX); // Element type. | 693 __ pushl(ECX); // Element type. |
| 694 __ CallRuntime(kAllocateArrayRuntimeEntry, 2); | 694 __ CallRuntime(kAllocateArrayRuntimeEntry, 2); |
| 695 __ popl(EAX); // Pop element type argument. | 695 __ popl(EAX); // Pop element type argument. |
| 696 __ popl(EDX); // Pop array length argument. | 696 __ popl(EDX); // Pop array length argument. |
| 697 __ popl(EAX); // Pop return value from return slot. | 697 __ popl(EAX); // Pop return value from return slot. |
| 698 __ LeaveFrame(); | 698 __ LeaveFrame(); |
| 699 __ ret(); | 699 __ ret(); |
| 700 } | 700 } |
| 701 | 701 |
| 702 | 702 |
| 703 // Input parameters: | |
| 704 // EDX: Arguments descriptor array. | |
| 705 // Note: The closure object is the first argument to the function being | |
| 706 // called, the stub accesses the closure from this location directly | |
| 707 // when trying to resolve the call. | |
| 708 // Uses EDI. | |
| 709 void StubCode::GenerateCallClosureFunctionStub(Assembler* assembler) { | |
| 710 const Immediate& raw_null = | |
| 711 Immediate(reinterpret_cast<intptr_t>(Object::null())); | |
| 712 | |
| 713 // Load num_args. | |
| 714 __ movl(EAX, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); | |
| 715 // Load closure object in EDI. | |
| 716 __ movl(EDI, Address(ESP, EAX, TIMES_2, 0)); // EAX is a Smi. | |
| 717 | |
| 718 // Verify that EDI is a closure by checking its class. | |
| 719 Label not_closure; | |
| 720 __ cmpl(EDI, raw_null); | |
| 721 // Not a closure, but null object. | |
| 722 __ j(EQUAL, ¬_closure, Assembler::kNearJump); | |
| 723 __ testl(EDI, Immediate(kSmiTagMask)); | |
| 724 __ j(ZERO, ¬_closure, Assembler::kNearJump); // Not a closure, but a smi. | |
| 725 // Verify that the class of the object is a closure class by checking that | |
| 726 // class.signature_function() is not null. | |
| 727 __ LoadClass(EAX, EDI, ECX); | |
| 728 __ movl(EAX, FieldAddress(EAX, Class::signature_function_offset())); | |
| 729 __ cmpl(EAX, raw_null); | |
| 730 // Actual class is not a closure class. | |
| 731 __ j(EQUAL, ¬_closure, Assembler::kNearJump); | |
| 732 | |
| 733 // EAX is just the signature function. Load the actual closure function. | |
| 734 __ movl(EAX, FieldAddress(EDI, Closure::function_offset())); | |
| 735 | |
| 736 // Load closure context in CTX; note that CTX has already been preserved. | |
| 737 __ movl(CTX, FieldAddress(EDI, Closure::context_offset())); | |
| 738 | |
| 739 // EBX: Code (compiled code or lazy compile stub). | |
| 740 __ movl(EBX, FieldAddress(EAX, Function::code_offset())); | |
| 741 | |
| 742 // EAX: Function. | |
| 743 // EDX: Arguments descriptor array. | |
| 744 // ECX: Smi 0 (no IC data; the lazy-compile stub expects a GC-safe value). | |
| 745 __ xorl(ECX, ECX); | |
| 746 __ movl(EBX, FieldAddress(EBX, Code::instructions_offset())); | |
| 747 __ addl(EBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | |
| 748 __ jmp(EBX); | |
| 749 | |
| 750 __ Bind(¬_closure); | |
| 751 // Call runtime to attempt to resolve and invoke a call method on a | |
| 752 // non-closure object, passing the non-closure object and its arguments array, | |
| 753 // returning here. | |
| 754 // If no call method exists, throw a NoSuchMethodError. | |
| 755 // EDI: non-closure object. | |
| 756 // EDX: arguments descriptor array. | |
| 757 | |
| 758 // Create a stub frame as we are pushing some objects on the stack before | |
| 759 // calling into the runtime. | |
| 760 __ EnterStubFrame(); | |
| 761 | |
| 762 __ pushl(raw_null); // Setup space on stack for result from error reporting. | |
| 763 __ pushl(EDX); // Arguments descriptor. | |
| 764 // Load smi-tagged arguments array length, including the non-closure. | |
| 765 __ movl(EDX, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); | |
| 766 PushArgumentsArray(assembler); | |
| 767 | |
| 768 __ CallRuntime(kInvokeNonClosureRuntimeEntry, 2); | |
| 769 // Remove arguments. | |
| 770 __ Drop(2); | |
| 771 __ popl(EAX); // Get result into EAX. | |
| 772 | |
| 773 // Remove the stub frame as we are about to return. | |
| 774 __ LeaveFrame(); | |
| 775 __ ret(); | |
| 776 } | |
| 777 | |
| 778 | |
| 779 // Called when invoking dart code from C++ (VM code). | 703 // Called when invoking dart code from C++ (VM code). |
| 780 // Input parameters: | 704 // Input parameters: |
| 781 // ESP : points to return address. | 705 // ESP : points to return address. |
| 782 // ESP + 4 : entrypoint of the dart function to call. | 706 // ESP + 4 : entrypoint of the dart function to call. |
| 783 // ESP + 8 : arguments descriptor array. | 707 // ESP + 8 : arguments descriptor array. |
| 784 // ESP + 12 : arguments array. | 708 // ESP + 12 : arguments array. |
| 785 // ESP + 16 : new context containing the current isolate pointer. | 709 // ESP + 16 : new context containing the current isolate pointer. |
| 786 // Uses EAX, EDX, ECX, EDI as temporary registers. | 710 // Uses EAX, EDX, ECX, EDI as temporary registers. |
| 787 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) { | 711 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) { |
| 788 const intptr_t kEntryPointOffset = 2 * kWordSize; | 712 const intptr_t kEntryPointOffset = 2 * kWordSize; |
| (...skipping 1151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1940 const Register temp = ECX; | 1864 const Register temp = ECX; |
| 1941 __ movl(left, Address(ESP, 2 * kWordSize)); | 1865 __ movl(left, Address(ESP, 2 * kWordSize)); |
| 1942 __ movl(right, Address(ESP, 1 * kWordSize)); | 1866 __ movl(right, Address(ESP, 1 * kWordSize)); |
| 1943 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); | 1867 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); |
| 1944 __ ret(); | 1868 __ ret(); |
| 1945 } | 1869 } |
| 1946 | 1870 |
| 1947 } // namespace dart | 1871 } // namespace dart |
| 1948 | 1872 |
| 1949 #endif // defined TARGET_ARCH_IA32 | 1873 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |