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

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

Issue 12547018: Add the allocator intrinsics for dart:typeddata implementation. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 9 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/intrinsifier_arm.cc ('k') | runtime/vm/intrinsifier_mips.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) 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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/intrinsifier_arm.cc ('k') | runtime/vm/intrinsifier_mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698