Chromium Code Reviews| 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/ic_data.h" | 10 #include "vm/ic_data.h" |
| (...skipping 629 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 640 // ECX: array element type. | 640 // ECX: array element type. |
| 641 // EDX: Array length as Smi. | 641 // EDX: Array length as Smi. |
| 642 // EDI: Points to new space object. | 642 // EDI: Points to new space object. |
| 643 __ cmpl(EBX, Address(EDI, Scavenger::end_offset())); | 643 __ cmpl(EBX, Address(EDI, Scavenger::end_offset())); |
| 644 __ j(ABOVE_EQUAL, &slow_case, Assembler::kNearJump); | 644 __ j(ABOVE_EQUAL, &slow_case, Assembler::kNearJump); |
| 645 | 645 |
| 646 // Successfully allocated the object(s), now update top to point to | 646 // Successfully allocated the object(s), now update top to point to |
| 647 // next object start and initialize the object. | 647 // next object start and initialize the object. |
| 648 // EAX: potential new object start. | 648 // EAX: potential new object start. |
| 649 // EBX: potential next object start. | 649 // EBX: potential next object start. |
| 650 // EDX: Array length as Smi. | |
| 650 // EDI: Points to new space object. | 651 // EDI: Points to new space object. |
| 651 __ movl(Address(EDI, Scavenger::top_offset()), EBX); | 652 __ movl(Address(EDI, Scavenger::top_offset()), EBX); |
| 652 __ addl(EAX, Immediate(kHeapObjectTag)); | 653 __ addl(EAX, Immediate(kHeapObjectTag)); |
| 653 | 654 |
| 654 // EAX: new object start as a tagged pointer. | 655 // EAX: new object start as a tagged pointer. |
| 655 // EBX: new object end address. | 656 // EBX: new object end address. |
| 656 // ECX: array element type. | 657 // ECX: array element type. |
| 657 // EDX: Array length as Smi. | 658 // EDX: Array length as Smi. |
| 658 | 659 |
| 659 // Store the type argument field. | 660 // Store the type argument field. |
| 660 __ StoreIntoObject(EAX, | 661 __ StoreIntoObject(EAX, |
| 661 FieldAddress(EAX, Array::type_arguments_offset()), | 662 FieldAddress(EAX, Array::type_arguments_offset()), |
| 662 ECX); | 663 ECX); |
| 663 | 664 |
| 664 // Set the length field. | 665 // Set the length field. |
| 665 __ StoreIntoObject(EAX, | 666 __ StoreIntoObject(EAX, |
| 666 FieldAddress(EAX, Array::length_offset()), | 667 FieldAddress(EAX, Array::length_offset()), |
| 667 EDX); | 668 EDX); |
| 668 | 669 |
| 670 // EAX: new object start as a tagged pointer. | |
| 671 // EBX: new object end address. | |
| 672 // EDX: Array length as Smi. | |
| 669 // Store class value for array. | 673 // Store class value for array. |
| 670 __ movl(ECX, FieldAddress(CTX, Context::isolate_offset())); | 674 __ movl(ECX, FieldAddress(CTX, Context::isolate_offset())); |
| 671 __ movl(ECX, Address(ECX, Isolate::object_store_offset())); | 675 __ movl(ECX, Address(ECX, Isolate::object_store_offset())); |
| 672 __ movl(ECX, Address(ECX, ObjectStore::array_class_offset())); | 676 __ movl(ECX, Address(ECX, ObjectStore::array_class_offset())); |
| 673 __ StoreIntoObject(EAX, | 677 __ StoreIntoObject(EAX, |
| 674 FieldAddress(EAX, Array::class_offset()), | 678 FieldAddress(EAX, Array::class_offset()), |
| 675 ECX); | 679 ECX); |
| 676 __ movl(FieldAddress(EAX, Array::tags_offset()), Immediate(0)); // Tags. | 680 // Calculate the size tag. |
| 681 // EAX: new object start as a tagged pointer. | |
| 682 // EBX: new object end address. | |
| 683 // EDX: Array length as Smi. | |
| 684 { | |
| 685 Label size_tag_overflow, done; | |
| 686 __ leal(ECX, Address(EDX, TIMES_2, fixed_size)); // EDX is Smi. | |
| 687 ASSERT(kSmiTagShift == 1); | |
| 688 __ andl(ECX, Immediate(-kObjectAlignment)); | |
| 689 __ cmpl(ECX, | |
| 690 Immediate(RawObject::SizeTag::kMaxSizeTag)); | |
|
siva
2012/01/04 01:56:03
Can't this be in one line?
Ivan Posva
2012/01/04 07:59:42
Done.
| |
| 691 __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump); | |
| 692 __ shll(ECX, Immediate(RawObject::kSizeTagBit - kObjectAlignmentLog2)); | |
| 693 __ movl(FieldAddress(EAX, Array::tags_offset()), ECX); | |
| 694 __ jmp(&done); | |
| 695 | |
| 696 __ Bind(&size_tag_overflow); | |
| 697 __ movl(FieldAddress(EAX, Array::tags_offset()), Immediate(0)); | |
| 698 __ Bind(&done); | |
| 699 } | |
| 677 | 700 |
| 678 // Initialize all array elements to raw_null. | 701 // Initialize all array elements to raw_null. |
| 679 // EAX: new object start as a tagged pointer. | 702 // EAX: new object start as a tagged pointer. |
| 680 // EBX: new object end address. | 703 // EBX: new object end address. |
| 704 // EDX: Array length as Smi. | |
| 705 __ leal(ECX, FieldAddress(EAX, Array::data_offset())); | |
| 681 // ECX: iterator which initially points to the start of the variable | 706 // ECX: iterator which initially points to the start of the variable |
| 682 // data area to be initialized. | 707 // data area to be initialized. |
| 683 __ leal(ECX, FieldAddress(EAX, Array::data_offset())); | |
| 684 Label done; | 708 Label done; |
| 685 Label init_loop; | 709 Label init_loop; |
| 686 __ Bind(&init_loop); | 710 __ Bind(&init_loop); |
| 687 __ cmpl(ECX, EBX); | 711 __ cmpl(ECX, EBX); |
| 688 __ j(ABOVE_EQUAL, &done, Assembler::kNearJump); | 712 __ j(ABOVE_EQUAL, &done, Assembler::kNearJump); |
| 689 __ movl(Address(ECX, 0), raw_null); | 713 __ movl(Address(ECX, 0), raw_null); |
| 690 __ addl(ECX, Immediate(kWordSize)); | 714 __ addl(ECX, Immediate(kWordSize)); |
| 691 __ jmp(&init_loop, Assembler::kNearJump); | 715 __ jmp(&init_loop, Assembler::kNearJump); |
| 692 __ Bind(&done); | 716 __ Bind(&done); |
| 693 | 717 |
| 694 // Done allocating and initializing the array. | 718 // Done allocating and initializing the array. |
| 695 // EAX: new object. | 719 // EAX: new object. |
| 720 // EDX: Array length as Smi (preserved for the caller.) | |
| 696 __ ret(); | 721 __ ret(); |
| 697 } | 722 } |
| 698 | 723 |
| 699 // Unable to allocate the array using the fast inline code, just call | 724 // Unable to allocate the array using the fast inline code, just call |
| 700 // into the runtime. | 725 // into the runtime. |
| 701 __ Bind(&slow_case); | 726 __ Bind(&slow_case); |
| 702 __ EnterFrame(0); | 727 __ EnterFrame(0); |
| 703 __ pushl(raw_null); // Setup space on stack for return value. | 728 __ pushl(raw_null); // Setup space on stack for return value. |
| 704 __ pushl(EDX); // Array length as Smi. | 729 __ pushl(EDX); // Array length as Smi. |
| 705 __ pushl(ECX); // Element type. | 730 __ pushl(ECX); // Element type. |
| (...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 970 __ movl(Address::Absolute(heap->TopAddress()), EBX); | 995 __ movl(Address::Absolute(heap->TopAddress()), EBX); |
| 971 __ addl(EAX, Immediate(kHeapObjectTag)); | 996 __ addl(EAX, Immediate(kHeapObjectTag)); |
| 972 | 997 |
| 973 // Initialize the class field in the context object. | 998 // Initialize the class field in the context object. |
| 974 // EAX: new object. | 999 // EAX: new object. |
| 975 // EDX: number of context variables. | 1000 // EDX: number of context variables. |
| 976 __ LoadObject(EBX, context_class); // Load up class field of context. | 1001 __ LoadObject(EBX, context_class); // Load up class field of context. |
| 977 __ StoreIntoObject(EAX, | 1002 __ StoreIntoObject(EAX, |
| 978 FieldAddress(EAX, Context::class_offset()), | 1003 FieldAddress(EAX, Context::class_offset()), |
| 979 EBX); | 1004 EBX); |
| 980 __ movl(FieldAddress(EAX, Context::tags_offset()), Immediate(0)); // Tags. | 1005 // Calculate the size tag. |
| 1006 // EAX: new object. | |
| 1007 // EDX: number of context variables. | |
| 1008 { | |
| 1009 Label size_tag_overflow, done; | |
| 1010 __ leal(EBX, Address(EDX, TIMES_4, fixed_size)); | |
| 1011 __ andl(EBX, Immediate(-kObjectAlignment)); | |
| 1012 __ cmpl(EBX, | |
| 1013 Immediate(RawObject::SizeTag::kMaxSizeTag)); | |
|
siva
2012/01/04 01:56:03
Can't this be in one line?
Ivan Posva
2012/01/04 07:59:42
Done.
| |
| 1014 __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump); | |
| 1015 __ shll(EBX, Immediate(RawObject::kSizeTagBit - kObjectAlignmentLog2)); | |
| 1016 __ movl(FieldAddress(EAX, Context::tags_offset()), EBX); // Tags. | |
| 1017 __ jmp(&done); | |
| 1018 | |
| 1019 __ Bind(&size_tag_overflow); | |
| 1020 // Set overflow size tag value. | |
| 1021 __ movl(FieldAddress(EAX, Context::tags_offset()), Immediate(0)); | |
| 1022 __ Bind(&done); | |
|
siva
2012/01/04 01:56:03
Can this piece of code which is repeated here and
Ivan Posva
2012/01/04 07:59:42
We should evaluate that once we are done with sett
| |
| 1023 } | |
| 981 | 1024 |
| 982 // Setup up number of context variables field. | 1025 // Setup up number of context variables field. |
| 983 // EAX: new object. | 1026 // EAX: new object. |
| 984 // EDX: number of context variables as integer value (not object). | 1027 // EDX: number of context variables as integer value (not object). |
| 985 __ movl(FieldAddress(EAX, Context::num_variables_offset()), EDX); | 1028 __ movl(FieldAddress(EAX, Context::num_variables_offset()), EDX); |
| 986 | 1029 |
| 987 // Setup isolate field. | 1030 // Setup isolate field. |
| 988 // Load Isolate pointer from Context structure into EBX. | 1031 // Load Isolate pointer from Context structure into EBX. |
| 989 // EAX: new object. | 1032 // EAX: new object. |
| 990 // EDX: number of context variables. | 1033 // EDX: number of context variables. |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1104 __ movl(Address(ECX, | 1147 __ movl(Address(ECX, |
| 1105 InstantiatedTypeArguments::uninstantiated_type_arguments_offset()), | 1148 InstantiatedTypeArguments::uninstantiated_type_arguments_offset()), |
| 1106 EDI); | 1149 EDI); |
| 1107 __ movl(EDX, Address(ESP, kInstantiatorTypeArgumentsOffset)); | 1150 __ movl(EDX, Address(ESP, kInstantiatorTypeArgumentsOffset)); |
| 1108 __ movl(Address(ECX, | 1151 __ movl(Address(ECX, |
| 1109 InstantiatedTypeArguments::instantiator_type_arguments_offset()), | 1152 InstantiatedTypeArguments::instantiator_type_arguments_offset()), |
| 1110 EDX); | 1153 EDX); |
| 1111 __ LoadObject(EDX, | 1154 __ LoadObject(EDX, |
| 1112 Class::ZoneHandle(Object::instantiated_type_arguments_class())); | 1155 Class::ZoneHandle(Object::instantiated_type_arguments_class())); |
| 1113 __ movl(Address(ECX, Instance::class_offset()), EDX); // Set its class. | 1156 __ movl(Address(ECX, Instance::class_offset()), EDX); // Set its class. |
| 1114 __ movl(Address(ECX, Instance::tags_offset()), Immediate(0)); // Tags. | 1157 // Set the tags. |
|
siva
2012/01/04 01:56:03
ASSERT(type_args_size <= RawObject::SizeTag::kMaxS
Ivan Posva
2012/01/04 07:59:42
ditto
| |
| 1158 __ movl(Address(ECX, Instance::tags_offset()), | |
| 1159 Immediate(RawObject::SizeTag::encode(type_args_size))); | |
| 1115 // Set the new InstantiatedTypeArguments object (ECX) as the type | 1160 // Set the new InstantiatedTypeArguments object (ECX) as the type |
| 1116 // arguments (EDI) of the new object (EAX). | 1161 // arguments (EDI) of the new object (EAX). |
| 1117 __ movl(EDI, ECX); | 1162 __ movl(EDI, ECX); |
| 1118 __ addl(EDI, Immediate(kHeapObjectTag)); | 1163 __ addl(EDI, Immediate(kHeapObjectTag)); |
| 1119 // Set EBX to new object end. | 1164 // Set EBX to new object end. |
| 1120 __ movl(EBX, ECX); | 1165 __ movl(EBX, ECX); |
| 1121 __ Bind(&type_arguments_ready); | 1166 __ Bind(&type_arguments_ready); |
| 1122 // EAX: new object. | 1167 // EAX: new object. |
| 1123 // EDI: new object type arguments. | 1168 // EDI: new object type arguments. |
| 1124 } | 1169 } |
| 1125 | 1170 |
| 1126 // Initialize the class field in the object. | 1171 // Initialize the class field in the object. |
| 1127 // EAX: new object start. | 1172 // EAX: new object start. |
| 1128 // EBX: next object start. | 1173 // EBX: next object start. |
| 1129 // EDI: new object type arguments (if is_cls_parameterized). | 1174 // EDI: new object type arguments (if is_cls_parameterized). |
| 1130 __ LoadObject(EDX, cls); // Load class of object to be allocated. | 1175 __ LoadObject(EDX, cls); // Load class of object to be allocated. |
| 1131 __ movl(Address(EAX, Instance::class_offset()), EDX); | 1176 __ movl(Address(EAX, Instance::class_offset()), EDX); |
| 1132 __ movl(Address(EAX, Instance::tags_offset()), Immediate(0)); // Tags. | 1177 // Set the tags. |
|
siva
2012/01/04 01:56:03
ASSERT(instance_size <= RawObject::SizeTag::kMaxSi
Ivan Posva
2012/01/04 07:59:42
ditto
| |
| 1178 __ movl(Address(EAX, Instance::tags_offset()), | |
| 1179 Immediate(RawObject::SizeTag::encode(instance_size))); | |
| 1133 | 1180 |
| 1134 // Initialize the remaining words of the object. | 1181 // Initialize the remaining words of the object. |
| 1135 const Immediate raw_null = | 1182 const Immediate raw_null = |
| 1136 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 1183 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 1137 | 1184 |
| 1138 // EAX: new object start. | 1185 // EAX: new object start. |
| 1139 // EBX: next object start. | 1186 // EBX: next object start. |
| 1140 // EDX: class of the object to be allocated. | 1187 // EDX: class of the object to be allocated. |
| 1141 // First try inlining the initialization without a loop. | 1188 // First try inlining the initialization without a loop. |
| 1142 if (instance_size < (kInlineInstanceSize * kWordSize) && | 1189 if (instance_size < (kInlineInstanceSize * kWordSize) && |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1270 | 1317 |
| 1271 // Successfully allocated the object, now update top to point to | 1318 // Successfully allocated the object, now update top to point to |
| 1272 // next object start and initialize the object. | 1319 // next object start and initialize the object. |
| 1273 __ movl(Address::Absolute(heap->TopAddress()), EBX); | 1320 __ movl(Address::Absolute(heap->TopAddress()), EBX); |
| 1274 | 1321 |
| 1275 // Initialize the class field in the object. | 1322 // Initialize the class field in the object. |
| 1276 // EAX: new closure object. | 1323 // EAX: new closure object. |
| 1277 // ECX: new context object (only if is_implicit_closure). | 1324 // ECX: new context object (only if is_implicit_closure). |
| 1278 __ LoadObject(EDX, cls); // Load signature class of closure. | 1325 __ LoadObject(EDX, cls); // Load signature class of closure. |
| 1279 __ movl(Address(EAX, Closure::class_offset()), EDX); | 1326 __ movl(Address(EAX, Closure::class_offset()), EDX); |
| 1280 __ movl(Address(EAX, Closure::tags_offset()), Immediate(0)); // Tags. | 1327 // Set the tags. |
|
siva
2012/01/04 01:56:03
ASSERT(closure_size <= RawObject::SizeTag::kMaxSiz
Ivan Posva
2012/01/04 07:59:42
ditto.
| |
| 1328 __ movl(Address(EAX, Closure::tags_offset()), | |
| 1329 Immediate(RawObject::SizeTag::encode(closure_size))); | |
| 1281 | 1330 |
| 1282 // Initialize the function field in the object. | 1331 // Initialize the function field in the object. |
| 1283 // EAX: new closure object. | 1332 // EAX: new closure object. |
| 1284 // ECX: new context object (only if is_implicit_closure). | 1333 // ECX: new context object (only if is_implicit_closure). |
| 1285 // EBX: next object start. | 1334 // EBX: next object start. |
| 1286 __ LoadObject(EDX, func); // Load function of closure to be allocated. | 1335 __ LoadObject(EDX, func); // Load function of closure to be allocated. |
| 1287 __ movl(Address(EAX, Closure::function_offset()), EDX); | 1336 __ movl(Address(EAX, Closure::function_offset()), EDX); |
| 1288 | 1337 |
| 1289 // Setup the context for this closure. | 1338 // Setup the context for this closure. |
| 1290 if (is_implicit_static_closure) { | 1339 if (is_implicit_static_closure) { |
| 1291 ObjectStore* object_store = Isolate::Current()->object_store(); | 1340 ObjectStore* object_store = Isolate::Current()->object_store(); |
| 1292 ASSERT(object_store != NULL); | 1341 ASSERT(object_store != NULL); |
| 1293 const Context& empty_context = | 1342 const Context& empty_context = |
| 1294 Context::ZoneHandle(object_store->empty_context()); | 1343 Context::ZoneHandle(object_store->empty_context()); |
| 1295 __ LoadObject(EDX, empty_context); | 1344 __ LoadObject(EDX, empty_context); |
| 1296 __ movl(Address(EAX, Closure::context_offset()), EDX); | 1345 __ movl(Address(EAX, Closure::context_offset()), EDX); |
| 1297 } else if (is_implicit_instance_closure) { | 1346 } else if (is_implicit_instance_closure) { |
| 1298 // Initialize the new context capturing the receiver. | 1347 // Initialize the new context capturing the receiver. |
| 1299 | 1348 |
| 1300 // Set the class field to the Context class. | 1349 // Set the class field to the Context class. |
| 1301 __ LoadObject(EBX, Class::ZoneHandle(Object::context_class())); | 1350 __ LoadObject(EBX, Class::ZoneHandle(Object::context_class())); |
| 1302 __ movl(Address(ECX, Context::class_offset()), EBX); | 1351 __ movl(Address(ECX, Context::class_offset()), EBX); |
| 1303 __ movl(Address(ECX, Context::tags_offset()), Immediate(0)); // Tags. | 1352 // Set the tags. |
|
siva
2012/01/04 01:56:03
ASSERT(context_size <= RawObject::SizeTag::kMaxSiz
Ivan Posva
2012/01/04 07:59:42
ditto.
| |
| 1353 __ movl(Address(ECX, Context::tags_offset()), | |
| 1354 Immediate(RawObject::SizeTag::encode(context_size))); | |
| 1304 | 1355 |
| 1305 // Set number of variables field to 1 (for captured receiver). | 1356 // Set number of variables field to 1 (for captured receiver). |
| 1306 __ movl(Address(ECX, Context::num_variables_offset()), Immediate(1)); | 1357 __ movl(Address(ECX, Context::num_variables_offset()), Immediate(1)); |
| 1307 | 1358 |
| 1308 // Set isolate field to isolate of current context. | 1359 // Set isolate field to isolate of current context. |
| 1309 __ movl(EDX, FieldAddress(CTX, Context::isolate_offset())); | 1360 __ movl(EDX, FieldAddress(CTX, Context::isolate_offset())); |
| 1310 __ movl(Address(ECX, Context::isolate_offset()), EDX); | 1361 __ movl(Address(ECX, Context::isolate_offset()), EDX); |
| 1311 | 1362 |
| 1312 // Set the parent field to null. | 1363 // Set the parent field to null. |
| 1313 __ movl(Address(ECX, Context::parent_offset()), raw_null); | 1364 __ movl(Address(ECX, Context::parent_offset()), raw_null); |
| (...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1638 __ popl(EDX); | 1689 __ popl(EDX); |
| 1639 __ popl(ECX); | 1690 __ popl(ECX); |
| 1640 __ LeaveFrame(); | 1691 __ LeaveFrame(); |
| 1641 // Now call the dynamic function. | 1692 // Now call the dynamic function. |
| 1642 __ jmp(&StubCode::OneArgCheckInlineCacheLabel()); | 1693 __ jmp(&StubCode::OneArgCheckInlineCacheLabel()); |
| 1643 } | 1694 } |
| 1644 | 1695 |
| 1645 } // namespace dart | 1696 } // namespace dart |
| 1646 | 1697 |
| 1647 #endif // defined TARGET_ARCH_IA32 | 1698 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |