| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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/object_store.h" | 10 #include "vm/object_store.h" |
| (...skipping 657 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 668 // R12: new object end address. | 668 // R12: new object end address. |
| 669 // R10: Array length as Smi. | 669 // R10: Array length as Smi. |
| 670 { | 670 { |
| 671 Label size_tag_overflow, done; | 671 Label size_tag_overflow, done; |
| 672 __ leaq(RBX, Address(R10, TIMES_4, fixed_size)); // R10 is Smi. | 672 __ leaq(RBX, Address(R10, TIMES_4, fixed_size)); // R10 is Smi. |
| 673 ASSERT(kSmiTagShift == 1); | 673 ASSERT(kSmiTagShift == 1); |
| 674 __ andq(RBX, Immediate(-kObjectAlignment)); | 674 __ andq(RBX, Immediate(-kObjectAlignment)); |
| 675 __ cmpq(RBX, Immediate(RawObject::SizeTag::kMaxSizeTag)); | 675 __ cmpq(RBX, Immediate(RawObject::SizeTag::kMaxSizeTag)); |
| 676 __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump); | 676 __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump); |
| 677 __ shlq(RBX, Immediate(RawObject::kSizeTagBit - kObjectAlignmentLog2)); | 677 __ shlq(RBX, Immediate(RawObject::kSizeTagBit - kObjectAlignmentLog2)); |
| 678 __ movq(FieldAddress(RAX, Array::tags_offset()), RBX); | |
| 679 __ jmp(&done); | 678 __ jmp(&done); |
| 680 | 679 |
| 681 __ Bind(&size_tag_overflow); | 680 __ Bind(&size_tag_overflow); |
| 682 __ movq(FieldAddress(RAX, Array::tags_offset()), Immediate(0)); | 681 __ movq(RBX, Immediate(0)); |
| 683 __ Bind(&done); | 682 __ Bind(&done); |
| 683 |
| 684 // Get the class index and insert it into the tags. |
| 685 __ orq(RBX, Immediate(RawObject::ClassTag::encode(kArray))); |
| 686 __ movq(FieldAddress(RAX, Array::tags_offset()), RBX); |
| 684 } | 687 } |
| 685 | 688 |
| 686 // Initialize all array elements to raw_null. | 689 // Initialize all array elements to raw_null. |
| 687 // RAX: new object start as a tagged pointer. | 690 // RAX: new object start as a tagged pointer. |
| 688 // R12: new object end address. | 691 // R12: new object end address. |
| 689 __ leaq(RBX, FieldAddress(RAX, Array::data_offset())); | 692 __ leaq(RBX, FieldAddress(RAX, Array::data_offset())); |
| 690 // RBX: iterator which initially points to the start of the variable | 693 // RBX: iterator which initially points to the start of the variable |
| 691 // data area to be initialized. | 694 // data area to be initialized. |
| 692 Label done; | 695 Label done; |
| 693 Label init_loop; | 696 Label init_loop; |
| (...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 989 // Calculate the size tag. | 992 // Calculate the size tag. |
| 990 // RAX: new object. | 993 // RAX: new object. |
| 991 // R10: number of context variables. | 994 // R10: number of context variables. |
| 992 { | 995 { |
| 993 Label size_tag_overflow, done; | 996 Label size_tag_overflow, done; |
| 994 __ leaq(R13, Address(R10, TIMES_8, fixed_size)); | 997 __ leaq(R13, Address(R10, TIMES_8, fixed_size)); |
| 995 __ andq(R13, Immediate(-kObjectAlignment)); | 998 __ andq(R13, Immediate(-kObjectAlignment)); |
| 996 __ cmpq(R13, Immediate(RawObject::SizeTag::kMaxSizeTag)); | 999 __ cmpq(R13, Immediate(RawObject::SizeTag::kMaxSizeTag)); |
| 997 __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump); | 1000 __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump); |
| 998 __ shlq(R13, Immediate(RawObject::kSizeTagBit - kObjectAlignmentLog2)); | 1001 __ shlq(R13, Immediate(RawObject::kSizeTagBit - kObjectAlignmentLog2)); |
| 999 __ movq(FieldAddress(RAX, Context::tags_offset()), R13); // Tags. | |
| 1000 __ jmp(&done); | 1002 __ jmp(&done); |
| 1001 | 1003 |
| 1002 __ Bind(&size_tag_overflow); | 1004 __ Bind(&size_tag_overflow); |
| 1003 // Set overflow size tag value. | 1005 // Set overflow size tag value. |
| 1004 __ movq(FieldAddress(RAX, Context::tags_offset()), Immediate(0)); | 1006 __ movq(R13, Immediate(0)); |
| 1007 |
| 1005 __ Bind(&done); | 1008 __ Bind(&done); |
| 1009 // RAX: new object. |
| 1010 // R10: number of context variables. |
| 1011 // R13: size and bit tags. |
| 1012 __ orq(R13, |
| 1013 Immediate(RawObject::ClassTag::encode(context_class.index()))); |
| 1014 __ movq(FieldAddress(RAX, Context::tags_offset()), R13); // Tags. |
| 1006 } | 1015 } |
| 1007 | 1016 |
| 1008 // Setup up number of context variables field. | 1017 // Setup up number of context variables field. |
| 1009 // RAX: new object. | 1018 // RAX: new object. |
| 1010 // R10: number of context variables as integer value (not object). | 1019 // R10: number of context variables as integer value (not object). |
| 1011 __ movq(FieldAddress(RAX, Context::num_variables_offset()), R10); | 1020 __ movq(FieldAddress(RAX, Context::num_variables_offset()), R10); |
| 1012 | 1021 |
| 1013 // Setup isolate field. | 1022 // Setup isolate field. |
| 1014 // Load Isolate pointer from Context structure into R13. | 1023 // Load Isolate pointer from Context structure into R13. |
| 1015 // RAX: new object. | 1024 // RAX: new object. |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1154 // RDI: new object type arguments. | 1163 // RDI: new object type arguments. |
| 1155 } | 1164 } |
| 1156 | 1165 |
| 1157 // Initialize the class field in the object. | 1166 // Initialize the class field in the object. |
| 1158 // RAX: new object start. | 1167 // RAX: new object start. |
| 1159 // RBX: next object start. | 1168 // RBX: next object start. |
| 1160 // RDI: new object type arguments (if is_cls_parameterized). | 1169 // RDI: new object type arguments (if is_cls_parameterized). |
| 1161 __ LoadObject(RDX, cls); // Load class of object to be allocated. | 1170 __ LoadObject(RDX, cls); // Load class of object to be allocated. |
| 1162 __ movq(Address(RAX, Instance::class_offset()), RDX); | 1171 __ movq(Address(RAX, Instance::class_offset()), RDX); |
| 1163 // Set the tags. | 1172 // Set the tags. |
| 1164 __ movq(Address(RAX, Instance::tags_offset()), | 1173 intptr_t tags = 0; |
| 1165 Immediate(RawObject::SizeTag::encode(instance_size))); | 1174 tags = RawObject::SizeTag::update(instance_size, tags); |
| 1175 ASSERT(cls.index() != kIllegalObjectKind); |
| 1176 tags = RawObject::ClassTag::update(cls.index(), tags); |
| 1177 __ movq(Address(RAX, Instance::tags_offset()), Immediate(tags)); |
| 1166 | 1178 |
| 1167 // Initialize the remaining words of the object. | 1179 // Initialize the remaining words of the object. |
| 1168 const Immediate raw_null = | 1180 const Immediate raw_null = |
| 1169 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 1181 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 1170 | 1182 |
| 1171 // RAX: new object start. | 1183 // RAX: new object start. |
| 1172 // RBX: next object start. | 1184 // RBX: next object start. |
| 1173 // RDX: class of the object to be allocated. | 1185 // RDX: class of the object to be allocated. |
| 1174 // First try inlining the initialization without a loop. | 1186 // First try inlining the initialization without a loop. |
| 1175 if (instance_size < (kInlineInstanceSize * kWordSize) && | 1187 if (instance_size < (kInlineInstanceSize * kWordSize) && |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1306 // next object start and initialize the object. | 1318 // next object start and initialize the object. |
| 1307 __ movq(RDI, Immediate(heap->TopAddress())); | 1319 __ movq(RDI, Immediate(heap->TopAddress())); |
| 1308 __ movq(Address(RDI, 0), R13); | 1320 __ movq(Address(RDI, 0), R13); |
| 1309 | 1321 |
| 1310 // Initialize the class field in the object. | 1322 // Initialize the class field in the object. |
| 1311 // RAX: new closure object. | 1323 // RAX: new closure object. |
| 1312 // RBX: new context object (only if is_implicit_closure). | 1324 // RBX: new context object (only if is_implicit_closure). |
| 1313 __ LoadObject(R10, cls); // Load signature class of closure. | 1325 __ LoadObject(R10, cls); // Load signature class of closure. |
| 1314 __ movq(Address(RAX, Closure::class_offset()), R10); | 1326 __ movq(Address(RAX, Closure::class_offset()), R10); |
| 1315 // Set the tags. | 1327 // Set the tags. |
| 1316 __ movq(Address(RAX, Closure::tags_offset()), | 1328 intptr_t tags = 0; |
| 1317 Immediate(RawObject::SizeTag::encode(closure_size))); | 1329 tags = RawObject::SizeTag::update(closure_size, tags); |
| 1330 tags = RawObject::ClassTag::update(cls.index(), tags); |
| 1331 __ movq(Address(RAX, Closure::tags_offset()), Immediate(tags)); |
| 1318 | 1332 |
| 1319 // Initialize the function field in the object. | 1333 // Initialize the function field in the object. |
| 1320 // RAX: new closure object. | 1334 // RAX: new closure object. |
| 1321 // RBX: new context object (only if is_implicit_closure). | 1335 // RBX: new context object (only if is_implicit_closure). |
| 1322 // R13: next object start. | 1336 // R13: next object start. |
| 1323 __ LoadObject(R10, func); // Load function of closure to be allocated. | 1337 __ LoadObject(R10, func); // Load function of closure to be allocated. |
| 1324 __ movq(Address(RAX, Closure::function_offset()), R10); | 1338 __ movq(Address(RAX, Closure::function_offset()), R10); |
| 1325 | 1339 |
| 1326 // Setup the context for this closure. | 1340 // Setup the context for this closure. |
| 1327 if (is_implicit_static_closure) { | 1341 if (is_implicit_static_closure) { |
| 1328 ObjectStore* object_store = Isolate::Current()->object_store(); | 1342 ObjectStore* object_store = Isolate::Current()->object_store(); |
| 1329 ASSERT(object_store != NULL); | 1343 ASSERT(object_store != NULL); |
| 1330 const Context& empty_context = | 1344 const Context& empty_context = |
| 1331 Context::ZoneHandle(object_store->empty_context()); | 1345 Context::ZoneHandle(object_store->empty_context()); |
| 1332 __ LoadObject(R10, empty_context); | 1346 __ LoadObject(R10, empty_context); |
| 1333 __ movq(Address(RAX, Closure::context_offset()), R10); | 1347 __ movq(Address(RAX, Closure::context_offset()), R10); |
| 1334 } else if (is_implicit_instance_closure) { | 1348 } else if (is_implicit_instance_closure) { |
| 1335 // Initialize the new context capturing the receiver. | 1349 // Initialize the new context capturing the receiver. |
| 1336 | 1350 |
| 1337 // Set the class field to the Context class. | 1351 // Set the class field to the Context class. |
| 1338 __ LoadObject(R13, Class::ZoneHandle(Object::context_class())); | 1352 const Class& context_class = Class::ZoneHandle(Object::context_class()); |
| 1353 __ LoadObject(R13, context_class); |
| 1339 __ movq(Address(RBX, Context::class_offset()), R13); | 1354 __ movq(Address(RBX, Context::class_offset()), R13); |
| 1340 // Set the tags. | 1355 // Set the tags. |
| 1341 __ movq(Address(RBX, Context::tags_offset()), | 1356 intptr_t tags = 0; |
| 1342 Immediate(RawObject::SizeTag::encode(context_size))); | 1357 tags = RawObject::SizeTag::update(context_size, tags); |
| 1358 tags = RawObject::ClassTag::update(context_class.index(), tags); |
| 1359 __ movq(Address(RBX, Context::tags_offset()), Immediate(tags)); |
| 1343 | 1360 |
| 1344 // Set number of variables field to 1 (for captured receiver). | 1361 // Set number of variables field to 1 (for captured receiver). |
| 1345 __ movq(Address(RBX, Context::num_variables_offset()), Immediate(1)); | 1362 __ movq(Address(RBX, Context::num_variables_offset()), Immediate(1)); |
| 1346 | 1363 |
| 1347 // Set isolate field to isolate of current context. | 1364 // Set isolate field to isolate of current context. |
| 1348 __ movq(R10, FieldAddress(CTX, Context::isolate_offset())); | 1365 __ movq(R10, FieldAddress(CTX, Context::isolate_offset())); |
| 1349 __ movq(Address(RBX, Context::isolate_offset()), R10); | 1366 __ movq(Address(RBX, Context::isolate_offset()), R10); |
| 1350 | 1367 |
| 1351 // Set the parent field to null. | 1368 // Set the parent field to null. |
| 1352 __ movq(Address(RBX, Context::parent_offset()), raw_null); | 1369 __ movq(Address(RBX, Context::parent_offset()), raw_null); |
| (...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1779 __ j(EQUAL, ¬_found, Assembler::kNearJump); | 1796 __ j(EQUAL, ¬_found, Assembler::kNearJump); |
| 1780 __ movq(R10, FieldAddress(R10, Type::type_class_offset())); | 1797 __ movq(R10, FieldAddress(R10, Type::type_class_offset())); |
| 1781 __ cmpq(RCX, R10); | 1798 __ cmpq(RCX, R10); |
| 1782 __ j(NOT_EQUAL, &super_loop, Assembler::kNearJump); | 1799 __ j(NOT_EQUAL, &super_loop, Assembler::kNearJump); |
| 1783 __ jmp(&found, Assembler::kNearJump); | 1800 __ jmp(&found, Assembler::kNearJump); |
| 1784 } | 1801 } |
| 1785 | 1802 |
| 1786 } // namespace dart | 1803 } // namespace dart |
| 1787 | 1804 |
| 1788 #endif // defined TARGET_ARCH_X64 | 1805 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |