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 369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 380 // .... | 380 // .... |
| 381 // Total number of args is the first Smi in args descriptor array (R10). | 381 // Total number of args is the first Smi in args descriptor array (R10). |
| 382 __ movq(RAX, FieldAddress(R10, Array::data_offset())); | 382 __ movq(RAX, FieldAddress(R10, Array::data_offset())); |
| 383 __ movq(RAX, Address(RSP, RAX, TIMES_4, kWordSize)); // Get receiver. | 383 __ movq(RAX, Address(RSP, RAX, TIMES_4, kWordSize)); // Get receiver. |
| 384 __ pushq(R10); // Preserve arguments descriptor array. | 384 __ pushq(R10); // Preserve arguments descriptor array. |
| 385 __ pushq(RAX); // Preserve receiver. | 385 __ pushq(RAX); // Preserve receiver. |
| 386 __ pushq(RBX); // Preserve ic-data array. | 386 __ pushq(RBX); // Preserve ic-data array. |
| 387 // First resolve the function to get the function object. | 387 // First resolve the function to get the function object. |
| 388 | 388 |
| 389 // Setup space for return value on stack by pushing smi 0. | 389 // Setup space for return value on stack by pushing smi 0. |
| 390 __ pushq(Immediate(0)); | 390 __ pushq(Immediate(0)); |
|
siva
2011/12/27 21:33:11
Should this be
__ pushq(raw_null); ?
Not sure wha
Ivan Posva
2011/12/27 22:59:42
Filed issue 995 to address this in general for bot
| |
| 391 __ pushq(RAX); // Push receiver. | 391 __ pushq(RAX); // Push receiver. |
| 392 __ CallRuntimeFromStub(kResolveCompileInstanceFunctionRuntimeEntry); | 392 __ CallRuntimeFromStub(kResolveCompileInstanceFunctionRuntimeEntry); |
| 393 __ popq(RAX); // Remove receiver pushed earlier. | 393 __ popq(RAX); // Remove receiver pushed earlier. |
| 394 __ popq(RBX); // Pop returned code object into RBX. | 394 __ popq(RBX); // Pop returned code object into RBX. |
| 395 // Pop preserved values | 395 // Pop preserved values |
| 396 __ popq(R10); // Restore ic-data array. | 396 __ popq(R10); // Restore ic-data array. |
| 397 __ popq(RAX); // Restore receiver. | 397 __ popq(RAX); // Restore receiver. |
| 398 __ popq(R13); // Restore arguments descriptor array. | 398 __ popq(R13); // Restore arguments descriptor array. |
| 399 | 399 |
| 400 __ cmpq(RBX, raw_null); | 400 __ cmpq(RBX, raw_null); |
| (...skipping 380 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 if (false) { |
| 799 // TODO(regis): Implement fast inline allocation of contexts. | |
| 800 __ Unimplemented("AllocateContext stub - inline allocation"); | |
| 801 } | |
| 802 // Create the stub frame. | |
| 803 __ EnterFrame(0); | |
| 804 const Context& new_context = Context::ZoneHandle(); | |
| 805 __ PushObject(new_context); // Push Null context for return value. | |
|
siva
2011/12/27 21:33:11
const Immediate raw_null =
Immediate(reinter
Ivan Posva
2011/12/27 22:59:42
Done.
| |
| 806 __ SmiTag(RDX); | |
| 807 __ pushq(RDX); | |
|
siva
2011/12/27 21:33:11
// Push number of context variables argument.
Ivan Posva
2011/12/27 22:59:42
Done.
| |
| 808 __ CallRuntimeFromStub(kAllocateContextRuntimeEntry); // Allocate context. | |
| 809 __ popq(RAX); // Pop number of context variables argument. | |
| 810 __ popq(RAX); // Pop the new context object. | |
| 811 // RAX: new object | |
| 812 // Restore the frame pointer. | |
| 813 __ LeaveFrame(); | |
| 814 __ ret(); | |
| 793 } | 815 } |
| 794 | 816 |
| 795 | 817 |
| 796 | 818 |
| 797 | 819 |
| 798 // Called for inline allocation of objects. | 820 // Called for inline allocation of objects. |
| 799 // Input parameters: | 821 // Input parameters: |
| 800 // RSP + 16 : type arguments object (only if class is parameterized). | 822 // RSP + 16 : type arguments object (only if class is parameterized). |
| 801 // RSP + 8 : type arguments of instantiator (only if class is parameterized). | 823 // RSP + 8 : type arguments of instantiator (only if class is parameterized). |
| 802 // RSP : points to return address. | 824 // RSP : points to return address. |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 837 // InstantiatedTypeArguments object start. | 859 // InstantiatedTypeArguments object start. |
| 838 } | 860 } |
| 839 // Check if the allocation fits into the remaining space. | 861 // Check if the allocation fits into the remaining space. |
| 840 // RAX: potential new object start. | 862 // RAX: potential new object start. |
| 841 // RBX: potential next object start. | 863 // RBX: potential next object start. |
| 842 __ movq(RDI, Immediate(heap->EndAddress())); | 864 __ movq(RDI, Immediate(heap->EndAddress())); |
| 843 __ cmpq(RBX, Address(RDI, 0)); | 865 __ cmpq(RBX, Address(RDI, 0)); |
| 844 if (FLAG_use_slow_path) { | 866 if (FLAG_use_slow_path) { |
| 845 __ jmp(&slow_case); | 867 __ jmp(&slow_case); |
| 846 } else { | 868 } else { |
| 847 __ j(ABOVE_EQUAL, &slow_case, Assembler::kNearJump); | 869 __ j(ABOVE_EQUAL, &slow_case); |
| 848 } | 870 } |
| 849 | 871 |
| 850 // Successfully allocated the object(s), now update top to point to | 872 // Successfully allocated the object(s), now update top to point to |
| 851 // next object start and initialize the object. | 873 // next object start and initialize the object. |
| 852 __ movq(RDI, Immediate(heap->TopAddress())); | 874 __ movq(RDI, Immediate(heap->TopAddress())); |
| 853 __ movq(Address(RDI, 0), RBX); | 875 __ movq(Address(RDI, 0), RBX); |
| 854 | 876 |
| 855 if (is_cls_parameterized) { | 877 if (is_cls_parameterized) { |
| 856 // Initialize the type arguments field in the object. | 878 // Initialize the type arguments field in the object. |
| 857 // RAX: new object start. | 879 // 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). | 1002 __ popq(RAX); // Pop argument (type arguments of object). |
| 981 __ popq(RAX); // Pop argument (class of object). | 1003 __ popq(RAX); // Pop argument (class of object). |
| 982 __ popq(RAX); // Pop result (newly allocated object). | 1004 __ popq(RAX); // Pop result (newly allocated object). |
| 983 // RAX: new object | 1005 // RAX: new object |
| 984 // Restore the frame pointer. | 1006 // Restore the frame pointer. |
| 985 __ LeaveFrame(); | 1007 __ LeaveFrame(); |
| 986 __ ret(); | 1008 __ ret(); |
| 987 } | 1009 } |
| 988 | 1010 |
| 989 | 1011 |
| 1012 // Called for inline allocation of closures. | |
| 1013 // Input parameters: | |
| 1014 // If the signature class is not parameterized, the receiver, if any, will be | |
| 1015 // at RSP + 4 instead of RSP + 8, since no type arguments are passed. | |
| 1016 // RSP + 8 (or RSP + 4): receiver (only if implicit instance closure). | |
| 1017 // RSP + 4 : type arguments object (only if signature class is parameterized). | |
| 1018 // RSP : points to return address. | |
| 1019 // Uses RAX, RBX, RCX, RDX as temporary registers. | |
| 990 void StubCode::GenerateAllocationStubForClosure(Assembler* assembler, | 1020 void StubCode::GenerateAllocationStubForClosure(Assembler* assembler, |
| 991 const Function& func) { | 1021 const Function& func) { |
| 992 __ Unimplemented("AllocateClosure stub"); | 1022 const Immediate raw_null = |
| 1023 Immediate(reinterpret_cast<intptr_t>(Object::null())); | |
| 1024 ASSERT(func.IsClosureFunction()); | |
| 1025 const bool is_implicit_static_closure = | |
| 1026 func.IsImplicitStaticClosureFunction(); | |
| 1027 const bool is_implicit_instance_closure = | |
| 1028 func.IsImplicitInstanceClosureFunction(); | |
| 1029 const Class& cls = Class::ZoneHandle(func.signature_class()); | |
| 1030 const bool has_type_arguments = cls.HasTypeArguments(); | |
| 1031 const intptr_t kTypeArgumentsOffset = 1 * kWordSize; | |
| 1032 const intptr_t kReceiverOffset = (has_type_arguments ? 2 : 1) * kWordSize; | |
| 1033 if (false) { | |
| 1034 // TODO(regis): Implement inline context allocation. | |
| 1035 __ Unimplemented("AllocateClosure stub - inline allocation"); | |
| 1036 } | |
| 1037 if (has_type_arguments) { | |
| 1038 __ movq(RCX, Address(RSP, kTypeArgumentsOffset)); | |
| 1039 } | |
| 1040 if (is_implicit_instance_closure) { | |
| 1041 __ movq(RAX, Address(RSP, kReceiverOffset)); | |
| 1042 } | |
| 1043 // Create the stub frame. | |
| 1044 __ EnterFrame(0); | |
| 1045 const Closure& new_closure = Closure::ZoneHandle(); | |
| 1046 __ PushObject(new_closure); // Push Null closure for return value. | |
|
siva
2011/12/27 21:33:11
Ditto comment regarding __ pushq(raw_null);
Ivan Posva
2011/12/27 22:59:42
Done.
| |
| 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 |