Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 449 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 460 | 460 |
| 461 // Gets the length of a ByteArray. | 461 // Gets the length of a ByteArray. |
| 462 bool Intrinsifier::ByteArrayBase_getLength(Assembler* assembler) { | 462 bool Intrinsifier::ByteArrayBase_getLength(Assembler* assembler) { |
| 463 __ movl(EAX, Address(ESP, + 1 * kWordSize)); | 463 __ movl(EAX, Address(ESP, + 1 * kWordSize)); |
| 464 __ movl(EAX, FieldAddress(EAX, ByteArray::length_offset())); | 464 __ movl(EAX, FieldAddress(EAX, ByteArray::length_offset())); |
| 465 __ ret(); | 465 __ ret(); |
| 466 return true; | 466 return true; |
| 467 } | 467 } |
| 468 | 468 |
| 469 | 469 |
| 470 #define TYPED_ARRAY_ALLOCATION(type_name, scale_factor) \ | 470 #define TYPED_ARRAY_ALLOCATION(type_name, cid, max_len, scale_factor) \ |
| 471 Label fall_through; \ | 471 Label fall_through; \ |
| 472 const intptr_t kArrayLengthStackOffset = 1 * kWordSize; \ | 472 const intptr_t kArrayLengthStackOffset = 1 * kWordSize; \ |
| 473 __ movl(EDI, Address(ESP, kArrayLengthStackOffset)); /* Array length. */ \ | 473 __ movl(EDI, Address(ESP, kArrayLengthStackOffset)); /* Array length. */ \ |
| 474 /* Check that length is a positive Smi. */ \ | 474 /* Check that length is a positive Smi. */ \ |
| 475 /* EDI: requested array length argument. */ \ | 475 /* EDI: requested array length argument. */ \ |
| 476 __ testl(EDI, Immediate(kSmiTagSize)); \ | 476 __ testl(EDI, Immediate(kSmiTagSize)); \ |
| 477 __ j(NOT_ZERO, &fall_through); \ | 477 __ j(NOT_ZERO, &fall_through); \ |
| 478 __ cmpl(EDI, Immediate(0)); \ | 478 __ cmpl(EDI, Immediate(0)); \ |
| 479 __ j(LESS, &fall_through); \ | 479 __ j(LESS, &fall_through); \ |
| 480 __ SmiUntag(EDI); \ | 480 __ SmiUntag(EDI); \ |
| 481 /* Check for maximum allowed length. */ \ | 481 /* Check for maximum allowed length. */ \ |
| 482 /* EDI: untagged array length. */ \ | 482 /* EDI: untagged array length. */ \ |
| 483 __ cmpl(EDI, Immediate(type_name::kMaxElements)); \ | 483 __ cmpl(EDI, Immediate(max_len)); \ |
| 484 __ j(GREATER, &fall_through); \ | 484 __ j(GREATER, &fall_through); \ |
| 485 const intptr_t fixed_size = sizeof(Raw##type_name) + kObjectAlignment - 1; \ | 485 const intptr_t fixed_size = sizeof(Raw##type_name) + kObjectAlignment - 1; \ |
| 486 __ leal(EDI, Address(EDI, scale_factor, fixed_size)); \ | 486 __ leal(EDI, Address(EDI, scale_factor, fixed_size)); \ |
| 487 __ andl(EDI, Immediate(-kObjectAlignment)); \ | 487 __ andl(EDI, Immediate(-kObjectAlignment)); \ |
| 488 Heap* heap = Isolate::Current()->heap(); \ | 488 Heap* heap = Isolate::Current()->heap(); \ |
| 489 \ | 489 \ |
| 490 __ movl(EAX, Address::Absolute(heap->TopAddress())); \ | 490 __ movl(EAX, Address::Absolute(heap->TopAddress())); \ |
| 491 __ movl(EBX, EAX); \ | 491 __ movl(EBX, EAX); \ |
| 492 \ | 492 \ |
| 493 /* EDI: allocation size. */ \ | 493 /* EDI: allocation size. */ \ |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 515 __ cmpl(EDI, Immediate(RawObject::SizeTag::kMaxSizeTag)); \ | 515 __ cmpl(EDI, Immediate(RawObject::SizeTag::kMaxSizeTag)); \ |
| 516 __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump); \ | 516 __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump); \ |
| 517 __ shll(EDI, Immediate(RawObject::kSizeTagBit - kObjectAlignmentLog2)); \ | 517 __ shll(EDI, Immediate(RawObject::kSizeTagBit - kObjectAlignmentLog2)); \ |
| 518 __ jmp(&done, Assembler::kNearJump); \ | 518 __ jmp(&done, Assembler::kNearJump); \ |
| 519 \ | 519 \ |
| 520 __ Bind(&size_tag_overflow); \ | 520 __ Bind(&size_tag_overflow); \ |
| 521 __ movl(EDI, Immediate(0)); \ | 521 __ movl(EDI, Immediate(0)); \ |
| 522 __ Bind(&done); \ | 522 __ Bind(&done); \ |
| 523 \ | 523 \ |
| 524 /* Get the class index and insert it into the tags. */ \ | 524 /* Get the class index and insert it into the tags. */ \ |
| 525 __ orl(EDI, Immediate(RawObject::ClassIdTag::encode(k##type_name##Cid))); \ | 525 __ orl(EDI, Immediate(RawObject::ClassIdTag::encode(cid))); \ |
| 526 __ movl(FieldAddress(EAX, type_name::tags_offset()), EDI); /* Tags. */ \ | 526 __ movl(FieldAddress(EAX, type_name::tags_offset()), EDI); /* Tags. */ \ |
| 527 } \ | 527 } \ |
| 528 /* Set the length field. */ \ | 528 /* Set the length field. */ \ |
| 529 /* EAX: new object start as a tagged pointer. */ \ | 529 /* EAX: new object start as a tagged pointer. */ \ |
| 530 /* EBX: new object end address. */ \ | 530 /* EBX: new object end address. */ \ |
| 531 __ movl(EDI, Address(ESP, kArrayLengthStackOffset)); /* Array length. */ \ | 531 __ movl(EDI, Address(ESP, kArrayLengthStackOffset)); /* Array length. */ \ |
| 532 __ StoreIntoObjectNoBarrier(EAX, \ | 532 __ StoreIntoObjectNoBarrier(EAX, \ |
| 533 FieldAddress(EAX, type_name::length_offset()), \ | 533 FieldAddress(EAX, type_name::length_offset()), \ |
| 534 EDI); \ | 534 EDI); \ |
| 535 /* Initialize all array elements to 0. */ \ | 535 /* Initialize all array elements to 0. */ \ |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 546 __ j(ABOVE_EQUAL, &done, Assembler::kNearJump); \ | 546 __ j(ABOVE_EQUAL, &done, Assembler::kNearJump); \ |
| 547 __ movl(Address(EDI, 0), ECX); \ | 547 __ movl(Address(EDI, 0), ECX); \ |
| 548 __ addl(EDI, Immediate(kWordSize)); \ | 548 __ addl(EDI, Immediate(kWordSize)); \ |
| 549 __ jmp(&init_loop, Assembler::kNearJump); \ | 549 __ jmp(&init_loop, Assembler::kNearJump); \ |
| 550 __ Bind(&done); \ | 550 __ Bind(&done); \ |
| 551 \ | 551 \ |
| 552 __ ret(); \ | 552 __ ret(); \ |
| 553 __ Bind(&fall_through); \ | 553 __ Bind(&fall_through); \ |
| 554 | 554 |
| 555 | 555 |
| 556 bool Intrinsifier::Int8Array_new(Assembler* assembler) { | 556 #define SCALARLIST_ALLOCATOR(clazz, scale) \ |
| 557 TYPED_ARRAY_ALLOCATION(Int8Array, TIMES_1); | 557 bool Intrinsifier::clazz##_new(Assembler* assembler) { \ |
| 558 return false; | 558 TYPED_ARRAY_ALLOCATION(clazz, k##clazz##Cid, clazz::kMaxElements, scale); \ |
| 559 return false; \ | |
| 560 } \ | |
| 561 bool Intrinsifier::clazz##_factory(Assembler* assembler) { \ | |
| 562 TYPED_ARRAY_ALLOCATION(clazz, k##clazz##Cid, clazz::kMaxElements, scale); \ | |
| 563 return false; \ | |
| 559 } | 564 } |
| 560 | 565 |
| 561 | 566 |
| 562 bool Intrinsifier::Int8Array_factory(Assembler* assembler) { | 567 SCALARLIST_ALLOCATOR(Int8Array, TIMES_1) |
| 563 TYPED_ARRAY_ALLOCATION(Int8Array, TIMES_1); | 568 SCALARLIST_ALLOCATOR(Uint8Array, TIMES_1) |
| 564 return false; | 569 SCALARLIST_ALLOCATOR(Uint8ClampedArray, TIMES_1) |
| 565 } | 570 SCALARLIST_ALLOCATOR(Int16Array, TIMES_2) |
| 566 | 571 SCALARLIST_ALLOCATOR(Uint16Array, TIMES_2) |
| 567 | 572 SCALARLIST_ALLOCATOR(Int32Array, TIMES_4) |
| 568 bool Intrinsifier::Uint8Array_new(Assembler* assembler) { | 573 SCALARLIST_ALLOCATOR(Uint32Array, TIMES_4) |
| 569 TYPED_ARRAY_ALLOCATION(Uint8Array, TIMES_1); | 574 SCALARLIST_ALLOCATOR(Int64Array, TIMES_8) |
| 570 return false; | 575 SCALARLIST_ALLOCATOR(Uint64Array, TIMES_8) |
| 571 } | 576 SCALARLIST_ALLOCATOR(Float32Array, TIMES_4) |
| 572 | 577 SCALARLIST_ALLOCATOR(Float64Array, TIMES_8) |
| 573 | |
| 574 bool Intrinsifier::Uint8Array_factory(Assembler* assembler) { | |
| 575 TYPED_ARRAY_ALLOCATION(Uint8Array, TIMES_1); | |
| 576 return false; | |
| 577 } | |
| 578 | |
| 579 | |
| 580 bool Intrinsifier::Uint8ClampedArray_new(Assembler* assembler) { | |
| 581 TYPED_ARRAY_ALLOCATION(Uint8ClampedArray, TIMES_1); | |
| 582 return false; | |
| 583 } | |
| 584 | |
| 585 | |
| 586 bool Intrinsifier::Uint8ClampedArray_factory(Assembler* assembler) { | |
| 587 TYPED_ARRAY_ALLOCATION(Uint8ClampedArray, TIMES_1); | |
| 588 return false; | |
| 589 } | |
| 590 | |
| 591 | |
| 592 bool Intrinsifier::Int16Array_new(Assembler* assembler) { | |
| 593 TYPED_ARRAY_ALLOCATION(Int16Array, TIMES_2); | |
| 594 return false; | |
| 595 } | |
| 596 | |
| 597 | |
| 598 bool Intrinsifier::Int16Array_factory(Assembler* assembler) { | |
| 599 TYPED_ARRAY_ALLOCATION(Int16Array, TIMES_2); | |
| 600 return false; | |
| 601 } | |
| 602 | |
| 603 | |
| 604 bool Intrinsifier::Uint16Array_new(Assembler* assembler) { | |
| 605 TYPED_ARRAY_ALLOCATION(Uint16Array, TIMES_2); | |
| 606 return false; | |
| 607 } | |
| 608 | |
| 609 | |
| 610 bool Intrinsifier::Uint16Array_factory(Assembler* assembler) { | |
| 611 TYPED_ARRAY_ALLOCATION(Uint16Array, TIMES_2); | |
| 612 return false; | |
| 613 } | |
| 614 | |
| 615 | |
| 616 bool Intrinsifier::Int32Array_new(Assembler* assembler) { | |
| 617 TYPED_ARRAY_ALLOCATION(Int32Array, TIMES_4); | |
| 618 return false; | |
| 619 } | |
| 620 | |
| 621 | |
| 622 bool Intrinsifier::Int32Array_factory(Assembler* assembler) { | |
| 623 TYPED_ARRAY_ALLOCATION(Int32Array, TIMES_4); | |
| 624 return false; | |
| 625 } | |
| 626 | |
| 627 | |
| 628 bool Intrinsifier::Uint32Array_new(Assembler* assembler) { | |
| 629 TYPED_ARRAY_ALLOCATION(Uint32Array, TIMES_4); | |
| 630 return false; | |
| 631 } | |
| 632 | |
| 633 | |
| 634 bool Intrinsifier::Uint32Array_factory(Assembler* assembler) { | |
| 635 TYPED_ARRAY_ALLOCATION(Uint32Array, TIMES_4); | |
| 636 return false; | |
| 637 } | |
| 638 | 578 |
| 639 | 579 |
| 640 bool Intrinsifier::Int64Array_getIndexed(Assembler* assembler) { | 580 bool Intrinsifier::Int64Array_getIndexed(Assembler* assembler) { |
| 641 return false; | 581 return false; |
| 642 } | 582 } |
| 643 | 583 |
| 644 | 584 |
| 645 bool Intrinsifier::Int64Array_new(Assembler* assembler) { | |
| 646 TYPED_ARRAY_ALLOCATION(Int64Array, TIMES_8); | |
| 647 return false; | |
| 648 } | |
| 649 | |
| 650 | |
| 651 bool Intrinsifier::Int64Array_factory(Assembler* assembler) { | |
| 652 TYPED_ARRAY_ALLOCATION(Int64Array, TIMES_8); | |
| 653 return false; | |
| 654 } | |
| 655 | |
| 656 | |
| 657 bool Intrinsifier::Uint64Array_getIndexed(Assembler* assembler) { | 585 bool Intrinsifier::Uint64Array_getIndexed(Assembler* assembler) { |
| 658 return false; | 586 return false; |
| 659 } | 587 } |
| 660 | 588 |
| 661 | 589 |
| 662 bool Intrinsifier::Uint64Array_new(Assembler* assembler) { | 590 // Gets the length of a TypedData. |
| 663 TYPED_ARRAY_ALLOCATION(Uint64Array, TIMES_8); | 591 bool Intrinsifier::TypedData_getLength(Assembler* assembler) { |
| 664 return false; | 592 __ movl(EAX, Address(ESP, + 1 * kWordSize)); |
| 593 __ movl(EAX, FieldAddress(EAX, TypedData::length_offset())); | |
| 594 __ ret(); | |
| 595 return true; | |
| 665 } | 596 } |
| 666 | 597 |
| 667 | 598 |
| 668 bool Intrinsifier::Uint64Array_factory(Assembler* assembler) { | 599 static ScaleFactor GetScaleFactor(intptr_t size) { |
| 669 TYPED_ARRAY_ALLOCATION(Uint64Array, TIMES_8); | 600 switch (size) { |
| 670 return false; | 601 case 1: return TIMES_1; |
| 671 } | 602 case 2: return TIMES_2; |
| 603 case 4: return TIMES_4; | |
| 604 case 8: return TIMES_8; | |
| 605 } | |
| 606 UNREACHABLE(); | |
| 607 return static_cast<ScaleFactor>(0); | |
| 608 }; | |
|
srdjan
2013/03/08 17:40:24
Maybe we could factor this out. There are 3 identi
siva
2013/03/09 00:02:48
Good idea, In an new CL I will factor this into Ut
| |
| 672 | 609 |
| 673 | 610 |
| 674 bool Intrinsifier::Float32Array_new(Assembler* assembler) { | 611 #define TYPEDDATA_ALLOCATOR(clazz) \ |
| 675 TYPED_ARRAY_ALLOCATION(Float32Array, TIMES_4); | 612 bool Intrinsifier::TypedData_##clazz##_new(Assembler* assembler) { \ |
| 676 return false; | 613 intptr_t size = TypedData::ElementSizeInBytes(kTypedData##clazz##Cid); \ |
| 614 intptr_t max_len = kSmiMax / size; \ | |
|
srdjan
2013/03/08 17:40:24
max_len may be needed by other parts of code. Plea
siva
2013/03/09 00:02:48
I have added TypedData::MaxElements which computes
| |
| 615 ScaleFactor scale = GetScaleFactor(size); \ | |
| 616 TYPED_ARRAY_ALLOCATION(TypedData, kTypedData##clazz##Cid, max_len, scale); \ | |
| 617 return false; \ | |
| 618 } \ | |
| 619 bool Intrinsifier::TypedData_##clazz##_factory(Assembler* assembler) { \ | |
| 620 intptr_t size = TypedData::ElementSizeInBytes(kTypedData##clazz##Cid); \ | |
| 621 intptr_t max_len = kSmiMax / size; \ | |
| 622 ScaleFactor scale = GetScaleFactor(size); \ | |
| 623 TYPED_ARRAY_ALLOCATION(TypedData, kTypedData##clazz##Cid, max_len, scale); \ | |
| 624 return false; \ | |
| 677 } | 625 } |
| 678 | 626 CLASS_LIST_TYPED_DATA(TYPEDDATA_ALLOCATOR) |
| 679 | 627 #undef TYPEDDATA_ALLOCATOR |
| 680 bool Intrinsifier::Float32Array_factory(Assembler* assembler) { | |
| 681 TYPED_ARRAY_ALLOCATION(Float32Array, TIMES_4); | |
| 682 return false; | |
| 683 } | |
| 684 | |
| 685 | |
| 686 bool Intrinsifier::Float64Array_new(Assembler* assembler) { | |
| 687 TYPED_ARRAY_ALLOCATION(Float64Array, TIMES_8); | |
| 688 return false; | |
| 689 } | |
| 690 | |
| 691 | |
| 692 bool Intrinsifier::Float64Array_factory(Assembler* assembler) { | |
| 693 TYPED_ARRAY_ALLOCATION(Float64Array, TIMES_8); | |
| 694 return false; | |
| 695 } | |
| 696 | 628 |
| 697 | 629 |
| 698 // Tests if two top most arguments are smis, jumps to label not_smi if not. | 630 // Tests if two top most arguments are smis, jumps to label not_smi if not. |
| 699 // Topmost argument is in EAX. | 631 // Topmost argument is in EAX. |
| 700 static void TestBothArgumentsSmis(Assembler* assembler, Label* not_smi) { | 632 static void TestBothArgumentsSmis(Assembler* assembler, Label* not_smi) { |
| 701 __ movl(EAX, Address(ESP, + 1 * kWordSize)); | 633 __ movl(EAX, Address(ESP, + 1 * kWordSize)); |
| 702 __ movl(EBX, Address(ESP, + 2 * kWordSize)); | 634 __ movl(EBX, Address(ESP, + 2 * kWordSize)); |
| 703 __ orl(EBX, EAX); | 635 __ orl(EBX, EAX); |
| 704 __ testl(EBX, Immediate(kSmiTagMask)); | 636 __ testl(EBX, Immediate(kSmiTagMask)); |
| 705 __ j(NOT_ZERO, not_smi, Assembler::kNearJump); | 637 __ j(NOT_ZERO, not_smi, Assembler::kNearJump); |
| (...skipping 891 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1597 __ SmiTag(EAX); | 1529 __ SmiTag(EAX); |
| 1598 __ movl(FieldAddress(EBX, String::hash_offset()), EAX); | 1530 __ movl(FieldAddress(EBX, String::hash_offset()), EAX); |
| 1599 __ ret(); | 1531 __ ret(); |
| 1600 return true; | 1532 return true; |
| 1601 } | 1533 } |
| 1602 | 1534 |
| 1603 #undef __ | 1535 #undef __ |
| 1604 } // namespace dart | 1536 } // namespace dart |
| 1605 | 1537 |
| 1606 #endif // defined TARGET_ARCH_IA32 | 1538 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |