| 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_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
| 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 662 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 673 // EBX: new object end address. | 673 // EBX: new object end address. |
| 674 // EDX: Array length as Smi. | 674 // EDX: Array length as Smi. |
| 675 { | 675 { |
| 676 Label size_tag_overflow, done; | 676 Label size_tag_overflow, done; |
| 677 __ leal(ECX, Address(EDX, TIMES_2, fixed_size)); // EDX is Smi. | 677 __ leal(ECX, Address(EDX, TIMES_2, fixed_size)); // EDX is Smi. |
| 678 ASSERT(kSmiTagShift == 1); | 678 ASSERT(kSmiTagShift == 1); |
| 679 __ andl(ECX, Immediate(-kObjectAlignment)); | 679 __ andl(ECX, Immediate(-kObjectAlignment)); |
| 680 __ cmpl(ECX, Immediate(RawObject::SizeTag::kMaxSizeTag)); | 680 __ cmpl(ECX, Immediate(RawObject::SizeTag::kMaxSizeTag)); |
| 681 __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump); | 681 __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump); |
| 682 __ shll(ECX, Immediate(RawObject::kSizeTagBit - kObjectAlignmentLog2)); | 682 __ shll(ECX, Immediate(RawObject::kSizeTagBit - kObjectAlignmentLog2)); |
| 683 __ movl(FieldAddress(EAX, Array::tags_offset()), ECX); | |
| 684 __ jmp(&done); | 683 __ jmp(&done); |
| 685 | 684 |
| 686 __ Bind(&size_tag_overflow); | 685 __ Bind(&size_tag_overflow); |
| 687 __ movl(FieldAddress(EAX, Array::tags_offset()), Immediate(0)); | 686 __ movl(ECX, Immediate(0)); |
| 688 __ Bind(&done); | 687 __ Bind(&done); |
| 688 |
| 689 // Get the class index and insert it into the tags. |
| 690 __ orl(ECX, Immediate(RawObject::ClassTag::encode(kArray))); |
| 691 __ movl(FieldAddress(EAX, Array::tags_offset()), ECX); |
| 689 } | 692 } |
| 690 | 693 |
| 691 // Initialize all array elements to raw_null. | 694 // Initialize all array elements to raw_null. |
| 692 // EAX: new object start as a tagged pointer. | 695 // EAX: new object start as a tagged pointer. |
| 693 // EBX: new object end address. | 696 // EBX: new object end address. |
| 694 // EDX: Array length as Smi. | 697 // EDX: Array length as Smi. |
| 695 __ leal(ECX, FieldAddress(EAX, Array::data_offset())); | 698 __ leal(ECX, FieldAddress(EAX, Array::data_offset())); |
| 696 // ECX: iterator which initially points to the start of the variable | 699 // ECX: iterator which initially points to the start of the variable |
| 697 // data area to be initialized. | 700 // data area to be initialized. |
| 698 Label done; | 701 Label done; |
| (...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 993 // Calculate the size tag. | 996 // Calculate the size tag. |
| 994 // EAX: new object. | 997 // EAX: new object. |
| 995 // EDX: number of context variables. | 998 // EDX: number of context variables. |
| 996 { | 999 { |
| 997 Label size_tag_overflow, done; | 1000 Label size_tag_overflow, done; |
| 998 __ leal(EBX, Address(EDX, TIMES_4, fixed_size)); | 1001 __ leal(EBX, Address(EDX, TIMES_4, fixed_size)); |
| 999 __ andl(EBX, Immediate(-kObjectAlignment)); | 1002 __ andl(EBX, Immediate(-kObjectAlignment)); |
| 1000 __ cmpl(EBX, Immediate(RawObject::SizeTag::kMaxSizeTag)); | 1003 __ cmpl(EBX, Immediate(RawObject::SizeTag::kMaxSizeTag)); |
| 1001 __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump); | 1004 __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump); |
| 1002 __ shll(EBX, Immediate(RawObject::kSizeTagBit - kObjectAlignmentLog2)); | 1005 __ shll(EBX, Immediate(RawObject::kSizeTagBit - kObjectAlignmentLog2)); |
| 1003 __ movl(FieldAddress(EAX, Context::tags_offset()), EBX); // Tags. | |
| 1004 __ jmp(&done); | 1006 __ jmp(&done); |
| 1005 | 1007 |
| 1006 __ Bind(&size_tag_overflow); | 1008 __ Bind(&size_tag_overflow); |
| 1007 // Set overflow size tag value. | 1009 // Set overflow size tag value. |
| 1008 __ movl(FieldAddress(EAX, Context::tags_offset()), Immediate(0)); | 1010 __ movl(EBX, Immediate(0)); |
| 1011 |
| 1009 __ Bind(&done); | 1012 __ Bind(&done); |
| 1013 // EAX: new object. |
| 1014 // EDX: number of context variables. |
| 1015 // EBX: size and bit tags. |
| 1016 __ orl(EBX, |
| 1017 Immediate(RawObject::ClassTag::encode(context_class.index()))); |
| 1018 __ movl(FieldAddress(EAX, Context::tags_offset()), EBX); // Tags. |
| 1010 } | 1019 } |
| 1011 | 1020 |
| 1012 // Setup up number of context variables field. | 1021 // Setup up number of context variables field. |
| 1013 // EAX: new object. | 1022 // EAX: new object. |
| 1014 // EDX: number of context variables as integer value (not object). | 1023 // EDX: number of context variables as integer value (not object). |
| 1015 __ movl(FieldAddress(EAX, Context::num_variables_offset()), EDX); | 1024 __ movl(FieldAddress(EAX, Context::num_variables_offset()), EDX); |
| 1016 | 1025 |
| 1017 // Setup isolate field. | 1026 // Setup isolate field. |
| 1018 // Load Isolate pointer from Context structure into EBX. | 1027 // Load Isolate pointer from Context structure into EBX. |
| 1019 // EAX: new object. | 1028 // EAX: new object. |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1156 // EDI: new object type arguments. | 1165 // EDI: new object type arguments. |
| 1157 } | 1166 } |
| 1158 | 1167 |
| 1159 // Initialize the class field in the object. | 1168 // Initialize the class field in the object. |
| 1160 // EAX: new object start. | 1169 // EAX: new object start. |
| 1161 // EBX: next object start. | 1170 // EBX: next object start. |
| 1162 // EDI: new object type arguments (if is_cls_parameterized). | 1171 // EDI: new object type arguments (if is_cls_parameterized). |
| 1163 __ LoadObject(EDX, cls); // Load class of object to be allocated. | 1172 __ LoadObject(EDX, cls); // Load class of object to be allocated. |
| 1164 __ movl(Address(EAX, Instance::class_offset()), EDX); | 1173 __ movl(Address(EAX, Instance::class_offset()), EDX); |
| 1165 // Set the tags. | 1174 // Set the tags. |
| 1166 __ movl(Address(EAX, Instance::tags_offset()), | 1175 intptr_t tags = 0; |
| 1167 Immediate(RawObject::SizeTag::encode(instance_size))); | 1176 tags = RawObject::SizeTag::update(instance_size, tags); |
| 1177 ASSERT(cls.index() != kIllegalObjectKind); |
| 1178 tags = RawObject::ClassTag::update(cls.index(), tags); |
| 1179 __ movl(Address(EAX, Instance::tags_offset()), Immediate(tags)); |
| 1168 | 1180 |
| 1169 // Initialize the remaining words of the object. | 1181 // Initialize the remaining words of the object. |
| 1170 const Immediate raw_null = | 1182 const Immediate raw_null = |
| 1171 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 1183 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 1172 | 1184 |
| 1173 // EAX: new object start. | 1185 // EAX: new object start. |
| 1174 // EBX: next object start. | 1186 // EBX: next object start. |
| 1175 // EDX: class of the object to be allocated. | 1187 // EDX: class of the object to be allocated. |
| 1176 // First try inlining the initialization without a loop. | 1188 // First try inlining the initialization without a loop. |
| 1177 if (instance_size < (kInlineInstanceSize * kWordSize) && | 1189 if (instance_size < (kInlineInstanceSize * kWordSize) && |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1306 // Successfully allocated the object, now update top to point to | 1318 // Successfully allocated the object, now update top to point to |
| 1307 // next object start and initialize the object. | 1319 // next object start and initialize the object. |
| 1308 __ movl(Address::Absolute(heap->TopAddress()), EBX); | 1320 __ movl(Address::Absolute(heap->TopAddress()), EBX); |
| 1309 | 1321 |
| 1310 // Initialize the class field in the object. | 1322 // Initialize the class field in the object. |
| 1311 // EAX: new closure object. | 1323 // EAX: new closure object. |
| 1312 // ECX: new context object (only if is_implicit_closure). | 1324 // ECX: new context object (only if is_implicit_closure). |
| 1313 __ LoadObject(EDX, cls); // Load signature class of closure. | 1325 __ LoadObject(EDX, cls); // Load signature class of closure. |
| 1314 __ movl(Address(EAX, Closure::class_offset()), EDX); | 1326 __ movl(Address(EAX, Closure::class_offset()), EDX); |
| 1315 // Set the tags. | 1327 // Set the tags. |
| 1316 __ movl(Address(EAX, 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 __ movl(Address(EAX, Closure::tags_offset()), Immediate(tags)); |
| 1318 | 1332 |
| 1319 // Initialize the function field in the object. | 1333 // Initialize the function field in the object. |
| 1320 // EAX: new closure object. | 1334 // EAX: new closure object. |
| 1321 // ECX: new context object (only if is_implicit_closure). | 1335 // ECX: new context object (only if is_implicit_closure). |
| 1322 // EBX: next object start. | 1336 // EBX: next object start. |
| 1323 __ LoadObject(EDX, func); // Load function of closure to be allocated. | 1337 __ LoadObject(EDX, func); // Load function of closure to be allocated. |
| 1324 __ movl(Address(EAX, Closure::function_offset()), EDX); | 1338 __ movl(Address(EAX, Closure::function_offset()), EDX); |
| 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(EDX, empty_context); | 1346 __ LoadObject(EDX, empty_context); |
| 1333 __ movl(Address(EAX, Closure::context_offset()), EDX); | 1347 __ movl(Address(EAX, Closure::context_offset()), EDX); |
| 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(EBX, Class::ZoneHandle(Object::context_class())); | 1352 const Class& context_class = Class::ZoneHandle(Object::context_class()); |
| 1353 __ LoadObject(EBX, context_class); |
| 1339 __ movl(Address(ECX, Context::class_offset()), EBX); | 1354 __ movl(Address(ECX, Context::class_offset()), EBX); |
| 1340 // Set the tags. | 1355 // Set the tags. |
| 1341 __ movl(Address(ECX, 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 __ movl(Address(ECX, 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 __ movl(Address(ECX, Context::num_variables_offset()), Immediate(1)); | 1362 __ movl(Address(ECX, 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 __ movl(EDX, FieldAddress(CTX, Context::isolate_offset())); | 1365 __ movl(EDX, FieldAddress(CTX, Context::isolate_offset())); |
| 1349 __ movl(Address(ECX, Context::isolate_offset()), EDX); | 1366 __ movl(Address(ECX, Context::isolate_offset()), EDX); |
| 1350 | 1367 |
| 1351 // Set the parent field to null. | 1368 // Set the parent field to null. |
| 1352 __ movl(Address(ECX, Context::parent_offset()), raw_null); | 1369 __ movl(Address(ECX, Context::parent_offset()), raw_null); |
| (...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1793 __ j(EQUAL, ¬_found, Assembler::kNearJump); | 1810 __ j(EQUAL, ¬_found, Assembler::kNearJump); |
| 1794 __ movl(ECX, FieldAddress(ECX, Type::type_class_offset())); | 1811 __ movl(ECX, FieldAddress(ECX, Type::type_class_offset())); |
| 1795 __ cmpl(EDX, ECX); | 1812 __ cmpl(EDX, ECX); |
| 1796 __ j(NOT_EQUAL, &super_loop, Assembler::kNearJump); | 1813 __ j(NOT_EQUAL, &super_loop, Assembler::kNearJump); |
| 1797 __ jmp(&found, Assembler::kNearJump); | 1814 __ jmp(&found, Assembler::kNearJump); |
| 1798 } | 1815 } |
| 1799 | 1816 |
| 1800 } // namespace dart | 1817 } // namespace dart |
| 1801 | 1818 |
| 1802 #endif // defined TARGET_ARCH_IA32 | 1819 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |