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

Side by Side Diff: runtime/vm/stub_code_x64.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, 6 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
« runtime/vm/raw_object.cc ('K') | « runtime/vm/stub_code_ia32.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/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 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
287 // Total number of args is the first Smi in args descriptor array (R10). 287 // Total number of args is the first Smi in args descriptor array (R10).
288 __ movq(RAX, FieldAddress(R10, Array::data_offset())); 288 __ movq(RAX, FieldAddress(R10, Array::data_offset()));
289 __ movq(RAX, Address(RSP, RAX, TIMES_4, 0)); // Get receiver. RAX is a Smi. 289 __ movq(RAX, Address(RSP, RAX, TIMES_4, 0)); // Get receiver. RAX is a Smi.
290 // TODO(srdjan): Remove the special casing below for null receiver, once 290 // TODO(srdjan): Remove the special casing below for null receiver, once
291 // NullClass is implemented. 291 // NullClass is implemented.
292 __ cmpq(RAX, raw_null); 292 __ cmpq(RAX, raw_null);
293 // Use Object class if receiver is null. 293 // Use Object class if receiver is null.
294 __ j(EQUAL, &null_receiver, Assembler::kNearJump); 294 __ j(EQUAL, &null_receiver, Assembler::kNearJump);
295 __ testq(RAX, Immediate(kSmiTagMask)); 295 __ testq(RAX, Immediate(kSmiTagMask));
296 __ j(ZERO, &smi_receiver, Assembler::kNearJump); 296 __ j(ZERO, &smi_receiver, Assembler::kNearJump);
297 __ movq(RAX, FieldAddress(RAX, Object::class_offset())); 297 __ GetClassOf(RAX, RAX);
298 __ jmp(&class_in_rax, Assembler::kNearJump); 298 __ jmp(&class_in_rax, Assembler::kNearJump);
299 __ Bind(&smi_receiver); 299 __ Bind(&smi_receiver);
300 // For Smis we need to get the class from the isolate. 300 // For Smis we need to get the class from the isolate.
301 // Load current Isolate pointer from Context structure into RAX. 301 // Load current Isolate pointer from Context structure into RAX.
302 __ movq(RAX, FieldAddress(CTX, Context::isolate_offset())); 302 __ movq(RAX, FieldAddress(CTX, Context::isolate_offset()));
303 __ movq(RAX, Address(RAX, Isolate::object_store_offset())); 303 __ movq(RAX, Address(RAX, Isolate::object_store_offset()));
304 __ movq(RAX, Address(RAX, ObjectStore::smi_class_offset())); 304 __ movq(RAX, Address(RAX, ObjectStore::smi_class_offset()));
305 __ jmp(&class_in_rax, Assembler::kNearJump); 305 __ jmp(&class_in_rax, Assembler::kNearJump);
306 __ Bind(&null_receiver); 306 __ Bind(&null_receiver);
307 __ movq(RAX, FieldAddress(CTX, Context::isolate_offset())); 307 __ movq(RAX, FieldAddress(CTX, Context::isolate_offset()));
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after
658 // R10: Array length as Smi. 658 // R10: Array length as Smi.
659 659
660 // Store the type argument field. 660 // Store the type argument field.
661 __ StoreIntoObject(RAX, 661 __ StoreIntoObject(RAX,
662 FieldAddress(RAX, Array::type_arguments_offset()), 662 FieldAddress(RAX, Array::type_arguments_offset()),
663 RBX); 663 RBX);
664 664
665 // Set the length field. 665 // Set the length field.
666 __ StoreIntoObject(RAX, FieldAddress(RAX, Array::length_offset()), R10); 666 __ StoreIntoObject(RAX, FieldAddress(RAX, Array::length_offset()), R10);
667 667
668 // Store class value for array.
669 __ movq(RBX, FieldAddress(CTX, Context::isolate_offset()));
670 __ movq(RBX, Address(RBX, Isolate::object_store_offset()));
671 __ movq(RBX, Address(RBX, ObjectStore::array_class_offset()));
672 __ StoreIntoObject(RAX, FieldAddress(RAX, Array::class_offset()), RBX);
673 // Calculate the size tag. 668 // Calculate the size tag.
674 // RAX: new object start as a tagged pointer. 669 // RAX: new object start as a tagged pointer.
675 // R12: new object end address. 670 // R12: new object end address.
676 // R10: Array length as Smi. 671 // R10: Array length as Smi.
677 { 672 {
678 Label size_tag_overflow, done; 673 Label size_tag_overflow, done;
679 __ leaq(RBX, Address(R10, TIMES_4, fixed_size)); // R10 is Smi. 674 __ leaq(RBX, Address(R10, TIMES_4, fixed_size)); // R10 is Smi.
680 ASSERT(kSmiTagShift == 1); 675 ASSERT(kSmiTagShift == 1);
681 __ andq(RBX, Immediate(-kObjectAlignment)); 676 __ andq(RBX, Immediate(-kObjectAlignment));
682 __ cmpq(RBX, Immediate(RawObject::SizeTag::kMaxSizeTag)); 677 __ cmpq(RBX, Immediate(RawObject::SizeTag::kMaxSizeTag));
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
748 743
749 // Verify that R13 is a closure by checking its class. 744 // Verify that R13 is a closure by checking its class.
750 Label not_closure; 745 Label not_closure;
751 __ cmpq(R13, raw_null); 746 __ cmpq(R13, raw_null);
752 // Not a closure, but null object. 747 // Not a closure, but null object.
753 __ j(EQUAL, &not_closure, Assembler::kNearJump); 748 __ j(EQUAL, &not_closure, Assembler::kNearJump);
754 __ testq(R13, Immediate(kSmiTagMask)); 749 __ testq(R13, Immediate(kSmiTagMask));
755 __ j(ZERO, &not_closure, Assembler::kNearJump); // Not a closure, but a smi. 750 __ j(ZERO, &not_closure, Assembler::kNearJump); // Not a closure, but a smi.
756 // Verify that the class of the object is a closure class by checking that 751 // Verify that the class of the object is a closure class by checking that
757 // class.signature_function() is not null. 752 // class.signature_function() is not null.
758 __ movq(RAX, FieldAddress(R13, Object::class_offset())); 753 __ GetClassOf(RAX, R13);
759 __ movq(RAX, FieldAddress(RAX, Class::signature_function_offset())); 754 __ movq(RAX, FieldAddress(RAX, Class::signature_function_offset()));
760 __ cmpq(RAX, raw_null); 755 __ cmpq(RAX, raw_null);
761 // Actual class is not a closure class. 756 // Actual class is not a closure class.
762 __ j(EQUAL, &not_closure, Assembler::kNearJump); 757 __ j(EQUAL, &not_closure, Assembler::kNearJump);
763 758
764 // RAX is just the signature function. Load the actual closure function. 759 // RAX is just the signature function. Load the actual closure function.
765 __ movq(RBX, FieldAddress(R13, Closure::function_offset())); 760 __ movq(RBX, FieldAddress(R13, Closure::function_offset()));
766 761
767 // Load closure context in CTX; note that CTX has already been preserved. 762 // Load closure context in CTX; note that CTX has already been preserved.
768 __ movq(CTX, FieldAddress(R13, Closure::context_offset())); 763 __ movq(CTX, FieldAddress(R13, Closure::context_offset()));
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
983 978
984 // Successfully allocated the object, now update top to point to 979 // Successfully allocated the object, now update top to point to
985 // next object start and initialize the object. 980 // next object start and initialize the object.
986 // RAX: new object. 981 // RAX: new object.
987 // R13: next object start. 982 // R13: next object start.
988 // R10: number of context variables. 983 // R10: number of context variables.
989 __ movq(RDI, Immediate(heap->TopAddress())); 984 __ movq(RDI, Immediate(heap->TopAddress()));
990 __ movq(Address(RDI, 0), R13); 985 __ movq(Address(RDI, 0), R13);
991 __ addq(RAX, Immediate(kHeapObjectTag)); 986 __ addq(RAX, Immediate(kHeapObjectTag));
992 987
993 // Initialize the class field in the context object.
994 // RAX: new object.
995 // R10: number of context variables.
996 __ LoadObject(R13, context_class); // Load up class field of context.
997 __ StoreIntoObject(RAX,
998 FieldAddress(RAX, Context::class_offset()),
999 R13);
1000 // Calculate the size tag. 988 // Calculate the size tag.
1001 // RAX: new object. 989 // RAX: new object.
1002 // R10: number of context variables. 990 // R10: number of context variables.
1003 { 991 {
1004 Label size_tag_overflow, done; 992 Label size_tag_overflow, done;
1005 __ leaq(R13, Address(R10, TIMES_8, fixed_size)); 993 __ leaq(R13, Address(R10, TIMES_8, fixed_size));
1006 __ andq(R13, Immediate(-kObjectAlignment)); 994 __ andq(R13, Immediate(-kObjectAlignment));
1007 __ cmpq(R13, Immediate(RawObject::SizeTag::kMaxSizeTag)); 995 __ cmpq(R13, Immediate(RawObject::SizeTag::kMaxSizeTag));
1008 __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump); 996 __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump);
1009 __ shlq(R13, Immediate(RawObject::kSizeTagBit - kObjectAlignmentLog2)); 997 __ shlq(R13, Immediate(RawObject::kSizeTagBit - kObjectAlignmentLog2));
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
1149 // Initialize InstantiatedTypeArguments object at RCX. 1137 // Initialize InstantiatedTypeArguments object at RCX.
1150 __ movq(Address(RCX, 1138 __ movq(Address(RCX,
1151 InstantiatedTypeArguments::uninstantiated_type_arguments_offset()), 1139 InstantiatedTypeArguments::uninstantiated_type_arguments_offset()),
1152 RDI); 1140 RDI);
1153 __ movq(RDX, Address(RSP, kInstantiatorTypeArgumentsOffset)); 1141 __ movq(RDX, Address(RSP, kInstantiatorTypeArgumentsOffset));
1154 __ movq(Address(RCX, 1142 __ movq(Address(RCX,
1155 InstantiatedTypeArguments::instantiator_type_arguments_offset()), 1143 InstantiatedTypeArguments::instantiator_type_arguments_offset()),
1156 RDX); 1144 RDX);
1157 const Class& ita_cls = 1145 const Class& ita_cls =
1158 Class::ZoneHandle(Object::instantiated_type_arguments_class()); 1146 Class::ZoneHandle(Object::instantiated_type_arguments_class());
1159 __ LoadObject(RDX, ita_cls);
1160 __ movq(Address(RCX, Instance::class_offset()), RDX); // Set its class.
1161 // Set the tags. 1147 // Set the tags.
1162 uword tags = 0; 1148 uword tags = 0;
1163 tags = RawObject::SizeTag::update(type_args_size, tags); 1149 tags = RawObject::SizeTag::update(type_args_size, tags);
1164 tags = RawObject::ClassTag::update(ita_cls.index(), tags); 1150 tags = RawObject::ClassTag::update(ita_cls.index(), tags);
1165 __ movq(Address(RCX, Instance::tags_offset()), Immediate(tags)); 1151 __ movq(Address(RCX, Instance::tags_offset()), Immediate(tags));
1166 // Set the new InstantiatedTypeArguments object (RCX) as the type 1152 // Set the new InstantiatedTypeArguments object (RCX) as the type
1167 // arguments (RDI) of the new object (RAX). 1153 // arguments (RDI) of the new object (RAX).
1168 __ movq(RDI, RCX); 1154 __ movq(RDI, RCX);
1169 __ addq(RDI, Immediate(kHeapObjectTag)); 1155 __ addq(RDI, Immediate(kHeapObjectTag));
1170 // Set RBX to new object end. 1156 // Set RBX to new object end.
1171 __ movq(RBX, RCX); 1157 __ movq(RBX, RCX);
1172 __ Bind(&type_arguments_ready); 1158 __ Bind(&type_arguments_ready);
1173 // RAX: new object. 1159 // RAX: new object.
1174 // RDI: new object type arguments. 1160 // RDI: new object type arguments.
1175 } 1161 }
1176 1162
1177 // Initialize the class field in the object.
1178 // RAX: new object start. 1163 // RAX: new object start.
1179 // RBX: next object start. 1164 // RBX: next object start.
1180 // RDI: new object type arguments (if is_cls_parameterized). 1165 // RDI: new object type arguments (if is_cls_parameterized).
1181 __ LoadObject(RDX, cls); // Load class of object to be allocated. 1166 __ LoadObject(RDX, cls); // Load class of object to be allocated.
1182 __ movq(Address(RAX, Instance::class_offset()), RDX);
1183 // Set the tags. 1167 // Set the tags.
1184 uword tags = 0; 1168 uword tags = 0;
1185 tags = RawObject::SizeTag::update(instance_size, tags); 1169 tags = RawObject::SizeTag::update(instance_size, tags);
1186 ASSERT(cls.index() != kIllegalObjectKind); 1170 ASSERT(cls.index() != kIllegalObjectKind);
1187 tags = RawObject::ClassTag::update(cls.index(), tags); 1171 tags = RawObject::ClassTag::update(cls.index(), tags);
1188 __ movq(Address(RAX, Instance::tags_offset()), Immediate(tags)); 1172 __ movq(Address(RAX, Instance::tags_offset()), Immediate(tags));
1189 1173
1190 // Initialize the remaining words of the object. 1174 // Initialize the remaining words of the object.
1191 const Immediate raw_null = 1175 const Immediate raw_null =
1192 Immediate(reinterpret_cast<intptr_t>(Object::null())); 1176 Immediate(reinterpret_cast<intptr_t>(Object::null()));
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
1323 __ jmp(&slow_case); 1307 __ jmp(&slow_case);
1324 } else { 1308 } else {
1325 __ j(ABOVE_EQUAL, &slow_case); 1309 __ j(ABOVE_EQUAL, &slow_case);
1326 } 1310 }
1327 1311
1328 // Successfully allocated the object, now update top to point to 1312 // Successfully allocated the object, now update top to point to
1329 // next object start and initialize the object. 1313 // next object start and initialize the object.
1330 __ movq(RDI, Immediate(heap->TopAddress())); 1314 __ movq(RDI, Immediate(heap->TopAddress()));
1331 __ movq(Address(RDI, 0), R13); 1315 __ movq(Address(RDI, 0), R13);
1332 1316
1333 // Initialize the class field in the object.
1334 // RAX: new closure object. 1317 // RAX: new closure object.
1335 // RBX: new context object (only if is_implicit_closure). 1318 // RBX: new context object (only if is_implicit_closure).
1336 __ LoadObject(R10, cls); // Load signature class of closure.
1337 __ movq(Address(RAX, Closure::class_offset()), R10);
1338 // Set the tags. 1319 // Set the tags.
1339 uword tags = 0; 1320 uword tags = 0;
1340 tags = RawObject::SizeTag::update(closure_size, tags); 1321 tags = RawObject::SizeTag::update(closure_size, tags);
1341 tags = RawObject::ClassTag::update(cls.index(), tags); 1322 tags = RawObject::ClassTag::update(cls.index(), tags);
1342 __ movq(Address(RAX, Closure::tags_offset()), Immediate(tags)); 1323 __ movq(Address(RAX, Closure::tags_offset()), Immediate(tags));
1343 1324
1344 // Initialize the function field in the object. 1325 // Initialize the function field in the object.
1345 // RAX: new closure object. 1326 // RAX: new closure object.
1346 // RBX: new context object (only if is_implicit_closure). 1327 // RBX: new context object (only if is_implicit_closure).
1347 // R13: next object start. 1328 // R13: next object start.
1348 __ LoadObject(R10, func); // Load function of closure to be allocated. 1329 __ LoadObject(R10, func); // Load function of closure to be allocated.
1349 __ movq(Address(RAX, Closure::function_offset()), R10); 1330 __ movq(Address(RAX, Closure::function_offset()), R10);
1350 1331
1351 // Setup the context for this closure. 1332 // Setup the context for this closure.
1352 if (is_implicit_static_closure) { 1333 if (is_implicit_static_closure) {
1353 ObjectStore* object_store = Isolate::Current()->object_store(); 1334 ObjectStore* object_store = Isolate::Current()->object_store();
1354 ASSERT(object_store != NULL); 1335 ASSERT(object_store != NULL);
1355 const Context& empty_context = 1336 const Context& empty_context =
1356 Context::ZoneHandle(object_store->empty_context()); 1337 Context::ZoneHandle(object_store->empty_context());
1357 __ LoadObject(R10, empty_context); 1338 __ LoadObject(R10, empty_context);
1358 __ movq(Address(RAX, Closure::context_offset()), R10); 1339 __ movq(Address(RAX, Closure::context_offset()), R10);
1359 } else if (is_implicit_instance_closure) { 1340 } else if (is_implicit_instance_closure) {
1360 // Initialize the new context capturing the receiver. 1341 // Initialize the new context capturing the receiver.
1361 1342
1362 // Set the class field to the Context class.
1363 const Class& context_class = Class::ZoneHandle(Object::context_class()); 1343 const Class& context_class = Class::ZoneHandle(Object::context_class());
1364 __ LoadObject(R13, context_class);
1365 __ movq(Address(RBX, Context::class_offset()), R13);
1366 // Set the tags. 1344 // Set the tags.
1367 uword tags = 0; 1345 uword tags = 0;
1368 tags = RawObject::SizeTag::update(context_size, tags); 1346 tags = RawObject::SizeTag::update(context_size, tags);
1369 tags = RawObject::ClassTag::update(context_class.index(), tags); 1347 tags = RawObject::ClassTag::update(context_class.index(), tags);
1370 __ movq(Address(RBX, Context::tags_offset()), Immediate(tags)); 1348 __ movq(Address(RBX, Context::tags_offset()), Immediate(tags));
1371 1349
1372 // Set number of variables field to 1 (for captured receiver). 1350 // Set number of variables field to 1 (for captured receiver).
1373 __ movq(Address(RBX, Context::num_variables_offset()), Immediate(1)); 1351 __ movq(Address(RBX, Context::num_variables_offset()), Immediate(1));
1374 1352
1375 // Set isolate field to isolate of current context. 1353 // Set isolate field to isolate of current context.
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after
1663 Label not_smi; 1641 Label not_smi;
1664 // Test if Smi -> load Smi class for comparison. 1642 // Test if Smi -> load Smi class for comparison.
1665 __ testq(RAX, Immediate(kSmiTagMask)); 1643 __ testq(RAX, Immediate(kSmiTagMask));
1666 __ j(NOT_ZERO, &not_smi, Assembler::kNearJump); 1644 __ j(NOT_ZERO, &not_smi, Assembler::kNearJump);
1667 const Class& smi_class = 1645 const Class& smi_class =
1668 Class::ZoneHandle(Isolate::Current()->object_store()->smi_class()); 1646 Class::ZoneHandle(Isolate::Current()->object_store()->smi_class());
1669 __ LoadObject(RAX, smi_class); 1647 __ LoadObject(RAX, smi_class);
1670 __ ret(); 1648 __ ret();
1671 1649
1672 __ Bind(&not_smi); 1650 __ Bind(&not_smi);
1673 __ movq(RAX, FieldAddress(RAX, Object::class_offset())); 1651 __ GetClassOf(RAX, RAX);
1674 __ ret(); 1652 __ ret();
1675 } 1653 }
1676 1654
1677 1655
1678 // Use inline cache data array to invoke the target or continue in inline 1656 // Use inline cache data array to invoke the target or continue in inline
1679 // cache miss handler. Stub for 1-argument check (receiver class). 1657 // cache miss handler. Stub for 1-argument check (receiver class).
1680 // RCX: Inline cache data array 1658 // RCX: Inline cache data array
1681 // RDX: Arguments array 1659 // RDX: Arguments array
1682 // TOS(0): return address 1660 // TOS(0): return address
1683 // Inline cache data array structure: 1661 // Inline cache data array structure:
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
1761 // TOS + 3: SubtypeTestCache. 1739 // TOS + 3: SubtypeTestCache.
1762 // Result in RCX: null -> not found, otherwise result (true or false). 1740 // Result in RCX: null -> not found, otherwise result (true or false).
1763 static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) { 1741 static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) {
1764 ASSERT((1 <= n) && (n <= 3)); 1742 ASSERT((1 <= n) && (n <= 3));
1765 const Immediate raw_null = 1743 const Immediate raw_null =
1766 Immediate(reinterpret_cast<intptr_t>(Object::null())); 1744 Immediate(reinterpret_cast<intptr_t>(Object::null()));
1767 const intptr_t kInstantiatorTypeArgumentsInBytes = 1 * kWordSize; 1745 const intptr_t kInstantiatorTypeArgumentsInBytes = 1 * kWordSize;
1768 const intptr_t kInstanceOffsetInBytes = 2 * kWordSize; 1746 const intptr_t kInstanceOffsetInBytes = 2 * kWordSize;
1769 const intptr_t kCacheOffsetInBytes = 3 * kWordSize; 1747 const intptr_t kCacheOffsetInBytes = 3 * kWordSize;
1770 __ movq(RAX, Address(RSP, kInstanceOffsetInBytes)); 1748 __ movq(RAX, Address(RSP, kInstanceOffsetInBytes));
1771 __ movq(R10, FieldAddress(RAX, Object::class_offset())); 1749 __ GetClassOf(R10, RAX);
1772 // RAX: instance, R10: instance class. 1750 // RAX: instance, R10: instance class.
1773 if (n > 1) { 1751 if (n > 1) {
1774 // Compute instance type arguments into R13. 1752 // Compute instance type arguments into R13.
1775 Label has_no_type_arguments; 1753 Label has_no_type_arguments;
1776 __ movq(R13, raw_null); 1754 __ movq(R13, raw_null);
1777 __ movq(RDI, FieldAddress(R10, 1755 __ movq(RDI, FieldAddress(R10,
1778 Class::type_arguments_instance_field_offset_offset())); 1756 Class::type_arguments_instance_field_offset_offset()));
1779 __ cmpq(RDI, Immediate(Class::kNoTypeArguments)); 1757 __ cmpq(RDI, Immediate(Class::kNoTypeArguments));
1780 __ j(EQUAL, &has_no_type_arguments, Assembler::kNearJump); 1758 __ j(EQUAL, &has_no_type_arguments, Assembler::kNearJump);
1781 __ movq(R13, FieldAddress(RAX, RDI, TIMES_1, 0)); 1759 __ movq(R13, FieldAddress(RAX, RDI, TIMES_1, 0));
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
1856 // TOS + 2: instance. 1834 // TOS + 2: instance.
1857 // TOS + 3: cache array. 1835 // TOS + 3: cache array.
1858 // Result in RCX: null -> not found, otherwise result (true or false). 1836 // Result in RCX: null -> not found, otherwise result (true or false).
1859 void StubCode::GenerateSubtype3TestCacheStub(Assembler* assembler) { 1837 void StubCode::GenerateSubtype3TestCacheStub(Assembler* assembler) {
1860 GenerateSubtypeNTestCacheStub(assembler, 3); 1838 GenerateSubtypeNTestCacheStub(assembler, 3);
1861 } 1839 }
1862 1840
1863 } // namespace dart 1841 } // namespace dart
1864 1842
1865 #endif // defined TARGET_ARCH_X64 1843 #endif // defined TARGET_ARCH_X64
OLDNEW
« runtime/vm/raw_object.cc ('K') | « runtime/vm/stub_code_ia32.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698