| 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(), kWord); | 1093 __ LoadFieldFromOffset(TMP, R0, Object::tags_offset()); |
| 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. | |
| 1110 Label retry; | 1108 Label retry; |
| 1111 __ Bind(&retry); | 1109 __ Bind(&retry); |
| 1112 __ ldxr(R2, R3, kWord); | 1110 __ ldxr(R2, R3); |
| 1113 __ orri(R2, R2, Immediate(1 << RawObject::kRememberedBit)); | 1111 __ orri(R2, R2, Immediate(1 << RawObject::kRememberedBit)); |
| 1114 __ stxr(R1, R2, R3, kWord); | 1112 __ stxr(R1, R2, R3); |
| 1115 __ cmp(R1, Operand(1)); | 1113 __ cmp(R1, Operand(1)); |
| 1116 __ b(&retry, EQ); | 1114 __ b(&retry, EQ); |
| 1117 | 1115 |
| 1118 // Load the StoreBuffer block out of the thread. Then load top_ out of the | 1116 // Load the StoreBuffer block out of the thread. Then load top_ out of the |
| 1119 // StoreBufferBlock and add the address to the pointers_. | 1117 // StoreBufferBlock and add the address to the pointers_. |
| 1120 __ LoadFromOffset(R1, THR, Thread::store_buffer_block_offset()); | 1118 __ LoadFromOffset(R1, THR, Thread::store_buffer_block_offset()); |
| 1121 __ LoadFromOffset(R2, R1, StoreBufferBlock::top_offset(), kUnsignedWord); | 1119 __ LoadFromOffset(R2, R1, StoreBufferBlock::top_offset(), kUnsignedWord); |
| 1122 __ add(R3, R1, Operand(R2, LSL, 3)); | 1120 __ add(R3, R1, Operand(R2, LSL, 3)); |
| 1123 __ StoreToOffset(R0, R3, StoreBufferBlock::pointers_offset()); | 1121 __ StoreToOffset(R0, R3, StoreBufferBlock::pointers_offset()); |
| 1124 | 1122 |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1191 } else { | 1189 } else { |
| 1192 __ b(&slow_case, CS); // Unsigned higher or equal. | 1190 __ b(&slow_case, CS); // Unsigned higher or equal. |
| 1193 } | 1191 } |
| 1194 __ str(R3, Address(R5, Heap::TopOffset(space))); | 1192 __ str(R3, Address(R5, Heap::TopOffset(space))); |
| 1195 NOT_IN_PRODUCT(__ UpdateAllocationStats(cls.id(), space)); | 1193 NOT_IN_PRODUCT(__ UpdateAllocationStats(cls.id(), space)); |
| 1196 | 1194 |
| 1197 // R2: new object start. | 1195 // R2: new object start. |
| 1198 // R3: next object start. | 1196 // R3: next object start. |
| 1199 // R1: new object type arguments (if is_cls_parameterized). | 1197 // R1: new object type arguments (if is_cls_parameterized). |
| 1200 // Set the tags. | 1198 // Set the tags. |
| 1201 uint32_t tags = 0; | 1199 uword tags = 0; |
| 1202 tags = RawObject::SizeTag::update(instance_size, tags); | 1200 tags = RawObject::SizeTag::update(instance_size, tags); |
| 1203 ASSERT(cls.id() != kIllegalCid); | 1201 ASSERT(cls.id() != kIllegalCid); |
| 1204 tags = RawObject::ClassIdTag::update(cls.id(), tags); | 1202 tags = RawObject::ClassIdTag::update(cls.id(), tags); |
| 1205 __ LoadImmediate(R0, tags); | 1203 __ LoadImmediate(R0, tags); |
| 1206 // 64 bit store also zeros the hash_field. | |
| 1207 __ StoreToOffset(R0, R2, Instance::tags_offset()); | 1204 __ StoreToOffset(R0, R2, Instance::tags_offset()); |
| 1208 | 1205 |
| 1209 // Initialize the remaining words of the object. | 1206 // Initialize the remaining words of the object. |
| 1210 __ LoadObject(R0, Object::null_object()); | 1207 __ LoadObject(R0, Object::null_object()); |
| 1211 | 1208 |
| 1212 // R0: raw null. | 1209 // R0: raw null. |
| 1213 // R2: new object start. | 1210 // R2: new object start. |
| 1214 // R3: next object start. | 1211 // R3: next object start. |
| 1215 // R1: new object type arguments (if is_cls_parameterized). | 1212 // R1: new object type arguments (if is_cls_parameterized). |
| 1216 // First try inlining the initialization without a loop. | 1213 // First try inlining the initialization without a loop. |
| (...skipping 1163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2380 } | 2377 } |
| 2381 | 2378 |
| 2382 | 2379 |
| 2383 void StubCode::GenerateAsynchronousGapMarkerStub(Assembler* assembler) { | 2380 void StubCode::GenerateAsynchronousGapMarkerStub(Assembler* assembler) { |
| 2384 __ brk(0); | 2381 __ brk(0); |
| 2385 } | 2382 } |
| 2386 | 2383 |
| 2387 } // namespace dart | 2384 } // namespace dart |
| 2388 | 2385 |
| 2389 #endif // defined TARGET_ARCH_ARM64 | 2386 #endif // defined TARGET_ARCH_ARM64 |
| OLD | NEW |