| 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 647 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 658 const intptr_t fixed_size = sizeof(RawArray) + kObjectAlignment - 1; | 658 const intptr_t fixed_size = sizeof(RawArray) + kObjectAlignment - 1; |
| 659 __ LoadImmediate(R9, fixed_size); | 659 __ LoadImmediate(R9, fixed_size); |
| 660 __ add(R9, R9, Operand(R3, LSL, 1)); // R3 is a Smi. | 660 __ add(R9, R9, Operand(R3, LSL, 1)); // R3 is a Smi. |
| 661 ASSERT(kSmiTagShift == 1); | 661 ASSERT(kSmiTagShift == 1); |
| 662 __ bic(R9, R9, Operand(kObjectAlignment - 1)); | 662 __ bic(R9, R9, Operand(kObjectAlignment - 1)); |
| 663 | 663 |
| 664 // R9: Allocation size. | 664 // R9: Allocation size. |
| 665 | 665 |
| 666 Heap* heap = isolate->heap(); | 666 Heap* heap = isolate->heap(); |
| 667 const intptr_t cid = kArrayCid; | 667 const intptr_t cid = kArrayCid; |
| 668 Heap::Space space = heap->SpaceForAllocation(cid); | 668 Heap::Space space = Heap::SpaceForAllocation(cid); |
| 669 __ LoadImmediate(R6, heap->TopAddress(space)); | 669 __ LoadImmediate(R6, heap->TopAddress(space)); |
| 670 __ ldr(R0, Address(R6, 0)); // Potential new object start. | 670 __ ldr(R0, Address(R6, 0)); // Potential new object start. |
| 671 __ adds(R7, R0, Operand(R9)); // Potential next object start. | 671 __ adds(R7, R0, Operand(R9)); // Potential next object start. |
| 672 __ b(&slow_case, CS); // Branch if unsigned overflow. | 672 __ b(&slow_case, CS); // Branch if unsigned overflow. |
| 673 | 673 |
| 674 // Check if the allocation fits into the remaining space. | 674 // Check if the allocation fits into the remaining space. |
| 675 // R0: potential new object start. | 675 // R0: potential new object start. |
| 676 // R7: potential next object start. | 676 // R7: potential next object start. |
| 677 // R9: allocation size. | 677 // R9: allocation size. |
| 678 __ LoadImmediate(R3, heap->EndAddress(space)); | 678 __ LoadImmediate(R3, heap->EndAddress(space)); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 723 // R4, R5: null | 723 // R4, R5: null |
| 724 // R6: iterator which initially points to the start of the variable | 724 // R6: iterator which initially points to the start of the variable |
| 725 // data area to be initialized. | 725 // data area to be initialized. |
| 726 // R7: new object end address. | 726 // R7: new object end address. |
| 727 // R9: allocation size. | 727 // R9: allocation size. |
| 728 | 728 |
| 729 __ LoadImmediate(R4, reinterpret_cast<intptr_t>(Object::null())); | 729 __ LoadImmediate(R4, reinterpret_cast<intptr_t>(Object::null())); |
| 730 __ mov(R5, Operand(R4)); | 730 __ mov(R5, Operand(R4)); |
| 731 __ AddImmediate(R6, R0, sizeof(RawArray) - kHeapObjectTag); | 731 __ AddImmediate(R6, R0, sizeof(RawArray) - kHeapObjectTag); |
| 732 __ InitializeFieldsNoBarrier(R0, R6, R7, R4, R5); | 732 __ InitializeFieldsNoBarrier(R0, R6, R7, R4, R5); |
| 733 __ IncrementAllocationStatsWithSize(R3, R9, cid, space); | 733 __ IncrementAllocationStatsWithSize(R3, R9, space); |
| 734 __ Ret(); // Returns the newly allocated object in R0. | 734 __ Ret(); // Returns the newly allocated object in R0. |
| 735 // Unable to allocate the array using the fast inline code, just call | 735 // Unable to allocate the array using the fast inline code, just call |
| 736 // into the runtime. | 736 // into the runtime. |
| 737 __ Bind(&slow_case); | 737 __ Bind(&slow_case); |
| 738 | 738 |
| 739 // Create a stub frame as we are pushing some objects on the stack before | 739 // Create a stub frame as we are pushing some objects on the stack before |
| 740 // calling into the runtime. | 740 // calling into the runtime. |
| 741 __ EnterStubFrame(); | 741 __ EnterStubFrame(); |
| 742 __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null())); | 742 __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null())); |
| 743 // Setup space on stack for return value. | 743 // Setup space on stack for return value. |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 871 | 871 |
| 872 | 872 |
| 873 // Called for inline allocation of contexts. | 873 // Called for inline allocation of contexts. |
| 874 // Input: | 874 // Input: |
| 875 // R1: number of context variables. | 875 // R1: number of context variables. |
| 876 // Output: | 876 // Output: |
| 877 // R0: new allocated RawContext object. | 877 // R0: new allocated RawContext object. |
| 878 void StubCode::GenerateAllocateContextStub(Assembler* assembler) { | 878 void StubCode::GenerateAllocateContextStub(Assembler* assembler) { |
| 879 if (FLAG_inline_alloc) { | 879 if (FLAG_inline_alloc) { |
| 880 Label slow_case; | 880 Label slow_case; |
| 881 Heap* heap = Isolate::Current()->heap(); | |
| 882 // First compute the rounded instance size. | 881 // First compute the rounded instance size. |
| 883 // R1: number of context variables. | 882 // R1: number of context variables. |
| 884 intptr_t fixed_size = sizeof(RawContext) + kObjectAlignment - 1; | 883 intptr_t fixed_size = sizeof(RawContext) + kObjectAlignment - 1; |
| 885 __ LoadImmediate(R2, fixed_size); | 884 __ LoadImmediate(R2, fixed_size); |
| 886 __ add(R2, R2, Operand(R1, LSL, 2)); | 885 __ add(R2, R2, Operand(R1, LSL, 2)); |
| 887 ASSERT(kSmiTagShift == 1); | 886 ASSERT(kSmiTagShift == 1); |
| 888 __ bic(R2, R2, Operand(kObjectAlignment - 1)); | 887 __ bic(R2, R2, Operand(kObjectAlignment - 1)); |
| 889 | 888 |
| 890 // Now allocate the object. | 889 // Now allocate the object. |
| 891 // R1: number of context variables. | 890 // R1: number of context variables. |
| 892 // R2: object size. | 891 // R2: object size. |
| 893 const intptr_t cid = kContextCid; | 892 const intptr_t cid = kContextCid; |
| 894 Heap::Space space = heap->SpaceForAllocation(cid); | 893 Heap::Space space = Heap::SpaceForAllocation(cid); |
| 895 __ LoadImmediate(R5, heap->TopAddress(space)); | 894 __ LoadIsolate(R5); |
| 896 __ ldr(R0, Address(R5, 0)); | 895 __ ldr(R5, Address(R5, Isolate::heap_offset())); |
| 896 __ ldr(R0, Address(R5, Heap::TopOffset(space))); |
| 897 __ add(R3, R2, Operand(R0)); | 897 __ add(R3, R2, Operand(R0)); |
| 898 // Check if the allocation fits into the remaining space. | 898 // Check if the allocation fits into the remaining space. |
| 899 // R0: potential new object. | 899 // R0: potential new object. |
| 900 // R1: number of context variables. | 900 // R1: number of context variables. |
| 901 // R2: object size. | 901 // R2: object size. |
| 902 // R3: potential next object start. | 902 // R3: potential next object start. |
| 903 // R5: top address. | 903 // R5: heap. |
| 904 __ LoadImmediate(IP, heap->EndAddress(space)); | 904 __ ldr(IP, Address(R5, Heap::EndOffset(space))); |
| 905 __ ldr(IP, Address(IP, 0)); | |
| 906 __ cmp(R3, Operand(IP)); | 905 __ cmp(R3, Operand(IP)); |
| 907 if (FLAG_use_slow_path) { | 906 if (FLAG_use_slow_path) { |
| 908 __ b(&slow_case); | 907 __ b(&slow_case); |
| 909 } else { | 908 } else { |
| 910 __ b(&slow_case, CS); // Branch if unsigned higher or equal. | 909 __ b(&slow_case, CS); // Branch if unsigned higher or equal. |
| 911 } | 910 } |
| 912 | 911 |
| 913 // Successfully allocated the object, now update top to point to | 912 // Successfully allocated the object, now update top to point to |
| 914 // next object start and initialize the object. | 913 // next object start and initialize the object. |
| 915 // R0: new object start (untagged). | 914 // R0: new object start (untagged). |
| 916 // R1: number of context variables. | 915 // R1: number of context variables. |
| 917 // R2: object size. | 916 // R2: object size. |
| 918 // R3: next object start. | 917 // R3: next object start. |
| 919 // R5: top address. | 918 // R5: heap. |
| 920 __ LoadAllocationStatsAddress(R6, cid); | 919 __ LoadAllocationStatsAddress(R6, cid, /* inline_isolate = */ false); |
| 921 __ str(R3, Address(R5, 0)); | 920 __ str(R3, Address(R5, Heap::TopOffset(space))); |
| 922 __ add(R0, R0, Operand(kHeapObjectTag)); | 921 __ add(R0, R0, Operand(kHeapObjectTag)); |
| 923 | 922 |
| 924 // Calculate the size tag. | 923 // Calculate the size tag. |
| 925 // R0: new object (tagged). | 924 // R0: new object (tagged). |
| 926 // R1: number of context variables. | 925 // R1: number of context variables. |
| 927 // R2: object size. | 926 // R2: object size. |
| 928 // R3: next object start. | 927 // R3: next object start. |
| 929 // R6: allocation stats address. | 928 // R6: allocation stats address. |
| 930 const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2; | 929 const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2; |
| 931 __ CompareImmediate(R2, RawObject::SizeTag::kMaxSizeTag); | 930 __ CompareImmediate(R2, RawObject::SizeTag::kMaxSizeTag); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 960 // Initialize the context variables. | 959 // Initialize the context variables. |
| 961 // R0: new object. | 960 // R0: new object. |
| 962 // R1: number of context variables. | 961 // R1: number of context variables. |
| 963 // R2: object size. | 962 // R2: object size. |
| 964 // R3: next object start. | 963 // R3: next object start. |
| 965 // R4, R5: raw null. | 964 // R4, R5: raw null. |
| 966 // R6: allocation stats address. | 965 // R6: allocation stats address. |
| 967 Label loop; | 966 Label loop; |
| 968 __ AddImmediate(R7, R0, Context::variable_offset(0) - kHeapObjectTag); | 967 __ AddImmediate(R7, R0, Context::variable_offset(0) - kHeapObjectTag); |
| 969 __ InitializeFieldsNoBarrier(R0, R7, R3, R4, R5); | 968 __ InitializeFieldsNoBarrier(R0, R7, R3, R4, R5); |
| 970 __ IncrementAllocationStatsWithSize(R6, R2, cid, space); | 969 __ IncrementAllocationStatsWithSize(R6, R2, space); |
| 971 | 970 |
| 972 // Done allocating and initializing the context. | 971 // Done allocating and initializing the context. |
| 973 // R0: new object. | 972 // R0: new object. |
| 974 __ Ret(); | 973 __ Ret(); |
| 975 | 974 |
| 976 __ Bind(&slow_case); | 975 __ Bind(&slow_case); |
| 977 } | 976 } |
| 978 // Create a stub frame as we are pushing some objects on the stack before | 977 // Create a stub frame as we are pushing some objects on the stack before |
| 979 // calling into the runtime. | 978 // calling into the runtime. |
| 980 __ EnterStubFrame(); | 979 __ EnterStubFrame(); |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1086 // straight line code. | 1085 // straight line code. |
| 1087 const int kInlineInstanceSize = 12; | 1086 const int kInlineInstanceSize = 12; |
| 1088 const intptr_t instance_size = cls.instance_size(); | 1087 const intptr_t instance_size = cls.instance_size(); |
| 1089 ASSERT(instance_size > 0); | 1088 ASSERT(instance_size > 0); |
| 1090 if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size) && | 1089 if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size) && |
| 1091 !cls.trace_allocation()) { | 1090 !cls.trace_allocation()) { |
| 1092 Label slow_case; | 1091 Label slow_case; |
| 1093 // Allocate the object and update top to point to | 1092 // Allocate the object and update top to point to |
| 1094 // next object start and initialize the allocated object. | 1093 // next object start and initialize the allocated object. |
| 1095 Heap* heap = Isolate::Current()->heap(); | 1094 Heap* heap = Isolate::Current()->heap(); |
| 1096 Heap::Space space = heap->SpaceForAllocation(cls.id()); | 1095 Heap::Space space = Heap::SpaceForAllocation(cls.id()); |
| 1097 __ LoadImmediate(R5, heap->TopAddress(space)); | 1096 __ LoadImmediate(R5, heap->TopAddress(space)); |
| 1098 __ ldr(R0, Address(R5, 0)); | 1097 __ ldr(R0, Address(R5, 0)); |
| 1099 __ AddImmediate(R1, R0, instance_size); | 1098 __ AddImmediate(R1, R0, instance_size); |
| 1100 // Check if the allocation fits into the remaining space. | 1099 // Check if the allocation fits into the remaining space. |
| 1101 // R0: potential new object start. | 1100 // R0: potential new object start. |
| 1102 // R1: potential next object start. | 1101 // R1: potential next object start. |
| 1103 __ LoadImmediate(IP, heap->EndAddress(space)); | 1102 __ LoadImmediate(IP, heap->EndAddress(space)); |
| 1104 __ ldr(IP, Address(IP, 0)); | 1103 __ ldr(IP, Address(IP, 0)); |
| 1105 __ cmp(R1, Operand(IP)); | 1104 __ cmp(R1, Operand(IP)); |
| 1106 if (FLAG_use_slow_path) { | 1105 if (FLAG_use_slow_path) { |
| (...skipping 1020 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2127 // Result: | 2126 // Result: |
| 2128 // R1: entry point. | 2127 // R1: entry point. |
| 2129 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { | 2128 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { |
| 2130 EmitMegamorphicLookup(assembler, R0, R1, R1); | 2129 EmitMegamorphicLookup(assembler, R0, R1, R1); |
| 2131 __ Ret(); | 2130 __ Ret(); |
| 2132 } | 2131 } |
| 2133 | 2132 |
| 2134 } // namespace dart | 2133 } // namespace dart |
| 2135 | 2134 |
| 2136 #endif // defined TARGET_ARCH_ARM | 2135 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |