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

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

Issue 17421003: Store arguments descriptor in ICData. Remove loading of arguments descriptor at unoptimized call si… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 6 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/raw_object.h ('k') | runtime/vm/stub_code_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" 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/compiler.h" 10 #include "vm/compiler.h"
(...skipping 1296 matching lines...) Expand 10 before | Expand all | Expand 10 after
1307 // Remove arguments. 1307 // Remove arguments.
1308 __ Drop(4); 1308 __ Drop(4);
1309 __ Pop(R0); // Get result into R0. 1309 __ Pop(R0); // Get result into R0.
1310 __ LeaveStubFrame(); 1310 __ LeaveStubFrame();
1311 __ Ret(); 1311 __ Ret();
1312 } 1312 }
1313 1313
1314 1314
1315 // R6: function object. 1315 // R6: function object.
1316 // R5: inline cache data object. 1316 // R5: inline cache data object.
1317 // R4: arguments descriptor array. 1317 // Cannot use function object from ICData as it may be the inlined
1318 // function and not the top-scope function.
1318 void StubCode::GenerateOptimizedUsageCounterIncrement(Assembler* assembler) { 1319 void StubCode::GenerateOptimizedUsageCounterIncrement(Assembler* assembler) {
1319 Register ic_reg = R5; 1320 Register ic_reg = R5;
1320 Register func_reg = R6; 1321 Register func_reg = R6;
1321 if (FLAG_trace_optimized_ic_calls) { 1322 if (FLAG_trace_optimized_ic_calls) {
1322 __ EnterStubFrame(); 1323 __ EnterStubFrame();
1323 __ PushList((1 << R4) | (1 << R5) | (1 << R6)); // Preserve. 1324 __ PushList((1 << R5) | (1 << R6)); // Preserve.
1324 __ Push(ic_reg); // Argument. 1325 __ Push(ic_reg); // Argument.
1325 __ Push(func_reg); // Argument. 1326 __ Push(func_reg); // Argument.
1326 __ CallRuntime(kTraceICCallRuntimeEntry); 1327 __ CallRuntime(kTraceICCallRuntimeEntry);
1327 __ Drop(2); // Discard argument; 1328 __ Drop(2); // Discard argument;
1328 __ PushList((1 << R4) | (1 << R5) | (1 << R6)); // Restore. 1329 __ PopList((1 << R5) | (1 << R6)); // Restore.
1329 __ LeaveStubFrame(); 1330 __ LeaveStubFrame();
1330 } 1331 }
1331 __ ldr(R7, FieldAddress(func_reg, Function::usage_counter_offset())); 1332 __ ldr(R7, FieldAddress(func_reg, Function::usage_counter_offset()));
1332 Label is_hot; 1333 Label is_hot;
1333 if (FlowGraphCompiler::CanOptimize()) { 1334 if (FlowGraphCompiler::CanOptimize()) {
1334 ASSERT(FLAG_optimization_counter_threshold > 1); 1335 ASSERT(FLAG_optimization_counter_threshold > 1);
1335 __ CompareImmediate(R7, FLAG_optimization_counter_threshold); 1336 __ CompareImmediate(R7, FLAG_optimization_counter_threshold);
1336 __ b(&is_hot, GE); 1337 __ b(&is_hot, GE);
1337 // As long as VM has no OSR do not optimize in the middle of the function 1338 // As long as VM has no OSR do not optimize in the middle of the function
1338 // but only at exit so that we have collected all type feedback before 1339 // but only at exit so that we have collected all type feedback before
(...skipping 26 matching lines...) Expand all
1365 } 1366 }
1366 __ add(R7, R7, ShifterOperand(1)); 1367 __ add(R7, R7, ShifterOperand(1));
1367 __ str(R7, FieldAddress(func_reg, Function::usage_counter_offset())); 1368 __ str(R7, FieldAddress(func_reg, Function::usage_counter_offset()));
1368 __ Bind(&is_hot); 1369 __ Bind(&is_hot);
1369 } 1370 }
1370 1371
1371 1372
1372 // Generate inline cache check for 'num_args'. 1373 // Generate inline cache check for 'num_args'.
1373 // LR: return address. 1374 // LR: return address.
1374 // R5: inline cache data object. 1375 // R5: inline cache data object.
1375 // R4: arguments descriptor array.
1376 // Control flow: 1376 // Control flow:
1377 // - If receiver is null -> jump to IC miss. 1377 // - If receiver is null -> jump to IC miss.
1378 // - If receiver is Smi -> load Smi class. 1378 // - If receiver is Smi -> load Smi class.
1379 // - If receiver is not-Smi -> load receiver's class. 1379 // - If receiver is not-Smi -> load receiver's class.
1380 // - Check if 'num_args' (including receiver) match any IC data group. 1380 // - Check if 'num_args' (including receiver) match any IC data group.
1381 // - Match found -> jump to target. 1381 // - Match found -> jump to target.
1382 // - Match not found -> jump to IC miss. 1382 // - Match not found -> jump to IC miss.
1383 void StubCode::GenerateNArgsCheckInlineCacheStub(Assembler* assembler, 1383 void StubCode::GenerateNArgsCheckInlineCacheStub(Assembler* assembler,
1384 intptr_t num_args) { 1384 intptr_t num_args) {
1385 ASSERT(num_args > 0); 1385 ASSERT(num_args > 0);
1386 #if defined(DEBUG) 1386 #if defined(DEBUG)
1387 { Label ok; 1387 { Label ok;
1388 // Check that the IC data array has NumberOfArgumentsChecked() == num_args. 1388 // Check that the IC data array has NumberOfArgumentsChecked() == num_args.
1389 // 'num_args_tested' is stored as an untagged int. 1389 // 'num_args_tested' is stored as an untagged int.
1390 __ ldr(R6, FieldAddress(R5, ICData::num_args_tested_offset())); 1390 __ ldr(R6, FieldAddress(R5, ICData::num_args_tested_offset()));
1391 __ CompareImmediate(R6, num_args); 1391 __ CompareImmediate(R6, num_args);
1392 __ b(&ok, EQ); 1392 __ b(&ok, EQ);
1393 __ Stop("Incorrect stub for IC data"); 1393 __ Stop("Incorrect stub for IC data");
1394 __ Bind(&ok); 1394 __ Bind(&ok);
1395 } 1395 }
1396 #endif // DEBUG 1396 #endif // DEBUG
1397 1397
1398 // Load arguments descriptor into R4.
1399 __ ldr(R4, FieldAddress(R5, ICData::arguments_descriptor_offset()));
1398 // Preserve return address, since LR is needed for subroutine call. 1400 // Preserve return address, since LR is needed for subroutine call.
1399 __ mov(R8, ShifterOperand(LR)); 1401 __ mov(R8, ShifterOperand(LR));
1400 // Loop that checks if there is an IC data match. 1402 // Loop that checks if there is an IC data match.
1401 Label loop, update, test, found, get_class_id_as_smi; 1403 Label loop, update, test, found, get_class_id_as_smi;
1402 // R5: IC data object (preserved). 1404 // R5: IC data object (preserved).
1403 __ ldr(R6, FieldAddress(R5, ICData::ic_data_offset())); 1405 __ ldr(R6, FieldAddress(R5, ICData::ic_data_offset()));
1404 // R6: ic_data_array with check entries: classes and target functions. 1406 // R6: ic_data_array with check entries: classes and target functions.
1405 __ AddImmediate(R6, R6, Array::data_offset() - kHeapObjectTag); 1407 __ AddImmediate(R6, R6, Array::data_offset() - kHeapObjectTag);
1406 // R6: points directly to the first ic data array element. 1408 // R6: points directly to the first ic data array element.
1407 1409
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
1529 __ LoadClassId(R0, R0); 1531 __ LoadClassId(R0, R0);
1530 __ SmiTag(R0); 1532 __ SmiTag(R0);
1531 __ bx(LR); 1533 __ bx(LR);
1532 } 1534 }
1533 1535
1534 1536
1535 // Use inline cache data array to invoke the target or continue in inline 1537 // Use inline cache data array to invoke the target or continue in inline
1536 // cache miss handler. Stub for 1-argument check (receiver class). 1538 // cache miss handler. Stub for 1-argument check (receiver class).
1537 // LR: return address. 1539 // LR: return address.
1538 // R5: inline cache data object. 1540 // R5: inline cache data object.
1539 // R4: arguments descriptor array.
1540 // Inline cache data object structure: 1541 // Inline cache data object structure:
1541 // 0: function-name 1542 // 0: function-name
1542 // 1: N, number of arguments checked. 1543 // 1: N, number of arguments checked.
1543 // 2 .. (length - 1): group of checks, each check containing: 1544 // 2 .. (length - 1): group of checks, each check containing:
1544 // - N classes. 1545 // - N classes.
1545 // - 1 target function. 1546 // - 1 target function.
1546 void StubCode::GenerateOneArgCheckInlineCacheStub(Assembler* assembler) { 1547 void StubCode::GenerateOneArgCheckInlineCacheStub(Assembler* assembler) {
1547 GenerateUsageCounterIncrement(assembler, R6); 1548 GenerateUsageCounterIncrement(assembler, R6);
1548 GenerateNArgsCheckInlineCacheStub(assembler, 1); 1549 GenerateNArgsCheckInlineCacheStub(assembler, 1);
1549 } 1550 }
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
1631 1632
1632 // Instead of returning to the patched Dart function, emulate the 1633 // Instead of returning to the patched Dart function, emulate the
1633 // smashed return code pattern and return to the function's caller. 1634 // smashed return code pattern and return to the function's caller.
1634 __ LeaveDartFrame(); 1635 __ LeaveDartFrame();
1635 __ Ret(); 1636 __ Ret();
1636 } 1637 }
1637 1638
1638 1639
1639 // LR: return address (Dart code). 1640 // LR: return address (Dart code).
1640 // R5: inline cache data array. 1641 // R5: inline cache data array.
1641 // R4: arguments descriptor array.
1642 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) { 1642 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) {
1643 // Create a stub frame as we are pushing some objects on the stack before 1643 // Create a stub frame as we are pushing some objects on the stack before
1644 // calling into the runtime. 1644 // calling into the runtime.
1645 __ EnterStubFrame(); 1645 __ EnterStubFrame();
1646 __ PushList((1 << R4) | (1 << R5)); 1646 __ Push(R5);
1647 __ CallRuntime(kBreakpointDynamicHandlerRuntimeEntry); 1647 __ CallRuntime(kBreakpointDynamicHandlerRuntimeEntry);
1648 __ PopList((1 << R4) | (1 << R5)); 1648 __ Pop(R5);
1649 __ LeaveStubFrame(); 1649 __ LeaveStubFrame();
1650 1650
1651 // Find out which dispatch stub to call. 1651 // Find out which dispatch stub to call.
1652 __ ldr(IP, FieldAddress(R5, ICData::num_args_tested_offset())); 1652 __ ldr(IP, FieldAddress(R5, ICData::num_args_tested_offset()));
1653 __ cmp(IP, ShifterOperand(1)); 1653 __ cmp(IP, ShifterOperand(1));
1654 __ Branch(&StubCode::OneArgCheckInlineCacheLabel(), EQ); 1654 __ Branch(&StubCode::OneArgCheckInlineCacheLabel(), EQ);
1655 __ cmp(IP, ShifterOperand(2)); 1655 __ cmp(IP, ShifterOperand(2));
1656 __ Branch(&StubCode::TwoArgsCheckInlineCacheLabel(), EQ); 1656 __ Branch(&StubCode::TwoArgsCheckInlineCacheLabel(), EQ);
1657 __ cmp(IP, ShifterOperand(3)); 1657 __ cmp(IP, ShifterOperand(3));
1658 __ Branch(&StubCode::ThreeArgsCheckInlineCacheLabel(), EQ); 1658 __ Branch(&StubCode::ThreeArgsCheckInlineCacheLabel(), EQ);
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after
1980 __ Bind(&reference_compare); 1980 __ Bind(&reference_compare);
1981 __ cmp(left, ShifterOperand(right)); 1981 __ cmp(left, ShifterOperand(right));
1982 __ Bind(&done); 1982 __ Bind(&done);
1983 __ PopList((1 << R0) | (1 << R1) | (1 << R2)); 1983 __ PopList((1 << R0) | (1 << R1) | (1 << R2));
1984 __ Ret(); 1984 __ Ret();
1985 } 1985 }
1986 1986
1987 } // namespace dart 1987 } // namespace dart
1988 1988
1989 #endif // defined TARGET_ARCH_ARM 1989 #endif // defined TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « runtime/vm/raw_object.h ('k') | runtime/vm/stub_code_ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698