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