Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(914)

Side by Side Diff: runtime/vm/stub_code_ia32.cc

Issue 10450014: Request for comments on overall approach. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: fix scavenger and freelist handling Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/assembler.h" 8 #include "vm/assembler.h"
9 #include "vm/assembler_macros.h" 9 #include "vm/assembler_macros.h"
10 #include "vm/code_generator.h" 10 #include "vm/code_generator.h"
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after
288 // Total number of args is the first Smi in args descriptor array (EDX). 288 // Total number of args is the first Smi in args descriptor array (EDX).
289 __ movl(EAX, FieldAddress(EDX, Array::data_offset())); 289 __ movl(EAX, FieldAddress(EDX, Array::data_offset()));
290 __ movl(EAX, Address(ESP, EAX, TIMES_2, 0)); // Get receiver. EAX is a Smi. 290 __ movl(EAX, Address(ESP, EAX, TIMES_2, 0)); // Get receiver. EAX is a Smi.
291 // TODO(srdjan): Remove the special casing below for null receiver, once 291 // TODO(srdjan): Remove the special casing below for null receiver, once
292 // NullClass is implemented. 292 // NullClass is implemented.
293 __ cmpl(EAX, raw_null); 293 __ cmpl(EAX, raw_null);
294 // Use Object class if receiver is null. 294 // Use Object class if receiver is null.
295 __ j(EQUAL, &null_receiver, Assembler::kNearJump); 295 __ j(EQUAL, &null_receiver, Assembler::kNearJump);
296 __ testl(EAX, Immediate(kSmiTagMask)); 296 __ testl(EAX, Immediate(kSmiTagMask));
297 __ j(ZERO, &smi_receiver, Assembler::kNearJump); 297 __ j(ZERO, &smi_receiver, Assembler::kNearJump);
298 __ movl(EAX, FieldAddress(EAX, Object::class_offset())); 298 __ GetClassOf(EAX, EAX, EDI);
299 __ jmp(&class_in_eax, Assembler::kNearJump); 299 __ jmp(&class_in_eax, Assembler::kNearJump);
300 __ Bind(&smi_receiver); 300 __ Bind(&smi_receiver);
301 // For Smis we need to get the class from the isolate. 301 // For Smis we need to get the class from the isolate.
302 // Load current Isolate pointer from Context structure into EAX. 302 // Load current Isolate pointer from Context structure into EAX.
303 __ movl(EAX, FieldAddress(CTX, Context::isolate_offset())); 303 __ movl(EAX, FieldAddress(CTX, Context::isolate_offset()));
304 __ movl(EAX, Address(EAX, Isolate::object_store_offset())); 304 __ movl(EAX, Address(EAX, Isolate::object_store_offset()));
305 __ movl(EAX, Address(EAX, ObjectStore::smi_class_offset())); 305 __ movl(EAX, Address(EAX, ObjectStore::smi_class_offset()));
306 __ jmp(&class_in_eax, Assembler::kNearJump); 306 __ jmp(&class_in_eax, Assembler::kNearJump);
307 __ Bind(&null_receiver); 307 __ Bind(&null_receiver);
308 __ movl(EAX, FieldAddress(CTX, Context::isolate_offset())); 308 __ movl(EAX, FieldAddress(CTX, Context::isolate_offset()));
(...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after
666 // Store the type argument field. 666 // Store the type argument field.
667 __ StoreIntoObject(EAX, 667 __ StoreIntoObject(EAX,
668 FieldAddress(EAX, Array::type_arguments_offset()), 668 FieldAddress(EAX, Array::type_arguments_offset()),
669 ECX); 669 ECX);
670 670
671 // Set the length field. 671 // Set the length field.
672 __ StoreIntoObject(EAX, 672 __ StoreIntoObject(EAX,
673 FieldAddress(EAX, Array::length_offset()), 673 FieldAddress(EAX, Array::length_offset()),
674 EDX); 674 EDX);
675 675
676 // EAX: new object start as a tagged pointer.
677 // EBX: new object end address.
678 // EDX: Array length as Smi.
679 // Store class value for array.
680 __ movl(ECX, FieldAddress(CTX, Context::isolate_offset()));
681 __ movl(ECX, Address(ECX, Isolate::object_store_offset()));
682 __ movl(ECX, Address(ECX, ObjectStore::array_class_offset()));
683 __ StoreIntoObject(EAX,
684 FieldAddress(EAX, Array::class_offset()),
685 ECX);
686 // Calculate the size tag. 676 // Calculate the size tag.
687 // EAX: new object start as a tagged pointer. 677 // EAX: new object start as a tagged pointer.
688 // EBX: new object end address. 678 // EBX: new object end address.
689 // EDX: Array length as Smi. 679 // EDX: Array length as Smi.
690 { 680 {
691 Label size_tag_overflow, done; 681 Label size_tag_overflow, done;
692 __ leal(ECX, Address(EDX, TIMES_2, fixed_size)); // EDX is Smi. 682 __ leal(ECX, Address(EDX, TIMES_2, fixed_size)); // EDX is Smi.
693 ASSERT(kSmiTagShift == 1); 683 ASSERT(kSmiTagShift == 1);
694 __ andl(ECX, Immediate(-kObjectAlignment)); 684 __ andl(ECX, Immediate(-kObjectAlignment));
695 __ cmpl(ECX, Immediate(RawObject::SizeTag::kMaxSizeTag)); 685 __ cmpl(ECX, Immediate(RawObject::SizeTag::kMaxSizeTag));
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
765 755
766 // Verify that EDI is a closure by checking its class. 756 // Verify that EDI is a closure by checking its class.
767 Label not_closure; 757 Label not_closure;
768 __ cmpl(EDI, raw_null); 758 __ cmpl(EDI, raw_null);
769 // Not a closure, but null object. 759 // Not a closure, but null object.
770 __ j(EQUAL, &not_closure, Assembler::kNearJump); 760 __ j(EQUAL, &not_closure, Assembler::kNearJump);
771 __ testl(EDI, Immediate(kSmiTagMask)); 761 __ testl(EDI, Immediate(kSmiTagMask));
772 __ j(ZERO, &not_closure, Assembler::kNearJump); // Not a closure, but a smi. 762 __ j(ZERO, &not_closure, Assembler::kNearJump); // Not a closure, but a smi.
773 // Verify that the class of the object is a closure class by checking that 763 // Verify that the class of the object is a closure class by checking that
774 // class.signature_function() is not null. 764 // class.signature_function() is not null.
775 __ movl(EAX, FieldAddress(EDI, Object::class_offset())); 765 __ GetClassOf(EAX, EDI, ECX);
776 __ movl(EAX, FieldAddress(EAX, Class::signature_function_offset())); 766 __ movl(EAX, FieldAddress(EAX, Class::signature_function_offset()));
777 __ cmpl(EAX, raw_null); 767 __ cmpl(EAX, raw_null);
778 // Actual class is not a closure class. 768 // Actual class is not a closure class.
779 __ j(EQUAL, &not_closure, Assembler::kNearJump); 769 __ j(EQUAL, &not_closure, Assembler::kNearJump);
780 770
781 // EAX is just the signature function. Load the actual closure function. 771 // EAX is just the signature function. Load the actual closure function.
782 __ movl(ECX, FieldAddress(EDI, Closure::function_offset())); 772 __ movl(ECX, FieldAddress(EDI, Closure::function_offset()));
783 773
784 // Load closure context in CTX; note that CTX has already been preserved. 774 // Load closure context in CTX; note that CTX has already been preserved.
785 __ movl(CTX, FieldAddress(EDI, Closure::context_offset())); 775 __ movl(CTX, FieldAddress(EDI, Closure::context_offset()));
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
997 } 987 }
998 988
999 // Successfully allocated the object, now update top to point to 989 // Successfully allocated the object, now update top to point to
1000 // next object start and initialize the object. 990 // next object start and initialize the object.
1001 // EAX: new object. 991 // EAX: new object.
1002 // EBX: next object start. 992 // EBX: next object start.
1003 // EDX: number of context variables. 993 // EDX: number of context variables.
1004 __ movl(Address::Absolute(heap->TopAddress()), EBX); 994 __ movl(Address::Absolute(heap->TopAddress()), EBX);
1005 __ addl(EAX, Immediate(kHeapObjectTag)); 995 __ addl(EAX, Immediate(kHeapObjectTag));
1006 996
1007 // Initialize the class field in the context object.
1008 // EAX: new object.
1009 // EDX: number of context variables.
1010 __ LoadObject(EBX, context_class); // Load up class field of context.
1011 __ StoreIntoObject(EAX,
1012 FieldAddress(EAX, Context::class_offset()),
1013 EBX);
1014 // Calculate the size tag. 997 // Calculate the size tag.
1015 // EAX: new object. 998 // EAX: new object.
1016 // EDX: number of context variables. 999 // EDX: number of context variables.
1017 { 1000 {
1018 Label size_tag_overflow, done; 1001 Label size_tag_overflow, done;
1019 __ leal(EBX, Address(EDX, TIMES_4, fixed_size)); 1002 __ leal(EBX, Address(EDX, TIMES_4, fixed_size));
1020 __ andl(EBX, Immediate(-kObjectAlignment)); 1003 __ andl(EBX, Immediate(-kObjectAlignment));
1021 __ cmpl(EBX, Immediate(RawObject::SizeTag::kMaxSizeTag)); 1004 __ cmpl(EBX, Immediate(RawObject::SizeTag::kMaxSizeTag));
1022 __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump); 1005 __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump);
1023 __ shll(EBX, Immediate(RawObject::kSizeTagBit - kObjectAlignmentLog2)); 1006 __ shll(EBX, Immediate(RawObject::kSizeTagBit - kObjectAlignmentLog2));
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
1162 // Initialize InstantiatedTypeArguments object at ECX. 1145 // Initialize InstantiatedTypeArguments object at ECX.
1163 __ movl(Address(ECX, 1146 __ movl(Address(ECX,
1164 InstantiatedTypeArguments::uninstantiated_type_arguments_offset()), 1147 InstantiatedTypeArguments::uninstantiated_type_arguments_offset()),
1165 EDI); 1148 EDI);
1166 __ movl(EDX, Address(ESP, kInstantiatorTypeArgumentsOffset)); 1149 __ movl(EDX, Address(ESP, kInstantiatorTypeArgumentsOffset));
1167 __ movl(Address(ECX, 1150 __ movl(Address(ECX,
1168 InstantiatedTypeArguments::instantiator_type_arguments_offset()), 1151 InstantiatedTypeArguments::instantiator_type_arguments_offset()),
1169 EDX); 1152 EDX);
1170 const Class& ita_cls = 1153 const Class& ita_cls =
1171 Class::ZoneHandle(Object::instantiated_type_arguments_class()); 1154 Class::ZoneHandle(Object::instantiated_type_arguments_class());
1172 __ LoadObject(EDX, ita_cls);
1173 __ movl(Address(ECX, Instance::class_offset()), EDX); // Set its class.
1174 // Set the tags. 1155 // Set the tags.
1175 uword tags = 0; 1156 uword tags = 0;
1176 tags = RawObject::SizeTag::update(type_args_size, tags); 1157 tags = RawObject::SizeTag::update(type_args_size, tags);
1177 tags = RawObject::ClassTag::update(ita_cls.index(), tags); 1158 tags = RawObject::ClassTag::update(ita_cls.index(), tags);
1178 __ movl(Address(ECX, Instance::tags_offset()), Immediate(tags)); 1159 __ movl(Address(ECX, Instance::tags_offset()), Immediate(tags));
1179 // Set the new InstantiatedTypeArguments object (ECX) as the type 1160 // Set the new InstantiatedTypeArguments object (ECX) as the type
1180 // arguments (EDI) of the new object (EAX). 1161 // arguments (EDI) of the new object (EAX).
1181 __ movl(EDI, ECX); 1162 __ movl(EDI, ECX);
1182 __ addl(EDI, Immediate(kHeapObjectTag)); 1163 __ addl(EDI, Immediate(kHeapObjectTag));
1183 // Set EBX to new object end. 1164 // Set EBX to new object end.
1184 __ movl(EBX, ECX); 1165 __ movl(EBX, ECX);
1185 __ Bind(&type_arguments_ready); 1166 __ Bind(&type_arguments_ready);
1186 // EAX: new object. 1167 // EAX: new object.
1187 // EDI: new object type arguments. 1168 // EDI: new object type arguments.
1188 } 1169 }
1189 1170
1190 // Initialize the class field in the object. 1171 // Initialize the class field in the object.
1191 // EAX: new object start. 1172 // EAX: new object start.
1192 // EBX: next object start. 1173 // EBX: next object start.
1193 // EDI: new object type arguments (if is_cls_parameterized). 1174 // EDI: new object type arguments (if is_cls_parameterized).
1194 __ LoadObject(EDX, cls); // Load class of object to be allocated. 1175 __ LoadObject(EDX, cls); // Load class of object to be allocated.
1195 __ movl(Address(EAX, Instance::class_offset()), EDX);
1196 // Set the tags. 1176 // Set the tags.
1197 uword tags = 0; 1177 uword tags = 0;
1198 tags = RawObject::SizeTag::update(instance_size, tags); 1178 tags = RawObject::SizeTag::update(instance_size, tags);
1199 ASSERT(cls.index() != kIllegalObjectKind); 1179 ASSERT(cls.index() != kIllegalObjectKind);
1200 tags = RawObject::ClassTag::update(cls.index(), tags); 1180 tags = RawObject::ClassTag::update(cls.index(), tags);
1201 __ movl(Address(EAX, Instance::tags_offset()), Immediate(tags)); 1181 __ movl(Address(EAX, Instance::tags_offset()), Immediate(tags));
1202 1182
1203 // Initialize the remaining words of the object. 1183 // Initialize the remaining words of the object.
1204 const Immediate raw_null = 1184 const Immediate raw_null =
1205 Immediate(reinterpret_cast<intptr_t>(Object::null())); 1185 Immediate(reinterpret_cast<intptr_t>(Object::null()));
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
1335 if (FLAG_use_slow_path) { 1315 if (FLAG_use_slow_path) {
1336 __ jmp(&slow_case); 1316 __ jmp(&slow_case);
1337 } else { 1317 } else {
1338 __ j(ABOVE_EQUAL, &slow_case, Assembler::kNearJump); 1318 __ j(ABOVE_EQUAL, &slow_case, Assembler::kNearJump);
1339 } 1319 }
1340 1320
1341 // Successfully allocated the object, now update top to point to 1321 // Successfully allocated the object, now update top to point to
1342 // next object start and initialize the object. 1322 // next object start and initialize the object.
1343 __ movl(Address::Absolute(heap->TopAddress()), EBX); 1323 __ movl(Address::Absolute(heap->TopAddress()), EBX);
1344 1324
1345 // Initialize the class field in the object.
1346 // EAX: new closure object. 1325 // EAX: new closure object.
1347 // ECX: new context object (only if is_implicit_closure). 1326 // ECX: new context object (only if is_implicit_closure).
1348 __ LoadObject(EDX, cls); // Load signature class of closure.
1349 __ movl(Address(EAX, Closure::class_offset()), EDX);
1350 // Set the tags. 1327 // Set the tags.
1351 uword tags = 0; 1328 uword tags = 0;
1352 tags = RawObject::SizeTag::update(closure_size, tags); 1329 tags = RawObject::SizeTag::update(closure_size, tags);
1353 tags = RawObject::ClassTag::update(cls.index(), tags); 1330 tags = RawObject::ClassTag::update(cls.index(), tags);
1354 __ movl(Address(EAX, Closure::tags_offset()), Immediate(tags)); 1331 __ movl(Address(EAX, Closure::tags_offset()), Immediate(tags));
1355 1332
1356 // Initialize the function field in the object. 1333 // Initialize the function field in the object.
1357 // EAX: new closure object. 1334 // EAX: new closure object.
1358 // ECX: new context object (only if is_implicit_closure). 1335 // ECX: new context object (only if is_implicit_closure).
1359 // EBX: next object start. 1336 // EBX: next object start.
1360 __ LoadObject(EDX, func); // Load function of closure to be allocated. 1337 __ LoadObject(EDX, func); // Load function of closure to be allocated.
1361 __ movl(Address(EAX, Closure::function_offset()), EDX); 1338 __ movl(Address(EAX, Closure::function_offset()), EDX);
1362 1339
1363 // Setup the context for this closure. 1340 // Setup the context for this closure.
1364 if (is_implicit_static_closure) { 1341 if (is_implicit_static_closure) {
1365 ObjectStore* object_store = Isolate::Current()->object_store(); 1342 ObjectStore* object_store = Isolate::Current()->object_store();
1366 ASSERT(object_store != NULL); 1343 ASSERT(object_store != NULL);
1367 const Context& empty_context = 1344 const Context& empty_context =
1368 Context::ZoneHandle(object_store->empty_context()); 1345 Context::ZoneHandle(object_store->empty_context());
1369 __ LoadObject(EDX, empty_context); 1346 __ LoadObject(EDX, empty_context);
1370 __ movl(Address(EAX, Closure::context_offset()), EDX); 1347 __ movl(Address(EAX, Closure::context_offset()), EDX);
1371 } else if (is_implicit_instance_closure) { 1348 } else if (is_implicit_instance_closure) {
1372 // Initialize the new context capturing the receiver. 1349 // Initialize the new context capturing the receiver.
1373 1350
1374 // Set the class field to the Context class.
1375 const Class& context_class = Class::ZoneHandle(Object::context_class()); 1351 const Class& context_class = Class::ZoneHandle(Object::context_class());
1376 __ LoadObject(EBX, context_class);
1377 __ movl(Address(ECX, Context::class_offset()), EBX);
1378 // Set the tags. 1352 // Set the tags.
1379 uword tags = 0; 1353 uword tags = 0;
1380 tags = RawObject::SizeTag::update(context_size, tags); 1354 tags = RawObject::SizeTag::update(context_size, tags);
1381 tags = RawObject::ClassTag::update(context_class.index(), tags); 1355 tags = RawObject::ClassTag::update(context_class.index(), tags);
1382 __ movl(Address(ECX, Context::tags_offset()), Immediate(tags)); 1356 __ movl(Address(ECX, Context::tags_offset()), Immediate(tags));
1383 1357
1384 // Set number of variables field to 1 (for captured receiver). 1358 // Set number of variables field to 1 (for captured receiver).
1385 __ movl(Address(ECX, Context::num_variables_offset()), Immediate(1)); 1359 __ movl(Address(ECX, Context::num_variables_offset()), Immediate(1));
1386 1360
1387 // Set isolate field to isolate of current context. 1361 // Set isolate field to isolate of current context.
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
1569 __ Bind(&not_yet_hot); 1543 __ Bind(&not_yet_hot);
1570 } 1544 }
1571 1545
1572 ASSERT(num_args > 0); 1546 ASSERT(num_args > 0);
1573 // Get receiver (first read number of arguments from argument descriptor array 1547 // Get receiver (first read number of arguments from argument descriptor array
1574 // and then access the receiver from the stack). 1548 // and then access the receiver from the stack).
1575 __ movl(EAX, FieldAddress(EDX, Array::data_offset())); 1549 __ movl(EAX, FieldAddress(EDX, Array::data_offset()));
1576 __ movl(EAX, Address(ESP, EAX, TIMES_2, 0)); // EAX (argument_count) is Smi. 1550 __ movl(EAX, Address(ESP, EAX, TIMES_2, 0)); // EAX (argument_count) is Smi.
1577 1551
1578 Label get_class, ic_miss; 1552 Label get_class, ic_miss;
1579 __ call(&get_class);
1580 // EAX: receiver's class
1581 // ECX: IC data array. 1553 // ECX: IC data array.
1582 1554
1583 #if defined(DEBUG) 1555 #if defined(DEBUG)
1584 { Label ok; 1556 { Label ok;
1585 // Check that the IC data array has NumberOfArgumentsChecked() == num_args. 1557 // Check that the IC data array has NumberOfArgumentsChecked() == num_args.
1586 // 'num_args_tested' is stored as an untagged int. 1558 // 'num_args_tested' is stored as an untagged int.
1587 __ movl(EBX, FieldAddress(ECX, ICData::num_args_tested_offset())); 1559 __ movl(EBX, FieldAddress(ECX, ICData::num_args_tested_offset()));
1588 __ cmpl(EBX, Immediate(num_args)); 1560 __ cmpl(EBX, Immediate(num_args));
1589 __ j(EQUAL, &ok, Assembler::kNearJump); 1561 __ j(EQUAL, &ok, Assembler::kNearJump);
1590 __ Stop("Incorrect stub for IC data"); 1562 __ Stop("Incorrect stub for IC data");
1591 __ Bind(&ok); 1563 __ Bind(&ok);
1592 } 1564 }
1593 #endif // DEBUG 1565 #endif // DEBUG
1594 1566
1595 // Loop that checks if there is an IC data match. 1567 // Loop that checks if there is an IC data match.
1596 // EAX: receiver's class. 1568 // EAX: receiver's class.
1597 // ECX: IC data object (preserved). 1569 // ECX: IC data object (preserved).
1598 __ movl(EBX, FieldAddress(ECX, ICData::ic_data_offset())); 1570 __ movl(EBX, FieldAddress(ECX, ICData::ic_data_offset()));
1599 // EBX: ic_data_array with check entries: classes and target functions. 1571 // EBX: ic_data_array with check entries: classes and target functions.
1600 __ leal(EBX, FieldAddress(EBX, Array::data_offset())); 1572 __ leal(EBX, FieldAddress(EBX, Array::data_offset()));
1601 // EBX: points directly to the first ic data array element. 1573 // EBX: points directly to the first ic data array element.
1602 Label loop, found; 1574 Label loop, found;
1603 if (num_args == 1) { 1575 if (num_args == 1) {
1576 __ call(&get_class);
1577 // EAX: receiver's class
1604 __ Bind(&loop); 1578 __ Bind(&loop);
1605 __ movl(EDI, Address(EBX, 0)); // Get class to check. 1579 __ movl(EDI, Address(EBX, 0)); // Get class to check.
1606 __ cmpl(EAX, EDI); // Match? 1580 __ cmpl(EAX, EDI); // Match?
1607 __ j(EQUAL, &found, Assembler::kNearJump); 1581 __ j(EQUAL, &found, Assembler::kNearJump);
1608 __ addl(EBX, Immediate(kWordSize * 2)); // Next element (class + target). 1582 __ addl(EBX, Immediate(kWordSize * 2)); // Next element (class + target).
1609 __ cmpl(EDI, raw_null); // Done? 1583 __ cmpl(EDI, raw_null); // Done?
1610 __ j(NOT_EQUAL, &loop, Assembler::kNearJump); 1584 __ j(NOT_EQUAL, &loop, Assembler::kNearJump);
1611 } else if (num_args == 2) { 1585 } else if (num_args == 2) {
1612 // EDI: class to check. 1586 // EDI: class to check.
1613 Label no_match; 1587 Label no_match;
1614 __ Bind(&loop); 1588 __ Bind(&loop);
1615 // Get class from IC data to check. 1589 // Get class from IC data to check.
1616 __ movl(EDI, Address(EBX, 0));
1617 // Get receiver using argument descriptor in EDX. 1590 // Get receiver using argument descriptor in EDX.
1618 __ movl(EAX, FieldAddress(EDX, Array::data_offset())); 1591 __ movl(EAX, FieldAddress(EDX, Array::data_offset()));
1619 __ movl(EAX, Address(ESP, EAX, TIMES_2, 0)); // EAX (arg. count) is Smi. 1592 __ movl(EAX, Address(ESP, EAX, TIMES_2, 0)); // EAX (arg. count) is Smi.
1620 __ call(&get_class); 1593 __ call(&get_class);
1594 // TODO(vegorov): is it possible to switch this code to use class ids?
1595 __ movl(EDI, Address(EBX, 0));
1621 __ cmpl(EAX, EDI); // Match? 1596 __ cmpl(EAX, EDI); // Match?
1622 __ j(NOT_EQUAL, &no_match, Assembler::kNearJump); 1597 __ j(NOT_EQUAL, &no_match, Assembler::kNearJump);
1623 // Check second class/argument. 1598 // Check second class/argument.
1624 // Get class from IC data to check. 1599 // Get class from IC data to check.
1625 __ movl(EDI, Address(EBX, kWordSize));
1626 // Get next argument. 1600 // Get next argument.
1627 __ movl(EAX, FieldAddress(EDX, Array::data_offset())); 1601 __ movl(EAX, FieldAddress(EDX, Array::data_offset()));
1628 __ movl(EAX, Address(ESP, EAX, TIMES_2, -kWordSize)); 1602 __ movl(EAX, Address(ESP, EAX, TIMES_2, -kWordSize));
1629 // EAX (argument count) is Smi. 1603 // EAX (argument count) is Smi.
1630 __ call(&get_class); 1604 __ call(&get_class);
1605 __ movl(EDI, Address(EBX, kWordSize));
1631 __ cmpl(EAX, EDI); // Match? 1606 __ cmpl(EAX, EDI); // Match?
1632 __ j(EQUAL, &found, Assembler::kNearJump); 1607 __ j(EQUAL, &found, Assembler::kNearJump);
1633 __ Bind(&no_match); 1608 __ Bind(&no_match);
1634 // Each test entry has (1 + num_args) array elements. 1609 // Each test entry has (1 + num_args) array elements.
1635 __ addl(EBX, Immediate(kWordSize * (1 + num_args))); // Next element. 1610 __ addl(EBX, Immediate(kWordSize * (1 + num_args))); // Next element.
1636 __ cmpl(EDI, raw_null); // Done? 1611 __ cmpl(EDI, raw_null); // Done?
1637 __ j(NOT_EQUAL, &loop, Assembler::kNearJump); 1612 __ j(NOT_EQUAL, &loop, Assembler::kNearJump);
1638 } 1613 }
1639 1614
1640 __ Bind(&ic_miss); 1615 __ Bind(&ic_miss);
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1689 Label not_smi; 1664 Label not_smi;
1690 // Test if Smi -> load Smi class for comparison. 1665 // Test if Smi -> load Smi class for comparison.
1691 __ testl(EAX, Immediate(kSmiTagMask)); 1666 __ testl(EAX, Immediate(kSmiTagMask));
1692 __ j(NOT_ZERO, &not_smi, Assembler::kNearJump); 1667 __ j(NOT_ZERO, &not_smi, Assembler::kNearJump);
1693 const Class& smi_class = 1668 const Class& smi_class =
1694 Class::ZoneHandle(Isolate::Current()->object_store()->smi_class()); 1669 Class::ZoneHandle(Isolate::Current()->object_store()->smi_class());
1695 __ LoadObject(EAX, smi_class); 1670 __ LoadObject(EAX, smi_class);
1696 __ ret(); 1671 __ ret();
1697 1672
1698 __ Bind(&not_smi); 1673 __ Bind(&not_smi);
1699 __ movl(EAX, FieldAddress(EAX, Object::class_offset())); 1674 __ GetClassOf(EAX, EAX, EDI);
1700 __ ret(); 1675 __ ret();
1701 } 1676 }
1702 1677
1703 1678
1704 // Use inline cache data array to invoke the target or continue in inline 1679 // Use inline cache data array to invoke the target or continue in inline
1705 // cache miss handler. Stub for 1-argument check (receiver class). 1680 // cache miss handler. Stub for 1-argument check (receiver class).
1706 // ECX: Inline cache data array 1681 // ECX: Inline cache data array
1707 // EDX: Arguments array 1682 // EDX: Arguments array
1708 // TOS(0): return address 1683 // TOS(0): return address
1709 // Inline cache data array structure: 1684 // Inline cache data array structure:
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
1795 // TOS + 3: SubtypeTestCache. 1770 // TOS + 3: SubtypeTestCache.
1796 // Result in ECX: null -> not found, otherwise result (true or false). 1771 // Result in ECX: null -> not found, otherwise result (true or false).
1797 static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) { 1772 static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) {
1798 ASSERT((1 <= n) && (n <= 3)); 1773 ASSERT((1 <= n) && (n <= 3));
1799 const intptr_t kInstantiatorTypeArgumentsInBytes = 1 * kWordSize; 1774 const intptr_t kInstantiatorTypeArgumentsInBytes = 1 * kWordSize;
1800 const intptr_t kInstanceOffsetInBytes = 2 * kWordSize; 1775 const intptr_t kInstanceOffsetInBytes = 2 * kWordSize;
1801 const intptr_t kCacheOffsetInBytes = 3 * kWordSize; 1776 const intptr_t kCacheOffsetInBytes = 3 * kWordSize;
1802 const Immediate raw_null = 1777 const Immediate raw_null =
1803 Immediate(reinterpret_cast<intptr_t>(Object::null())); 1778 Immediate(reinterpret_cast<intptr_t>(Object::null()));
1804 __ movl(EAX, Address(ESP, kInstanceOffsetInBytes)); 1779 __ movl(EAX, Address(ESP, kInstanceOffsetInBytes));
1805 __ movl(ECX, FieldAddress(EAX, Object::class_offset())); 1780 __ GetClassOf(ECX, EAX, EBX);
1806 // EAX: instance, ECX: instance-class. 1781 // EAX: instance, ECX: instance-class.
1807 // Get instance type arguments 1782 // Get instance type arguments
1808 if (n > 1) { 1783 if (n > 1) {
1809 // Compute instance type arguments into EBX. 1784 // Compute instance type arguments into EBX.
1810 Label has_no_type_arguments; 1785 Label has_no_type_arguments;
1811 __ movl(EBX, raw_null); 1786 __ movl(EBX, raw_null);
1812 __ movl(EDI, FieldAddress(ECX, 1787 __ movl(EDI, FieldAddress(ECX,
1813 Class::type_arguments_instance_field_offset_offset())); 1788 Class::type_arguments_instance_field_offset_offset()));
1814 __ cmpl(EDI, Immediate(Class::kNoTypeArguments)); 1789 __ cmpl(EDI, Immediate(Class::kNoTypeArguments));
1815 __ j(EQUAL, &has_no_type_arguments, Assembler::kNearJump); 1790 __ j(EQUAL, &has_no_type_arguments, Assembler::kNearJump);
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
1891 // TOS + 2: instance. 1866 // TOS + 2: instance.
1892 // TOS + 3: cache array. 1867 // TOS + 3: cache array.
1893 // Result in ECX: null -> not found, otherwise result (true or false). 1868 // Result in ECX: null -> not found, otherwise result (true or false).
1894 void StubCode::GenerateSubtype3TestCacheStub(Assembler* assembler) { 1869 void StubCode::GenerateSubtype3TestCacheStub(Assembler* assembler) {
1895 GenerateSubtypeNTestCacheStub(assembler, 3); 1870 GenerateSubtypeNTestCacheStub(assembler, 3);
1896 } 1871 }
1897 1872
1898 } // namespace dart 1873 } // namespace dart
1899 1874
1900 #endif // defined TARGET_ARCH_IA32 1875 #endif // defined TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698