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/compiler.h" | 9 #include "vm/compiler.h" |
10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
(...skipping 1072 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1083 } | 1083 } |
1084 | 1084 |
1085 | 1085 |
1086 // Helper stub to implement Assembler::StoreIntoObject. | 1086 // Helper stub to implement Assembler::StoreIntoObject. |
1087 // Input parameters: | 1087 // Input parameters: |
1088 // R0: Address being stored | 1088 // R0: Address being stored |
1089 void StubCode::GenerateUpdateStoreBufferStub(Assembler* assembler) { | 1089 void StubCode::GenerateUpdateStoreBufferStub(Assembler* assembler) { |
1090 Label add_to_buffer; | 1090 Label add_to_buffer; |
1091 // Check whether this object has already been remembered. Skip adding to the | 1091 // Check whether this object has already been remembered. Skip adding to the |
1092 // store buffer if the object is in the store buffer already. | 1092 // store buffer if the object is in the store buffer already. |
1093 __ LoadFieldFromOffset(TMP, R0, Object::tags_offset()); | 1093 __ LoadFieldFromOffset(TMP, R0, Object::tags_offset(), kWord); |
1094 __ tsti(TMP, Immediate(1 << RawObject::kRememberedBit)); | 1094 __ tsti(TMP, Immediate(1 << RawObject::kRememberedBit)); |
1095 __ b(&add_to_buffer, EQ); | 1095 __ b(&add_to_buffer, EQ); |
1096 __ ret(); | 1096 __ ret(); |
1097 | 1097 |
1098 __ Bind(&add_to_buffer); | 1098 __ Bind(&add_to_buffer); |
1099 // Save values being destroyed. | 1099 // Save values being destroyed. |
1100 __ Push(R1); | 1100 __ Push(R1); |
1101 __ Push(R2); | 1101 __ Push(R2); |
1102 __ Push(R3); | 1102 __ Push(R3); |
1103 | 1103 |
1104 // Atomically set the remembered bit of the object header. | 1104 // Atomically set the remembered bit of the object header. |
1105 ASSERT(Object::tags_offset() == 0); | 1105 ASSERT(Object::tags_offset() == 0); |
1106 __ sub(R3, R0, Operand(kHeapObjectTag)); | 1106 __ sub(R3, R0, Operand(kHeapObjectTag)); |
1107 // R3: Untagged address of header word (ldxr/stxr do not support offsets). | 1107 // R3: Untagged address of header word (ldxr/stxr do not support offsets). |
| 1108 // Note that we use 32 bit operations here to match the size of the |
| 1109 // background sweeper which is also manipulating this 32 bit word. |
1108 Label retry; | 1110 Label retry; |
1109 __ Bind(&retry); | 1111 __ Bind(&retry); |
1110 __ ldxr(R2, R3); | 1112 __ ldxr(R2, R3, kWord); |
1111 __ orri(R2, R2, Immediate(1 << RawObject::kRememberedBit)); | 1113 __ orri(R2, R2, Immediate(1 << RawObject::kRememberedBit)); |
1112 __ stxr(R1, R2, R3); | 1114 __ stxr(R1, R2, R3, kWord); |
1113 __ cmp(R1, Operand(1)); | 1115 __ cmp(R1, Operand(1)); |
1114 __ b(&retry, EQ); | 1116 __ b(&retry, EQ); |
1115 | 1117 |
1116 // Load the StoreBuffer block out of the thread. Then load top_ out of the | 1118 // Load the StoreBuffer block out of the thread. Then load top_ out of the |
1117 // StoreBufferBlock and add the address to the pointers_. | 1119 // StoreBufferBlock and add the address to the pointers_. |
1118 __ LoadFromOffset(R1, THR, Thread::store_buffer_block_offset()); | 1120 __ LoadFromOffset(R1, THR, Thread::store_buffer_block_offset()); |
1119 __ LoadFromOffset(R2, R1, StoreBufferBlock::top_offset(), kUnsignedWord); | 1121 __ LoadFromOffset(R2, R1, StoreBufferBlock::top_offset(), kUnsignedWord); |
1120 __ add(R3, R1, Operand(R2, LSL, 3)); | 1122 __ add(R3, R1, Operand(R2, LSL, 3)); |
1121 __ StoreToOffset(R0, R3, StoreBufferBlock::pointers_offset()); | 1123 __ StoreToOffset(R0, R3, StoreBufferBlock::pointers_offset()); |
1122 | 1124 |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1189 } else { | 1191 } else { |
1190 __ b(&slow_case, CS); // Unsigned higher or equal. | 1192 __ b(&slow_case, CS); // Unsigned higher or equal. |
1191 } | 1193 } |
1192 __ str(R3, Address(R5, Heap::TopOffset(space))); | 1194 __ str(R3, Address(R5, Heap::TopOffset(space))); |
1193 NOT_IN_PRODUCT(__ UpdateAllocationStats(cls.id(), space)); | 1195 NOT_IN_PRODUCT(__ UpdateAllocationStats(cls.id(), space)); |
1194 | 1196 |
1195 // R2: new object start. | 1197 // R2: new object start. |
1196 // R3: next object start. | 1198 // R3: next object start. |
1197 // R1: new object type arguments (if is_cls_parameterized). | 1199 // R1: new object type arguments (if is_cls_parameterized). |
1198 // Set the tags. | 1200 // Set the tags. |
1199 uword tags = 0; | 1201 uint32_t tags = 0; |
1200 tags = RawObject::SizeTag::update(instance_size, tags); | 1202 tags = RawObject::SizeTag::update(instance_size, tags); |
1201 ASSERT(cls.id() != kIllegalCid); | 1203 ASSERT(cls.id() != kIllegalCid); |
1202 tags = RawObject::ClassIdTag::update(cls.id(), tags); | 1204 tags = RawObject::ClassIdTag::update(cls.id(), tags); |
1203 __ LoadImmediate(R0, tags); | 1205 __ LoadImmediate(R0, tags); |
| 1206 // 64 bit store also zeros the hash_field. |
1204 __ StoreToOffset(R0, R2, Instance::tags_offset()); | 1207 __ StoreToOffset(R0, R2, Instance::tags_offset()); |
1205 | 1208 |
1206 // Initialize the remaining words of the object. | 1209 // Initialize the remaining words of the object. |
1207 __ LoadObject(R0, Object::null_object()); | 1210 __ LoadObject(R0, Object::null_object()); |
1208 | 1211 |
1209 // R0: raw null. | 1212 // R0: raw null. |
1210 // R2: new object start. | 1213 // R2: new object start. |
1211 // R3: next object start. | 1214 // R3: next object start. |
1212 // R1: new object type arguments (if is_cls_parameterized). | 1215 // R1: new object type arguments (if is_cls_parameterized). |
1213 // First try inlining the initialization without a loop. | 1216 // First try inlining the initialization without a loop. |
(...skipping 1163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2377 } | 2380 } |
2378 | 2381 |
2379 | 2382 |
2380 void StubCode::GenerateAsynchronousGapMarkerStub(Assembler* assembler) { | 2383 void StubCode::GenerateAsynchronousGapMarkerStub(Assembler* assembler) { |
2381 __ brk(0); | 2384 __ brk(0); |
2382 } | 2385 } |
2383 | 2386 |
2384 } // namespace dart | 2387 } // namespace dart |
2385 | 2388 |
2386 #endif // defined TARGET_ARCH_ARM64 | 2389 #endif // defined TARGET_ARCH_ARM64 |
OLD | NEW |