| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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_ARM64) | 6 #if defined(TARGET_ARCH_ARM64) |
| 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/compiler.h" | 10 #include "vm/compiler.h" |
| (...skipping 661 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 672 if (FLAG_use_slow_path || cls.trace_allocation()) { | 672 if (FLAG_use_slow_path || cls.trace_allocation()) { |
| 673 __ b(&slow_case); | 673 __ b(&slow_case); |
| 674 } else { | 674 } else { |
| 675 __ b(&slow_case, NE); | 675 __ b(&slow_case, NE); |
| 676 } | 676 } |
| 677 __ cmp(R2, Operand(0)); | 677 __ cmp(R2, Operand(0)); |
| 678 __ b(&slow_case, LT); | 678 __ b(&slow_case, LT); |
| 679 | 679 |
| 680 Heap* heap = isolate->heap(); | 680 Heap* heap = isolate->heap(); |
| 681 const intptr_t cid = kArrayCid; | 681 const intptr_t cid = kArrayCid; |
| 682 Heap::Space space = heap->SpaceForAllocation(cid); | 682 Heap::Space space = Heap::SpaceForAllocation(cid); |
| 683 const uword top_address = heap->TopAddress(space); | 683 const uword top_address = heap->TopAddress(space); |
| 684 __ LoadImmediate(R8, top_address, kNoPP); | 684 __ LoadImmediate(R8, top_address, kNoPP); |
| 685 const uword end_address = heap->EndAddress(space); | 685 const uword end_address = heap->EndAddress(space); |
| 686 ASSERT(top_address < end_address); | 686 ASSERT(top_address < end_address); |
| 687 const uword top_offset = 0; | 687 const uword top_offset = 0; |
| 688 const uword end_offset = end_address - top_address; | 688 const uword end_offset = end_address - top_address; |
| 689 | 689 |
| 690 // Calculate and align allocation size. | 690 // Calculate and align allocation size. |
| 691 // Load new object start and calculate next object start. | 691 // Load new object start and calculate next object start. |
| 692 // R1: array element type. | 692 // R1: array element type. |
| (...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 935 | 935 |
| 936 | 936 |
| 937 // Called for inline allocation of contexts. | 937 // Called for inline allocation of contexts. |
| 938 // Input: | 938 // Input: |
| 939 // R1: number of context variables. | 939 // R1: number of context variables. |
| 940 // Output: | 940 // Output: |
| 941 // R0: new allocated RawContext object. | 941 // R0: new allocated RawContext object. |
| 942 void StubCode::GenerateAllocateContextStub(Assembler* assembler) { | 942 void StubCode::GenerateAllocateContextStub(Assembler* assembler) { |
| 943 if (FLAG_inline_alloc) { | 943 if (FLAG_inline_alloc) { |
| 944 Label slow_case; | 944 Label slow_case; |
| 945 Heap* heap = Isolate::Current()->heap(); | |
| 946 // First compute the rounded instance size. | 945 // First compute the rounded instance size. |
| 947 // R1: number of context variables. | 946 // R1: number of context variables. |
| 948 intptr_t fixed_size = sizeof(RawContext) + kObjectAlignment - 1; | 947 intptr_t fixed_size = sizeof(RawContext) + kObjectAlignment - 1; |
| 949 __ LoadImmediate(R2, fixed_size, kNoPP); | 948 __ LoadImmediate(R2, fixed_size, kNoPP); |
| 950 __ add(R2, R2, Operand(R1, LSL, 3)); | 949 __ add(R2, R2, Operand(R1, LSL, 3)); |
| 951 ASSERT(kSmiTagShift == 1); | 950 ASSERT(kSmiTagShift == 1); |
| 952 __ andi(R2, R2, Immediate(~(kObjectAlignment - 1))); | 951 __ andi(R2, R2, Immediate(~(kObjectAlignment - 1))); |
| 953 | 952 |
| 954 // Now allocate the object. | 953 // Now allocate the object. |
| 955 // R1: number of context variables. | 954 // R1: number of context variables. |
| 956 // R2: object size. | 955 // R2: object size. |
| 957 const intptr_t cid = kContextCid; | 956 const intptr_t cid = kContextCid; |
| 958 Heap::Space space = heap->SpaceForAllocation(cid); | 957 Heap::Space space = Heap::SpaceForAllocation(cid); |
| 959 __ LoadImmediate(R5, heap->TopAddress(space), kNoPP); | 958 __ LoadIsolate(R5); |
| 960 __ ldr(R0, Address(R5)); | 959 __ ldr(R5, Address(R5, Isolate::heap_offset())); |
| 960 __ ldr(R0, Address(R5, Heap::TopOffset(space))); |
| 961 __ add(R3, R2, Operand(R0)); | 961 __ add(R3, R2, Operand(R0)); |
| 962 // Check if the allocation fits into the remaining space. | 962 // Check if the allocation fits into the remaining space. |
| 963 // R0: potential new object. | 963 // R0: potential new object. |
| 964 // R1: number of context variables. | 964 // R1: number of context variables. |
| 965 // R2: object size. | 965 // R2: object size. |
| 966 // R3: potential next object start. | 966 // R3: potential next object start. |
| 967 __ LoadImmediate(TMP, heap->EndAddress(space), kNoPP); | 967 // R5: heap. |
| 968 __ ldr(TMP, Address(TMP)); | 968 __ ldr(TMP, Address(R5, Heap::EndOffset(space))); |
| 969 __ CompareRegisters(R3, TMP); | 969 __ CompareRegisters(R3, TMP); |
| 970 if (FLAG_use_slow_path) { | 970 if (FLAG_use_slow_path) { |
| 971 __ b(&slow_case); | 971 __ b(&slow_case); |
| 972 } else { | 972 } else { |
| 973 __ b(&slow_case, CS); // Branch if unsigned higher or equal. | 973 __ b(&slow_case, CS); // Branch if unsigned higher or equal. |
| 974 } | 974 } |
| 975 | 975 |
| 976 // Successfully allocated the object, now update top to point to | 976 // Successfully allocated the object, now update top to point to |
| 977 // next object start and initialize the object. | 977 // next object start and initialize the object. |
| 978 // R0: new object. | 978 // R0: new object. |
| 979 // R1: number of context variables. | 979 // R1: number of context variables. |
| 980 // R2: object size. | 980 // R2: object size. |
| 981 // R3: next object start. | 981 // R3: next object start. |
| 982 __ str(R3, Address(R5)); | 982 // R5: heap. |
| 983 __ str(R3, Address(R5, Heap::TopOffset(space))); |
| 983 __ add(R0, R0, Operand(kHeapObjectTag)); | 984 __ add(R0, R0, Operand(kHeapObjectTag)); |
| 984 __ UpdateAllocationStatsWithSize(cid, R2, kNoPP, space); | 985 __ UpdateAllocationStatsWithSize(cid, R2, kNoPP, space, |
| 986 /* inline_isolate = */ false); |
| 985 | 987 |
| 986 // Calculate the size tag. | 988 // Calculate the size tag. |
| 987 // R0: new object. | 989 // R0: new object. |
| 988 // R1: number of context variables. | 990 // R1: number of context variables. |
| 989 // R2: object size. | 991 // R2: object size. |
| 990 const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2; | 992 const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2; |
| 991 __ CompareImmediate(R2, RawObject::SizeTag::kMaxSizeTag, kNoPP); | 993 __ CompareImmediate(R2, RawObject::SizeTag::kMaxSizeTag, kNoPP); |
| 992 // If no size tag overflow, shift R2 left, else set R2 to zero. | 994 // If no size tag overflow, shift R2 left, else set R2 to zero. |
| 993 __ LslImmediate(TMP, R2, shift); | 995 __ LslImmediate(TMP, R2, shift); |
| 994 __ csel(R2, TMP, R2, LS); | 996 __ csel(R2, TMP, R2, LS); |
| 995 __ csel(R2, ZR, R2, HI); | 997 __ csel(R2, ZR, R2, HI); |
| 996 | 998 |
| 997 // Get the class index and insert it into the tags. | 999 // Get the class index and insert it into the tags. |
| 998 // R2: size and bit tags. | 1000 // R2: size and bit tags. |
| 999 __ LoadImmediate( | 1001 __ LoadImmediate(TMP, RawObject::ClassIdTag::encode(cid), kNoPP); |
| 1000 TMP, RawObject::ClassIdTag::encode(cid), kNoPP); | |
| 1001 __ orr(R2, R2, Operand(TMP)); | 1002 __ orr(R2, R2, Operand(TMP)); |
| 1002 __ StoreFieldToOffset(R2, R0, Context::tags_offset(), kNoPP); | 1003 __ StoreFieldToOffset(R2, R0, Context::tags_offset(), kNoPP); |
| 1003 | 1004 |
| 1004 // Setup up number of context variables field. | 1005 // Setup up number of context variables field. |
| 1005 // R0: new object. | 1006 // R0: new object. |
| 1006 // R1: number of context variables as integer value (not object). | 1007 // R1: number of context variables as integer value (not object). |
| 1007 __ StoreFieldToOffset(R1, R0, Context::num_variables_offset(), kNoPP); | 1008 __ StoreFieldToOffset(R1, R0, Context::num_variables_offset(), kNoPP); |
| 1008 | 1009 |
| 1009 // Setup the parent field. | 1010 // Setup the parent field. |
| 1010 // R0: new object. | 1011 // R0: new object. |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1130 __ ldr(R1, Address(SP)); | 1131 __ ldr(R1, Address(SP)); |
| 1131 // R1: instantiated type arguments. | 1132 // R1: instantiated type arguments. |
| 1132 } | 1133 } |
| 1133 if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size) && | 1134 if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size) && |
| 1134 !cls.trace_allocation()) { | 1135 !cls.trace_allocation()) { |
| 1135 Label slow_case; | 1136 Label slow_case; |
| 1136 // Allocate the object and update top to point to | 1137 // Allocate the object and update top to point to |
| 1137 // next object start and initialize the allocated object. | 1138 // next object start and initialize the allocated object. |
| 1138 // R1: instantiated type arguments (if is_cls_parameterized). | 1139 // R1: instantiated type arguments (if is_cls_parameterized). |
| 1139 Heap* heap = Isolate::Current()->heap(); | 1140 Heap* heap = Isolate::Current()->heap(); |
| 1140 Heap::Space space = heap->SpaceForAllocation(cls.id()); | 1141 Heap::Space space = Heap::SpaceForAllocation(cls.id()); |
| 1141 __ LoadImmediate(R5, heap->TopAddress(space), kNoPP); | 1142 __ LoadImmediate(R5, heap->TopAddress(space), kNoPP); |
| 1142 __ ldr(R2, Address(R5)); | 1143 __ ldr(R2, Address(R5)); |
| 1143 __ AddImmediate(R3, R2, instance_size, kNoPP); | 1144 __ AddImmediate(R3, R2, instance_size, kNoPP); |
| 1144 // Check if the allocation fits into the remaining space. | 1145 // Check if the allocation fits into the remaining space. |
| 1145 // R2: potential new object start. | 1146 // R2: potential new object start. |
| 1146 // R3: potential next object start. | 1147 // R3: potential next object start. |
| 1147 __ LoadImmediate(TMP, heap->EndAddress(space), kNoPP); | 1148 __ LoadImmediate(TMP, heap->EndAddress(space), kNoPP); |
| 1148 __ ldr(TMP, Address(TMP)); | 1149 __ ldr(TMP, Address(TMP)); |
| 1149 __ CompareRegisters(R3, TMP); | 1150 __ CompareRegisters(R3, TMP); |
| 1150 if (FLAG_use_slow_path) { | 1151 if (FLAG_use_slow_path) { |
| (...skipping 1038 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2189 // Result: | 2190 // Result: |
| 2190 // R1: entry point. | 2191 // R1: entry point. |
| 2191 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { | 2192 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { |
| 2192 EmitMegamorphicLookup(assembler, R0, R1, R1); | 2193 EmitMegamorphicLookup(assembler, R0, R1, R1); |
| 2193 __ ret(); | 2194 __ ret(); |
| 2194 } | 2195 } |
| 2195 | 2196 |
| 2196 } // namespace dart | 2197 } // namespace dart |
| 2197 | 2198 |
| 2198 #endif // defined TARGET_ARCH_ARM64 | 2199 #endif // defined TARGET_ARCH_ARM64 |
| OLD | NEW |