| 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 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 63 V(Double, /, Double_div) \ | 63 V(Double, /, Double_div) \ |
| 64 V(Double, toDouble, Double_toDouble) \ | 64 V(Double, toDouble, Double_toDouble) \ |
| 65 V(Double, mulFromInteger, Double_mulFromInteger) \ | 65 V(Double, mulFromInteger, Double_mulFromInteger) \ |
| 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, GrowableObjectArray.fromObjectArray, GArray_Allocate) \ |
| 73 V(GrowableObjectArray, get:length, GrowableArray_getLength) \ | 74 V(GrowableObjectArray, get:length, GrowableArray_getLength) \ |
| 75 V(GrowableObjectArray, get:capacity, GrowableArray_getCapacity) \ |
| 74 V(GrowableObjectArray, [], GrowableArray_getIndexed) \ | 76 V(GrowableObjectArray, [], GrowableArray_getIndexed) \ |
| 75 V(GrowableObjectArray, []=, GrowableArray_setIndexed) \ | 77 V(GrowableObjectArray, []=, GrowableArray_setIndexed) \ |
| 78 V(GrowableObjectArray, _setLength, GrowableArray_setLength) \ |
| 79 V(GrowableObjectArray, set:data, GrowableArray_setData) \ |
| 76 V(_ByteArrayBase, get:length, ByteArrayBase_getLength) \ | 80 V(_ByteArrayBase, get:length, ByteArrayBase_getLength) \ |
| 77 V(_ByteArrayBase, [], ByteArrayBase_getIndexed) \ | 81 V(_ByteArrayBase, [], ByteArrayBase_getIndexed) \ |
| 78 V(ImmutableArray, [], Array_getIndexed) \ | 82 V(ImmutableArray, [], Array_getIndexed) \ |
| 79 V(ImmutableArray, get:length, Array_getLength) \ | 83 V(ImmutableArray, get:length, Array_getLength) \ |
| 80 V(Math, sqrt, Math_sqrt) \ | 84 V(Math, sqrt, Math_sqrt) \ |
| 81 V(Math, sin, Math_sin) \ | 85 V(Math, sin, Math_sin) \ |
| 82 V(Math, cos, Math_cos) \ | 86 V(Math, cos, Math_cos) \ |
| 83 V(Object, ==, Object_equal) \ | 87 V(Object, ==, Object_equal) \ |
| 84 V(FixedSizeArrayIterator, next, FixedSizeArrayIterator_next) \ | 88 V(FixedSizeArrayIterator, next, FixedSizeArrayIterator_next) \ |
| 85 V(FixedSizeArrayIterator, hasNext, FixedSizeArrayIterator_hasNext) \ | 89 V(FixedSizeArrayIterator, hasNext, FixedSizeArrayIterator_hasNext) \ |
| (...skipping 11 matching lines...) Expand all Loading... |
| 97 const intptr_t kTypeArgumentsOffset = 2 * kWordSize; | 101 const intptr_t kTypeArgumentsOffset = 2 * kWordSize; |
| 98 const intptr_t kArrayLengthOffset = 1 * kWordSize; | 102 const intptr_t kArrayLengthOffset = 1 * kWordSize; |
| 99 Label fall_through; | 103 Label fall_through; |
| 100 | 104 |
| 101 // Compute the size to be allocated, it is based on the array length | 105 // Compute the size to be allocated, it is based on the array length |
| 102 // and it computed as: | 106 // and it computed as: |
| 103 // RoundedAllocationSize((array_length * kwordSize) + sizeof(RawArray)). | 107 // RoundedAllocationSize((array_length * kwordSize) + sizeof(RawArray)). |
| 104 __ movl(EDI, Address(ESP, kArrayLengthOffset)); // Array Length. | 108 __ movl(EDI, Address(ESP, kArrayLengthOffset)); // Array Length. |
| 105 // Assert that length is a Smi. | 109 // Assert that length is a Smi. |
| 106 __ testl(EDI, Immediate(kSmiTagSize)); | 110 __ testl(EDI, Immediate(kSmiTagSize)); |
| 107 __ j(NOT_ZERO, &fall_through); | 111 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); |
| 108 __ cmpl(EDI, Immediate(0)); | 112 __ cmpl(EDI, Immediate(0)); |
| 109 __ j(LESS, &fall_through, Assembler::kNearJump); | 113 __ j(LESS, &fall_through, Assembler::kNearJump); |
| 110 intptr_t fixed_size = sizeof(RawArray) + kObjectAlignment - 1; | 114 intptr_t fixed_size = sizeof(RawArray) + kObjectAlignment - 1; |
| 111 __ leal(EDI, Address(EDI, TIMES_2, fixed_size)); // EDI is a Smi. | 115 __ leal(EDI, Address(EDI, TIMES_2, fixed_size)); // EDI is a Smi. |
| 112 ASSERT(kSmiTagShift == 1); | 116 ASSERT(kSmiTagShift == 1); |
| 113 __ andl(EDI, Immediate(-kObjectAlignment)); | 117 __ andl(EDI, Immediate(-kObjectAlignment)); |
| 114 | 118 |
| 115 Heap* heap = Isolate::Current()->heap(); | 119 Heap* heap = Isolate::Current()->heap(); |
| 116 | 120 |
| 117 // EDI: allocation size. | 121 // EDI: allocation size. |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 297 const String& field_name = String::Handle(String::NewSymbol(field_name_p)); | 301 const String& field_name = String::Handle(String::NewSymbol(field_name_p)); |
| 298 const Class& cls = Class::Handle(Library::Handle( | 302 const Class& cls = Class::Handle(Library::Handle( |
| 299 Library::CoreImplLibrary()).LookupClass(class_name)); | 303 Library::CoreImplLibrary()).LookupClass(class_name)); |
| 300 ASSERT(!cls.IsNull()); | 304 ASSERT(!cls.IsNull()); |
| 301 const Field& field = Field::ZoneHandle(cls.LookupInstanceField(field_name)); | 305 const Field& field = Field::ZoneHandle(cls.LookupInstanceField(field_name)); |
| 302 ASSERT(!field.IsNull()); | 306 ASSERT(!field.IsNull()); |
| 303 return field.Offset(); | 307 return field.Offset(); |
| 304 } | 308 } |
| 305 | 309 |
| 306 | 310 |
| 307 static const char* kGrowableArrayClassName = "GrowableObjectArray"; | 311 // Allocate a GrowableObjectArray using the backing array specified. |
| 308 static const char* kGrowableArrayLengthFieldName = "_length"; | 312 // On stack: type argument (+2), data (+1), return-address (+0). |
| 309 static const char* kGrowableArrayArrayFieldName = "backingArray"; | 313 static bool GArray_Allocate(Assembler* assembler) { |
| 314 // This snippet of inlined code uses the following registers: |
| 315 // EAX, EBX |
| 316 // and the newly allocated object is returned in EAX. |
| 317 const intptr_t kTypeArgumentsOffset = 2 * kWordSize; |
| 318 const intptr_t kArrayOffset = 1 * kWordSize; |
| 319 Label fall_through; |
| 310 | 320 |
| 311 // Read the length_ instance field. | 321 // Compute the size to be allocated, it is based on the array length |
| 322 // and it computed as: |
| 323 // RoundedAllocationSize(sizeof(RawGrowableObjectArray)) + |
| 324 intptr_t fixed_size = GrowableObjectArray::InstanceSize(); |
| 325 |
| 326 Heap* heap = Isolate::Current()->heap(); |
| 327 |
| 328 __ movl(EAX, Address::Absolute(heap->TopAddress())); |
| 329 __ leal(EBX, Address(EAX, fixed_size)); |
| 330 |
| 331 // Check if the allocation fits into the remaining space. |
| 332 // EAX: potential new backing array object start. |
| 333 // EBX: potential next object start. |
| 334 __ cmpl(EBX, Address::Absolute(heap->EndAddress())); |
| 335 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); |
| 336 |
| 337 // Successfully allocated the object(s), now update top to point to |
| 338 // next object start and initialize the object. |
| 339 __ movl(Address::Absolute(heap->TopAddress()), EBX); |
| 340 __ addl(EAX, Immediate(kHeapObjectTag)); |
| 341 |
| 342 // Initialize the tags. |
| 343 // EAX: new growable array object start as a tagged pointer. |
| 344 __ movl(FieldAddress(EAX, GrowableObjectArray::tags_offset()), |
| 345 Immediate(RawObject::SizeTag::update(fixed_size, 0))); |
| 346 |
| 347 // Store backing array object in growable array object. |
| 348 __ movl(EBX, Address(ESP, kArrayOffset)); // data argument. |
| 349 __ StoreIntoObject(EAX, |
| 350 FieldAddress(EAX, GrowableObjectArray::data_offset()), |
| 351 EBX); |
| 352 |
| 353 // Store class value for the growable array object. |
| 354 // EAX: new growable array object start as a tagged pointer. |
| 355 __ movl(EBX, FieldAddress(CTX, Context::isolate_offset())); |
| 356 __ movl(EBX, Address(EBX, Isolate::object_store_offset())); |
| 357 __ movl(EBX, Address(EBX, ObjectStore::growable_object_array_class_offset())); |
| 358 __ StoreIntoObject(EAX, |
| 359 FieldAddress(EAX, GrowableObjectArray::class_offset()), |
| 360 EBX); |
| 361 |
| 362 // Store the type argument field in the growable array object. |
| 363 __ movl(EBX, Address(ESP, kTypeArgumentsOffset)); // type argument. |
| 364 __ StoreIntoObject(EAX, |
| 365 FieldAddress(EAX, |
| 366 GrowableObjectArray::type_arguments_offset()), |
| 367 EBX); |
| 368 |
| 369 // Set the length field in the growable array object to 0. |
| 370 __ movl(FieldAddress(EAX, GrowableObjectArray::length_offset()), |
| 371 Immediate(0)); |
| 372 __ ret(); // returns the newly allocated object in EAX. |
| 373 |
| 374 __ Bind(&fall_through); |
| 375 return false; |
| 376 } |
| 377 |
| 378 |
| 379 // Get length of growable object array. |
| 380 // On stack: growable array (+1), return-address (+0). |
| 312 static bool GrowableArray_getLength(Assembler* assembler) { | 381 static bool GrowableArray_getLength(Assembler* assembler) { |
| 313 intptr_t length_offset = GetOffsetForField(kGrowableArrayClassName, | |
| 314 kGrowableArrayLengthFieldName); | |
| 315 __ movl(EAX, Address(ESP, + 1 * kWordSize)); | 382 __ movl(EAX, Address(ESP, + 1 * kWordSize)); |
| 316 __ movl(EAX, FieldAddress(EAX, length_offset)); | 383 __ movl(EAX, FieldAddress(EAX, GrowableObjectArray::length_offset())); |
| 317 __ ret(); | 384 __ ret(); |
| 318 return true; | 385 return true; |
| 319 } | 386 } |
| 320 | 387 |
| 321 | 388 |
| 389 // Get capacity of growable object array. |
| 390 // On stack: growable array (+1), return-address (+0). |
| 391 static bool GrowableArray_getCapacity(Assembler* assembler) { |
| 392 __ movl(EAX, Address(ESP, + 1 * kWordSize)); |
| 393 __ movl(EAX, FieldAddress(EAX, GrowableObjectArray::data_offset())); |
| 394 __ movl(EAX, FieldAddress(EAX, Array::length_offset())); |
| 395 __ ret(); |
| 396 return true; |
| 397 } |
| 398 |
| 399 |
| 400 // Access growable object array at specified index. |
| 401 // On stack: growable array (+2), index (+1), return-address (+0). |
| 322 static bool GrowableArray_getIndexed(Assembler* assembler) { | 402 static bool GrowableArray_getIndexed(Assembler* assembler) { |
| 323 intptr_t length_offset = GetOffsetForField(kGrowableArrayClassName, | |
| 324 kGrowableArrayLengthFieldName); | |
| 325 intptr_t array_offset = GetOffsetForField(kGrowableArrayClassName, | |
| 326 kGrowableArrayArrayFieldName); | |
| 327 Label fall_through; | 403 Label fall_through; |
| 328 __ movl(EBX, Address(ESP, + 1 * kWordSize)); // Index. | 404 __ movl(EBX, Address(ESP, + 1 * kWordSize)); // Index. |
| 329 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // GrowableArray. | 405 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // GrowableArray. |
| 330 __ testl(EBX, Immediate(kSmiTagMask)); | 406 __ testl(EBX, Immediate(kSmiTagMask)); |
| 331 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index. | 407 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index. |
| 332 // Range check using _length field. | 408 // Range check using _length field. |
| 333 __ cmpl(EBX, FieldAddress(EAX, length_offset)); | 409 __ cmpl(EBX, FieldAddress(EAX, GrowableObjectArray::length_offset())); |
| 334 // Runtime throws exception. | 410 // Runtime throws exception. |
| 335 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); | 411 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); |
| 336 __ movl(EAX, FieldAddress(EAX, array_offset)); // backingArray. | 412 __ movl(EAX, FieldAddress(EAX, GrowableObjectArray::data_offset())); // data. |
| 337 | 413 |
| 338 // Note that EBX is Smi, i.e, times 2. | 414 // Note that EBX is Smi, i.e, times 2. |
| 339 ASSERT(kSmiTagShift == 1); | 415 ASSERT(kSmiTagShift == 1); |
| 340 __ movl(EAX, FieldAddress(EAX, EBX, TIMES_2, sizeof(RawArray))); | 416 __ movl(EAX, FieldAddress(EAX, EBX, TIMES_2, sizeof(RawArray))); |
| 341 __ ret(); | 417 __ ret(); |
| 342 __ Bind(&fall_through); | 418 __ Bind(&fall_through); |
| 343 return false; | 419 return false; |
| 344 } | 420 } |
| 345 | 421 |
| 346 | 422 |
| 347 // On stack: array (+3), index (+2), value (+1), return-address (+0). | 423 // Set value into growable object array at specified index. |
| 424 // On stack: growable array (+3), index (+2), value (+1), return-address (+0). |
| 348 static bool GrowableArray_setIndexed(Assembler* assembler) { | 425 static bool GrowableArray_setIndexed(Assembler* assembler) { |
| 349 if (FLAG_enable_type_checks) { | 426 if (FLAG_enable_type_checks) { |
| 350 return false; | 427 return false; |
| 351 } | 428 } |
| 352 Label fall_through; | 429 Label fall_through; |
| 353 intptr_t length_offset = GetOffsetForField(kGrowableArrayClassName, | |
| 354 kGrowableArrayLengthFieldName); | |
| 355 intptr_t array_offset = GetOffsetForField(kGrowableArrayClassName, | |
| 356 kGrowableArrayArrayFieldName); | |
| 357 __ movl(EBX, Address(ESP, + 2 * kWordSize)); // Index. | 430 __ movl(EBX, Address(ESP, + 2 * kWordSize)); // Index. |
| 358 __ movl(EAX, Address(ESP, + 3 * kWordSize)); // GrowableArray. | 431 __ movl(EAX, Address(ESP, + 3 * kWordSize)); // GrowableArray. |
| 359 __ testl(EBX, Immediate(kSmiTagMask)); | 432 __ testl(EBX, Immediate(kSmiTagMask)); |
| 360 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index. | 433 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index. |
| 361 // Range check using _length field. | 434 // Range check using _length field. |
| 362 __ cmpl(EBX, FieldAddress(EAX, length_offset)); | 435 __ cmpl(EBX, FieldAddress(EAX, GrowableObjectArray::length_offset())); |
| 363 // Runtime throws exception. | 436 // Runtime throws exception. |
| 364 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); | 437 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); |
| 365 __ movl(EAX, FieldAddress(EAX, array_offset)); // backingArray. | 438 __ movl(EAX, FieldAddress(EAX, GrowableObjectArray::data_offset())); // data. |
| 366 __ movl(EDI, Address(ESP, + 1 * kWordSize)); // Value. | 439 __ movl(EDI, Address(ESP, + 1 * kWordSize)); // Value. |
| 367 // Note that EBX is Smi, i.e, times 2. | 440 // Note that EBX is Smi, i.e, times 2. |
| 368 ASSERT(kSmiTagShift == 1); | 441 ASSERT(kSmiTagShift == 1); |
| 369 __ StoreIntoObject(EAX, | 442 __ StoreIntoObject(EAX, |
| 370 FieldAddress(EAX, EBX, TIMES_2, sizeof(RawArray)), | 443 FieldAddress(EAX, EBX, TIMES_2, sizeof(RawArray)), |
| 371 EDI); | 444 EDI); |
| 372 __ ret(); | 445 __ ret(); |
| 373 __ Bind(&fall_through); | 446 __ Bind(&fall_through); |
| 374 return false; | 447 return false; |
| 375 } | 448 } |
| 376 | 449 |
| 377 | 450 |
| 451 // Set length of growable object array. |
| 452 // On stack: growable array (+2), length (+1), return-address (+0). |
| 453 static bool GrowableArray_setLength(Assembler* assembler) { |
| 454 Label fall_through; |
| 455 __ movl(EAX, Address(ESP, + 2 * kWordSize)); |
| 456 __ movl(EBX, Address(ESP, + 1 * kWordSize)); |
| 457 __ movl(EDI, FieldAddress(EAX, GrowableObjectArray::data_offset())); |
| 458 __ cmpl(EBX, FieldAddress(EDI, Array::length_offset())); |
| 459 __ j(ABOVE, &fall_through, Assembler::kNearJump); |
| 460 __ movl(FieldAddress(EAX, GrowableObjectArray::length_offset()), EBX); |
| 461 __ ret(); |
| 462 __ Bind(&fall_through); |
| 463 return true; |
| 464 } |
| 465 |
| 466 |
| 467 // Set data of growable object array. |
| 468 // On stack: growable array (+2), data (+1), return-address (+0). |
| 469 static bool GrowableArray_setData(Assembler* assembler) { |
| 470 if (FLAG_enable_type_checks) { |
| 471 return false; |
| 472 } |
| 473 __ movl(EAX, Address(ESP, + 2 * kWordSize)); |
| 474 __ movl(EBX, Address(ESP, + 1 * kWordSize)); |
| 475 __ movl(FieldAddress(EAX, GrowableObjectArray::data_offset()), EBX); |
| 476 __ ret(); |
| 477 return true; |
| 478 } |
| 479 |
| 480 |
| 378 // Handles only class InternalByteArray. | 481 // Handles only class InternalByteArray. |
| 379 static bool ByteArrayBase_getLength(Assembler* assembler) { | 482 static bool ByteArrayBase_getLength(Assembler* assembler) { |
| 380 ObjectStore* object_store = Isolate::Current()->object_store(); | 483 ObjectStore* object_store = Isolate::Current()->object_store(); |
| 381 Label fall_through; | 484 Label fall_through; |
| 382 __ movl(EAX, Address(ESP, + 1 * kWordSize)); | 485 __ movl(EAX, Address(ESP, + 1 * kWordSize)); |
| 383 __ movl(EBX, FieldAddress(EAX, Object::class_offset())); | 486 __ movl(EBX, FieldAddress(EAX, Object::class_offset())); |
| 384 __ CompareObject(EBX, | 487 __ CompareObject(EBX, |
| 385 Class::ZoneHandle(object_store->internal_byte_array_class())); | 488 Class::ZoneHandle(object_store->internal_byte_array_class())); |
| 386 __ j(NOT_EQUAL, &fall_through); | 489 __ j(NOT_EQUAL, &fall_through); |
| 387 __ movl(EAX, FieldAddress(EAX, InternalByteArray::length_offset())); | 490 __ movl(EAX, FieldAddress(EAX, InternalByteArray::length_offset())); |
| (...skipping 856 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1244 __ ret(); | 1347 __ ret(); |
| 1245 __ Bind(&is_true); | 1348 __ Bind(&is_true); |
| 1246 __ LoadObject(EAX, bool_true); | 1349 __ LoadObject(EAX, bool_true); |
| 1247 __ ret(); | 1350 __ ret(); |
| 1248 return true; | 1351 return true; |
| 1249 } | 1352 } |
| 1250 | 1353 |
| 1251 #undef __ | 1354 #undef __ |
| 1252 | 1355 |
| 1253 | 1356 |
| 1357 static bool CompareNames(const char* test_name, const char* name) { |
| 1358 if (strcmp(test_name, name) == 0) { |
| 1359 return true; |
| 1360 } |
| 1361 if ((name[0] == '_') && (test_name[0] == '_')) { |
| 1362 // Check if the private class is member of corelib and matches the |
| 1363 // test_class_name. |
| 1364 const Library& core_lib = Library::Handle(Library::CoreLibrary()); |
| 1365 const Library& core_impl_lib = Library::Handle(Library::CoreImplLibrary()); |
| 1366 String& test_str = String::Handle(String::New(test_name)); |
| 1367 String& test_str_with_key = String::Handle(); |
| 1368 test_str_with_key = |
| 1369 String::Concat(test_str, String::Handle(core_lib.private_key())); |
| 1370 if (strcmp(test_str_with_key.ToCString(), name) == 0) { |
| 1371 return true; |
| 1372 } |
| 1373 test_str_with_key = |
| 1374 String::Concat(test_str, String::Handle(core_impl_lib.private_key())); |
| 1375 if (strcmp(test_str_with_key.ToCString(), name) == 0) { |
| 1376 return true; |
| 1377 } |
| 1378 } |
| 1379 return false; |
| 1380 } |
| 1381 |
| 1382 |
| 1254 // Returns true if the function matches function_name and class_name, with | 1383 // Returns true if the function matches function_name and class_name, with |
| 1255 // special recognition of corelib private classes | 1384 // special recognition of corelib private classes |
| 1256 static bool TestFunction(const Function& function, | 1385 static bool TestFunction(const Function& function, |
| 1257 const char* function_class_name, | 1386 const char* function_class_name, |
| 1258 const char* function_name, | 1387 const char* function_name, |
| 1259 const char* test_class_name, | 1388 const char* test_class_name, |
| 1260 const char* test_function_name) { | 1389 const char* test_function_name) { |
| 1261 if (strcmp(test_function_name, function_name) != 0) return false; | 1390 return CompareNames(test_class_name, function_class_name) && |
| 1262 | 1391 CompareNames(test_function_name, function_name); |
| 1263 if ((function_class_name[0] == '_') && (test_class_name[0] == '_')) { | |
| 1264 // Check if the private class is member of corelib and matches the | |
| 1265 // test_class_name. | |
| 1266 const Library& core_lib = Library::Handle(Library::CoreLibrary()); | |
| 1267 const Library& core_impl_lib = Library::Handle(Library::CoreImplLibrary()); | |
| 1268 String& test_str = String::Handle(String::New(test_class_name)); | |
| 1269 String& test_str_with_key = String::Handle(); | |
| 1270 test_str_with_key = | |
| 1271 String::Concat(test_str, String::Handle(core_lib.private_key())); | |
| 1272 if (strcmp(test_str_with_key.ToCString(), function_class_name) == 0) { | |
| 1273 return true; | |
| 1274 } | |
| 1275 test_str_with_key = | |
| 1276 String::Concat(test_str, String::Handle(core_impl_lib.private_key())); | |
| 1277 if (strcmp(test_str_with_key.ToCString(), function_class_name) == 0) { | |
| 1278 return true; | |
| 1279 } | |
| 1280 } | |
| 1281 return strcmp(test_class_name, function_class_name) == 0; | |
| 1282 } | 1392 } |
| 1283 | 1393 |
| 1284 | 1394 |
| 1285 bool Intrinsifier::Intrinsify(const Function& function, Assembler* assembler) { | 1395 bool Intrinsifier::Intrinsify(const Function& function, Assembler* assembler) { |
| 1286 if (!FLAG_intrinsify) return false; | 1396 if (!FLAG_intrinsify) return false; |
| 1287 const char* function_name = String::Handle(function.name()).ToCString(); | 1397 const char* function_name = String::Handle(function.name()).ToCString(); |
| 1288 const Class& function_class = Class::Handle(function.owner()); | 1398 const Class& function_class = Class::Handle(function.owner()); |
| 1289 const char* class_name = String::Handle(function_class.Name()).ToCString(); | 1399 const char* class_name = String::Handle(function_class.Name()).ToCString(); |
| 1290 // Only core library methods can be intrinsified. | 1400 // Only core library methods can be intrinsified. |
| 1291 const Library& core_lib = Library::Handle(Library::CoreLibrary()); | 1401 const Library& core_lib = Library::Handle(Library::CoreLibrary()); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1302 } \ | 1412 } \ |
| 1303 | 1413 |
| 1304 INTRINSIC_LIST(FIND_INTRINSICS); | 1414 INTRINSIC_LIST(FIND_INTRINSICS); |
| 1305 #undef FIND_INTRINSICS | 1415 #undef FIND_INTRINSICS |
| 1306 return false; | 1416 return false; |
| 1307 } | 1417 } |
| 1308 | 1418 |
| 1309 } // namespace dart | 1419 } // namespace dart |
| 1310 | 1420 |
| 1311 #endif // defined TARGET_ARCH_IA32 | 1421 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |