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

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

Issue 10458031: In generated code for x64 don't load object's class directly from class_ field. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Eliminate CoreClass helpers on ia32/x64 and use class ids for array classes. 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
« no previous file with comments | « runtime/vm/intermediate_language_x64.cc ('k') | runtime/vm/opt_code_generator_ia32.cc » ('j') | 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 // The intrinsic code below is executed before a method has built its frame. 5 // The intrinsic code below is executed before a method has built its frame.
6 // The return address is on the stack and the arguments below it. 6 // The return address is on the stack and the arguments below it.
7 // Registers EDX (arguments descriptor) and ECX (function) must be preserved. 7 // Registers EDX (arguments descriptor) and ECX (function) must be preserved.
8 // Each intrinsification method returns true if the corresponding 8 // Each intrinsification method returns true if the corresponding
9 // Dart method was intrinsified. 9 // Dart method was intrinsified.
10 10
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
197 __ cmpl(EDI, raw_null); 197 __ cmpl(EDI, raw_null);
198 __ j(EQUAL, &checked_ok, Assembler::kNearJump); 198 __ j(EQUAL, &checked_ok, Assembler::kNearJump);
199 199
200 __ movl(EBX, Address(ESP, + 3 * kWordSize)); // Array. 200 __ movl(EBX, Address(ESP, + 3 * kWordSize)); // Array.
201 __ movl(EBX, FieldAddress(EBX, type_args_field_offset)); 201 __ movl(EBX, FieldAddress(EBX, type_args_field_offset));
202 // EBX: Type arguments of array. 202 // EBX: Type arguments of array.
203 __ cmpl(EBX, raw_null); 203 __ cmpl(EBX, raw_null);
204 __ j(EQUAL, &checked_ok, Assembler::kNearJump); 204 __ j(EQUAL, &checked_ok, Assembler::kNearJump);
205 // Check if it's Dynamic. 205 // Check if it's Dynamic.
206 // For now handle only TypeArguments and bail out if InstantiatedTypeArgs. 206 // For now handle only TypeArguments and bail out if InstantiatedTypeArgs.
207 __ CompareClassOfObject(EBX, 207 __ CompareClassId(EBX, kTypeArguments, EAX);
208 Class::Handle(Object::type_arguments_class()),
209 EAX);
210 __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump); 208 __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump);
211 // Get type at index 0. 209 // Get type at index 0.
212 __ movl(EAX, FieldAddress(EBX, TypeArguments::type_at_offset(0))); 210 __ movl(EAX, FieldAddress(EBX, TypeArguments::type_at_offset(0)));
213 __ CompareObject(EAX, Type::ZoneHandle(Type::DynamicType())); 211 __ CompareObject(EAX, Type::ZoneHandle(Type::DynamicType()));
214 __ j(EQUAL, &checked_ok, Assembler::kNearJump); 212 __ j(EQUAL, &checked_ok, Assembler::kNearJump);
215 // Check for int and num. 213 // Check for int and num.
216 __ testl(EDI, Immediate(kSmiTagMask)); // Value is Smi? 214 __ testl(EDI, Immediate(kSmiTagMask)); // Value is Smi?
217 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi value. 215 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi value.
218 __ CompareObject(EAX, Type::ZoneHandle(Type::IntInterface())); 216 __ CompareObject(EAX, Type::ZoneHandle(Type::IntInterface()));
219 __ j(EQUAL, &checked_ok, Assembler::kNearJump); 217 __ j(EQUAL, &checked_ok, Assembler::kNearJump);
(...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after
733 __ j(NOT_ZERO, &check_for_mint, Assembler::kNearJump); 731 __ j(NOT_ZERO, &check_for_mint, Assembler::kNearJump);
734 // Both arguments are smi, '===' is good enough. 732 // Both arguments are smi, '===' is good enough.
735 __ LoadObject(EAX, bool_false); 733 __ LoadObject(EAX, bool_false);
736 __ ret(); 734 __ ret();
737 __ Bind(&true_label); 735 __ Bind(&true_label);
738 __ LoadObject(EAX, bool_true); 736 __ LoadObject(EAX, bool_true);
739 __ ret(); 737 __ ret();
740 738
741 // At least one of the arguments was not Smi, inline code for Smi/Mint 739 // At least one of the arguments was not Smi, inline code for Smi/Mint
742 // equality comparison. 740 // equality comparison.
743 ObjectStore* object_store = Isolate::Current()->object_store();
744 Label receiver_not_smi; 741 Label receiver_not_smi;
745 __ Bind(&check_for_mint); 742 __ Bind(&check_for_mint);
746 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Receiver. 743 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Receiver.
747 __ testl(EAX, Immediate(kSmiTagMask)); 744 __ testl(EAX, Immediate(kSmiTagMask));
748 __ j(NOT_ZERO, &receiver_not_smi); 745 __ j(NOT_ZERO, &receiver_not_smi);
749 746
750 // Note that an instance of Mint never contains a value that can be 747 // Note that an instance of Mint never contains a value that can be
751 // represented by Smi. 748 // represented by Smi.
752 // Left is Smi, return false if right is Mint, otherwise fall through. 749 // Left is Smi, return false if right is Mint, otherwise fall through.
753 __ movl(EAX, Address(ESP, + 1 * kWordSize)); // Right argument. 750 __ movl(EAX, Address(ESP, + 1 * kWordSize)); // Right argument.
754 __ CompareClassOfObject(EAX, Class::Handle(object_store->mint_class()), EAX); 751 __ CompareClassId(EAX, kMint, EAX);
755 __ j(NOT_EQUAL, &fall_through); 752 __ j(NOT_EQUAL, &fall_through);
756 __ LoadObject(EAX, bool_false); // Smi == Mint -> false. 753 __ LoadObject(EAX, bool_false); // Smi == Mint -> false.
757 __ ret(); 754 __ ret();
758 755
759 __ Bind(&receiver_not_smi); 756 __ Bind(&receiver_not_smi);
760 // EAX:: receiver. 757 // EAX:: receiver.
761 __ CompareClassOfObject(EAX, Class::Handle(object_store->mint_class()), EAX); 758 __ CompareClassId(EAX, kMint, EAX);
762 __ j(NOT_EQUAL, &fall_through); 759 __ j(NOT_EQUAL, &fall_through);
763 // Receiver is Mint, return false if right is Smi. 760 // Receiver is Mint, return false if right is Smi.
764 __ movl(EAX, Address(ESP, + 1 * kWordSize)); // Right argument. 761 __ movl(EAX, Address(ESP, + 1 * kWordSize)); // Right argument.
765 __ testl(EAX, Immediate(kSmiTagMask)); 762 __ testl(EAX, Immediate(kSmiTagMask));
766 __ j(NOT_ZERO, &fall_through); 763 __ j(NOT_ZERO, &fall_through);
767 __ LoadObject(EAX, bool_false); // Smi == Mint -> false. 764 __ LoadObject(EAX, bool_false); // Smi == Mint -> false.
768 __ ret(); 765 __ ret();
769 // TODO(srdjan): Implement Mint == Mint comparison. 766 // TODO(srdjan): Implement Mint == Mint comparison.
770 767
771 __ Bind(&fall_through); 768 __ Bind(&fall_through);
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
820 817
821 // Check if the last argument is a double, jump to label 'is_smi' if smi 818 // Check if the last argument is a double, jump to label 'is_smi' if smi
822 // (easy to convert to double), otherwise jump to label 'not_double_smi', 819 // (easy to convert to double), otherwise jump to label 'not_double_smi',
823 // Returns the last argument in EAX. 820 // Returns the last argument in EAX.
824 static void TestLastArgumentIsDouble(Assembler* assembler, 821 static void TestLastArgumentIsDouble(Assembler* assembler,
825 Label* is_smi, 822 Label* is_smi,
826 Label* not_double_smi) { 823 Label* not_double_smi) {
827 __ movl(EAX, Address(ESP, + 1 * kWordSize)); 824 __ movl(EAX, Address(ESP, + 1 * kWordSize));
828 __ testl(EAX, Immediate(kSmiTagMask)); 825 __ testl(EAX, Immediate(kSmiTagMask));
829 __ j(ZERO, is_smi, Assembler::kNearJump); // Jump if Smi. 826 __ j(ZERO, is_smi, Assembler::kNearJump); // Jump if Smi.
830 __ CompareClassOfObject(EAX, Class::Handle( 827 __ CompareClassId(EAX, kDouble, EBX);
831 Isolate::Current()->object_store()->double_class()), EBX);
832 __ j(NOT_EQUAL, not_double_smi, Assembler::kNearJump); 828 __ j(NOT_EQUAL, not_double_smi, Assembler::kNearJump);
833 // Fall through if double. 829 // Fall through if double.
834 } 830 }
835 831
836 832
837 // Both arguments on stack, arg0 (left) is a double, arg1 (right) is of unknown 833 // Both arguments on stack, arg0 (left) is a double, arg1 (right) is of unknown
838 // type. Return true or false object in the register EAX. Any NaN argument 834 // type. Return true or false object in the register EAX. Any NaN argument
839 // returns false. Any non-double arg1 causes control flow to fall through to the 835 // returns false. Any non-double arg1 causes control flow to fall through to the
840 // slow case (compiled method body). 836 // slow case (compiled method body).
841 static bool CompareDoubles(Assembler* assembler, Condition true_condition) { 837 static bool CompareDoubles(Assembler* assembler, Condition true_condition) {
(...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after
1234 bool Intrinsifier::String_getLength(Assembler* assembler) { 1230 bool Intrinsifier::String_getLength(Assembler* assembler) {
1235 __ movl(EAX, Address(ESP, + 1 * kWordSize)); // String object. 1231 __ movl(EAX, Address(ESP, + 1 * kWordSize)); // String object.
1236 __ movl(EAX, FieldAddress(EAX, String::length_offset())); 1232 __ movl(EAX, FieldAddress(EAX, String::length_offset()));
1237 __ ret(); 1233 __ ret();
1238 return true; 1234 return true;
1239 } 1235 }
1240 1236
1241 1237
1242 // TODO(srdjan): Implement for two and four byte strings as well. 1238 // TODO(srdjan): Implement for two and four byte strings as well.
1243 bool Intrinsifier::String_charCodeAt(Assembler* assembler) { 1239 bool Intrinsifier::String_charCodeAt(Assembler* assembler) {
1244 ObjectStore* object_store = Isolate::Current()->object_store();
1245 Label fall_through; 1240 Label fall_through;
1246 __ movl(EBX, Address(ESP, + 1 * kWordSize)); // Index. 1241 __ movl(EBX, Address(ESP, + 1 * kWordSize)); // Index.
1247 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // String. 1242 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // String.
1248 __ testl(EBX, Immediate(kSmiTagMask)); 1243 __ testl(EBX, Immediate(kSmiTagMask));
1249 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index. 1244 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index.
1250 // Range check. 1245 // Range check.
1251 __ cmpl(EBX, FieldAddress(EAX, String::length_offset())); 1246 __ cmpl(EBX, FieldAddress(EAX, String::length_offset()));
1252 // Runtime throws exception. 1247 // Runtime throws exception.
1253 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); 1248 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump);
1254 __ CompareClassOfObject(EAX, 1249 __ CompareClassId(EAX, kOneByteString, EDI);
1255 Class::Handle(object_store->one_byte_string_class()),
1256 EDI);
1257 __ j(NOT_EQUAL, &fall_through); 1250 __ j(NOT_EQUAL, &fall_through);
1258 __ SmiUntag(EBX); 1251 __ SmiUntag(EBX);
1259 __ movzxb(EAX, FieldAddress(EAX, EBX, TIMES_1, OneByteString::data_offset())); 1252 __ movzxb(EAX, FieldAddress(EAX, EBX, TIMES_1, OneByteString::data_offset()));
1260 __ SmiTag(EAX); 1253 __ SmiTag(EAX);
1261 __ ret(); 1254 __ ret();
1262 __ Bind(&fall_through); 1255 __ Bind(&fall_through);
1263 return false; 1256 return false;
1264 } 1257 }
1265 1258
1266 1259
(...skipping 24 matching lines...) Expand all
1291 __ Bind(&is_true); 1284 __ Bind(&is_true);
1292 __ LoadObject(EAX, bool_true); 1285 __ LoadObject(EAX, bool_true);
1293 __ ret(); 1286 __ ret();
1294 return true; 1287 return true;
1295 } 1288 }
1296 1289
1297 #undef __ 1290 #undef __
1298 } // namespace dart 1291 } // namespace dart
1299 1292
1300 #endif // defined TARGET_ARCH_IA32 1293 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_x64.cc ('k') | runtime/vm/opt_code_generator_ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698