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 #include "vm/globals.h" | 5 #include "vm/globals.h" |
| 6 #if defined(TARGET_ARCH_ARM) | 6 #if defined(TARGET_ARCH_ARM) |
| 7 | 7 |
| 8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
| 9 #include "vm/code_generator.h" | 9 #include "vm/code_generator.h" |
| 10 #include "vm/cpu.h" | 10 #include "vm/cpu.h" |
| (...skipping 619 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 630 const intptr_t fixed_size = sizeof(RawArray) + kObjectAlignment - 1; | 630 const intptr_t fixed_size = sizeof(RawArray) + kObjectAlignment - 1; |
| 631 __ LoadImmediate(R8, fixed_size); | 631 __ LoadImmediate(R8, fixed_size); |
| 632 __ add(R8, R8, Operand(R3, LSL, 1)); // R3 is a Smi. | 632 __ add(R8, R8, Operand(R3, LSL, 1)); // R3 is a Smi. |
| 633 ASSERT(kSmiTagShift == 1); | 633 ASSERT(kSmiTagShift == 1); |
| 634 __ bic(R8, R8, Operand(kObjectAlignment - 1)); | 634 __ bic(R8, R8, Operand(kObjectAlignment - 1)); |
| 635 | 635 |
| 636 // R8: Allocation size. | 636 // R8: Allocation size. |
| 637 | 637 |
| 638 Isolate* isolate = Isolate::Current(); | 638 Isolate* isolate = Isolate::Current(); |
| 639 Heap* heap = isolate->heap(); | 639 Heap* heap = isolate->heap(); |
| 640 | 640 Heap::Space space = heap->SpaceForAllocation(kArrayCid); |
| 641 __ LoadImmediate(R6, heap->TopAddress()); | 641 __ LoadImmediate(R6, heap->TopAddress(space)); |
| 642 __ ldr(R0, Address(R6, 0)); // Potential new object start. | 642 __ ldr(R0, Address(R6, 0)); // Potential new object start. |
| 643 __ adds(R7, R0, Operand(R8)); // Potential next object start. | 643 __ adds(R7, R0, Operand(R8)); // Potential next object start. |
| 644 __ b(&slow_case, VS); | 644 __ b(&slow_case, VS); |
| 645 | 645 |
| 646 // Check if the allocation fits into the remaining space. | 646 // Check if the allocation fits into the remaining space. |
| 647 // R0: potential new object start. | 647 // R0: potential new object start. |
| 648 // R7: potential next object start. | 648 // R7: potential next object start. |
| 649 // R8: allocation size. | 649 // R8: allocation size. |
| 650 __ LoadImmediate(R3, heap->EndAddress()); | 650 __ LoadImmediate(R3, heap->EndAddress(space)); |
| 651 __ ldr(R3, Address(R3, 0)); | 651 __ ldr(R3, Address(R3, 0)); |
| 652 __ cmp(R7, Operand(R3)); | 652 __ cmp(R7, Operand(R3)); |
| 653 __ b(&slow_case, CS); | 653 __ b(&slow_case, CS); |
| 654 | 654 |
| 655 // Successfully allocated the object(s), now update top to point to | 655 // Successfully allocated the object(s), now update top to point to |
| 656 // next object start and initialize the object. | 656 // next object start and initialize the object. |
| 657 __ str(R7, Address(R6, 0)); | 657 __ str(R7, Address(R6, 0)); |
| 658 __ add(R0, R0, Operand(kHeapObjectTag)); | 658 __ add(R0, R0, Operand(kHeapObjectTag)); |
| 659 __ UpdateAllocationStatsWithSize(kArrayCid, R8, R4); | 659 __ UpdateAllocationStatsWithSize(kArrayCid, R8, R4, space); |
| 660 | 660 |
| 661 // Initialize the tags. | 661 // Initialize the tags. |
| 662 // R0: new object start as a tagged pointer. | 662 // R0: new object start as a tagged pointer. |
| 663 // R7: new object end address. | 663 // R7: new object end address. |
| 664 // R8: allocation size. | 664 // R8: allocation size. |
| 665 { | 665 { |
| 666 const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2; | 666 const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2; |
| 667 const Class& cls = Class::Handle(isolate->object_store()->array_class()); | 667 const Class& cls = Class::Handle(isolate->object_store()->array_class()); |
| 668 | 668 |
| 669 __ CompareImmediate(R8, RawObject::SizeTag::kMaxSizeTag); | 669 __ CompareImmediate(R8, RawObject::SizeTag::kMaxSizeTag); |
| 670 __ mov(R8, Operand(R8, LSL, shift), LS); | 670 __ mov(R8, Operand(R8, LSL, shift), LS); |
| 671 __ mov(R8, Operand(0), HI); | 671 __ mov(R8, Operand(0), HI); |
| 672 | 672 |
| 673 // Get the class index and insert it into the tags. | 673 // Get the class index and insert it into the tags. |
| 674 // R8: size and bit tags. | 674 // R8: size and bit tags. |
| 675 __ LoadImmediate(TMP, RawObject::ClassIdTag::encode(cls.id())); | 675 __ LoadImmediate(TMP, RawObject::ClassIdTag::encode(cls.id())); |
|
Ivan Posva
2014/09/19 18:45:55
ditto
koda
2014/09/19 20:48:29
Done.
| |
| 676 __ orr(R8, R8, Operand(TMP)); | 676 __ orr(R8, R8, Operand(TMP)); |
| 677 __ str(R8, FieldAddress(R0, Array::tags_offset())); // Store tags. | 677 __ str(R8, FieldAddress(R0, Array::tags_offset())); // Store tags. |
| 678 } | 678 } |
| 679 | 679 |
| 680 // R0: new object start as a tagged pointer. | 680 // R0: new object start as a tagged pointer. |
| 681 // R7: new object end address. | 681 // R7: new object end address. |
| 682 // Store the type argument field. | 682 // Store the type argument field. |
| 683 __ StoreIntoObjectNoBarrier(R0, | 683 __ StoreIntoObjectNoBarrier(R0, |
| 684 FieldAddress(R0, Array::type_arguments_offset()), | 684 FieldAddress(R0, Array::type_arguments_offset()), |
| 685 R1); | 685 R1); |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 863 } | 863 } |
| 864 | 864 |
| 865 | 865 |
| 866 // Called for inline allocation of contexts. | 866 // Called for inline allocation of contexts. |
| 867 // Input: | 867 // Input: |
| 868 // R1: number of context variables. | 868 // R1: number of context variables. |
| 869 // Output: | 869 // Output: |
| 870 // R0: new allocated RawContext object. | 870 // R0: new allocated RawContext object. |
| 871 void StubCode::GenerateAllocateContextStub(Assembler* assembler) { | 871 void StubCode::GenerateAllocateContextStub(Assembler* assembler) { |
| 872 if (FLAG_inline_alloc) { | 872 if (FLAG_inline_alloc) { |
| 873 const Class& context_class = Class::ZoneHandle(Object::context_class()); | 873 const Class& context_class = Class::ZoneHandle(Object::context_class()); |
|
Ivan Posva
2014/09/19 18:45:55
ditto: Just use the kXYZCid everywhere where we kn
koda
2014/09/19 20:48:29
Done.
| |
| 874 Label slow_case; | 874 Label slow_case; |
| 875 Heap* heap = Isolate::Current()->heap(); | 875 Heap* heap = Isolate::Current()->heap(); |
| 876 // First compute the rounded instance size. | 876 // First compute the rounded instance size. |
| 877 // R1: number of context variables. | 877 // R1: number of context variables. |
| 878 intptr_t fixed_size = sizeof(RawContext) + kObjectAlignment - 1; | 878 intptr_t fixed_size = sizeof(RawContext) + kObjectAlignment - 1; |
| 879 __ LoadImmediate(R2, fixed_size); | 879 __ LoadImmediate(R2, fixed_size); |
| 880 __ add(R2, R2, Operand(R1, LSL, 2)); | 880 __ add(R2, R2, Operand(R1, LSL, 2)); |
| 881 ASSERT(kSmiTagShift == 1); | 881 ASSERT(kSmiTagShift == 1); |
| 882 __ bic(R2, R2, Operand(kObjectAlignment - 1)); | 882 __ bic(R2, R2, Operand(kObjectAlignment - 1)); |
| 883 | 883 |
| 884 // Now allocate the object. | 884 // Now allocate the object. |
| 885 // R1: number of context variables. | 885 // R1: number of context variables. |
| 886 // R2: object size. | 886 // R2: object size. |
| 887 __ LoadImmediate(R5, heap->TopAddress()); | 887 intptr_t cid = context_class.id(); |
| 888 Heap::Space space = heap->SpaceForAllocation(cid); | |
| 889 __ LoadImmediate(R5, heap->TopAddress(space)); | |
| 888 __ ldr(R0, Address(R5, 0)); | 890 __ ldr(R0, Address(R5, 0)); |
| 889 __ add(R3, R2, Operand(R0)); | 891 __ add(R3, R2, Operand(R0)); |
| 890 // Check if the allocation fits into the remaining space. | 892 // Check if the allocation fits into the remaining space. |
| 891 // R0: potential new object. | 893 // R0: potential new object. |
| 892 // R1: number of context variables. | 894 // R1: number of context variables. |
| 893 // R2: object size. | 895 // R2: object size. |
| 894 // R3: potential next object start. | 896 // R3: potential next object start. |
| 895 __ LoadImmediate(IP, heap->EndAddress()); | 897 __ LoadImmediate(IP, heap->EndAddress(space)); |
| 896 __ ldr(IP, Address(IP, 0)); | 898 __ ldr(IP, Address(IP, 0)); |
| 897 __ cmp(R3, Operand(IP)); | 899 __ cmp(R3, Operand(IP)); |
| 898 if (FLAG_use_slow_path) { | 900 if (FLAG_use_slow_path) { |
| 899 __ b(&slow_case); | 901 __ b(&slow_case); |
| 900 } else { | 902 } else { |
| 901 __ b(&slow_case, CS); // Branch if unsigned higher or equal. | 903 __ b(&slow_case, CS); // Branch if unsigned higher or equal. |
| 902 } | 904 } |
| 903 | 905 |
| 904 // Successfully allocated the object, now update top to point to | 906 // Successfully allocated the object, now update top to point to |
| 905 // next object start and initialize the object. | 907 // next object start and initialize the object. |
| 906 // R0: new object. | 908 // R0: new object. |
| 907 // R1: number of context variables. | 909 // R1: number of context variables. |
| 908 // R2: object size. | 910 // R2: object size. |
| 909 // R3: next object start. | 911 // R3: next object start. |
| 910 __ str(R3, Address(R5, 0)); | 912 __ str(R3, Address(R5, 0)); |
| 911 __ add(R0, R0, Operand(kHeapObjectTag)); | 913 __ add(R0, R0, Operand(kHeapObjectTag)); |
| 912 __ UpdateAllocationStatsWithSize(context_class.id(), R2, R5); | 914 __ UpdateAllocationStatsWithSize(cid, R2, R5, space); |
| 913 | 915 |
| 914 // Calculate the size tag. | 916 // Calculate the size tag. |
| 915 // R0: new object. | 917 // R0: new object. |
| 916 // R1: number of context variables. | 918 // R1: number of context variables. |
| 917 // R2: object size. | 919 // R2: object size. |
| 918 const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2; | 920 const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2; |
| 919 __ CompareImmediate(R2, RawObject::SizeTag::kMaxSizeTag); | 921 __ CompareImmediate(R2, RawObject::SizeTag::kMaxSizeTag); |
| 920 // If no size tag overflow, shift R2 left, else set R2 to zero. | 922 // If no size tag overflow, shift R2 left, else set R2 to zero. |
| 921 __ mov(R2, Operand(R2, LSL, shift), LS); | 923 __ mov(R2, Operand(R2, LSL, shift), LS); |
| 922 __ mov(R2, Operand(0), HI); | 924 __ mov(R2, Operand(0), HI); |
| 923 | 925 |
| 924 // Get the class index and insert it into the tags. | 926 // Get the class index and insert it into the tags. |
| 925 // R2: size and bit tags. | 927 // R2: size and bit tags. |
| 926 __ LoadImmediate(IP, RawObject::ClassIdTag::encode(context_class.id())); | 928 __ LoadImmediate(IP, RawObject::ClassIdTag::encode(cid)); |
| 927 __ orr(R2, R2, Operand(IP)); | 929 __ orr(R2, R2, Operand(IP)); |
| 928 __ str(R2, FieldAddress(R0, Context::tags_offset())); | 930 __ str(R2, FieldAddress(R0, Context::tags_offset())); |
| 929 | 931 |
| 930 // Setup up number of context variables field. | 932 // Setup up number of context variables field. |
| 931 // R0: new object. | 933 // R0: new object. |
| 932 // R1: number of context variables as integer value (not object). | 934 // R1: number of context variables as integer value (not object). |
| 933 __ str(R1, FieldAddress(R0, Context::num_variables_offset())); | 935 __ str(R1, FieldAddress(R0, Context::num_variables_offset())); |
| 934 | 936 |
| 935 // Setup isolate field. | 937 // Setup isolate field. |
| 936 // Load Isolate pointer from Context structure into R2. | 938 // Load Isolate pointer from Context structure into R2. |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1063 if (is_cls_parameterized) { | 1065 if (is_cls_parameterized) { |
| 1064 __ ldr(R1, Address(SP, 0)); | 1066 __ ldr(R1, Address(SP, 0)); |
| 1065 // R1: instantiated type arguments. | 1067 // R1: instantiated type arguments. |
| 1066 } | 1068 } |
| 1067 if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size)) { | 1069 if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size)) { |
| 1068 Label slow_case; | 1070 Label slow_case; |
| 1069 // Allocate the object and update top to point to | 1071 // Allocate the object and update top to point to |
| 1070 // next object start and initialize the allocated object. | 1072 // next object start and initialize the allocated object. |
| 1071 // R1: instantiated type arguments (if is_cls_parameterized). | 1073 // R1: instantiated type arguments (if is_cls_parameterized). |
| 1072 Heap* heap = Isolate::Current()->heap(); | 1074 Heap* heap = Isolate::Current()->heap(); |
| 1073 __ LoadImmediate(R5, heap->TopAddress()); | 1075 Heap::Space space = heap->SpaceForAllocation(cls.id()); |
| 1076 __ LoadImmediate(R5, heap->TopAddress(space)); | |
| 1074 __ ldr(R2, Address(R5, 0)); | 1077 __ ldr(R2, Address(R5, 0)); |
| 1075 __ AddImmediate(R3, R2, instance_size); | 1078 __ AddImmediate(R3, R2, instance_size); |
| 1076 // Check if the allocation fits into the remaining space. | 1079 // Check if the allocation fits into the remaining space. |
| 1077 // R2: potential new object start. | 1080 // R2: potential new object start. |
| 1078 // R3: potential next object start. | 1081 // R3: potential next object start. |
| 1079 __ LoadImmediate(IP, heap->EndAddress()); | 1082 __ LoadImmediate(IP, heap->EndAddress(space)); |
| 1080 __ ldr(IP, Address(IP, 0)); | 1083 __ ldr(IP, Address(IP, 0)); |
| 1081 __ cmp(R3, Operand(IP)); | 1084 __ cmp(R3, Operand(IP)); |
| 1082 if (FLAG_use_slow_path) { | 1085 if (FLAG_use_slow_path) { |
| 1083 __ b(&slow_case); | 1086 __ b(&slow_case); |
| 1084 } else { | 1087 } else { |
| 1085 __ b(&slow_case, CS); // Unsigned higher or equal. | 1088 __ b(&slow_case, CS); // Unsigned higher or equal. |
| 1086 } | 1089 } |
| 1087 __ str(R3, Address(R5, 0)); | 1090 __ str(R3, Address(R5, 0)); |
| 1088 __ UpdateAllocationStats(cls.id(), R5); | 1091 __ UpdateAllocationStats(cls.id(), R5, space); |
| 1089 | 1092 |
| 1090 // R2: new object start. | 1093 // R2: new object start. |
| 1091 // R3: next object start. | 1094 // R3: next object start. |
| 1092 // R1: new object type arguments (if is_cls_parameterized). | 1095 // R1: new object type arguments (if is_cls_parameterized). |
| 1093 // Set the tags. | 1096 // Set the tags. |
| 1094 uword tags = 0; | 1097 uword tags = 0; |
| 1095 tags = RawObject::SizeTag::update(instance_size, tags); | 1098 tags = RawObject::SizeTag::update(instance_size, tags); |
| 1096 ASSERT(cls.id() != kIllegalCid); | 1099 ASSERT(cls.id() != kIllegalCid); |
| 1097 tags = RawObject::ClassIdTag::update(cls.id(), tags); | 1100 tags = RawObject::ClassIdTag::update(cls.id(), tags); |
| 1098 __ LoadImmediate(R0, tags); | 1101 __ LoadImmediate(R0, tags); |
| (...skipping 872 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1971 const Register right = R0; | 1974 const Register right = R0; |
| 1972 __ ldr(left, Address(SP, 1 * kWordSize)); | 1975 __ ldr(left, Address(SP, 1 * kWordSize)); |
| 1973 __ ldr(right, Address(SP, 0 * kWordSize)); | 1976 __ ldr(right, Address(SP, 0 * kWordSize)); |
| 1974 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); | 1977 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); |
| 1975 __ Ret(); | 1978 __ Ret(); |
| 1976 } | 1979 } |
| 1977 | 1980 |
| 1978 } // namespace dart | 1981 } // namespace dart |
| 1979 | 1982 |
| 1980 #endif // defined TARGET_ARCH_ARM | 1983 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |