| 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 607 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 618 __ cmp(R3, Operand(0)); | 618 __ cmp(R3, Operand(0)); |
| 619 __ b(&slow_case, LT); | 619 __ b(&slow_case, LT); |
| 620 | 620 |
| 621 // Check for maximum allowed length. | 621 // Check for maximum allowed length. |
| 622 const intptr_t max_len = | 622 const intptr_t max_len = |
| 623 reinterpret_cast<int32_t>(Smi::New(Array::kMaxElements)); | 623 reinterpret_cast<int32_t>(Smi::New(Array::kMaxElements)); |
| 624 __ CompareImmediate(R3, max_len); | 624 __ CompareImmediate(R3, max_len); |
| 625 __ b(&slow_case, GT); | 625 __ b(&slow_case, GT); |
| 626 | 626 |
| 627 const intptr_t cid = kArrayCid; | 627 const intptr_t cid = kArrayCid; |
| 628 __ MaybeTraceAllocation(cid, R4, &slow_case); | 628 NOT_IN_PRODUCT(__ MaybeTraceAllocation(cid, R4, &slow_case)); |
| 629 | 629 |
| 630 const intptr_t fixed_size = sizeof(RawArray) + kObjectAlignment - 1; | 630 const intptr_t fixed_size = sizeof(RawArray) + kObjectAlignment - 1; |
| 631 __ LoadImmediate(R9, fixed_size); | 631 __ LoadImmediate(R9, fixed_size); |
| 632 __ add(R9, R9, Operand(R3, LSL, 1)); // R3 is a Smi. | 632 __ add(R9, R9, Operand(R3, LSL, 1)); // R3 is a Smi. |
| 633 ASSERT(kSmiTagShift == 1); | 633 ASSERT(kSmiTagShift == 1); |
| 634 __ bic(R9, R9, Operand(kObjectAlignment - 1)); | 634 __ bic(R9, R9, Operand(kObjectAlignment - 1)); |
| 635 | 635 |
| 636 // R9: Allocation size. | 636 // R9: Allocation size. |
| 637 Heap::Space space = Heap::SpaceForAllocation(cid); | 637 Heap::Space space = Heap::SpaceForAllocation(cid); |
| 638 __ LoadIsolate(R8); | 638 __ LoadIsolate(R8); |
| 639 __ ldr(R8, Address(R8, Isolate::heap_offset())); | 639 __ ldr(R8, Address(R8, Isolate::heap_offset())); |
| 640 // Potential new object start. | 640 // Potential new object start. |
| 641 __ ldr(R0, Address(R8, Heap::TopOffset(space))); | 641 __ ldr(R0, Address(R8, Heap::TopOffset(space))); |
| 642 __ adds(NOTFP, R0, Operand(R9)); // Potential next object start. | 642 __ adds(NOTFP, R0, Operand(R9)); // Potential next object start. |
| 643 __ b(&slow_case, CS); // Branch if unsigned overflow. | 643 __ b(&slow_case, CS); // Branch if unsigned overflow. |
| 644 | 644 |
| 645 // Check if the allocation fits into the remaining space. | 645 // Check if the allocation fits into the remaining space. |
| 646 // R0: potential new object start. | 646 // R0: potential new object start. |
| 647 // NOTFP: potential next object start. | 647 // NOTFP: potential next object start. |
| 648 // R9: allocation size. | 648 // R9: allocation size. |
| 649 __ ldr(R3, Address(R8, Heap::EndOffset(space))); | 649 __ ldr(R3, Address(R8, Heap::EndOffset(space))); |
| 650 __ cmp(NOTFP, Operand(R3)); | 650 __ cmp(NOTFP, Operand(R3)); |
| 651 __ b(&slow_case, CS); | 651 __ b(&slow_case, CS); |
| 652 | 652 |
| 653 // Successfully allocated the object(s), now update top to point to | 653 // Successfully allocated the object(s), now update top to point to |
| 654 // next object start and initialize the object. | 654 // next object start and initialize the object. |
| 655 __ LoadAllocationStatsAddress(R3, cid); | 655 NOT_IN_PRODUCT(__ LoadAllocationStatsAddress(R3, cid)); |
| 656 __ str(NOTFP, Address(R8, Heap::TopOffset(space))); | 656 __ str(NOTFP, Address(R8, Heap::TopOffset(space))); |
| 657 __ add(R0, R0, Operand(kHeapObjectTag)); | 657 __ add(R0, R0, Operand(kHeapObjectTag)); |
| 658 | 658 |
| 659 // Initialize the tags. | 659 // Initialize the tags. |
| 660 // R0: new object start as a tagged pointer. | 660 // R0: new object start as a tagged pointer. |
| 661 // R3: allocation stats address. | 661 // R3: allocation stats address. |
| 662 // NOTFP: new object end address. | 662 // NOTFP: new object end address. |
| 663 // R9: allocation size. | 663 // R9: allocation size. |
| 664 { | 664 { |
| 665 const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2; | 665 const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 688 R2); | 688 R2); |
| 689 | 689 |
| 690 // Initialize all array elements to raw_null. | 690 // Initialize all array elements to raw_null. |
| 691 // R0: new object start as a tagged pointer. | 691 // R0: new object start as a tagged pointer. |
| 692 // R3: allocation stats address. | 692 // R3: allocation stats address. |
| 693 // R8, R9: null | 693 // R8, R9: null |
| 694 // R4: iterator which initially points to the start of the variable | 694 // R4: iterator which initially points to the start of the variable |
| 695 // data area to be initialized. | 695 // data area to be initialized. |
| 696 // NOTFP: new object end address. | 696 // NOTFP: new object end address. |
| 697 // R9: allocation size. | 697 // R9: allocation size. |
| 698 __ IncrementAllocationStatsWithSize(R3, R9, space); | 698 NOT_IN_PRODUCT(__ IncrementAllocationStatsWithSize(R3, R9, space)); |
| 699 | 699 |
| 700 __ LoadObject(R8, Object::null_object()); | 700 __ LoadObject(R8, Object::null_object()); |
| 701 __ mov(R9, Operand(R8)); | 701 __ mov(R9, Operand(R8)); |
| 702 __ AddImmediate(R4, R0, sizeof(RawArray) - kHeapObjectTag); | 702 __ AddImmediate(R4, R0, sizeof(RawArray) - kHeapObjectTag); |
| 703 __ InitializeFieldsNoBarrier(R0, R4, NOTFP, R8, R9); | 703 __ InitializeFieldsNoBarrier(R0, R4, NOTFP, R8, R9); |
| 704 __ Ret(); // Returns the newly allocated object in R0. | 704 __ Ret(); // Returns the newly allocated object in R0. |
| 705 // Unable to allocate the array using the fast inline code, just call | 705 // Unable to allocate the array using the fast inline code, just call |
| 706 // into the runtime. | 706 // into the runtime. |
| 707 __ Bind(&slow_case); | 707 __ Bind(&slow_case); |
| 708 | 708 |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 851 if (FLAG_inline_alloc) { | 851 if (FLAG_inline_alloc) { |
| 852 Label slow_case; | 852 Label slow_case; |
| 853 // First compute the rounded instance size. | 853 // First compute the rounded instance size. |
| 854 // R1: number of context variables. | 854 // R1: number of context variables. |
| 855 intptr_t fixed_size = sizeof(RawContext) + kObjectAlignment - 1; | 855 intptr_t fixed_size = sizeof(RawContext) + kObjectAlignment - 1; |
| 856 __ LoadImmediate(R2, fixed_size); | 856 __ LoadImmediate(R2, fixed_size); |
| 857 __ add(R2, R2, Operand(R1, LSL, 2)); | 857 __ add(R2, R2, Operand(R1, LSL, 2)); |
| 858 ASSERT(kSmiTagShift == 1); | 858 ASSERT(kSmiTagShift == 1); |
| 859 __ bic(R2, R2, Operand(kObjectAlignment - 1)); | 859 __ bic(R2, R2, Operand(kObjectAlignment - 1)); |
| 860 | 860 |
| 861 __ MaybeTraceAllocation(kContextCid, R8, &slow_case); | 861 NOT_IN_PRODUCT(__ MaybeTraceAllocation(kContextCid, R8, &slow_case)); |
| 862 // Now allocate the object. | 862 // Now allocate the object. |
| 863 // R1: number of context variables. | 863 // R1: number of context variables. |
| 864 // R2: object size. | 864 // R2: object size. |
| 865 const intptr_t cid = kContextCid; | 865 const intptr_t cid = kContextCid; |
| 866 Heap::Space space = Heap::SpaceForAllocation(cid); | 866 Heap::Space space = Heap::SpaceForAllocation(cid); |
| 867 __ LoadIsolate(R9); | 867 __ LoadIsolate(R9); |
| 868 __ ldr(R9, Address(R9, Isolate::heap_offset())); | 868 __ ldr(R9, Address(R9, Isolate::heap_offset())); |
| 869 __ ldr(R0, Address(R9, Heap::TopOffset(space))); | 869 __ ldr(R0, Address(R9, Heap::TopOffset(space))); |
| 870 __ add(R3, R2, Operand(R0)); | 870 __ add(R3, R2, Operand(R0)); |
| 871 // Check if the allocation fits into the remaining space. | 871 // Check if the allocation fits into the remaining space. |
| (...skipping 10 matching lines...) Expand all Loading... |
| 882 __ b(&slow_case, CS); // Branch if unsigned higher or equal. | 882 __ b(&slow_case, CS); // Branch if unsigned higher or equal. |
| 883 } | 883 } |
| 884 | 884 |
| 885 // Successfully allocated the object, now update top to point to | 885 // Successfully allocated the object, now update top to point to |
| 886 // next object start and initialize the object. | 886 // next object start and initialize the object. |
| 887 // R0: new object start (untagged). | 887 // R0: new object start (untagged). |
| 888 // R1: number of context variables. | 888 // R1: number of context variables. |
| 889 // R2: object size. | 889 // R2: object size. |
| 890 // R3: next object start. | 890 // R3: next object start. |
| 891 // R9: heap. | 891 // R9: heap. |
| 892 __ LoadAllocationStatsAddress(R4, cid); | 892 NOT_IN_PRODUCT(__ LoadAllocationStatsAddress(R4, cid)); |
| 893 __ str(R3, Address(R9, Heap::TopOffset(space))); | 893 __ str(R3, Address(R9, Heap::TopOffset(space))); |
| 894 __ add(R0, R0, Operand(kHeapObjectTag)); | 894 __ add(R0, R0, Operand(kHeapObjectTag)); |
| 895 | 895 |
| 896 // Calculate the size tag. | 896 // Calculate the size tag. |
| 897 // R0: new object (tagged). | 897 // R0: new object (tagged). |
| 898 // R1: number of context variables. | 898 // R1: number of context variables. |
| 899 // R2: object size. | 899 // R2: object size. |
| 900 // R3: next object start. | 900 // R3: next object start. |
| 901 // R4: allocation stats address. | 901 // R4: allocation stats address. |
| 902 const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2; | 902 const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2; |
| (...skipping 29 matching lines...) Expand all Loading... |
| 932 // Initialize the context variables. | 932 // Initialize the context variables. |
| 933 // R0: new object. | 933 // R0: new object. |
| 934 // R1: number of context variables. | 934 // R1: number of context variables. |
| 935 // R2: object size. | 935 // R2: object size. |
| 936 // R3: next object start. | 936 // R3: next object start. |
| 937 // R8, R9: raw null. | 937 // R8, R9: raw null. |
| 938 // R4: allocation stats address. | 938 // R4: allocation stats address. |
| 939 Label loop; | 939 Label loop; |
| 940 __ AddImmediate(NOTFP, R0, Context::variable_offset(0) - kHeapObjectTag); | 940 __ AddImmediate(NOTFP, R0, Context::variable_offset(0) - kHeapObjectTag); |
| 941 __ InitializeFieldsNoBarrier(R0, NOTFP, R3, R8, R9); | 941 __ InitializeFieldsNoBarrier(R0, NOTFP, R3, R8, R9); |
| 942 __ IncrementAllocationStatsWithSize(R4, R2, space); | 942 NOT_IN_PRODUCT(__ IncrementAllocationStatsWithSize(R4, R2, space)); |
| 943 | 943 |
| 944 // Done allocating and initializing the context. | 944 // Done allocating and initializing the context. |
| 945 // R0: new object. | 945 // R0: new object. |
| 946 __ Ret(); | 946 __ Ret(); |
| 947 | 947 |
| 948 __ Bind(&slow_case); | 948 __ Bind(&slow_case); |
| 949 } | 949 } |
| 950 // Create a stub frame as we are pushing some objects on the stack before | 950 // Create a stub frame as we are pushing some objects on the stack before |
| 951 // calling into the runtime. | 951 // calling into the runtime. |
| 952 __ EnterStubFrame(); | 952 __ EnterStubFrame(); |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1074 __ cmp(R1, Operand(IP)); | 1074 __ cmp(R1, Operand(IP)); |
| 1075 if (FLAG_use_slow_path) { | 1075 if (FLAG_use_slow_path) { |
| 1076 __ b(&slow_case); | 1076 __ b(&slow_case); |
| 1077 } else { | 1077 } else { |
| 1078 __ b(&slow_case, CS); // Unsigned higher or equal. | 1078 __ b(&slow_case, CS); // Unsigned higher or equal. |
| 1079 } | 1079 } |
| 1080 __ str(R1, Address(R9, Heap::TopOffset(space))); | 1080 __ str(R1, Address(R9, Heap::TopOffset(space))); |
| 1081 | 1081 |
| 1082 // Load the address of the allocation stats table. We split up the load | 1082 // Load the address of the allocation stats table. We split up the load |
| 1083 // and the increment so that the dependent load is not too nearby. | 1083 // and the increment so that the dependent load is not too nearby. |
| 1084 __ LoadAllocationStatsAddress(R9, cls.id()); | 1084 NOT_IN_PRODUCT(__ LoadAllocationStatsAddress(R9, cls.id())); |
| 1085 | 1085 |
| 1086 // R0: new object start. | 1086 // R0: new object start. |
| 1087 // R1: next object start. | 1087 // R1: next object start. |
| 1088 // R9: allocation stats table. | 1088 // R9: allocation stats table. |
| 1089 // Set the tags. | 1089 // Set the tags. |
| 1090 uword tags = 0; | 1090 uword tags = 0; |
| 1091 tags = RawObject::SizeTag::update(instance_size, tags); | 1091 tags = RawObject::SizeTag::update(instance_size, tags); |
| 1092 ASSERT(cls.id() != kIllegalCid); | 1092 ASSERT(cls.id() != kIllegalCid); |
| 1093 tags = RawObject::ClassIdTag::update(cls.id(), tags); | 1093 tags = RawObject::ClassIdTag::update(cls.id(), tags); |
| 1094 __ LoadImmediate(R2, tags); | 1094 __ LoadImmediate(R2, tags); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1131 __ ldr(R4, Address(SP, 0)); | 1131 __ ldr(R4, Address(SP, 0)); |
| 1132 FieldAddress type_args(R0, cls.type_arguments_field_offset()); | 1132 FieldAddress type_args(R0, cls.type_arguments_field_offset()); |
| 1133 __ InitializeFieldNoBarrier(R0, type_args, R4); | 1133 __ InitializeFieldNoBarrier(R0, type_args, R4); |
| 1134 } | 1134 } |
| 1135 | 1135 |
| 1136 // Done allocating and initializing the instance. | 1136 // Done allocating and initializing the instance. |
| 1137 // R0: new object (tagged). | 1137 // R0: new object (tagged). |
| 1138 // R9: allocation stats table. | 1138 // R9: allocation stats table. |
| 1139 | 1139 |
| 1140 // Update allocation stats. | 1140 // Update allocation stats. |
| 1141 __ IncrementAllocationStats(R9, cls.id(), space); | 1141 NOT_IN_PRODUCT(__ IncrementAllocationStats(R9, cls.id(), space)); |
| 1142 | 1142 |
| 1143 // R0: new object (tagged). | 1143 // R0: new object (tagged). |
| 1144 __ Ret(); | 1144 __ Ret(); |
| 1145 | 1145 |
| 1146 __ Bind(&slow_case); | 1146 __ Bind(&slow_case); |
| 1147 } | 1147 } |
| 1148 if (is_cls_parameterized) { | 1148 if (is_cls_parameterized) { |
| 1149 // Load the type arguments. | 1149 // Load the type arguments. |
| 1150 __ ldr(R4, Address(SP, 0)); | 1150 __ ldr(R4, Address(SP, 0)); |
| 1151 } | 1151 } |
| (...skipping 1027 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2179 } | 2179 } |
| 2180 | 2180 |
| 2181 | 2181 |
| 2182 void StubCode::GenerateFrameAwaitingMaterializationStub(Assembler* assembler) { | 2182 void StubCode::GenerateFrameAwaitingMaterializationStub(Assembler* assembler) { |
| 2183 __ bkpt(0); | 2183 __ bkpt(0); |
| 2184 } | 2184 } |
| 2185 | 2185 |
| 2186 } // namespace dart | 2186 } // namespace dart |
| 2187 | 2187 |
| 2188 #endif // defined TARGET_ARCH_ARM | 2188 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |