| 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 |