| 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 |