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

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

Issue 9114054: Port a couple more stubs to x64. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 11 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
OLDNEW
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 658 matching lines...) Expand 10 before | Expand all | Expand 10 after
669 __ movq(RBX, FieldAddress(CTX, Context::isolate_offset())); 669 __ movq(RBX, FieldAddress(CTX, Context::isolate_offset()));
670 __ movq(RBX, Address(RBX, Isolate::object_store_offset())); 670 __ movq(RBX, Address(RBX, Isolate::object_store_offset()));
671 __ movq(RBX, Address(RBX, ObjectStore::array_class_offset())); 671 __ movq(RBX, Address(RBX, ObjectStore::array_class_offset()));
672 __ StoreIntoObject(RAX, FieldAddress(RAX, Array::class_offset()), RBX); 672 __ StoreIntoObject(RAX, FieldAddress(RAX, Array::class_offset()), RBX);
673 // Calculate the size tag. 673 // Calculate the size tag.
674 // RAX: new object start as a tagged pointer. 674 // RAX: new object start as a tagged pointer.
675 // R12: new object end address. 675 // R12: new object end address.
676 // R10: Array length as Smi. 676 // R10: Array length as Smi.
677 { 677 {
678 Label size_tag_overflow, done; 678 Label size_tag_overflow, done;
679 __ leaq(RBX, Address(R10, TIMES_2, fixed_size)); // R10 is Smi. 679 __ leaq(RBX, Address(R10, TIMES_4, fixed_size)); // R10 is Smi.
680 ASSERT(kSmiTagShift == 1); 680 ASSERT(kSmiTagShift == 1);
681 __ andq(RBX, Immediate(-kObjectAlignment)); 681 __ andq(RBX, Immediate(-kObjectAlignment));
682 __ cmpq(RBX, Immediate(RawObject::SizeTag::kMaxSizeTag)); 682 __ cmpq(RBX, Immediate(RawObject::SizeTag::kMaxSizeTag));
683 __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump); 683 __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump);
684 __ shlq(RBX, Immediate(RawObject::kSizeTagBit - kObjectAlignmentLog2)); 684 __ shlq(RBX, Immediate(RawObject::kSizeTagBit - kObjectAlignmentLog2));
685 __ movq(FieldAddress(RAX, Array::tags_offset()), RBX); 685 __ movq(FieldAddress(RAX, Array::tags_offset()), RBX);
686 __ jmp(&done); 686 __ jmp(&done);
687 687
688 __ Bind(&size_tag_overflow); 688 __ Bind(&size_tag_overflow);
689 __ movq(FieldAddress(RAX, Array::tags_offset()), Immediate(0)); 689 __ movq(FieldAddress(RAX, Array::tags_offset()), Immediate(0));
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
723 __ CallRuntimeFromStub(kAllocateArrayRuntimeEntry); 723 __ CallRuntimeFromStub(kAllocateArrayRuntimeEntry);
724 __ popq(RAX); // Pop instantiator. 724 __ popq(RAX); // Pop instantiator.
725 __ popq(RAX); // Pop element type argument. 725 __ popq(RAX); // Pop element type argument.
726 __ popq(R10); // Pop array length argument. 726 __ popq(R10); // Pop array length argument.
727 __ popq(RAX); // Pop return value from return slot. 727 __ popq(RAX); // Pop return value from return slot.
728 __ LeaveFrame(); 728 __ LeaveFrame();
729 __ ret(); 729 __ ret();
730 } 730 }
731 731
732 732
733 // Input parameters:
734 // R10: Arguments descriptor array (num_args is first Smi element, closure
735 // object is not included in num_args).
736 // Note: The closure object is pushed before the first argument to the function
737 // being called, the stub accesses the closure from this location directly
738 // when setting up the context and resolving the entry point.
739 // Uses R13.
733 void StubCode::GenerateCallClosureFunctionStub(Assembler* assembler) { 740 void StubCode::GenerateCallClosureFunctionStub(Assembler* assembler) {
734 __ Unimplemented("CallClosureFunction stub"); 741 const Immediate raw_null =
742 Immediate(reinterpret_cast<intptr_t>(Object::null()));
743
744 // Total number of args is the first Smi in args descriptor array (R10).
745 __ movq(RAX, FieldAddress(R10, Array::data_offset())); // Load num_args.
746 // Load closure object in R13.
747 __ movq(R13, Address(RSP, RAX, TIMES_4, kWordSize)); // RAX is a Smi.
748
749 // Verify that R13 is a closure by checking its class.
750 Label not_closure;
751 __ cmpq(R13, raw_null);
752 // Not a closure, but null object.
753 __ j(EQUAL, &not_closure, Assembler::kNearJump);
754 __ testq(R13, Immediate(kSmiTagMask));
755 __ j(ZERO, &not_closure, Assembler::kNearJump); // Not a closure, but a smi.
756 // Verify that the class of the object is a closure class by checking that
757 // class.signature_function() is not null.
758 __ movq(RAX, FieldAddress(R13, Object::class_offset()));
759 __ movq(RAX, FieldAddress(RAX, Class::signature_function_offset()));
760 __ cmpq(RAX, raw_null);
761 // Actual class is not a closure class.
762 __ j(EQUAL, &not_closure, Assembler::kNearJump);
763
764 // RAX is just the signature function. Load the actual closure function.
765 __ movq(RBX, FieldAddress(R13, Closure::function_offset()));
766
767 // Load closure context in CTX; note that CTX has already been preserved.
768 __ movq(CTX, FieldAddress(R13, Closure::context_offset()));
769
770 // Load closure function code in RAX.
771 __ movq(RAX, FieldAddress(RBX, Function::code_offset()));
772 __ cmpq(RAX, raw_null);
773 Label function_compiled;
774 __ j(NOT_EQUAL, &function_compiled, Assembler::kNearJump);
775
776 // Create a stub frame as we are pushing some objects on the stack before
777 // calling into the runtime.
778 __ EnterFrame(0);
779
780 __ pushq(R10); // Preserve arguments descriptor array.
781 __ pushq(RBX);
782 __ CallRuntimeFromStub(kCompileFunctionRuntimeEntry);
783 __ popq(RBX); // Restore read-only function object argument in RBX.
784 __ popq(R10); // Restore arguments descriptor array.
785 // Restore RAX.
786 __ movq(RAX, FieldAddress(RBX, Function::code_offset()));
787
788 // Remove the stub frame as we are about to jump to the closure function.
789 __ LeaveFrame();
790
791 __ Bind(&function_compiled);
792 // RAX: Code.
793 // RBX: Function.
794 // R10: Arguments descriptor array (num_args is first Smi element).
795
796 __ movq(RBX, FieldAddress(RAX, Code::instructions_offset()));
797 __ addq(RBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
798 __ jmp(RBX);
799
800 __ Bind(&not_closure);
801 // Call runtime to report that a closure call was attempted on a non-closure
802 // object, passing the non-closure object and its arguments array.
803 // R13: non-closure object.
804 // R10: arguments descriptor array (num_args is first Smi element, closure
805 // object is not included in num_args).
806
807 // Create a stub frame as we are pushing some objects on the stack before
808 // calling into the runtime.
809 __ EnterFrame(0);
810
811 __ pushq(raw_null); // Setup space on stack for result from error reporting.
812 __ pushq(R13); // Non-closure object.
813 // Total number of args is the first Smi in args descriptor array (R10).
814 __ movq(R13, FieldAddress(R10, Array::data_offset())); // Load num_args.
815 __ SmiUntag(R13);
816 // See stack layout below explaining "wordSize * 4" offset.
817 PushArgumentsArray(assembler, (kWordSize * 4));
818
819 // Stack:
820 // TOS + 0: Argument array.
821 // TOS + 1: Non-closure object.
822 // TOS + 2: Place for result from reporting the error.
823 // TOS + 3: Saved RBP of previous frame. <== RBP
824 // TOS + 4: Dart code return address
825 // TOS + 5: Last argument of caller.
826 // ....
827 __ CallRuntimeFromStub(kReportObjectNotClosureRuntimeEntry);
828 __ Stop("runtime call throws an exception");
735 } 829 }
736 830
737 831
738 // Called when invoking Dart code from C++ (VM code). 832 // Called when invoking Dart code from C++ (VM code).
739 // Input parameters: 833 // Input parameters:
740 // RSP : points to return address. 834 // RSP : points to return address.
741 // RDI : entrypoint of the Dart function to call. 835 // RDI : entrypoint of the Dart function to call.
742 // RSI : arguments descriptor array. 836 // RSI : arguments descriptor array.
743 // RDX : pointer to the argument array. 837 // RDX : pointer to the argument array.
744 // RCX : new context containing the current isolate pointer. 838 // RCX : new context containing the current isolate pointer.
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
846 940
847 // Restore the frame pointer. 941 // Restore the frame pointer.
848 __ LeaveFrame(); 942 __ LeaveFrame();
849 943
850 __ ret(); 944 __ ret();
851 } 945 }
852 946
853 947
854 // Called for inline allocation of contexts. 948 // Called for inline allocation of contexts.
855 // Input: 949 // Input:
856 // RDX: number of context variables. 950 // R10: number of context variables.
857 // Output: 951 // Output:
858 // RAX: new allocated RawContext object. 952 // RAX: new allocated RawContext object.
859 // RBX and RDX are destroyed.
860 void StubCode::GenerateAllocateContextStub(Assembler* assembler) { 953 void StubCode::GenerateAllocateContextStub(Assembler* assembler) {
861 const Immediate raw_null = 954 const Immediate raw_null =
862 Immediate(reinterpret_cast<intptr_t>(Object::null())); 955 Immediate(reinterpret_cast<intptr_t>(Object::null()));
863 if (false) { 956 if (false) {
864 // TODO(regis): Implement fast inline allocation of contexts. 957 // TODO(regis): Implement fast inline allocation of contexts.
865 __ Unimplemented("AllocateContext stub - inline allocation"); 958 __ Unimplemented("AllocateContext stub - inline allocation");
866 } 959 }
867 // Create the stub frame. 960 // Create the stub frame.
868 __ EnterFrame(0); 961 __ EnterFrame(0);
869 __ pushq(raw_null); // Setup space on stack for the return value. 962 __ pushq(raw_null); // Setup space on stack for the return value.
870 __ SmiTag(RDX); 963 __ SmiTag(R10);
871 __ pushq(RDX); // Push number of context variables. 964 __ pushq(R10); // Push number of context variables.
872 __ CallRuntimeFromStub(kAllocateContextRuntimeEntry); // Allocate context. 965 __ CallRuntimeFromStub(kAllocateContextRuntimeEntry); // Allocate context.
873 __ popq(RAX); // Pop number of context variables argument. 966 __ popq(RAX); // Pop number of context variables argument.
874 __ popq(RAX); // Pop the new context object. 967 __ popq(RAX); // Pop the new context object.
875 // RAX: new object 968 // RAX: new object
876 // Restore the frame pointer. 969 // Restore the frame pointer.
877 __ LeaveFrame(); 970 __ LeaveFrame();
878 __ ret(); 971 __ ret();
879 } 972 }
880 973
881 974
882
883
884 // Called for inline allocation of objects. 975 // Called for inline allocation of objects.
885 // Input parameters: 976 // Input parameters:
886 // RSP + 16 : type arguments object (only if class is parameterized). 977 // RSP + 16 : type arguments object (only if class is parameterized).
887 // RSP + 8 : type arguments of instantiator (only if class is parameterized). 978 // RSP + 8 : type arguments of instantiator (only if class is parameterized).
888 // RSP : points to return address. 979 // RSP : points to return address.
889 // Uses RAX, RBX, RCX, RDX, RDI as temporary registers. 980 // Uses RAX, RBX, RCX, RDX, RDI as temporary registers.
890 void StubCode::GenerateAllocationStubForClass(Assembler* assembler, 981 void StubCode::GenerateAllocationStubForClass(Assembler* assembler,
891 const Class& cls) { 982 const Class& cls) {
892 const intptr_t kObjectTypeArgumentsOffset = 2 * kWordSize; 983 const intptr_t kObjectTypeArgumentsOffset = 2 * kWordSize;
893 const intptr_t kInstantiatorTypeArgumentsOffset = 1 * kWordSize; 984 const intptr_t kInstantiatorTypeArgumentsOffset = 1 * kWordSize;
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after
1134 } 1225 }
1135 __ popq(RAX); // Pop the function object. 1226 __ popq(RAX); // Pop the function object.
1136 __ popq(RAX); // Pop the result. 1227 __ popq(RAX); // Pop the result.
1137 // RAX: New closure object. 1228 // RAX: New closure object.
1138 // Restore the calling frame. 1229 // Restore the calling frame.
1139 __ LeaveFrame(); 1230 __ LeaveFrame();
1140 __ ret(); 1231 __ ret();
1141 } 1232 }
1142 1233
1143 1234
1235 // Called for invoking noSuchMethod function from the entry code of a dart
1236 // function after an error in passed named arguments is detected.
1237 // Input parameters:
1238 // RBP : points to previous frame pointer.
1239 // RBP + 8 : points to return address.
1240 // RBP + 16 : address of last argument (arg n-1).
1241 // RBP + 16 + 8*(n-1) : address of first argument (arg 0).
1242 // RBX : ic-data array.
1243 // R10 : arguments descriptor array.
1144 void StubCode::GenerateCallNoSuchMethodFunctionStub(Assembler* assembler) { 1244 void StubCode::GenerateCallNoSuchMethodFunctionStub(Assembler* assembler) {
1145 __ Unimplemented("CallNoSuchMethodFunction stub"); 1245 // The target function was not found, so invoke method
1246 // "void noSuchMethod(function_name, Array arguments)".
1247 // TODO(regis): For now, we simply pass the actual arguments, both positional
1248 // and named, as the argument array. This is not correct if out-of-order
1249 // named arguments were passed.
1250 // The signature of the "noSuchMethod" method has to change from
1251 // noSuchMethod(String name, Array arguments) to something like
1252 // noSuchMethod(InvocationMirror call).
1253 // Also, the class NoSuchMethodException has to be modified accordingly.
1254 // Total number of args is the first Smi in args descriptor array (R10).
1255 const Immediate raw_null =
1256 Immediate(reinterpret_cast<intptr_t>(Object::null()));
1257 __ movq(R13, FieldAddress(R10, Array::data_offset())); // R13 is Smi.
1258 __ movq(RAX, Address(RBP, R13, TIMES_4, kWordSize)); // Get receiver.
1259
1260 __ EnterFrame(0);
1261 __ pushq(raw_null); // Setup space on stack for result from noSuchMethod.
1262 __ pushq(RAX); // Receiver.
1263 __ pushq(RBX); // IC data array.
1264 __ pushq(R10); // Arguments descriptor array.
1265 __ SmiUntag(R13);
1266 __ subq(R13, Immediate(1)); // Arguments array length, minus the receiver.
1267 // See stack layout below explaining "wordSize * 8" offset.
1268 PushArgumentsArray(assembler, (kWordSize * 8));
1269
1270 // Stack:
1271 // TOS + 0: Argument array.
1272 // TOS + 1: Arguments descriptor array.
1273 // TOS + 2: Ic-data array.
1274 // TOS + 3: Receiver.
1275 // TOS + 4: Place for result from noSuchMethod.
1276 // TOS + 5: Saved RBP of previous frame. <== RBP
1277 // TOS + 6: Dart callee (or stub) code return address
1278 // TOS + 7: Saved RBP of dart caller frame.
1279 // TOS + 8: Dart caller code return address
1280 // TOS + 9: Last argument of caller.
1281 // ....
1282 __ CallRuntimeFromStub(kInvokeNoSuchMethodFunctionRuntimeEntry);
1283 // Remove arguments.
1284 __ popq(RAX);
1285 __ popq(RAX);
1286 __ popq(RAX);
1287 __ popq(RAX);
1288 __ popq(RAX); // Get result into RAX.
1289
1290 // Remove the stub frame as we are about to return.
1291 __ LeaveFrame();
1292 __ ret();
1146 } 1293 }
1147 1294
1148 1295
1296
1149 // Generate inline cache check for 'num_args'. 1297 // Generate inline cache check for 'num_args'.
1150 // RBX: Inline cache data array. 1298 // RBX: Inline cache data array.
1151 // R10: Arguments array. 1299 // R10: Arguments array.
1152 // TOS(0): return address 1300 // TOS(0): return address
1153 // Control flow: 1301 // Control flow:
1154 // - If receiver is null -> jump to IC miss. 1302 // - If receiver is null -> jump to IC miss.
1155 // - If receiver is Smi -> load Smi class. 1303 // - If receiver is Smi -> load Smi class.
1156 // - If receiver is not-Smi -> load receiver's class. 1304 // - If receiver is not-Smi -> load receiver's class.
1157 // - Check if 'num_args' (including receiver) match any IC data group. 1305 // - Check if 'num_args' (including receiver) match any IC data group.
1158 // - Match found -> jump to target. 1306 // - Match found -> jump to target.
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
1312 } 1460 }
1313 1461
1314 1462
1315 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) { 1463 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) {
1316 __ Unimplemented("BreakpointDynamic stub"); 1464 __ Unimplemented("BreakpointDynamic stub");
1317 } 1465 }
1318 1466
1319 } // namespace dart 1467 } // namespace dart
1320 1468
1321 #endif // defined TARGET_ARCH_X64 1469 #endif // defined TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698