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

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

Issue 51653006: Track live instance and allocation counts for classes (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 11 months 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/intermediate_language_mips.cc ('k') | runtime/vm/intrinsifier_ia32.cc » ('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" // Needed here to get TARGET_ARCH_ARM. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM.
6 #if defined(TARGET_ARCH_ARM) 6 #if defined(TARGET_ARCH_ARM)
7 7
8 #include "vm/intrinsifier.h" 8 #include "vm/intrinsifier.h"
9 9
10 #include "vm/assembler.h" 10 #include "vm/assembler.h"
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
64 // R2: allocation size. 64 // R2: allocation size.
65 __ LoadImmediate(R3, heap->EndAddress()); 65 __ LoadImmediate(R3, heap->EndAddress());
66 __ ldr(R3, Address(R3, 0)); 66 __ ldr(R3, Address(R3, 0));
67 __ cmp(R1, ShifterOperand(R3)); 67 __ cmp(R1, ShifterOperand(R3));
68 __ b(&fall_through, CS); 68 __ b(&fall_through, CS);
69 69
70 // Successfully allocated the object(s), now update top to point to 70 // Successfully allocated the object(s), now update top to point to
71 // next object start and initialize the object. 71 // next object start and initialize the object.
72 __ str(R1, Address(R6, 0)); 72 __ str(R1, Address(R6, 0));
73 __ add(R0, R0, ShifterOperand(kHeapObjectTag)); 73 __ add(R0, R0, ShifterOperand(kHeapObjectTag));
74 __ UpdateAllocationStatsWithSize(kArrayCid, R2, R4);
74 75
75 // Initialize the tags. 76 // Initialize the tags.
76 // R0: new object start as a tagged pointer. 77 // R0: new object start as a tagged pointer.
77 // R1: new object end address. 78 // R1: new object end address.
78 // R2: allocation size. 79 // R2: allocation size.
79 { 80 {
80 const intptr_t shift = RawObject::kSizeTagBit - kObjectAlignmentLog2; 81 const intptr_t shift = RawObject::kSizeTagBit - kObjectAlignmentLog2;
81 const Class& cls = Class::Handle(isolate->object_store()->array_class()); 82 const Class& cls = Class::Handle(isolate->object_store()->array_class());
82 83
83 __ CompareImmediate(R2, RawObject::SizeTag::kMaxSizeTag); 84 __ CompareImmediate(R2, RawObject::SizeTag::kMaxSizeTag);
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
299 // Store the type argument field in the growable array object. 300 // Store the type argument field in the growable array object.
300 __ ldr(R1, Address(SP, kTypeArgumentsOffset)); // Type argument. 301 __ ldr(R1, Address(SP, kTypeArgumentsOffset)); // Type argument.
301 __ StoreIntoObjectNoBarrier( 302 __ StoreIntoObjectNoBarrier(
302 R0, 303 R0,
303 FieldAddress(R0, GrowableObjectArray::type_arguments_offset()), 304 FieldAddress(R0, GrowableObjectArray::type_arguments_offset()),
304 R1); 305 R1);
305 306
306 // Set the length field in the growable array object to 0. 307 // Set the length field in the growable array object to 0.
307 __ LoadImmediate(R1, 0); 308 __ LoadImmediate(R1, 0);
308 __ str(R1, FieldAddress(R0, GrowableObjectArray::length_offset())); 309 __ str(R1, FieldAddress(R0, GrowableObjectArray::length_offset()));
310 __ UpdateAllocationStats(kGrowableObjectArrayCid, R1);
309 __ Ret(); // Returns the newly allocated object in R0. 311 __ Ret(); // Returns the newly allocated object in R0.
310 312
311 __ Bind(&fall_through); 313 __ Bind(&fall_through);
312 } 314 }
313 315
314 316
315 void Intrinsifier::GrowableList_getLength(Assembler* assembler) { 317 void Intrinsifier::GrowableList_getLength(Assembler* assembler) {
316 __ ldr(R0, Address(SP, 0 * kWordSize)); 318 __ ldr(R0, Address(SP, 0 * kWordSize));
317 __ ldr(R0, FieldAddress(R0, GrowableObjectArray::length_offset())); 319 __ ldr(R0, FieldAddress(R0, GrowableObjectArray::length_offset()));
318 __ Ret(); 320 __ Ret();
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
484 __ LoadImmediate(R3, heap->EndAddress()); \ 486 __ LoadImmediate(R3, heap->EndAddress()); \
485 __ ldr(R3, Address(R3, 0)); \ 487 __ ldr(R3, Address(R3, 0)); \
486 __ cmp(R1, ShifterOperand(R3)); \ 488 __ cmp(R1, ShifterOperand(R3)); \
487 __ b(&fall_through, CS); \ 489 __ b(&fall_through, CS); \
488 \ 490 \
489 /* Successfully allocated the object(s), now update top to point to */ \ 491 /* Successfully allocated the object(s), now update top to point to */ \
490 /* next object start and initialize the object. */ \ 492 /* next object start and initialize the object. */ \
491 __ LoadImmediate(R3, heap->TopAddress()); \ 493 __ LoadImmediate(R3, heap->TopAddress()); \
492 __ str(R1, Address(R3, 0)); \ 494 __ str(R1, Address(R3, 0)); \
493 __ AddImmediate(R0, kHeapObjectTag); \ 495 __ AddImmediate(R0, kHeapObjectTag); \
494 \ 496 __ UpdateAllocationStatsWithSize(cid, R2, R4); \
495 /* Initialize the tags. */ \ 497 /* Initialize the tags. */ \
496 /* R0: new object start as a tagged pointer. */ \ 498 /* R0: new object start as a tagged pointer. */ \
497 /* R1: new object end address. */ \ 499 /* R1: new object end address. */ \
498 /* R2: allocation size. */ \ 500 /* R2: allocation size. */ \
499 { \ 501 { \
500 __ CompareImmediate(R2, RawObject::SizeTag::kMaxSizeTag); \ 502 __ CompareImmediate(R2, RawObject::SizeTag::kMaxSizeTag); \
501 __ mov(R2, ShifterOperand(R2, LSL, \ 503 __ mov(R2, ShifterOperand(R2, LSL, \
502 RawObject::kSizeTagBit - kObjectAlignmentLog2), LS); \ 504 RawObject::kSizeTagBit - kObjectAlignmentLog2), LS); \
503 __ mov(R2, ShifterOperand(0), HI); \ 505 __ mov(R2, ShifterOperand(0), HI); \
504 \ 506 \
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after
839 __ sub(R7, R7, ShifterOperand(1)); // R7 <- R7 - 1 841 __ sub(R7, R7, ShifterOperand(1)); // R7 <- R7 - 1
840 __ rsb(R8, R0, ShifterOperand(32)); // R8 <- 32 - R0 842 __ rsb(R8, R0, ShifterOperand(32)); // R8 <- 32 - R0
841 __ mov(R7, ShifterOperand(R7, LSL, R8)); // R7 <- R7 << R8 843 __ mov(R7, ShifterOperand(R7, LSL, R8)); // R7 <- R7 << R8
842 __ and_(R7, R1, ShifterOperand(R7)); // R7 <- R7 & R1 844 __ and_(R7, R1, ShifterOperand(R7)); // R7 <- R7 & R1
843 __ mov(R7, ShifterOperand(R7, LSR, R8)); // R7 <- R7 >> R8 845 __ mov(R7, ShifterOperand(R7, LSR, R8)); // R7 <- R7 >> R8
844 // Now R7 has the bits that fall off of R1 on a left shift. 846 // Now R7 has the bits that fall off of R1 on a left shift.
845 __ mov(R1, ShifterOperand(R1, LSL, R0)); // R1 gets the low bits. 847 __ mov(R1, ShifterOperand(R1, LSL, R0)); // R1 gets the low bits.
846 848
847 const Class& mint_class = Class::Handle( 849 const Class& mint_class = Class::Handle(
848 Isolate::Current()->object_store()->mint_class()); 850 Isolate::Current()->object_store()->mint_class());
849 __ TryAllocate(mint_class, &fall_through, R0); 851 __ TryAllocate(mint_class, &fall_through, R0, R2);
850 852
851 853
852 __ str(R1, FieldAddress(R0, Mint::value_offset())); 854 __ str(R1, FieldAddress(R0, Mint::value_offset()));
853 __ str(R7, FieldAddress(R0, Mint::value_offset() + kWordSize)); 855 __ str(R7, FieldAddress(R0, Mint::value_offset() + kWordSize));
854 __ Ret(); 856 __ Ret();
855 __ Bind(&fall_through); 857 __ Bind(&fall_through);
856 } 858 }
857 859
858 860
859 static void Get64SmiOrMint(Assembler* assembler, 861 static void Get64SmiOrMint(Assembler* assembler,
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after
1141 __ LoadDFromOffset(D0, R0, Double::value_offset() - kHeapObjectTag); 1143 __ LoadDFromOffset(D0, R0, Double::value_offset() - kHeapObjectTag);
1142 switch (kind) { 1144 switch (kind) {
1143 case Token::kADD: __ vaddd(D0, D0, D1); break; 1145 case Token::kADD: __ vaddd(D0, D0, D1); break;
1144 case Token::kSUB: __ vsubd(D0, D0, D1); break; 1146 case Token::kSUB: __ vsubd(D0, D0, D1); break;
1145 case Token::kMUL: __ vmuld(D0, D0, D1); break; 1147 case Token::kMUL: __ vmuld(D0, D0, D1); break;
1146 case Token::kDIV: __ vdivd(D0, D0, D1); break; 1148 case Token::kDIV: __ vdivd(D0, D0, D1); break;
1147 default: UNREACHABLE(); 1149 default: UNREACHABLE();
1148 } 1150 }
1149 const Class& double_class = Class::Handle( 1151 const Class& double_class = Class::Handle(
1150 Isolate::Current()->object_store()->double_class()); 1152 Isolate::Current()->object_store()->double_class());
1151 __ TryAllocate(double_class, &fall_through, R0); // Result register. 1153 __ TryAllocate(double_class, &fall_through, R0, R1); // Result register.
1152 __ StoreDToOffset(D0, R0, Double::value_offset() - kHeapObjectTag); 1154 __ StoreDToOffset(D0, R0, Double::value_offset() - kHeapObjectTag);
1153 __ Ret(); 1155 __ Ret();
1154 __ Bind(&fall_through); 1156 __ Bind(&fall_through);
1155 } 1157 }
1156 1158
1157 1159
1158 void Intrinsifier::Double_add(Assembler* assembler) { 1160 void Intrinsifier::Double_add(Assembler* assembler) {
1159 return DoubleArithmeticOperations(assembler, Token::kADD); 1161 return DoubleArithmeticOperations(assembler, Token::kADD);
1160 } 1162 }
1161 1163
(...skipping 22 matching lines...) Expand all
1184 __ b(&fall_through, NE); 1186 __ b(&fall_through, NE);
1185 // Is Smi. 1187 // Is Smi.
1186 __ SmiUntag(R0); 1188 __ SmiUntag(R0);
1187 __ vmovsr(S0, R0); 1189 __ vmovsr(S0, R0);
1188 __ vcvtdi(D1, S0); 1190 __ vcvtdi(D1, S0);
1189 __ ldr(R0, Address(SP, 1 * kWordSize)); 1191 __ ldr(R0, Address(SP, 1 * kWordSize));
1190 __ LoadDFromOffset(D0, R0, Double::value_offset() - kHeapObjectTag); 1192 __ LoadDFromOffset(D0, R0, Double::value_offset() - kHeapObjectTag);
1191 __ vmuld(D0, D0, D1); 1193 __ vmuld(D0, D0, D1);
1192 const Class& double_class = Class::Handle( 1194 const Class& double_class = Class::Handle(
1193 Isolate::Current()->object_store()->double_class()); 1195 Isolate::Current()->object_store()->double_class());
1194 __ TryAllocate(double_class, &fall_through, R0); // Result register. 1196 __ TryAllocate(double_class, &fall_through, R0, R1); // Result register.
1195 __ StoreDToOffset(D0, R0, Double::value_offset() - kHeapObjectTag); 1197 __ StoreDToOffset(D0, R0, Double::value_offset() - kHeapObjectTag);
1196 __ Ret(); 1198 __ Ret();
1197 __ Bind(&fall_through); 1199 __ Bind(&fall_through);
1198 } 1200 }
1199 1201
1200 1202
1201 void Intrinsifier::Double_fromInteger(Assembler* assembler) { 1203 void Intrinsifier::Double_fromInteger(Assembler* assembler) {
1202 Label fall_through; 1204 Label fall_through;
1203 1205
1204 __ ldr(R0, Address(SP, 0 * kWordSize)); 1206 __ ldr(R0, Address(SP, 0 * kWordSize));
1205 __ tst(R0, ShifterOperand(kSmiTagMask)); 1207 __ tst(R0, ShifterOperand(kSmiTagMask));
1206 __ b(&fall_through, NE); 1208 __ b(&fall_through, NE);
1207 // Is Smi. 1209 // Is Smi.
1208 __ SmiUntag(R0); 1210 __ SmiUntag(R0);
1209 __ vmovsr(S0, R0); 1211 __ vmovsr(S0, R0);
1210 __ vcvtdi(D0, S0); 1212 __ vcvtdi(D0, S0);
1211 const Class& double_class = Class::Handle( 1213 const Class& double_class = Class::Handle(
1212 Isolate::Current()->object_store()->double_class()); 1214 Isolate::Current()->object_store()->double_class());
1213 __ TryAllocate(double_class, &fall_through, R0); // Result register. 1215 __ TryAllocate(double_class, &fall_through, R0, R1); // Result register.
1214 __ StoreDToOffset(D0, R0, Double::value_offset() - kHeapObjectTag); 1216 __ StoreDToOffset(D0, R0, Double::value_offset() - kHeapObjectTag);
1215 __ Ret(); 1217 __ Ret();
1216 __ Bind(&fall_through); 1218 __ Bind(&fall_through);
1217 } 1219 }
1218 1220
1219 1221
1220 void Intrinsifier::Double_getIsNaN(Assembler* assembler) { 1222 void Intrinsifier::Double_getIsNaN(Assembler* assembler) {
1221 Label is_true; 1223 Label is_true;
1222 __ ldr(R0, Address(SP, 0 * kWordSize)); 1224 __ ldr(R0, Address(SP, 0 * kWordSize));
1223 __ LoadDFromOffset(D0, R0, Double::value_offset() - kHeapObjectTag); 1225 __ LoadDFromOffset(D0, R0, Double::value_offset() - kHeapObjectTag);
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1284 1286
1285 void Intrinsifier::Math_sqrt(Assembler* assembler) { 1287 void Intrinsifier::Math_sqrt(Assembler* assembler) {
1286 Label fall_through, is_smi, double_op; 1288 Label fall_through, is_smi, double_op;
1287 TestLastArgumentIsDouble(assembler, &is_smi, &fall_through); 1289 TestLastArgumentIsDouble(assembler, &is_smi, &fall_through);
1288 // Argument is double and is in R0. 1290 // Argument is double and is in R0.
1289 __ LoadDFromOffset(D1, R0, Double::value_offset() - kHeapObjectTag); 1291 __ LoadDFromOffset(D1, R0, Double::value_offset() - kHeapObjectTag);
1290 __ Bind(&double_op); 1292 __ Bind(&double_op);
1291 __ vsqrtd(D0, D1); 1293 __ vsqrtd(D0, D1);
1292 const Class& double_class = Class::Handle( 1294 const Class& double_class = Class::Handle(
1293 Isolate::Current()->object_store()->double_class()); 1295 Isolate::Current()->object_store()->double_class());
1294 __ TryAllocate(double_class, &fall_through, R0); // Result register. 1296 __ TryAllocate(double_class, &fall_through, R0, R1); // Result register.
1295 __ StoreDToOffset(D0, R0, Double::value_offset() - kHeapObjectTag); 1297 __ StoreDToOffset(D0, R0, Double::value_offset() - kHeapObjectTag);
1296 __ Ret(); 1298 __ Ret();
1297 __ Bind(&is_smi); 1299 __ Bind(&is_smi);
1298 __ SmiUntag(R0); 1300 __ SmiUntag(R0);
1299 __ vmovsr(S0, R0); 1301 __ vmovsr(S0, R0);
1300 __ vcvtdi(D1, S0); 1302 __ vcvtdi(D1, S0);
1301 __ b(&double_op); 1303 __ b(&double_op);
1302 __ Bind(&fall_through); 1304 __ Bind(&fall_through);
1303 } 1305 }
1304 1306
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
1507 // R3: heap->Top->Address(). 1509 // R3: heap->Top->Address().
1508 __ LoadImmediate(R7, heap->EndAddress()); 1510 __ LoadImmediate(R7, heap->EndAddress());
1509 __ ldr(R7, Address(R7, 0)); 1511 __ ldr(R7, Address(R7, 0));
1510 __ cmp(R1, ShifterOperand(R7)); 1512 __ cmp(R1, ShifterOperand(R7));
1511 __ b(&fail, CS); 1513 __ b(&fail, CS);
1512 1514
1513 // Successfully allocated the object(s), now update top to point to 1515 // Successfully allocated the object(s), now update top to point to
1514 // next object start and initialize the object. 1516 // next object start and initialize the object.
1515 __ str(R1, Address(R3, 0)); 1517 __ str(R1, Address(R3, 0));
1516 __ AddImmediate(R0, kHeapObjectTag); 1518 __ AddImmediate(R0, kHeapObjectTag);
1519 __ UpdateAllocationStatsWithSize(kOneByteStringCid, R2, R3);
1517 1520
1518 // Initialize the tags. 1521 // Initialize the tags.
1519 // R0: new object start as a tagged pointer. 1522 // R0: new object start as a tagged pointer.
1520 // R1: new object end address. 1523 // R1: new object end address.
1521 // R2: allocation size. 1524 // R2: allocation size.
1522 { 1525 {
1523 const intptr_t shift = RawObject::kSizeTagBit - kObjectAlignmentLog2; 1526 const intptr_t shift = RawObject::kSizeTagBit - kObjectAlignmentLog2;
1524 const Class& cls = 1527 const Class& cls =
1525 Class::Handle(isolate->object_store()->one_byte_string_class()); 1528 Class::Handle(isolate->object_store()->one_byte_string_class());
1526 1529
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
1703 1706
1704 1707
1705 void Intrinsifier::TwoByteString_equality(Assembler* assembler) { 1708 void Intrinsifier::TwoByteString_equality(Assembler* assembler) {
1706 StringEquality(assembler, kTwoByteStringCid); 1709 StringEquality(assembler, kTwoByteStringCid);
1707 } 1710 }
1708 1711
1709 1712
1710 } // namespace dart 1713 } // namespace dart
1711 1714
1712 #endif // defined TARGET_ARCH_ARM 1715 #endif // defined TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_mips.cc ('k') | runtime/vm/intrinsifier_ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698