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

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

Issue 1127453003: VM: Don't emit usage counter and range feedback code and when optimizations are disabled. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 5 years, 7 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
OLDNEW
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/code_generator.h" 9 #include "vm/code_generator.h"
10 #include "vm/compiler.h" 10 #include "vm/compiler.h"
11 #include "vm/dart_entry.h" 11 #include "vm/dart_entry.h"
12 #include "vm/flow_graph_compiler.h" 12 #include "vm/flow_graph_compiler.h"
13 #include "vm/heap.h" 13 #include "vm/heap.h"
14 #include "vm/instructions.h" 14 #include "vm/instructions.h"
15 #include "vm/object_store.h" 15 #include "vm/object_store.h"
16 #include "vm/stack_frame.h" 16 #include "vm/stack_frame.h"
17 #include "vm/stub_code.h" 17 #include "vm/stub_code.h"
18 #include "vm/tags.h" 18 #include "vm/tags.h"
19 19
20 #define __ assembler-> 20 #define __ assembler->
21 21
22 namespace dart { 22 namespace dart {
23 23
24 DEFINE_FLAG(bool, inline_alloc, true, "Inline allocation of objects."); 24 DEFINE_FLAG(bool, inline_alloc, true, "Inline allocation of objects.");
25 DEFINE_FLAG(bool, use_slow_path, false, 25 DEFINE_FLAG(bool, use_slow_path, false,
26 "Set to true for debugging & verifying the slow paths."); 26 "Set to true for debugging & verifying the slow paths.");
27 DECLARE_FLAG(bool, trace_optimized_ic_calls); 27 DECLARE_FLAG(bool, trace_optimized_ic_calls);
28 DECLARE_FLAG(int, optimization_counter_threshold);
28 29
29 // Input parameters: 30 // Input parameters:
30 // LR : return address. 31 // LR : return address.
31 // SP : address of last argument in argument array. 32 // SP : address of last argument in argument array.
32 // SP + 8*R4 - 8 : address of first argument in argument array. 33 // SP + 8*R4 - 8 : address of first argument in argument array.
33 // SP + 8*R4 : address of return value. 34 // SP + 8*R4 : address of return value.
34 // R5 : address of the runtime function to call. 35 // R5 : address of the runtime function to call.
35 // R4 : number of arguments to the call. 36 // R4 : number of arguments to the call.
36 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) { 37 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) {
37 const intptr_t isolate_offset = NativeArguments::isolate_offset(); 38 const intptr_t isolate_offset = NativeArguments::isolate_offset();
(...skipping 1220 matching lines...) Expand 10 before | Expand all | Expand 10 after
1258 R7, func_reg, Function::usage_counter_offset(), kNoPP, kWord); 1259 R7, func_reg, Function::usage_counter_offset(), kNoPP, kWord);
1259 __ add(R7, R7, Operand(1)); 1260 __ add(R7, R7, Operand(1));
1260 __ StoreFieldToOffset( 1261 __ StoreFieldToOffset(
1261 R7, func_reg, Function::usage_counter_offset(), kNoPP, kWord); 1262 R7, func_reg, Function::usage_counter_offset(), kNoPP, kWord);
1262 } 1263 }
1263 1264
1264 1265
1265 // Loads function into 'temp_reg'. 1266 // Loads function into 'temp_reg'.
1266 void StubCode::GenerateUsageCounterIncrement(Assembler* assembler, 1267 void StubCode::GenerateUsageCounterIncrement(Assembler* assembler,
1267 Register temp_reg) { 1268 Register temp_reg) {
1268 Register ic_reg = R5; 1269 if (FLAG_optimization_counter_threshold != -1) {
1269 Register func_reg = temp_reg; 1270 Register ic_reg = R5;
1270 ASSERT(temp_reg == R6); 1271 Register func_reg = temp_reg;
1271 __ Comment("Increment function counter"); 1272 ASSERT(temp_reg == R6);
1272 __ LoadFieldFromOffset(func_reg, ic_reg, ICData::owner_offset(), kNoPP); 1273 __ Comment("Increment function counter");
1273 __ LoadFieldFromOffset( 1274 __ LoadFieldFromOffset(func_reg, ic_reg, ICData::owner_offset(), kNoPP);
1274 R7, func_reg, Function::usage_counter_offset(), kNoPP, kWord); 1275 __ LoadFieldFromOffset(
1275 __ AddImmediate(R7, R7, 1, kNoPP); 1276 R7, func_reg, Function::usage_counter_offset(), kNoPP, kWord);
1276 __ StoreFieldToOffset( 1277 __ AddImmediate(R7, R7, 1, kNoPP);
1277 R7, func_reg, Function::usage_counter_offset(), kNoPP, kWord); 1278 __ StoreFieldToOffset(
1279 R7, func_reg, Function::usage_counter_offset(), kNoPP, kWord);
1280 }
1278 } 1281 }
1279 1282
1280 1283
1281 // Note: R5 must be preserved. 1284 // Note: R5 must be preserved.
1282 // Attempt a quick Smi operation for known operations ('kind'). The ICData 1285 // Attempt a quick Smi operation for known operations ('kind'). The ICData
1283 // must have been primed with a Smi/Smi check that will be used for counting 1286 // must have been primed with a Smi/Smi check that will be used for counting
1284 // the invocations. 1287 // the invocations.
1285 static void EmitFastSmiOp(Assembler* assembler, 1288 static void EmitFastSmiOp(Assembler* assembler,
1286 Token::Kind kind, 1289 Token::Kind kind,
1287 intptr_t num_args, 1290 intptr_t num_args,
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1336 __ ldr(R1, Address(R6, 0)); 1339 __ ldr(R1, Address(R6, 0));
1337 __ CompareImmediate(R1, imm_smi_cid, kNoPP); 1340 __ CompareImmediate(R1, imm_smi_cid, kNoPP);
1338 __ b(&error, NE); 1341 __ b(&error, NE);
1339 __ ldr(R1, Address(R6, kWordSize)); 1342 __ ldr(R1, Address(R6, kWordSize));
1340 __ CompareImmediate(R1, imm_smi_cid, kNoPP); 1343 __ CompareImmediate(R1, imm_smi_cid, kNoPP);
1341 __ b(&ok, EQ); 1344 __ b(&ok, EQ);
1342 __ Bind(&error); 1345 __ Bind(&error);
1343 __ Stop("Incorrect IC data"); 1346 __ Stop("Incorrect IC data");
1344 __ Bind(&ok); 1347 __ Bind(&ok);
1345 #endif 1348 #endif
1346 const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize; 1349 if (FLAG_optimization_counter_threshold != -1) {
1347 // Update counter. 1350 const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize;
1348 __ LoadFromOffset(R1, R6, count_offset, kNoPP); 1351 // Update counter.
1349 __ adds(R1, R1, Operand(Smi::RawValue(1))); 1352 __ LoadFromOffset(R1, R6, count_offset, kNoPP);
1350 __ LoadImmediate(R2, Smi::RawValue(Smi::kMaxValue), kNoPP); 1353 __ adds(R1, R1, Operand(Smi::RawValue(1)));
1351 __ csel(R1, R2, R1, VS); // Overflow. 1354 __ LoadImmediate(R2, Smi::RawValue(Smi::kMaxValue), kNoPP);
1352 __ StoreToOffset(R1, R6, count_offset, kNoPP); 1355 __ csel(R1, R2, R1, VS); // Overflow.
1356 __ StoreToOffset(R1, R6, count_offset, kNoPP);
1357 }
1353 1358
1354 __ ret(); 1359 __ ret();
1355 } 1360 }
1356 1361
1357 1362
1358 // Generate inline cache check for 'num_args'. 1363 // Generate inline cache check for 'num_args'.
1359 // LR: return address. 1364 // LR: return address.
1360 // R5: inline cache data object. 1365 // R5: inline cache data object.
1361 // Control flow: 1366 // Control flow:
1362 // - If receiver is null -> jump to IC miss. 1367 // - If receiver is null -> jump to IC miss.
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
1513 Label call_target_function; 1518 Label call_target_function;
1514 __ b(&call_target_function); 1519 __ b(&call_target_function);
1515 1520
1516 __ Bind(&found); 1521 __ Bind(&found);
1517 __ Comment("Update caller's counter"); 1522 __ Comment("Update caller's counter");
1518 // R6: pointer to an IC data check group. 1523 // R6: pointer to an IC data check group.
1519 const intptr_t target_offset = ICData::TargetIndexFor(num_args) * kWordSize; 1524 const intptr_t target_offset = ICData::TargetIndexFor(num_args) * kWordSize;
1520 const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize; 1525 const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize;
1521 __ LoadFromOffset(R0, R6, target_offset, kNoPP); 1526 __ LoadFromOffset(R0, R6, target_offset, kNoPP);
1522 1527
1523 // Update counter. 1528 if (FLAG_optimization_counter_threshold != -1) {
1524 __ LoadFromOffset(R1, R6, count_offset, kNoPP); 1529 // Update counter.
1525 __ adds(R1, R1, Operand(Smi::RawValue(1))); 1530 __ LoadFromOffset(R1, R6, count_offset, kNoPP);
1526 __ LoadImmediate(R2, Smi::RawValue(Smi::kMaxValue), kNoPP); 1531 __ adds(R1, R1, Operand(Smi::RawValue(1)));
1527 __ csel(R1, R2, R1, VS); // Overflow. 1532 __ LoadImmediate(R2, Smi::RawValue(Smi::kMaxValue), kNoPP);
1528 __ StoreToOffset(R1, R6, count_offset, kNoPP); 1533 __ csel(R1, R2, R1, VS); // Overflow.
1534 __ StoreToOffset(R1, R6, count_offset, kNoPP);
1535 }
1529 1536
1530 __ Comment("Call target"); 1537 __ Comment("Call target");
1531 __ Bind(&call_target_function); 1538 __ Bind(&call_target_function);
1532 // R0: target function. 1539 // R0: target function.
1533 __ LoadFieldFromOffset(R2, R0, Function::instructions_offset(), kNoPP); 1540 __ LoadFieldFromOffset(R2, R0, Function::instructions_offset(), kNoPP);
1534 __ AddImmediate( 1541 __ AddImmediate(
1535 R2, R2, Instructions::HeaderSize() - kHeapObjectTag, kNoPP); 1542 R2, R2, Instructions::HeaderSize() - kHeapObjectTag, kNoPP);
1536 if (range_collection_mode == kCollectRanges) { 1543 if (range_collection_mode == kCollectRanges) {
1537 __ ldr(R1, Address(SP, 0 * kWordSize)); 1544 __ ldr(R1, Address(SP, 0 * kWordSize));
1538 if (num_args == 2) { 1545 if (num_args == 2) {
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
1698 __ Bind(&done_stepping); 1705 __ Bind(&done_stepping);
1699 1706
1700 // R5: IC data object (preserved). 1707 // R5: IC data object (preserved).
1701 __ LoadFieldFromOffset(R6, R5, ICData::ic_data_offset(), kNoPP); 1708 __ LoadFieldFromOffset(R6, R5, ICData::ic_data_offset(), kNoPP);
1702 // R6: ic_data_array with entries: target functions and count. 1709 // R6: ic_data_array with entries: target functions and count.
1703 __ AddImmediate(R6, R6, Array::data_offset() - kHeapObjectTag, kNoPP); 1710 __ AddImmediate(R6, R6, Array::data_offset() - kHeapObjectTag, kNoPP);
1704 // R6: points directly to the first ic data array element. 1711 // R6: points directly to the first ic data array element.
1705 const intptr_t target_offset = ICData::TargetIndexFor(0) * kWordSize; 1712 const intptr_t target_offset = ICData::TargetIndexFor(0) * kWordSize;
1706 const intptr_t count_offset = ICData::CountIndexFor(0) * kWordSize; 1713 const intptr_t count_offset = ICData::CountIndexFor(0) * kWordSize;
1707 1714
1708 // Increment count for this call. 1715 if (FLAG_optimization_counter_threshold != -1) {
1709 __ LoadFromOffset(R1, R6, count_offset, kNoPP); 1716 // Increment count for this call.
1710 __ adds(R1, R1, Operand(Smi::RawValue(1))); 1717 __ LoadFromOffset(R1, R6, count_offset, kNoPP);
1711 __ LoadImmediate(R2, Smi::RawValue(Smi::kMaxValue), kNoPP); 1718 __ adds(R1, R1, Operand(Smi::RawValue(1)));
1712 __ csel(R1, R2, R1, VS); // Overflow. 1719 __ LoadImmediate(R2, Smi::RawValue(Smi::kMaxValue), kNoPP);
1713 __ StoreToOffset(R1, R6, count_offset, kNoPP); 1720 __ csel(R1, R2, R1, VS); // Overflow.
1721 __ StoreToOffset(R1, R6, count_offset, kNoPP);
1722 }
1714 1723
1715 // Load arguments descriptor into R4. 1724 // Load arguments descriptor into R4.
1716 __ LoadFieldFromOffset(R4, R5, ICData::arguments_descriptor_offset(), kNoPP); 1725 __ LoadFieldFromOffset(R4, R5, ICData::arguments_descriptor_offset(), kNoPP);
1717 1726
1718 // Get function and call it, if possible. 1727 // Get function and call it, if possible.
1719 __ LoadFromOffset(R0, R6, target_offset, kNoPP); 1728 __ LoadFromOffset(R0, R6, target_offset, kNoPP);
1720 __ LoadFieldFromOffset(R2, R0, Function::instructions_offset(), kNoPP); 1729 __ LoadFieldFromOffset(R2, R0, Function::instructions_offset(), kNoPP);
1721 1730
1722 // R0: function. 1731 // R0: function.
1723 // R2: target instructons. 1732 // R2: target instructons.
(...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after
2104 const Register right = R0; 2113 const Register right = R0;
2105 __ LoadFromOffset(left, SP, 1 * kWordSize, kNoPP); 2114 __ LoadFromOffset(left, SP, 1 * kWordSize, kNoPP);
2106 __ LoadFromOffset(right, SP, 0 * kWordSize, kNoPP); 2115 __ LoadFromOffset(right, SP, 0 * kWordSize, kNoPP);
2107 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); 2116 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp);
2108 __ ret(); 2117 __ ret();
2109 } 2118 }
2110 2119
2111 } // namespace dart 2120 } // namespace dart
2112 2121
2113 #endif // defined TARGET_ARCH_ARM64 2122 #endif // defined TARGET_ARCH_ARM64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698