Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(220)

Side by Side Diff: runtime/vm/stub_code_arm.cc

Issue 730343005: Write-barrier verification on ARM. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 899 matching lines...) Expand 10 before | Expand all | Expand 10 after
910 // R6: allocation stats address. 910 // R6: allocation stats address.
911 __ str(R1, FieldAddress(R0, Context::num_variables_offset())); 911 __ str(R1, FieldAddress(R0, Context::num_variables_offset()));
912 912
913 // Setup the parent field. 913 // Setup the parent field.
914 // R0: new object. 914 // R0: new object.
915 // R1: number of context variables. 915 // R1: number of context variables.
916 // R2: object size. 916 // R2: object size.
917 // R3: next object start. 917 // R3: next object start.
918 // R6: allocation stats address. 918 // R6: allocation stats address.
919 __ LoadImmediate(R4, reinterpret_cast<intptr_t>(Object::null())); 919 __ LoadImmediate(R4, reinterpret_cast<intptr_t>(Object::null()));
920 __ StoreIntoObjectNoBarrier(R0, FieldAddress(R0, Context::parent_offset()),
921 R3);
920 __ str(R4, FieldAddress(R0, Context::parent_offset())); 922 __ str(R4, FieldAddress(R0, Context::parent_offset()));
921 923
922 // Initialize the context variables. 924 // Initialize the context variables.
923 // R0: new object. 925 // R0: new object.
924 // R1: number of context variables. 926 // R1: number of context variables.
925 // R2: object size. 927 // R2: object size.
926 // R3: next object start. 928 // R3: next object start.
927 // R4, R5: raw null. 929 // R4, R5: raw null.
928 // R6: allocation stats address. 930 // R6: allocation stats address.
929 Label loop; 931 Label loop;
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
1093 1095
1094 // Initialize the remaining words of the object. 1096 // Initialize the remaining words of the object.
1095 __ LoadImmediate(R2, reinterpret_cast<intptr_t>(Object::null())); 1097 __ LoadImmediate(R2, reinterpret_cast<intptr_t>(Object::null()));
1096 1098
1097 // R2: raw null. 1099 // R2: raw null.
1098 // R0: new object (tagged). 1100 // R0: new object (tagged).
1099 // R1: next object start. 1101 // R1: next object start.
1100 // R5: allocation stats table. 1102 // R5: allocation stats table.
1101 // First try inlining the initialization without a loop. 1103 // First try inlining the initialization without a loop.
1102 if (instance_size < (kInlineInstanceSize * kWordSize)) { 1104 if (instance_size < (kInlineInstanceSize * kWordSize)) {
1103 // Check if the object contains any non-header fields.
1104 // Small objects are initialized using a consecutive set of writes. 1105 // Small objects are initialized using a consecutive set of writes.
1105 intptr_t current_offset = Instance::NextFieldOffset(); 1106 intptr_t begin_offset = Instance::NextFieldOffset() - kHeapObjectTag;
1106 // Write two nulls at a time. 1107 intptr_t end_offset = instance_size - kHeapObjectTag;
1107 if (instance_size >= 2 * kWordSize) { 1108 // Save one move if less than two fields.
1109 if ((end_offset - begin_offset) >= (2 * kWordSize)) {
1108 __ mov(R3, Operand(R2)); 1110 __ mov(R3, Operand(R2));
1109 while (current_offset + kWordSize < instance_size) {
1110 __ StoreToOffset(kWordPair, R2, R0, current_offset - kHeapObjectTag);
1111 current_offset += 2 * kWordSize;
1112 }
1113 } 1111 }
1114 // Write remainder. 1112 __ InitializeFieldsNoBarrierUnrolled(R0, R0, begin_offset, end_offset,
1115 while (current_offset < instance_size) { 1113 R2, R3);
1116 __ StoreToOffset(kWord, R2, R0, current_offset - kHeapObjectTag);
1117 current_offset += kWordSize;
1118 }
1119 } else { 1114 } else {
1120 // There are more than kInlineInstanceSize(12) fields 1115 // There are more than kInlineInstanceSize(12) fields
1121 __ add(R4, R0, Operand(Instance::NextFieldOffset() - kHeapObjectTag)); 1116 __ add(R4, R0, Operand(Instance::NextFieldOffset() - kHeapObjectTag));
1122 __ mov(R3, Operand(R2)); 1117 __ mov(R3, Operand(R2));
1123 // Loop until the whole object is initialized. 1118 // Loop until the whole object is initialized.
1124 // R2: raw null. 1119 // R2: raw null.
1125 // R3: raw null. 1120 // R3: raw null.
1126 // R0: new object (tagged). 1121 // R0: new object (tagged).
1127 // R1: next object start. 1122 // R1: next object start.
1128 // R4: next word to be initialized. 1123 // R4: next word to be initialized.
1129 // R5: allocation stats table. 1124 // R5: allocation stats table.
1130 __ InitializeFieldsNoBarrier(R0, R4, R1, R2, R3); 1125 __ InitializeFieldsNoBarrier(R0, R4, R1, R2, R3);
1131 } 1126 }
1132 if (is_cls_parameterized) { 1127 if (is_cls_parameterized) {
1133 // Set the type arguments in the new object. 1128 // Set the type arguments in the new object.
1134 __ ldr(R4, Address(SP, 0)); 1129 __ ldr(R4, Address(SP, 0));
1135 __ StoreToOffset(kWord, R4, 1130 FieldAddress type_args(R0, cls.type_arguments_field_offset());
1136 R0, cls.type_arguments_field_offset() - kHeapObjectTag); 1131 __ StoreIntoObjectNoBarrier(R0, type_args, R4);
1137 } 1132 }
1138 1133
1139 // Done allocating and initializing the instance. 1134 // Done allocating and initializing the instance.
1140 // R0: new object (tagged). 1135 // R0: new object (tagged).
1141 // R5: allocation stats table. 1136 // R5: allocation stats table.
1142 1137
1143 // Update allocation stats. 1138 // Update allocation stats.
1144 __ IncrementAllocationStats(R5, cls.id(), space); 1139 __ IncrementAllocationStats(R5, cls.id(), space);
1145 1140
1146 // R0: new object (tagged). 1141 // R0: new object (tagged).
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
1296 __ b(&ok, EQ); 1291 __ b(&ok, EQ);
1297 __ Bind(&error); 1292 __ Bind(&error);
1298 __ Stop("Incorrect IC data"); 1293 __ Stop("Incorrect IC data");
1299 __ Bind(&ok); 1294 __ Bind(&ok);
1300 #endif 1295 #endif
1301 // Update counter. 1296 // Update counter.
1302 const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize; 1297 const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize;
1303 __ LoadFromOffset(kWord, R1, R6, count_offset); 1298 __ LoadFromOffset(kWord, R1, R6, count_offset);
1304 __ adds(R1, R1, Operand(Smi::RawValue(1))); 1299 __ adds(R1, R1, Operand(Smi::RawValue(1)));
1305 __ LoadImmediate(R1, Smi::RawValue(Smi::kMaxValue), VS); // Overflow. 1300 __ LoadImmediate(R1, Smi::RawValue(Smi::kMaxValue), VS); // Overflow.
1306 __ StoreToOffset(kWord, R1, R6, count_offset); 1301 __ StoreIntoSmiField(Address(R6, count_offset), R1);
1307 __ Ret(); 1302 __ Ret();
1308 } 1303 }
1309 1304
1310 1305
1311 // Generate inline cache check for 'num_args'. 1306 // Generate inline cache check for 'num_args'.
1312 // LR: return address. 1307 // LR: return address.
1313 // R5: inline cache data object. 1308 // R5: inline cache data object.
1314 // Control flow: 1309 // Control flow:
1315 // - If receiver is null -> jump to IC miss. 1310 // - If receiver is null -> jump to IC miss.
1316 // - If receiver is Smi -> load Smi class. 1311 // - If receiver is Smi -> load Smi class.
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
1440 __ Bind(&found); 1435 __ Bind(&found);
1441 // R6: pointer to an IC data check group. 1436 // R6: pointer to an IC data check group.
1442 const intptr_t target_offset = ICData::TargetIndexFor(num_args) * kWordSize; 1437 const intptr_t target_offset = ICData::TargetIndexFor(num_args) * kWordSize;
1443 const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize; 1438 const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize;
1444 __ LoadFromOffset(kWord, R0, R6, target_offset); 1439 __ LoadFromOffset(kWord, R0, R6, target_offset);
1445 1440
1446 // Update counter. 1441 // Update counter.
1447 __ LoadFromOffset(kWord, R1, R6, count_offset); 1442 __ LoadFromOffset(kWord, R1, R6, count_offset);
1448 __ adds(R1, R1, Operand(Smi::RawValue(1))); 1443 __ adds(R1, R1, Operand(Smi::RawValue(1)));
1449 __ LoadImmediate(R1, Smi::RawValue(Smi::kMaxValue), VS); // Overflow. 1444 __ LoadImmediate(R1, Smi::RawValue(Smi::kMaxValue), VS); // Overflow.
1450 __ StoreToOffset(kWord, R1, R6, count_offset); 1445 __ StoreIntoSmiField(Address(R6, count_offset), R1);
1451 1446
1452 __ Bind(&call_target_function); 1447 __ Bind(&call_target_function);
1453 // R0: target function. 1448 // R0: target function.
1454 __ ldr(R2, FieldAddress(R0, Function::instructions_offset())); 1449 __ ldr(R2, FieldAddress(R0, Function::instructions_offset()));
1455 __ AddImmediate(R2, Instructions::HeaderSize() - kHeapObjectTag); 1450 __ AddImmediate(R2, Instructions::HeaderSize() - kHeapObjectTag);
1456 __ bx(R2); 1451 __ bx(R2);
1457 1452
1458 __ Bind(&stepping); 1453 __ Bind(&stepping);
1459 __ EnterStubFrame(); 1454 __ EnterStubFrame();
1460 __ Push(R5); // Preserve IC data. 1455 __ Push(R5); // Preserve IC data.
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
1573 // R6: ic_data_array with entries: target functions and count. 1568 // R6: ic_data_array with entries: target functions and count.
1574 __ AddImmediate(R6, R6, Array::data_offset() - kHeapObjectTag); 1569 __ AddImmediate(R6, R6, Array::data_offset() - kHeapObjectTag);
1575 // R6: points directly to the first ic data array element. 1570 // R6: points directly to the first ic data array element.
1576 const intptr_t target_offset = ICData::TargetIndexFor(0) * kWordSize; 1571 const intptr_t target_offset = ICData::TargetIndexFor(0) * kWordSize;
1577 const intptr_t count_offset = ICData::CountIndexFor(0) * kWordSize; 1572 const intptr_t count_offset = ICData::CountIndexFor(0) * kWordSize;
1578 1573
1579 // Increment count for this call. 1574 // Increment count for this call.
1580 __ LoadFromOffset(kWord, R1, R6, count_offset); 1575 __ LoadFromOffset(kWord, R1, R6, count_offset);
1581 __ adds(R1, R1, Operand(Smi::RawValue(1))); 1576 __ adds(R1, R1, Operand(Smi::RawValue(1)));
1582 __ LoadImmediate(R1, Smi::RawValue(Smi::kMaxValue), VS); // Overflow. 1577 __ LoadImmediate(R1, Smi::RawValue(Smi::kMaxValue), VS); // Overflow.
1583 __ StoreToOffset(kWord, R1, R6, count_offset); 1578 __ StoreIntoSmiField(Address(R6, count_offset), R1);
1584 1579
1585 // Load arguments descriptor into R4. 1580 // Load arguments descriptor into R4.
1586 __ ldr(R4, FieldAddress(R5, ICData::arguments_descriptor_offset())); 1581 __ ldr(R4, FieldAddress(R5, ICData::arguments_descriptor_offset()));
1587 1582
1588 // Get function and call it, if possible. 1583 // Get function and call it, if possible.
1589 __ LoadFromOffset(kWord, R0, R6, target_offset); 1584 __ LoadFromOffset(kWord, R0, R6, target_offset);
1590 __ ldr(R2, FieldAddress(R0, Function::instructions_offset())); 1585 __ ldr(R2, FieldAddress(R0, Function::instructions_offset()));
1591 1586
1592 // R0: function. 1587 // R0: function.
1593 // R2: target instructions. 1588 // R2: target instructions.
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after
1977 const Register right = R0; 1972 const Register right = R0;
1978 __ ldr(left, Address(SP, 1 * kWordSize)); 1973 __ ldr(left, Address(SP, 1 * kWordSize));
1979 __ ldr(right, Address(SP, 0 * kWordSize)); 1974 __ ldr(right, Address(SP, 0 * kWordSize));
1980 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); 1975 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp);
1981 __ Ret(); 1976 __ Ret();
1982 } 1977 }
1983 1978
1984 } // namespace dart 1979 } // namespace dart
1985 1980
1986 #endif // defined TARGET_ARCH_ARM 1981 #endif // defined TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698