Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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/code_generator.h" | 8 #include "vm/code_generator.h" |
| 9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
| 10 #include "vm/ic_data.h" | 10 #include "vm/ic_data.h" |
| (...skipping 770 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 781 __ popq(R12); | 781 __ popq(R12); |
| 782 __ popq(RBX); | 782 __ popq(RBX); |
| 783 | 783 |
| 784 // Restore the frame pointer. | 784 // Restore the frame pointer. |
| 785 __ LeaveFrame(); | 785 __ LeaveFrame(); |
| 786 | 786 |
| 787 __ ret(); | 787 __ ret(); |
| 788 } | 788 } |
| 789 | 789 |
| 790 | 790 |
| 791 // Called for inline allocation of contexts. | |
| 792 // Input: | |
| 793 // RDX: number of context variables. | |
| 794 // Output: | |
| 795 // RAX: new allocated RawContext object. | |
| 796 // RBX and RDX are destroyed. | |
| 791 void StubCode::GenerateAllocateContextStub(Assembler* assembler) { | 797 void StubCode::GenerateAllocateContextStub(Assembler* assembler) { |
| 792 __ Unimplemented("AllocateContext stub"); | 798 const Immediate raw_null = |
| 799 Immediate(reinterpret_cast<intptr_t>(Object::null())); | |
| 800 if (false) { | |
| 801 // TODO(regis): Implement fast inline allocation of contexts. | |
| 802 __ Unimplemented("AllocateContext stub - inline allocation"); | |
| 803 } | |
| 804 // Create the stub frame. | |
| 805 __ EnterFrame(0); | |
| 806 __ pushq(raw_null); // Make space for the return value. | |
| 807 __ SmiTag(RDX); | |
| 808 __ pushq(RDX); // Push number of context variables. | |
| 809 __ CallRuntimeFromStub(kAllocateContextRuntimeEntry); // Allocate context. | |
| 810 __ popq(RAX); // Pop number of context variables argument. | |
| 811 __ popq(RAX); // Pop the new context object. | |
| 812 // RAX: new object | |
| 813 // Restore the frame pointer. | |
| 814 __ LeaveFrame(); | |
| 815 __ ret(); | |
| 793 } | 816 } |
| 794 | 817 |
| 795 | 818 |
| 796 | 819 |
| 797 | 820 |
| 798 // Called for inline allocation of objects. | 821 // Called for inline allocation of objects. |
| 799 // Input parameters: | 822 // Input parameters: |
| 800 // RSP + 16 : type arguments object (only if class is parameterized). | 823 // RSP + 16 : type arguments object (only if class is parameterized). |
| 801 // RSP + 8 : type arguments of instantiator (only if class is parameterized). | 824 // RSP + 8 : type arguments of instantiator (only if class is parameterized). |
| 802 // RSP : points to return address. | 825 // RSP : points to return address. |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 837 // InstantiatedTypeArguments object start. | 860 // InstantiatedTypeArguments object start. |
| 838 } | 861 } |
| 839 // Check if the allocation fits into the remaining space. | 862 // Check if the allocation fits into the remaining space. |
| 840 // RAX: potential new object start. | 863 // RAX: potential new object start. |
| 841 // RBX: potential next object start. | 864 // RBX: potential next object start. |
| 842 __ movq(RDI, Immediate(heap->EndAddress())); | 865 __ movq(RDI, Immediate(heap->EndAddress())); |
| 843 __ cmpq(RBX, Address(RDI, 0)); | 866 __ cmpq(RBX, Address(RDI, 0)); |
| 844 if (FLAG_use_slow_path) { | 867 if (FLAG_use_slow_path) { |
| 845 __ jmp(&slow_case); | 868 __ jmp(&slow_case); |
| 846 } else { | 869 } else { |
| 847 __ j(ABOVE_EQUAL, &slow_case, Assembler::kNearJump); | 870 __ j(ABOVE_EQUAL, &slow_case); |
| 848 } | 871 } |
| 849 | 872 |
| 850 // Successfully allocated the object(s), now update top to point to | 873 // Successfully allocated the object(s), now update top to point to |
| 851 // next object start and initialize the object. | 874 // next object start and initialize the object. |
| 852 __ movq(RDI, Immediate(heap->TopAddress())); | 875 __ movq(RDI, Immediate(heap->TopAddress())); |
| 853 __ movq(Address(RDI, 0), RBX); | 876 __ movq(Address(RDI, 0), RBX); |
| 854 | 877 |
| 855 if (is_cls_parameterized) { | 878 if (is_cls_parameterized) { |
| 856 // Initialize the type arguments field in the object. | 879 // Initialize the type arguments field in the object. |
| 857 // RAX: new object start. | 880 // RAX: new object start. |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 980 __ popq(RAX); // Pop argument (type arguments of object). | 1003 __ popq(RAX); // Pop argument (type arguments of object). |
| 981 __ popq(RAX); // Pop argument (class of object). | 1004 __ popq(RAX); // Pop argument (class of object). |
| 982 __ popq(RAX); // Pop result (newly allocated object). | 1005 __ popq(RAX); // Pop result (newly allocated object). |
| 983 // RAX: new object | 1006 // RAX: new object |
| 984 // Restore the frame pointer. | 1007 // Restore the frame pointer. |
| 985 __ LeaveFrame(); | 1008 __ LeaveFrame(); |
| 986 __ ret(); | 1009 __ ret(); |
| 987 } | 1010 } |
| 988 | 1011 |
| 989 | 1012 |
| 1013 // Called for inline allocation of closures. | |
| 1014 // Input parameters: | |
| 1015 // If the signature class is not parameterized, the receiver, if any, will be | |
| 1016 // at RSP + 4 instead of RSP + 8, since no type arguments are passed. | |
|
regis
2012/01/06 19:14:22
The offsets + 4 and + 8 are not correct. I will fi
| |
| 1017 // RSP + 8 (or RSP + 4): receiver (only if implicit instance closure). | |
| 1018 // RSP + 4 : type arguments object (only if signature class is parameterized). | |
| 1019 // RSP : points to return address. | |
| 1020 // Uses RAX, RBX, RCX, RDX as temporary registers. | |
|
regis
2012/01/06 19:14:22
Comment about used registers is not accurate eithe
| |
| 990 void StubCode::GenerateAllocationStubForClosure(Assembler* assembler, | 1021 void StubCode::GenerateAllocationStubForClosure(Assembler* assembler, |
| 991 const Function& func) { | 1022 const Function& func) { |
| 992 __ Unimplemented("AllocateClosure stub"); | 1023 const Immediate raw_null = |
| 1024 Immediate(reinterpret_cast<intptr_t>(Object::null())); | |
| 1025 ASSERT(func.IsClosureFunction()); | |
| 1026 const bool is_implicit_static_closure = | |
| 1027 func.IsImplicitStaticClosureFunction(); | |
| 1028 const bool is_implicit_instance_closure = | |
| 1029 func.IsImplicitInstanceClosureFunction(); | |
| 1030 const Class& cls = Class::ZoneHandle(func.signature_class()); | |
| 1031 const bool has_type_arguments = cls.HasTypeArguments(); | |
| 1032 const intptr_t kTypeArgumentsOffset = 1 * kWordSize; | |
| 1033 const intptr_t kReceiverOffset = (has_type_arguments ? 2 : 1) * kWordSize; | |
| 1034 if (false) { | |
| 1035 // TODO(regis): Implement inline context allocation. | |
| 1036 __ Unimplemented("AllocateClosure stub - inline allocation"); | |
| 1037 } | |
| 1038 if (has_type_arguments) { | |
| 1039 __ movq(RCX, Address(RSP, kTypeArgumentsOffset)); | |
| 1040 } | |
| 1041 if (is_implicit_instance_closure) { | |
| 1042 __ movq(RAX, Address(RSP, kReceiverOffset)); | |
| 1043 } | |
| 1044 // Create the stub frame. | |
| 1045 __ EnterFrame(0); | |
| 1046 __ pushq(raw_null); // Make space for the return value. | |
| 1047 __ PushObject(func); | |
| 1048 if (is_implicit_static_closure) { | |
| 1049 __ CallRuntimeFromStub(kAllocateImplicitStaticClosureRuntimeEntry); | |
| 1050 } else { | |
| 1051 if (is_implicit_instance_closure) { | |
| 1052 __ pushq(RAX); // Receiver. | |
| 1053 } | |
| 1054 if (has_type_arguments) { | |
| 1055 __ pushq(RCX); // Push type arguments of closure to be allocated. | |
| 1056 } else { | |
| 1057 __ pushq(raw_null); // Push null type arguments. | |
| 1058 } | |
| 1059 if (is_implicit_instance_closure) { | |
| 1060 __ CallRuntimeFromStub(kAllocateImplicitInstanceClosureRuntimeEntry); | |
| 1061 __ popq(RAX); // Pop type arguments. | |
| 1062 __ popq(RAX); // Pop receiver. | |
| 1063 } else { | |
| 1064 ASSERT(func.IsNonImplicitClosureFunction()); | |
| 1065 __ CallRuntimeFromStub(kAllocateClosureRuntimeEntry); | |
| 1066 __ popq(RAX); // Pop type arguments. | |
| 1067 } | |
| 1068 } | |
| 1069 __ popq(RAX); // Pop the function object. | |
| 1070 __ popq(RAX); // Pop the result. | |
| 1071 // RAX: New closure object. | |
| 1072 // Restore the calling frame. | |
| 1073 __ LeaveFrame(); | |
| 1074 __ ret(); | |
| 993 } | 1075 } |
| 994 | 1076 |
| 995 | 1077 |
| 996 void StubCode::GenerateCallNoSuchMethodFunctionStub(Assembler* assembler) { | 1078 void StubCode::GenerateCallNoSuchMethodFunctionStub(Assembler* assembler) { |
| 997 __ Unimplemented("CallNoSuchMethodFunction stub"); | 1079 __ Unimplemented("CallNoSuchMethodFunction stub"); |
| 998 } | 1080 } |
| 999 | 1081 |
| 1000 | 1082 |
| 1001 // Generate inline cache check for 'num_args'. | 1083 // Generate inline cache check for 'num_args'. |
| 1002 // RBX: Inline cache data array. | 1084 // RBX: Inline cache data array. |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1165 } | 1247 } |
| 1166 | 1248 |
| 1167 | 1249 |
| 1168 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) { | 1250 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) { |
| 1169 __ Unimplemented("BreakpointDynamic stub"); | 1251 __ Unimplemented("BreakpointDynamic stub"); |
| 1170 } | 1252 } |
| 1171 | 1253 |
| 1172 } // namespace dart | 1254 } // namespace dart |
| 1173 | 1255 |
| 1174 #endif // defined TARGET_ARCH_X64 | 1256 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |