| 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 // 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 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 66 V(Double, Double.fromInteger, Double_fromInteger) \ | 66 V(Double, Double.fromInteger, Double_fromInteger) \ |
| 67 V(Double, isNaN, Double_isNaN) \ | 67 V(Double, isNaN, Double_isNaN) \ |
| 68 V(Double, isNegative, Double_isNegative) \ | 68 V(Double, isNegative, Double_isNegative) \ |
| 69 V(ObjectArray, ObjectArray., ObjectArray_Allocate) \ | 69 V(ObjectArray, ObjectArray., ObjectArray_Allocate) \ |
| 70 V(ObjectArray, get:length, Array_getLength) \ | 70 V(ObjectArray, get:length, Array_getLength) \ |
| 71 V(ObjectArray, [], Array_getIndexed) \ | 71 V(ObjectArray, [], Array_getIndexed) \ |
| 72 V(ObjectArray, []=, Array_setIndexed) \ | 72 V(ObjectArray, []=, Array_setIndexed) \ |
| 73 V(GrowableObjectArray, get:length, GrowableArray_getLength) \ | 73 V(GrowableObjectArray, get:length, GrowableArray_getLength) \ |
| 74 V(GrowableObjectArray, [], GrowableArray_getIndexed) \ | 74 V(GrowableObjectArray, [], GrowableArray_getIndexed) \ |
| 75 V(GrowableObjectArray, []=, GrowableArray_setIndexed) \ | 75 V(GrowableObjectArray, []=, GrowableArray_setIndexed) \ |
| 76 V(_ByteArrayBase, get:length, ByteArrayBase_getLength) \ |
| 77 V(_ByteArrayBase, [], ByteArrayBase_getIndexed) \ |
| 76 V(ImmutableArray, [], Array_getIndexed) \ | 78 V(ImmutableArray, [], Array_getIndexed) \ |
| 77 V(ImmutableArray, get:length, Array_getLength) \ | 79 V(ImmutableArray, get:length, Array_getLength) \ |
| 78 V(Math, sqrt, Math_sqrt) \ | 80 V(Math, sqrt, Math_sqrt) \ |
| 79 V(Math, sin, Math_sin) \ | 81 V(Math, sin, Math_sin) \ |
| 80 V(Math, cos, Math_cos) \ | 82 V(Math, cos, Math_cos) \ |
| 81 V(Object, ==, Object_equal) \ | 83 V(Object, ==, Object_equal) \ |
| 82 V(FixedSizeArrayIterator, next, FixedSizeArrayIterator_next) \ | 84 V(FixedSizeArrayIterator, next, FixedSizeArrayIterator_next) \ |
| 83 V(FixedSizeArrayIterator, hasNext, FixedSizeArrayIterator_hasNext) \ | 85 V(FixedSizeArrayIterator, hasNext, FixedSizeArrayIterator_hasNext) \ |
| 84 V(StringBase, get:length, String_getLength) \ | 86 V(StringBase, get:length, String_getLength) \ |
| 85 V(StringBase, charCodeAt, String_charCodeAt) \ | 87 V(StringBase, charCodeAt, String_charCodeAt) \ |
| (...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 321 ASSERT(kSmiTagShift == 1); | 323 ASSERT(kSmiTagShift == 1); |
| 322 __ StoreIntoObject(EAX, | 324 __ StoreIntoObject(EAX, |
| 323 FieldAddress(EAX, EBX, TIMES_2, sizeof(RawArray)), | 325 FieldAddress(EAX, EBX, TIMES_2, sizeof(RawArray)), |
| 324 EDI); | 326 EDI); |
| 325 __ ret(); | 327 __ ret(); |
| 326 __ Bind(&fall_through); | 328 __ Bind(&fall_through); |
| 327 return false; | 329 return false; |
| 328 } | 330 } |
| 329 | 331 |
| 330 | 332 |
| 333 // Handles only class InternalByteArray. |
| 334 static bool ByteArrayBase_getLength(Assembler* assembler) { |
| 335 ObjectStore* object_store = Isolate::Current()->object_store(); |
| 336 Label fall_through; |
| 337 __ movl(EAX, Address(ESP, + 1 * kWordSize)); |
| 338 __ movl(EBX, FieldAddress(EAX, Object::class_offset())); |
| 339 __ CompareObject(EBX, |
| 340 Class::ZoneHandle(object_store->internal_byte_array_class())); |
| 341 __ j(NOT_EQUAL, &fall_through); |
| 342 __ movl(EAX, FieldAddress(EAX, InternalByteArray::length_offset())); |
| 343 __ ret(); |
| 344 __ Bind(&fall_through); |
| 345 return false; |
| 346 } |
| 347 |
| 348 |
| 349 // Handles only class InternalByteArray. |
| 350 static bool ByteArrayBase_getIndexed(Assembler* assembler) { |
| 351 ObjectStore* object_store = Isolate::Current()->object_store(); |
| 352 Label fall_through; |
| 353 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Array. |
| 354 __ movl(EBX, FieldAddress(EAX, Object::class_offset())); |
| 355 __ CompareObject(EBX, |
| 356 Class::ZoneHandle(object_store->internal_byte_array_class())); |
| 357 __ j(NOT_EQUAL, &fall_through); |
| 358 __ movl(EBX, Address(ESP, + 1 * kWordSize)); // Index. |
| 359 __ testl(EBX, Immediate(kSmiTagMask)); |
| 360 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index. |
| 361 // Range check. |
| 362 __ cmpl(EBX, FieldAddress(EAX, InternalByteArray::length_offset())); |
| 363 // Runtime throws exception. |
| 364 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); |
| 365 __ SmiUntag(EBX); |
| 366 __ movzxb(EAX, |
| 367 FieldAddress(EAX, EBX, TIMES_1, InternalByteArray::data_offset())); |
| 368 // The values stored in the byte array are regular, untagged values, |
| 369 // therefore they need to be tagged. |
| 370 __ SmiTag(EAX); |
| 371 __ ret(); |
| 372 __ Bind(&fall_through); |
| 373 return false; |
| 374 } |
| 375 |
| 376 |
| 331 // Tests if two top most arguments are smis, jumps to label not_smi if not. | 377 // Tests if two top most arguments are smis, jumps to label not_smi if not. |
| 332 // Topmost argument is in EAX. | 378 // Topmost argument is in EAX. |
| 333 static void TestBothArgumentsSmis(Assembler* assembler, Label* not_smi) { | 379 static void TestBothArgumentsSmis(Assembler* assembler, Label* not_smi) { |
| 334 __ movl(EAX, Address(ESP, + 1 * kWordSize)); | 380 __ movl(EAX, Address(ESP, + 1 * kWordSize)); |
| 335 __ movl(EBX, Address(ESP, + 2 * kWordSize)); | 381 __ movl(EBX, Address(ESP, + 2 * kWordSize)); |
| 336 __ orl(EBX, EAX); | 382 __ orl(EBX, EAX); |
| 337 __ testl(EBX, Immediate(kSmiTagMask)); | 383 __ testl(EBX, Immediate(kSmiTagMask)); |
| 338 __ j(NOT_ZERO, not_smi, Assembler::kNearJump); | 384 __ j(NOT_ZERO, not_smi, Assembler::kNearJump); |
| 339 } | 385 } |
| 340 | 386 |
| (...skipping 801 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1142 __ ret(); | 1188 __ ret(); |
| 1143 __ Bind(&is_true); | 1189 __ Bind(&is_true); |
| 1144 __ LoadObject(EAX, bool_true); | 1190 __ LoadObject(EAX, bool_true); |
| 1145 __ ret(); | 1191 __ ret(); |
| 1146 return true; | 1192 return true; |
| 1147 } | 1193 } |
| 1148 | 1194 |
| 1149 #undef __ | 1195 #undef __ |
| 1150 | 1196 |
| 1151 | 1197 |
| 1198 // Returns true if the function matches function_name and class_name, with |
| 1199 // special recognition of corelib private classes |
| 1200 static bool TestFunction(const Function& function, |
| 1201 const char* function_class_name, |
| 1202 const char* function_name, |
| 1203 const char* test_class_name, |
| 1204 const char* test_function_name) { |
| 1205 if (strcmp(test_function_name, function_name) != 0) return false; |
| 1206 |
| 1207 if ((function_class_name[0] == '_') && (test_class_name[0] == '_')) { |
| 1208 // Check if the private class is member of corelib and matches the |
| 1209 // test_class_name. |
| 1210 const Library& core_lib = Library::Handle(Library::CoreLibrary()); |
| 1211 const Library& core_impl_lib = Library::Handle(Library::CoreImplLibrary()); |
| 1212 String& test_str = String::Handle(String::New(test_class_name)); |
| 1213 String& test_str_with_key = String::Handle(); |
| 1214 test_str_with_key = |
| 1215 String::Concat(test_str, String::Handle(core_lib.private_key())); |
| 1216 if (strcmp(test_str_with_key.ToCString(), function_class_name) == 0) { |
| 1217 return true; |
| 1218 } |
| 1219 test_str_with_key = |
| 1220 String::Concat(test_str, String::Handle(core_impl_lib.private_key())); |
| 1221 if (strcmp(test_str_with_key.ToCString(), function_class_name) == 0) { |
| 1222 return true; |
| 1223 } |
| 1224 } |
| 1225 return strcmp(test_class_name, function_class_name) == 0; |
| 1226 } |
| 1227 |
| 1228 |
| 1152 bool Intrinsifier::Intrinsify(const Function& function, Assembler* assembler) { | 1229 bool Intrinsifier::Intrinsify(const Function& function, Assembler* assembler) { |
| 1153 if (!FLAG_intrinsify) return false; | 1230 if (!FLAG_intrinsify) return false; |
| 1154 const char* function_name = String::Handle(function.name()).ToCString(); | 1231 const char* function_name = String::Handle(function.name()).ToCString(); |
| 1155 const Class& function_class = Class::Handle(function.owner()); | 1232 const Class& function_class = Class::Handle(function.owner()); |
| 1156 const char* class_name = String::Handle(function_class.Name()).ToCString(); | 1233 const char* class_name = String::Handle(function_class.Name()).ToCString(); |
| 1234 // Only core library methods can be intrinsified. |
| 1235 const Library& core_lib = Library::Handle(Library::CoreLibrary()); |
| 1236 const Library& core_impl_lib = Library::Handle(Library::CoreImplLibrary()); |
| 1237 if ((function_class.library() != core_lib.raw()) && |
| 1238 (function_class.library() != core_impl_lib.raw())) { |
| 1239 return false; |
| 1240 } |
| 1157 #define FIND_INTRINSICS(test_class_name, test_function_name, destination) \ | 1241 #define FIND_INTRINSICS(test_class_name, test_function_name, destination) \ |
| 1158 if ((strcmp(#test_function_name, function_name) == 0) && \ | 1242 if (TestFunction(function, \ |
| 1159 (strcmp(#test_class_name, class_name) == 0)) { \ | 1243 class_name, function_name, \ |
| 1244 #test_class_name, #test_function_name)) { \ |
| 1160 return destination(assembler); \ | 1245 return destination(assembler); \ |
| 1161 } \ | 1246 } \ |
| 1162 | 1247 |
| 1163 INTRINSIC_LIST(FIND_INTRINSICS); | 1248 INTRINSIC_LIST(FIND_INTRINSICS); |
| 1164 #undef FIND_INTRINSICS | 1249 #undef FIND_INTRINSICS |
| 1165 return false; | 1250 return false; |
| 1166 } | 1251 } |
| 1167 | 1252 |
| 1168 } // namespace dart | 1253 } // namespace dart |
| 1169 | 1254 |
| 1170 #endif // defined TARGET_ARCH_IA32 | 1255 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |