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

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

Issue 15697009: Enable code optimization on ARM. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 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
« no previous file with comments | « runtime/vm/intermediate_language_arm.cc ('k') | no next file » | 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 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
284 // Push space for the return value. 284 // Push space for the return value.
285 // Push the receiver. 285 // Push the receiver.
286 // Push IC data object. 286 // Push IC data object.
287 // Push arguments descriptor array. 287 // Push arguments descriptor array.
288 __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null())); 288 __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null()));
289 __ PushList((1 << R4) | (1 << R5) | (1 << R6) | (1 << IP)); 289 __ PushList((1 << R4) | (1 << R5) | (1 << R6) | (1 << IP));
290 290
291 // R2: Smi-tagged arguments array length. 291 // R2: Smi-tagged arguments array length.
292 PushArgumentsArray(assembler); 292 PushArgumentsArray(assembler);
293 293
294 // Stack:
295 // TOS + 0: argument array.
296 // TOS + 1: arguments descriptor array.
297 // TOS + 2: IC data object.
298 // TOS + 3: Receiver.
299 // TOS + 4: place for result from the call.
300 // TOS + 5: saved FP of previous frame.
301 // TOS + 6: dart code return address
302 // TOS + 7: pc marker (0 for stub).
303 // TOS + 8: last argument of caller.
304 // ....
305 __ CallRuntime(kInstanceFunctionLookupRuntimeEntry); 294 __ CallRuntime(kInstanceFunctionLookupRuntimeEntry);
295
306 // Remove arguments. 296 // Remove arguments.
307 __ Drop(4); 297 __ Drop(4);
308 __ Pop(R0); // Get result into R0. 298 __ Pop(R0); // Get result into R0.
309 __ LeaveStubFrame(); 299 __ LeaveStubFrame();
310 __ Ret(); 300 __ Ret();
311 } 301 }
312 302
313 303
314 DECLARE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame, 304 DECLARE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame,
315 intptr_t deopt_reason, 305 intptr_t deopt_reason,
(...skipping 23 matching lines...) Expand all
339 // +------------------+ 329 // +------------------+
340 // | PC marker | 330 // | PC marker |
341 // +------------------+ 331 // +------------------+
342 // | ... | <- SP of optimized frame 332 // | ... | <- SP of optimized frame
343 // 333 //
344 // Parts of the code cannot GC, part of the code can GC. 334 // Parts of the code cannot GC, part of the code can GC.
345 static void GenerateDeoptimizationSequence(Assembler* assembler, 335 static void GenerateDeoptimizationSequence(Assembler* assembler,
346 bool preserve_result) { 336 bool preserve_result) {
347 // DeoptimizeCopyFrame expects a Dart frame, i.e. EnterDartFrame(0), but there 337 // DeoptimizeCopyFrame expects a Dart frame, i.e. EnterDartFrame(0), but there
348 // is no need to set the correct PC marker or load PP, since they get patched. 338 // is no need to set the correct PC marker or load PP, since they get patched.
349 __ EnterFrame((1 << PP) | (1 << FP) | (1 << LR) | (1 << PC), 0); 339 __ mov(IP, ShifterOperand(LR));
340 __ mov(LR, ShifterOperand(0));
341 __ EnterFrame((1 << PP) | (1 << FP) | (1 << IP) | (1 << LR), 0);
350 // The code in this frame may not cause GC. kDeoptimizeCopyFrameRuntimeEntry 342 // The code in this frame may not cause GC. kDeoptimizeCopyFrameRuntimeEntry
351 // and kDeoptimizeFillFrameRuntimeEntry are leaf runtime calls. 343 // and kDeoptimizeFillFrameRuntimeEntry are leaf runtime calls.
352 const intptr_t saved_result_slot_from_fp = 344 const intptr_t saved_result_slot_from_fp =
353 kFirstLocalSlotFromFp + 1 - (kNumberOfCpuRegisters - R0); 345 kFirstLocalSlotFromFp + 1 - (kNumberOfCpuRegisters - R0);
354 // Result in R0 is preserved as part of pushing all registers below. 346 // Result in R0 is preserved as part of pushing all registers below.
355 347
356 // TODO(regis): Should we align the stack before pushing the fpu registers? 348 // TODO(regis): Should we align the stack before pushing the fpu registers?
357 // If we do, saved_r0_offset_from_fp is not constant anymore. 349 // If we do, saved_r0_offset_from_fp is not constant anymore.
358 350
359 // Push registers in their enumeration order: lowest register number at 351 // Push registers in their enumeration order: lowest register number at
(...skipping 10 matching lines...) Expand all
370 if (preserve_result) { 362 if (preserve_result) {
371 // Restore result into R1 temporarily. 363 // Restore result into R1 temporarily.
372 __ ldr(R1, Address(FP, saved_result_slot_from_fp * kWordSize)); 364 __ ldr(R1, Address(FP, saved_result_slot_from_fp * kWordSize));
373 } 365 }
374 366
375 __ LeaveDartFrame(); 367 __ LeaveDartFrame();
376 __ sub(SP, FP, ShifterOperand(R0)); 368 __ sub(SP, FP, ShifterOperand(R0));
377 369
378 // DeoptimizeFillFrame expects a Dart frame, i.e. EnterDartFrame(0), but there 370 // DeoptimizeFillFrame expects a Dart frame, i.e. EnterDartFrame(0), but there
379 // is no need to set the correct PC marker or load PP, since they get patched. 371 // is no need to set the correct PC marker or load PP, since they get patched.
380 __ EnterFrame((1 << PP) | (1 << FP) | (1 << LR) | (1 << PC), 0); 372 __ mov(IP, ShifterOperand(LR));
373 __ mov(LR, ShifterOperand(0));
374 __ EnterFrame((1 << PP) | (1 << FP) | (1 << IP) | (1 << LR), 0);
381 __ mov(R0, ShifterOperand(FP)); // Get last FP address. 375 __ mov(R0, ShifterOperand(FP)); // Get last FP address.
382 if (preserve_result) { 376 if (preserve_result) {
383 __ Push(R1); // Preserve result as first local. 377 __ Push(R1); // Preserve result as first local.
384 } 378 }
385 __ ReserveAlignedFrameSpace(0); 379 __ ReserveAlignedFrameSpace(0);
386 __ CallRuntime(kDeoptimizeFillFrameRuntimeEntry); // Pass last FP in R0. 380 __ CallRuntime(kDeoptimizeFillFrameRuntimeEntry); // Pass last FP in R0.
387 if (preserve_result) { 381 if (preserve_result) {
388 // Restore result into R1. 382 // Restore result into R1.
389 __ ldr(R1, Address(FP, kFirstLocalSlotFromFp * kWordSize)); 383 __ ldr(R1, Address(FP, kFirstLocalSlotFromFp * kWordSize));
390 } 384 }
(...skipping 29 matching lines...) Expand all
420 GenerateDeoptimizationSequence(assembler, true); // Preserve R0. 414 GenerateDeoptimizationSequence(assembler, true); // Preserve R0.
421 } 415 }
422 416
423 417
424 void StubCode::GenerateDeoptimizeStub(Assembler* assembler) { 418 void StubCode::GenerateDeoptimizeStub(Assembler* assembler) {
425 GenerateDeoptimizationSequence(assembler, false); // Don't preserve R0. 419 GenerateDeoptimizationSequence(assembler, false); // Don't preserve R0.
426 } 420 }
427 421
428 422
429 void StubCode::GenerateMegamorphicMissStub(Assembler* assembler) { 423 void StubCode::GenerateMegamorphicMissStub(Assembler* assembler) {
430 __ Unimplemented("MegamorphicMiss stub"); 424 __ EnterStubFrame();
425
426 // Load the receiver.
427 __ ldr(R2, FieldAddress(R4, ArgumentsDescriptor::count_offset()));
428 __ add(IP, FP, ShifterOperand(R2, LSL, 1)); // R2 is Smi.
429 __ ldr(R6, Address(IP, kParamEndSlotFromFp * kWordSize));
430
431 // Preserve IC data and arguments descriptor.
432 __ PushList((1 << R4) | (1 << R5));
433
434 // Push space for the return value.
435 // Push the receiver.
436 // Push IC data object.
437 // Push arguments descriptor array.
438 __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null()));
439 __ PushList((1 << R4) | (1 << R5) | (1 << R6) | (1 << IP));
440
441 // R2: Smi-tagged arguments array length.
442 PushArgumentsArray(assembler);
443
444 __ CallRuntime(kMegamorphicCacheMissHandlerRuntimeEntry);
445 // Remove arguments.
446 __ Drop(4);
447 __ Pop(R0); // Get result into R0.
448
449 // Restore IC data and arguments descriptor.
450 __ PopList((1 << R4) | (1 << R5));
451
452 __ LeaveStubFrame();
453
454 __ CompareImmediate(R0, reinterpret_cast<intptr_t>(Object::null()));
455 __ Branch(&StubCode::InstanceFunctionLookupLabel(), EQ);
456 __ AddImmediate(R0, Instructions::HeaderSize() - kHeapObjectTag);
457 __ bx(R0);
431 } 458 }
432 459
433 460
434 // Called for inline allocation of arrays. 461 // Called for inline allocation of arrays.
435 // Input parameters: 462 // Input parameters:
436 // LR: return address. 463 // LR: return address.
437 // R2: array length as Smi. 464 // R2: array length as Smi.
438 // R1: array element type (either NULL or an instantiated type). 465 // R1: array element type (either NULL or an instantiated type).
439 // NOTE: R2 cannot be clobbered here as the caller relies on it being saved. 466 // NOTE: R2 cannot be clobbered here as the caller relies on it being saved.
440 // The newly allocated object is returned in R0. 467 // The newly allocated object is returned in R0.
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
638 // calling into the runtime. 665 // calling into the runtime.
639 __ EnterStubFrame(); 666 __ EnterStubFrame();
640 667
641 // Setup space on stack for result from error reporting. 668 // Setup space on stack for result from error reporting.
642 __ PushList((1 << R4) | (1 << R8)); // Arguments descriptor and raw null. 669 __ PushList((1 << R4) | (1 << R8)); // Arguments descriptor and raw null.
643 670
644 // Load smi-tagged arguments array length, including the non-closure. 671 // Load smi-tagged arguments array length, including the non-closure.
645 __ ldr(R2, FieldAddress(R4, ArgumentsDescriptor::count_offset())); 672 __ ldr(R2, FieldAddress(R4, ArgumentsDescriptor::count_offset()));
646 PushArgumentsArray(assembler); 673 PushArgumentsArray(assembler);
647 674
648 // Stack:
649 // TOS + 0: argument array.
650 // TOS + 1: arguments descriptor array.
651 // TOS + 2: place for result from the call.
652 // TOS + 3: saved FP of previous frame.
653 // TOS + 4: dart code return address
654 // TOS + 5: pc marker (0 for stub).
655 // TOS + 6: last argument of caller.
656 // ....
657 __ CallRuntime(kInvokeNonClosureRuntimeEntry); 675 __ CallRuntime(kInvokeNonClosureRuntimeEntry);
658 // Remove arguments. 676 // Remove arguments.
659 __ Drop(2); 677 __ Drop(2);
660 __ Pop(R0); // Get result into R0. 678 __ Pop(R0); // Get result into R0.
661 679
662 // Remove the stub frame as we are about to return. 680 // Remove the stub frame as we are about to return.
663 __ LeaveStubFrame(); 681 __ LeaveStubFrame();
664 __ Ret(); 682 __ Ret();
665 } 683 }
666 684
(...skipping 593 matching lines...) Expand 10 before | Expand all | Expand 10 after
1260 } 1278 }
1261 __ Drop(1); // Pop function object. 1279 __ Drop(1); // Pop function object.
1262 __ Pop(R0); 1280 __ Pop(R0);
1263 // R0: new object 1281 // R0: new object
1264 // Restore the frame pointer. 1282 // Restore the frame pointer.
1265 __ LeaveStubFrame(true); 1283 __ LeaveStubFrame(true);
1266 __ Ret(); 1284 __ Ret();
1267 } 1285 }
1268 1286
1269 1287
1288 // The target function was not found, so invoke method
1289 // "dynamic noSuchMethod(Invocation invocation)".
1290 // R5: inline cache data object.
1291 // R4: arguments descriptor array.
1270 void StubCode::GenerateCallNoSuchMethodFunctionStub(Assembler* assembler) { 1292 void StubCode::GenerateCallNoSuchMethodFunctionStub(Assembler* assembler) {
1271 __ Unimplemented("CallNoSuchMethodFunction stub"); 1293 __ EnterStubFrame();
1294
1295 // Load the receiver.
1296 __ ldr(R2, FieldAddress(R4, ArgumentsDescriptor::count_offset()));
1297 __ add(IP, FP, ShifterOperand(R2, LSL, 1)); // R2 is Smi.
1298 __ ldr(R6, Address(IP, kParamEndSlotFromFp * kWordSize));
1299
1300 // Push space for the return value.
1301 // Push the receiver.
1302 // Push IC data object.
1303 // Push arguments descriptor array.
1304 __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null()));
1305 __ PushList((1 << R4) | (1 << R5) | (1 << R6) | (1 << IP));
1306
1307 // R2: Smi-tagged arguments array length.
1308 PushArgumentsArray(assembler);
1309
1310 __ CallRuntime(kInvokeNoSuchMethodFunctionRuntimeEntry);
1311 // Remove arguments.
1312 __ Drop(4);
1313 __ Pop(R0); // Get result into R0.
1314 __ LeaveStubFrame();
1315 __ Ret();
1272 } 1316 }
1273 1317
1274 1318
1275 // R6: function object. 1319 // R6: function object.
1276 // R5: inline cache data object. 1320 // R5: inline cache data object.
1277 // R4: arguments descriptor array. 1321 // R4: arguments descriptor array.
1278 void StubCode::GenerateOptimizedUsageCounterIncrement(Assembler* assembler) { 1322 void StubCode::GenerateOptimizedUsageCounterIncrement(Assembler* assembler) {
1279 Register ic_reg = R5; 1323 Register ic_reg = R5;
1280 Register func_reg = R6; 1324 Register func_reg = R6;
1281 if (FLAG_trace_optimized_ic_calls) { 1325 if (FLAG_trace_optimized_ic_calls) {
(...skipping 665 matching lines...) Expand 10 before | Expand all | Expand 10 after
1947 __ Bind(&reference_compare); 1991 __ Bind(&reference_compare);
1948 __ cmp(left, ShifterOperand(right)); 1992 __ cmp(left, ShifterOperand(right));
1949 __ Bind(&done); 1993 __ Bind(&done);
1950 __ PopList((1 << R0) | (1 << R1) | (1 << R2)); 1994 __ PopList((1 << R0) | (1 << R1) | (1 << R2));
1951 __ Ret(); 1995 __ Ret();
1952 } 1996 }
1953 1997
1954 } // namespace dart 1998 } // namespace dart
1955 1999
1956 #endif // defined TARGET_ARCH_ARM 2000 #endif // defined TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_arm.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698