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

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

Powered by Google App Engine
This is Rietveld 408576698