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_X64) | 6 #if defined(TARGET_ARCH_X64) |
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 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
332 // RBX: address of first argument in array. | 332 // RBX: address of first argument in array. |
333 Label loop, loop_condition; | 333 Label loop, loop_condition; |
334 #if defined(DEBUG) | 334 #if defined(DEBUG) |
335 static const bool kJumpLength = Assembler::kFarJump; | 335 static const bool kJumpLength = Assembler::kFarJump; |
336 #else | 336 #else |
337 static const bool kJumpLength = Assembler::kNearJump; | 337 static const bool kJumpLength = Assembler::kNearJump; |
338 #endif // DEBUG | 338 #endif // DEBUG |
339 __ jmp(&loop_condition, kJumpLength); | 339 __ jmp(&loop_condition, kJumpLength); |
340 __ Bind(&loop); | 340 __ Bind(&loop); |
341 __ movq(RDI, Address(R12, 0)); | 341 __ movq(RDI, Address(R12, 0)); |
342 // No generational barrier needed, since array is in new space. | 342 // Generational barrier is needed, array is not necessarily in new space. |
343 __ InitializeFieldNoBarrier(RAX, Address(RBX, 0), RDI); | 343 __ StoreIntoObject(RAX, Address(RBX, 0), RDI); |
344 __ addq(RBX, Immediate(kWordSize)); | 344 __ addq(RBX, Immediate(kWordSize)); |
345 __ subq(R12, Immediate(kWordSize)); | 345 __ subq(R12, Immediate(kWordSize)); |
346 __ Bind(&loop_condition); | 346 __ Bind(&loop_condition); |
347 __ decq(R10); | 347 __ decq(R10); |
348 __ j(POSITIVE, &loop, Assembler::kNearJump); | 348 __ j(POSITIVE, &loop, Assembler::kNearJump); |
349 } | 349 } |
350 | 350 |
351 | 351 |
352 // Used by eager and lazy deoptimization. Preserve result in RAX if necessary. | 352 // Used by eager and lazy deoptimization. Preserve result in RAX if necessary. |
353 // This stub translates optimized frame into unoptimized frame. The optimized | 353 // This stub translates optimized frame into unoptimized frame. The optimized |
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
634 __ movq(RDI, Immediate(0)); | 634 __ movq(RDI, Immediate(0)); |
635 __ Bind(&done); | 635 __ Bind(&done); |
636 | 636 |
637 // Get the class index and insert it into the tags. | 637 // Get the class index and insert it into the tags. |
638 __ orq(RDI, Immediate(RawObject::ClassIdTag::encode(cid))); | 638 __ orq(RDI, Immediate(RawObject::ClassIdTag::encode(cid))); |
639 __ movq(FieldAddress(RAX, Array::tags_offset()), RDI); // Tags. | 639 __ movq(FieldAddress(RAX, Array::tags_offset()), RDI); // Tags. |
640 } | 640 } |
641 | 641 |
642 // RAX: new object start as a tagged pointer. | 642 // RAX: new object start as a tagged pointer. |
643 // Store the type argument field. | 643 // Store the type argument field. |
644 __ InitializeFieldNoBarrier(RAX, | 644 // No generetional barrier needed, since we store into a new object. |
| 645 __ StoreIntoObjectNoBarrier(RAX, |
645 FieldAddress(RAX, Array::type_arguments_offset()), | 646 FieldAddress(RAX, Array::type_arguments_offset()), |
646 RBX); | 647 RBX); |
647 | 648 |
648 // Set the length field. | 649 // Set the length field. |
649 __ InitializeFieldNoBarrier(RAX, | 650 __ StoreIntoObjectNoBarrier(RAX, |
650 FieldAddress(RAX, Array::length_offset()), | 651 FieldAddress(RAX, Array::length_offset()), |
651 R10); | 652 R10); |
652 | 653 |
653 // Initialize all array elements to raw_null. | 654 // Initialize all array elements to raw_null. |
654 // RAX: new object start as a tagged pointer. | 655 // RAX: new object start as a tagged pointer. |
655 // RCX: new object end address. | 656 // RCX: new object end address. |
656 // RDI: iterator which initially points to the start of the variable | 657 // RDI: iterator which initially points to the start of the variable |
657 // data area to be initialized. | 658 // data area to be initialized. |
658 __ LoadObject(R12, Object::null_object()); | 659 __ LoadObject(R12, Object::null_object()); |
659 __ leaq(RDI, FieldAddress(RAX, sizeof(RawArray))); | 660 __ leaq(RDI, FieldAddress(RAX, sizeof(RawArray))); |
660 Label done; | 661 Label done; |
661 Label init_loop; | 662 Label init_loop; |
662 __ Bind(&init_loop); | 663 __ Bind(&init_loop); |
663 __ cmpq(RDI, RCX); | 664 __ cmpq(RDI, RCX); |
664 #if defined(DEBUG) | 665 #if defined(DEBUG) |
665 static const bool kJumpLength = Assembler::kFarJump; | 666 static const bool kJumpLength = Assembler::kFarJump; |
666 #else | 667 #else |
667 static const bool kJumpLength = Assembler::kNearJump; | 668 static const bool kJumpLength = Assembler::kNearJump; |
668 #endif // DEBUG | 669 #endif // DEBUG |
669 __ j(ABOVE_EQUAL, &done, kJumpLength); | 670 __ j(ABOVE_EQUAL, &done, kJumpLength); |
670 // No generational barrier needed, since we are storing null. | 671 // No generational barrier needed, since we are storing null. |
671 __ InitializeFieldNoBarrier(RAX, Address(RDI, 0), R12); | 672 __ StoreIntoObjectNoBarrier(RAX, Address(RDI, 0), R12); |
672 __ addq(RDI, Immediate(kWordSize)); | 673 __ addq(RDI, Immediate(kWordSize)); |
673 __ jmp(&init_loop, kJumpLength); | 674 __ jmp(&init_loop, kJumpLength); |
674 __ Bind(&done); | 675 __ Bind(&done); |
675 __ ret(); // returns the newly allocated object in RAX. | 676 __ ret(); // returns the newly allocated object in RAX. |
676 | 677 |
677 // Unable to allocate the array using the fast inline code, just call | 678 // Unable to allocate the array using the fast inline code, just call |
678 // into the runtime. | 679 // into the runtime. |
679 __ Bind(&slow_case); | 680 __ Bind(&slow_case); |
680 // Create a stub frame as we are pushing some objects on the stack before | 681 // Create a stub frame as we are pushing some objects on the stack before |
681 // calling into the runtime. | 682 // calling into the runtime. |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
906 | 907 |
907 // Setup up number of context variables field. | 908 // Setup up number of context variables field. |
908 // RAX: new object. | 909 // RAX: new object. |
909 // R10: number of context variables as integer value (not object). | 910 // R10: number of context variables as integer value (not object). |
910 __ movq(FieldAddress(RAX, Context::num_variables_offset()), R10); | 911 __ movq(FieldAddress(RAX, Context::num_variables_offset()), R10); |
911 | 912 |
912 // Setup the parent field. | 913 // Setup the parent field. |
913 // RAX: new object. | 914 // RAX: new object. |
914 // R10: number of context variables. | 915 // R10: number of context variables. |
915 // No generational barrier needed, since we are storing null. | 916 // No generational barrier needed, since we are storing null. |
916 __ InitializeFieldNoBarrier(RAX, | 917 __ StoreIntoObjectNoBarrier(RAX, |
917 FieldAddress(RAX, Context::parent_offset()), | 918 FieldAddress(RAX, Context::parent_offset()), |
918 R9); | 919 R9); |
919 | 920 |
920 // Initialize the context variables. | 921 // Initialize the context variables. |
921 // RAX: new object. | 922 // RAX: new object. |
922 // R10: number of context variables. | 923 // R10: number of context variables. |
923 { | 924 { |
924 Label loop, entry; | 925 Label loop, entry; |
925 __ leaq(R13, FieldAddress(RAX, Context::variable_offset(0))); | 926 __ leaq(R13, FieldAddress(RAX, Context::variable_offset(0))); |
926 #if defined(DEBUG) | 927 #if defined(DEBUG) |
927 static const bool kJumpLength = Assembler::kFarJump; | 928 static const bool kJumpLength = Assembler::kFarJump; |
928 #else | 929 #else |
929 static const bool kJumpLength = Assembler::kNearJump; | 930 static const bool kJumpLength = Assembler::kNearJump; |
930 #endif // DEBUG | 931 #endif // DEBUG |
931 __ jmp(&entry, kJumpLength); | 932 __ jmp(&entry, kJumpLength); |
932 __ Bind(&loop); | 933 __ Bind(&loop); |
933 __ decq(R10); | 934 __ decq(R10); |
934 // No generational barrier needed, since we are storing null. | 935 // No generational barrier needed, since we are storing null. |
935 __ InitializeFieldNoBarrier(RAX, | 936 __ StoreIntoObjectNoBarrier(RAX, |
936 Address(R13, R10, TIMES_8, 0), | 937 Address(R13, R10, TIMES_8, 0), |
937 R9); | 938 R9); |
938 __ Bind(&entry); | 939 __ Bind(&entry); |
939 __ cmpq(R10, Immediate(0)); | 940 __ cmpq(R10, Immediate(0)); |
940 __ j(NOT_EQUAL, &loop, Assembler::kNearJump); | 941 __ j(NOT_EQUAL, &loop, Assembler::kNearJump); |
941 } | 942 } |
942 | 943 |
943 // Done allocating and initializing the context. | 944 // Done allocating and initializing the context. |
944 // RAX: new object. | 945 // RAX: new object. |
945 __ ret(); | 946 __ ret(); |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1086 // RBX: next object start. | 1087 // RBX: next object start. |
1087 // RDX: new object type arguments (if is_cls_parameterized). | 1088 // RDX: new object type arguments (if is_cls_parameterized). |
1088 // R9: raw null. | 1089 // R9: raw null. |
1089 // First try inlining the initialization without a loop. | 1090 // First try inlining the initialization without a loop. |
1090 if (instance_size < (kInlineInstanceSize * kWordSize)) { | 1091 if (instance_size < (kInlineInstanceSize * kWordSize)) { |
1091 // Check if the object contains any non-header fields. | 1092 // Check if the object contains any non-header fields. |
1092 // Small objects are initialized using a consecutive set of writes. | 1093 // Small objects are initialized using a consecutive set of writes. |
1093 for (intptr_t current_offset = Instance::NextFieldOffset(); | 1094 for (intptr_t current_offset = Instance::NextFieldOffset(); |
1094 current_offset < instance_size; | 1095 current_offset < instance_size; |
1095 current_offset += kWordSize) { | 1096 current_offset += kWordSize) { |
1096 __ InitializeFieldNoBarrier(RAX, | 1097 __ StoreIntoObjectNoBarrier(RAX, |
1097 FieldAddress(RAX, current_offset), | 1098 FieldAddress(RAX, current_offset), |
1098 R9); | 1099 R9); |
1099 } | 1100 } |
1100 } else { | 1101 } else { |
1101 __ leaq(RCX, FieldAddress(RAX, Instance::NextFieldOffset())); | 1102 __ leaq(RCX, FieldAddress(RAX, Instance::NextFieldOffset())); |
1102 // Loop until the whole object is initialized. | 1103 // Loop until the whole object is initialized. |
1103 // RAX: new object (tagged). | 1104 // RAX: new object (tagged). |
1104 // RBX: next object start. | 1105 // RBX: next object start. |
1105 // RCX: next word to be initialized. | 1106 // RCX: next word to be initialized. |
1106 // RDX: new object type arguments (if is_cls_parameterized). | 1107 // RDX: new object type arguments (if is_cls_parameterized). |
1107 Label init_loop; | 1108 Label init_loop; |
1108 Label done; | 1109 Label done; |
1109 __ Bind(&init_loop); | 1110 __ Bind(&init_loop); |
1110 __ cmpq(RCX, RBX); | 1111 __ cmpq(RCX, RBX); |
1111 #if defined(DEBUG) | 1112 #if defined(DEBUG) |
1112 static const bool kJumpLength = Assembler::kFarJump; | 1113 static const bool kJumpLength = Assembler::kFarJump; |
1113 #else | 1114 #else |
1114 static const bool kJumpLength = Assembler::kNearJump; | 1115 static const bool kJumpLength = Assembler::kNearJump; |
1115 #endif // DEBUG | 1116 #endif // DEBUG |
1116 __ j(ABOVE_EQUAL, &done, kJumpLength); | 1117 __ j(ABOVE_EQUAL, &done, kJumpLength); |
1117 __ InitializeFieldNoBarrier(RAX, Address(RCX, 0), R9); | 1118 __ StoreIntoObjectNoBarrier(RAX, Address(RCX, 0), R9); |
1118 __ addq(RCX, Immediate(kWordSize)); | 1119 __ addq(RCX, Immediate(kWordSize)); |
1119 __ jmp(&init_loop, Assembler::kNearJump); | 1120 __ jmp(&init_loop, Assembler::kNearJump); |
1120 __ Bind(&done); | 1121 __ Bind(&done); |
1121 } | 1122 } |
1122 if (is_cls_parameterized) { | 1123 if (is_cls_parameterized) { |
| 1124 // RAX: new object (tagged). |
1123 // RDX: new object type arguments. | 1125 // RDX: new object type arguments. |
1124 // Set the type arguments in the new object. | 1126 // Set the type arguments in the new object. |
1125 intptr_t offset = cls.type_arguments_field_offset(); | 1127 intptr_t offset = cls.type_arguments_field_offset(); |
1126 __ InitializeFieldNoBarrier(RAX, FieldAddress(RAX, offset), RDX); | 1128 __ StoreIntoObjectNoBarrier(RAX, FieldAddress(RAX, offset), RDX); |
1127 } | 1129 } |
1128 // Done allocating and initializing the instance. | 1130 // Done allocating and initializing the instance. |
1129 // RAX: new object (tagged). | 1131 // RAX: new object (tagged). |
1130 __ ret(); | 1132 __ ret(); |
1131 | 1133 |
1132 __ Bind(&slow_case); | 1134 __ Bind(&slow_case); |
1133 } | 1135 } |
1134 // If is_cls_parameterized: | 1136 // If is_cls_parameterized: |
1135 // RDX: new object type arguments. | 1137 // RDX: new object type arguments. |
1136 // Create a stub frame. | 1138 // Create a stub frame. |
(...skipping 1081 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2218 } | 2220 } |
2219 | 2221 |
2220 | 2222 |
2221 void StubCode::GenerateFrameAwaitingMaterializationStub(Assembler* assembler) { | 2223 void StubCode::GenerateFrameAwaitingMaterializationStub(Assembler* assembler) { |
2222 __ int3(); | 2224 __ int3(); |
2223 } | 2225 } |
2224 | 2226 |
2225 } // namespace dart | 2227 } // namespace dart |
2226 | 2228 |
2227 #endif // defined TARGET_ARCH_X64 | 2229 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |