Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(13)

Side by Side Diff: runtime/vm/stub_code_ia32.cc

Issue 227723002: VM: Implement closure calls as instance calls. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: adjust inlining of dispatchers Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/stub_code_arm64.cc ('k') | runtime/vm/stub_code_mips.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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, &not_closure, Assembler::kNearJump);
723 __ testl(EDI, Immediate(kSmiTagMask));
724 __ j(ZERO, &not_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, &not_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(&not_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
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
OLDNEW
« no previous file with comments | « runtime/vm/stub_code_arm64.cc ('k') | runtime/vm/stub_code_mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698