| OLD | NEW |
| 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 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 106 } | 106 } |
| 107 END_LEAF_RUNTIME_ENTRY | 107 END_LEAF_RUNTIME_ENTRY |
| 108 | 108 |
| 109 | 109 |
| 110 // Input parameters: | 110 // Input parameters: |
| 111 // R0 : stop message (const char*). | 111 // R0 : stop message (const char*). |
| 112 // Must preserve all registers. | 112 // Must preserve all registers. |
| 113 void StubCode::GeneratePrintStopMessageStub(Assembler* assembler) { | 113 void StubCode::GeneratePrintStopMessageStub(Assembler* assembler) { |
| 114 __ EnterCallRuntimeFrame(0); | 114 __ EnterCallRuntimeFrame(0); |
| 115 // Call the runtime leaf function. R0 already contains the parameter. | 115 // Call the runtime leaf function. R0 already contains the parameter. |
| 116 __ CallRuntime(kPrintStopMessageRuntimeEntry); | 116 __ CallRuntime(kPrintStopMessageRuntimeEntry, 1); |
| 117 __ LeaveCallRuntimeFrame(); | 117 __ LeaveCallRuntimeFrame(); |
| 118 __ Ret(); | 118 __ Ret(); |
| 119 } | 119 } |
| 120 | 120 |
| 121 | 121 |
| 122 // Input parameters: | 122 // Input parameters: |
| 123 // LR : return address. | 123 // LR : return address. |
| 124 // SP : address of return value. | 124 // SP : address of return value. |
| 125 // R5 : address of the native function to call. | 125 // R5 : address of the native function to call. |
| 126 // R2 : address of first argument in argument array. | 126 // R2 : address of first argument in argument array. |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 284 | 284 |
| 285 // Input parameters: | 285 // Input parameters: |
| 286 // R4: arguments descriptor array. | 286 // R4: arguments descriptor array. |
| 287 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { | 287 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { |
| 288 // Create a stub frame as we are pushing some objects on the stack before | 288 // Create a stub frame as we are pushing some objects on the stack before |
| 289 // calling into the runtime. | 289 // calling into the runtime. |
| 290 __ EnterStubFrame(); | 290 __ EnterStubFrame(); |
| 291 // Setup space on stack for return value and preserve arguments descriptor. | 291 // Setup space on stack for return value and preserve arguments descriptor. |
| 292 __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null())); | 292 __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null())); |
| 293 __ PushList((1 << R0) | (1 << R4)); | 293 __ PushList((1 << R0) | (1 << R4)); |
| 294 __ CallRuntime(kPatchStaticCallRuntimeEntry); | 294 __ CallRuntime(kPatchStaticCallRuntimeEntry, 0); |
| 295 // Get Code object result and restore arguments descriptor array. | 295 // Get Code object result and restore arguments descriptor array. |
| 296 __ PopList((1 << R0) | (1 << R4)); | 296 __ PopList((1 << R0) | (1 << R4)); |
| 297 // Remove the stub frame. | 297 // Remove the stub frame. |
| 298 __ LeaveStubFrame(); | 298 __ LeaveStubFrame(); |
| 299 // Jump to the dart function. | 299 // Jump to the dart function. |
| 300 __ ldr(R0, FieldAddress(R0, Code::instructions_offset())); | 300 __ ldr(R0, FieldAddress(R0, Code::instructions_offset())); |
| 301 __ AddImmediate(R0, R0, Instructions::HeaderSize() - kHeapObjectTag); | 301 __ AddImmediate(R0, R0, Instructions::HeaderSize() - kHeapObjectTag); |
| 302 __ bx(R0); | 302 __ bx(R0); |
| 303 } | 303 } |
| 304 | 304 |
| 305 | 305 |
| 306 // Called from a static call only when an invalid code has been entered | 306 // Called from a static call only when an invalid code has been entered |
| 307 // (invalid because its function was optimized or deoptimized). | 307 // (invalid because its function was optimized or deoptimized). |
| 308 // R4: arguments descriptor array. | 308 // R4: arguments descriptor array. |
| 309 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) { | 309 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) { |
| 310 // Create a stub frame as we are pushing some objects on the stack before | 310 // Create a stub frame as we are pushing some objects on the stack before |
| 311 // calling into the runtime. | 311 // calling into the runtime. |
| 312 __ EnterStubFrame(); | 312 __ EnterStubFrame(); |
| 313 // Setup space on stack for return value and preserve arguments descriptor. | 313 // Setup space on stack for return value and preserve arguments descriptor. |
| 314 __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null())); | 314 __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null())); |
| 315 __ PushList((1 << R0) | (1 << R4)); | 315 __ PushList((1 << R0) | (1 << R4)); |
| 316 __ CallRuntime(kFixCallersTargetRuntimeEntry); | 316 __ CallRuntime(kFixCallersTargetRuntimeEntry, 0); |
| 317 // Get Code object result and restore arguments descriptor array. | 317 // Get Code object result and restore arguments descriptor array. |
| 318 __ PopList((1 << R0) | (1 << R4)); | 318 __ PopList((1 << R0) | (1 << R4)); |
| 319 // Remove the stub frame. | 319 // Remove the stub frame. |
| 320 __ LeaveStubFrame(); | 320 __ LeaveStubFrame(); |
| 321 // Jump to the dart function. | 321 // Jump to the dart function. |
| 322 __ ldr(R0, FieldAddress(R0, Code::instructions_offset())); | 322 __ ldr(R0, FieldAddress(R0, Code::instructions_offset())); |
| 323 __ AddImmediate(R0, R0, Instructions::HeaderSize() - kHeapObjectTag); | 323 __ AddImmediate(R0, R0, Instructions::HeaderSize() - kHeapObjectTag); |
| 324 __ bx(R0); | 324 __ bx(R0); |
| 325 } | 325 } |
| 326 | 326 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 370 // Push space for the return value. | 370 // Push space for the return value. |
| 371 // Push the receiver. | 371 // Push the receiver. |
| 372 // Push IC data object. | 372 // Push IC data object. |
| 373 // Push arguments descriptor array. | 373 // Push arguments descriptor array. |
| 374 __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null())); | 374 __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null())); |
| 375 __ PushList((1 << R4) | (1 << R5) | (1 << R6) | (1 << IP)); | 375 __ PushList((1 << R4) | (1 << R5) | (1 << R6) | (1 << IP)); |
| 376 | 376 |
| 377 // R2: Smi-tagged arguments array length. | 377 // R2: Smi-tagged arguments array length. |
| 378 PushArgumentsArray(assembler); | 378 PushArgumentsArray(assembler); |
| 379 | 379 |
| 380 __ CallRuntime(kInstanceFunctionLookupRuntimeEntry); | 380 __ CallRuntime(kInstanceFunctionLookupRuntimeEntry, 4); |
| 381 | 381 |
| 382 // Remove arguments. | 382 // Remove arguments. |
| 383 __ Drop(4); | 383 __ Drop(4); |
| 384 __ Pop(R0); // Get result into R0. | 384 __ Pop(R0); // Get result into R0. |
| 385 __ LeaveStubFrame(); | 385 __ LeaveStubFrame(); |
| 386 __ Ret(); | 386 __ Ret(); |
| 387 } | 387 } |
| 388 | 388 |
| 389 | 389 |
| 390 DECLARE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame, | 390 DECLARE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame, |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 440 ASSERT(kFpuRegisterSize == 4 * kWordSize); | 440 ASSERT(kFpuRegisterSize == 4 * kWordSize); |
| 441 if (kNumberOfDRegisters > 16) { | 441 if (kNumberOfDRegisters > 16) { |
| 442 __ vstmd(DB_W, SP, D16, kNumberOfDRegisters - 16); | 442 __ vstmd(DB_W, SP, D16, kNumberOfDRegisters - 16); |
| 443 __ vstmd(DB_W, SP, D0, 16); | 443 __ vstmd(DB_W, SP, D0, 16); |
| 444 } else { | 444 } else { |
| 445 __ vstmd(DB_W, SP, D0, kNumberOfDRegisters); | 445 __ vstmd(DB_W, SP, D0, kNumberOfDRegisters); |
| 446 } | 446 } |
| 447 | 447 |
| 448 __ mov(R0, ShifterOperand(SP)); // Pass address of saved registers block. | 448 __ mov(R0, ShifterOperand(SP)); // Pass address of saved registers block. |
| 449 __ ReserveAlignedFrameSpace(0); | 449 __ ReserveAlignedFrameSpace(0); |
| 450 __ CallRuntime(kDeoptimizeCopyFrameRuntimeEntry); | 450 __ CallRuntime(kDeoptimizeCopyFrameRuntimeEntry, 1); |
| 451 // Result (R0) is stack-size (FP - SP) in bytes. | 451 // Result (R0) is stack-size (FP - SP) in bytes. |
| 452 | 452 |
| 453 if (preserve_result) { | 453 if (preserve_result) { |
| 454 // Restore result into R1 temporarily. | 454 // Restore result into R1 temporarily. |
| 455 __ ldr(R1, Address(FP, saved_result_slot_from_fp * kWordSize)); | 455 __ ldr(R1, Address(FP, saved_result_slot_from_fp * kWordSize)); |
| 456 } | 456 } |
| 457 | 457 |
| 458 __ LeaveDartFrame(); | 458 __ LeaveDartFrame(); |
| 459 __ sub(SP, FP, ShifterOperand(R0)); | 459 __ sub(SP, FP, ShifterOperand(R0)); |
| 460 | 460 |
| 461 // DeoptimizeFillFrame expects a Dart frame, i.e. EnterDartFrame(0), but there | 461 // DeoptimizeFillFrame expects a Dart frame, i.e. EnterDartFrame(0), but there |
| 462 // is no need to set the correct PC marker or load PP, since they get patched. | 462 // is no need to set the correct PC marker or load PP, since they get patched. |
| 463 __ mov(IP, ShifterOperand(LR)); | 463 __ mov(IP, ShifterOperand(LR)); |
| 464 __ mov(LR, ShifterOperand(0)); | 464 __ mov(LR, ShifterOperand(0)); |
| 465 __ EnterFrame((1 << PP) | (1 << FP) | (1 << IP) | (1 << LR), 0); | 465 __ EnterFrame((1 << PP) | (1 << FP) | (1 << IP) | (1 << LR), 0); |
| 466 __ mov(R0, ShifterOperand(FP)); // Get last FP address. | 466 __ mov(R0, ShifterOperand(FP)); // Get last FP address. |
| 467 if (preserve_result) { | 467 if (preserve_result) { |
| 468 __ Push(R1); // Preserve result as first local. | 468 __ Push(R1); // Preserve result as first local. |
| 469 } | 469 } |
| 470 __ ReserveAlignedFrameSpace(0); | 470 __ ReserveAlignedFrameSpace(0); |
| 471 __ CallRuntime(kDeoptimizeFillFrameRuntimeEntry); // Pass last FP in R0. | 471 __ CallRuntime(kDeoptimizeFillFrameRuntimeEntry, 1); // Pass last FP in R0. |
| 472 if (preserve_result) { | 472 if (preserve_result) { |
| 473 // Restore result into R1. | 473 // Restore result into R1. |
| 474 __ ldr(R1, Address(FP, kFirstLocalSlotFromFp * kWordSize)); | 474 __ ldr(R1, Address(FP, kFirstLocalSlotFromFp * kWordSize)); |
| 475 } | 475 } |
| 476 // Code above cannot cause GC. | 476 // Code above cannot cause GC. |
| 477 __ LeaveDartFrame(); | 477 __ LeaveDartFrame(); |
| 478 | 478 |
| 479 // Frame is fully rewritten at this point and it is safe to perform a GC. | 479 // Frame is fully rewritten at this point and it is safe to perform a GC. |
| 480 // Materialize any objects that were deferred by FillFrame because they | 480 // Materialize any objects that were deferred by FillFrame because they |
| 481 // require allocation. | 481 // require allocation. |
| 482 __ EnterStubFrame(); | 482 __ EnterStubFrame(); |
| 483 if (preserve_result) { | 483 if (preserve_result) { |
| 484 __ Push(R1); // Preserve result, it will be GC-d here. | 484 __ Push(R1); // Preserve result, it will be GC-d here. |
| 485 } | 485 } |
| 486 __ PushObject(Smi::ZoneHandle()); // Space for the result. | 486 __ PushObject(Smi::ZoneHandle()); // Space for the result. |
| 487 __ CallRuntime(kDeoptimizeMaterializeRuntimeEntry); | 487 __ CallRuntime(kDeoptimizeMaterializeRuntimeEntry, 0); |
| 488 // Result tells stub how many bytes to remove from the expression stack | 488 // Result tells stub how many bytes to remove from the expression stack |
| 489 // of the bottom-most frame. They were used as materialization arguments. | 489 // of the bottom-most frame. They were used as materialization arguments. |
| 490 __ Pop(R1); | 490 __ Pop(R1); |
| 491 if (preserve_result) { | 491 if (preserve_result) { |
| 492 __ Pop(R0); // Restore result. | 492 __ Pop(R0); // Restore result. |
| 493 } | 493 } |
| 494 __ LeaveStubFrame(); | 494 __ LeaveStubFrame(); |
| 495 // Remove materialization arguments. | 495 // Remove materialization arguments. |
| 496 __ add(SP, SP, ShifterOperand(R1, ASR, kSmiTagSize)); | 496 __ add(SP, SP, ShifterOperand(R1, ASR, kSmiTagSize)); |
| 497 __ Ret(); | 497 __ Ret(); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 521 | 521 |
| 522 // Preserve IC data and arguments descriptor. | 522 // Preserve IC data and arguments descriptor. |
| 523 __ PushList((1 << R4) | (1 << R5)); | 523 __ PushList((1 << R4) | (1 << R5)); |
| 524 | 524 |
| 525 // Push space for the return value. | 525 // Push space for the return value. |
| 526 // Push the receiver. | 526 // Push the receiver. |
| 527 // Push IC data object. | 527 // Push IC data object. |
| 528 // Push arguments descriptor array. | 528 // Push arguments descriptor array. |
| 529 __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null())); | 529 __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null())); |
| 530 __ PushList((1 << R4) | (1 << R5) | (1 << R6) | (1 << IP)); | 530 __ PushList((1 << R4) | (1 << R5) | (1 << R6) | (1 << IP)); |
| 531 __ CallRuntime(kMegamorphicCacheMissHandlerRuntimeEntry); | 531 __ CallRuntime(kMegamorphicCacheMissHandlerRuntimeEntry, 3); |
| 532 // Remove arguments. | 532 // Remove arguments. |
| 533 __ Drop(3); | 533 __ Drop(3); |
| 534 __ Pop(R0); // Get result into R0. | 534 __ Pop(R0); // Get result into R0. |
| 535 | 535 |
| 536 // Restore IC data and arguments descriptor. | 536 // Restore IC data and arguments descriptor. |
| 537 __ PopList((1 << R4) | (1 << R5)); | 537 __ PopList((1 << R4) | (1 << R5)); |
| 538 | 538 |
| 539 __ LeaveStubFrame(); | 539 __ LeaveStubFrame(); |
| 540 | 540 |
| 541 __ CompareImmediate(R0, reinterpret_cast<intptr_t>(Object::null())); | 541 __ CompareImmediate(R0, reinterpret_cast<intptr_t>(Object::null())); |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 660 // Unable to allocate the array using the fast inline code, just call | 660 // Unable to allocate the array using the fast inline code, just call |
| 661 // into the runtime. | 661 // into the runtime. |
| 662 __ Bind(&slow_case); | 662 __ Bind(&slow_case); |
| 663 // Create a stub frame as we are pushing some objects on the stack before | 663 // Create a stub frame as we are pushing some objects on the stack before |
| 664 // calling into the runtime. | 664 // calling into the runtime. |
| 665 __ EnterStubFrame(); | 665 __ EnterStubFrame(); |
| 666 __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null())); | 666 __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null())); |
| 667 // Setup space on stack for return value. | 667 // Setup space on stack for return value. |
| 668 // Push array length as Smi and element type. | 668 // Push array length as Smi and element type. |
| 669 __ PushList((1 << R1) | (1 << R2) | (1 << IP)); | 669 __ PushList((1 << R1) | (1 << R2) | (1 << IP)); |
| 670 __ CallRuntime(kAllocateArrayRuntimeEntry); | 670 __ CallRuntime(kAllocateArrayRuntimeEntry, 2); |
| 671 // Pop arguments; result is popped in IP. | 671 // Pop arguments; result is popped in IP. |
| 672 __ PopList((1 << R1) | (1 << R2) | (1 << IP)); // R2 is restored. | 672 __ PopList((1 << R1) | (1 << R2) | (1 << IP)); // R2 is restored. |
| 673 __ mov(R0, ShifterOperand(IP)); | 673 __ mov(R0, ShifterOperand(IP)); |
| 674 __ LeaveStubFrame(); | 674 __ LeaveStubFrame(); |
| 675 __ Ret(); | 675 __ Ret(); |
| 676 } | 676 } |
| 677 | 677 |
| 678 | 678 |
| 679 // Input parameters: | 679 // Input parameters: |
| 680 // LR: return address. | 680 // LR: return address. |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 717 __ cmp(R0, ShifterOperand(R8)); // R8 is raw null. | 717 __ cmp(R0, ShifterOperand(R8)); // R8 is raw null. |
| 718 Label function_compiled; | 718 Label function_compiled; |
| 719 __ b(&function_compiled, NE); | 719 __ b(&function_compiled, NE); |
| 720 | 720 |
| 721 // Create a stub frame as we are pushing some objects on the stack before | 721 // Create a stub frame as we are pushing some objects on the stack before |
| 722 // calling into the runtime. | 722 // calling into the runtime. |
| 723 __ EnterStubFrame(); | 723 __ EnterStubFrame(); |
| 724 | 724 |
| 725 // Preserve arguments descriptor array and read-only function object argument. | 725 // Preserve arguments descriptor array and read-only function object argument. |
| 726 __ PushList((1 << R2) | (1 << R4)); | 726 __ PushList((1 << R2) | (1 << R4)); |
| 727 __ CallRuntime(kCompileFunctionRuntimeEntry); | 727 __ CallRuntime(kCompileFunctionRuntimeEntry, 1); |
| 728 // Restore arguments descriptor array and read-only function object argument. | 728 // Restore arguments descriptor array and read-only function object argument. |
| 729 __ PopList((1 << R2) | (1 << R4)); | 729 __ PopList((1 << R2) | (1 << R4)); |
| 730 // Restore R0. | 730 // Restore R0. |
| 731 __ ldr(R0, FieldAddress(R2, Function::code_offset())); | 731 __ ldr(R0, FieldAddress(R2, Function::code_offset())); |
| 732 | 732 |
| 733 // Remove the stub frame as we are about to jump to the closure function. | 733 // Remove the stub frame as we are about to jump to the closure function. |
| 734 __ LeaveStubFrame(); | 734 __ LeaveStubFrame(); |
| 735 | 735 |
| 736 __ Bind(&function_compiled); | 736 __ Bind(&function_compiled); |
| 737 // R0: code. | 737 // R0: code. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 752 // calling into the runtime. | 752 // calling into the runtime. |
| 753 __ EnterStubFrame(); | 753 __ EnterStubFrame(); |
| 754 | 754 |
| 755 // Setup space on stack for result from error reporting. | 755 // Setup space on stack for result from error reporting. |
| 756 __ PushList((1 << R4) | (1 << R8)); // Arguments descriptor and raw null. | 756 __ PushList((1 << R4) | (1 << R8)); // Arguments descriptor and raw null. |
| 757 | 757 |
| 758 // Load smi-tagged arguments array length, including the non-closure. | 758 // Load smi-tagged arguments array length, including the non-closure. |
| 759 __ ldr(R2, FieldAddress(R4, ArgumentsDescriptor::count_offset())); | 759 __ ldr(R2, FieldAddress(R4, ArgumentsDescriptor::count_offset())); |
| 760 PushArgumentsArray(assembler); | 760 PushArgumentsArray(assembler); |
| 761 | 761 |
| 762 __ CallRuntime(kInvokeNonClosureRuntimeEntry); | 762 __ CallRuntime(kInvokeNonClosureRuntimeEntry, 2); |
| 763 // Remove arguments. | 763 // Remove arguments. |
| 764 __ Drop(2); | 764 __ Drop(2); |
| 765 __ Pop(R0); // Get result into R0. | 765 __ Pop(R0); // Get result into R0. |
| 766 | 766 |
| 767 // Remove the stub frame as we are about to return. | 767 // Remove the stub frame as we are about to return. |
| 768 __ LeaveStubFrame(); | 768 __ LeaveStubFrame(); |
| 769 __ Ret(); | 769 __ Ret(); |
| 770 } | 770 } |
| 771 | 771 |
| 772 | 772 |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 975 | 975 |
| 976 __ Bind(&slow_case); | 976 __ Bind(&slow_case); |
| 977 } | 977 } |
| 978 // Create a stub frame as we are pushing some objects on the stack before | 978 // Create a stub frame as we are pushing some objects on the stack before |
| 979 // calling into the runtime. | 979 // calling into the runtime. |
| 980 __ EnterStubFrame(); | 980 __ EnterStubFrame(); |
| 981 // Setup space on stack for return value. | 981 // Setup space on stack for return value. |
| 982 __ LoadImmediate(R2, reinterpret_cast<intptr_t>(Object::null())); | 982 __ LoadImmediate(R2, reinterpret_cast<intptr_t>(Object::null())); |
| 983 __ SmiTag(R1); | 983 __ SmiTag(R1); |
| 984 __ PushList((1 << R1) | (1 << R2)); | 984 __ PushList((1 << R1) | (1 << R2)); |
| 985 __ CallRuntime(kAllocateContextRuntimeEntry); // Allocate context. | 985 __ CallRuntime(kAllocateContextRuntimeEntry, 1); // Allocate context. |
| 986 __ Drop(1); // Pop number of context variables argument. | 986 __ Drop(1); // Pop number of context variables argument. |
| 987 __ Pop(R0); // Pop the new context object. | 987 __ Pop(R0); // Pop the new context object. |
| 988 // R0: new object | 988 // R0: new object |
| 989 // Restore the frame pointer. | 989 // Restore the frame pointer. |
| 990 __ LeaveStubFrame(); | 990 __ LeaveStubFrame(); |
| 991 __ Ret(); | 991 __ Ret(); |
| 992 } | 992 } |
| 993 | 993 |
| 994 | 994 |
| 995 DECLARE_LEAF_RUNTIME_ENTRY(void, StoreBufferBlockProcess, Isolate* isolate); | 995 DECLARE_LEAF_RUNTIME_ENTRY(void, StoreBufferBlockProcess, Isolate* isolate); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1040 __ PopList((1 << R1) | (1 << R2) | (1 << R3)); | 1040 __ PopList((1 << R1) | (1 << R2) | (1 << R3)); |
| 1041 __ b(&L, EQ); | 1041 __ b(&L, EQ); |
| 1042 __ Ret(); | 1042 __ Ret(); |
| 1043 | 1043 |
| 1044 // Handle overflow: Call the runtime leaf function. | 1044 // Handle overflow: Call the runtime leaf function. |
| 1045 __ Bind(&L); | 1045 __ Bind(&L); |
| 1046 // Setup frame, push callee-saved registers. | 1046 // Setup frame, push callee-saved registers. |
| 1047 | 1047 |
| 1048 __ EnterCallRuntimeFrame(0 * kWordSize); | 1048 __ EnterCallRuntimeFrame(0 * kWordSize); |
| 1049 __ ldr(R0, FieldAddress(CTX, Context::isolate_offset())); | 1049 __ ldr(R0, FieldAddress(CTX, Context::isolate_offset())); |
| 1050 __ CallRuntime(kStoreBufferBlockProcessRuntimeEntry); | 1050 __ CallRuntime(kStoreBufferBlockProcessRuntimeEntry, 1); |
| 1051 // Restore callee-saved registers, tear down frame. | 1051 // Restore callee-saved registers, tear down frame. |
| 1052 __ LeaveCallRuntimeFrame(); | 1052 __ LeaveCallRuntimeFrame(); |
| 1053 __ Ret(); | 1053 __ Ret(); |
| 1054 } | 1054 } |
| 1055 | 1055 |
| 1056 | 1056 |
| 1057 // Called for inline allocation of objects. | 1057 // Called for inline allocation of objects. |
| 1058 // Input parameters: | 1058 // Input parameters: |
| 1059 // LR : return address. | 1059 // LR : return address. |
| 1060 // SP + 4 : type arguments object (only if class is parameterized). | 1060 // SP + 4 : type arguments object (only if class is parameterized). |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1205 __ Push(R2); // Setup space on stack for return value. | 1205 __ Push(R2); // Setup space on stack for return value. |
| 1206 __ PushObject(cls); // Push class of object to be allocated. | 1206 __ PushObject(cls); // Push class of object to be allocated. |
| 1207 if (is_cls_parameterized) { | 1207 if (is_cls_parameterized) { |
| 1208 // Push type arguments of object to be allocated and of instantiator. | 1208 // Push type arguments of object to be allocated and of instantiator. |
| 1209 __ PushList((1 << R0) | (1 << R1)); | 1209 __ PushList((1 << R0) | (1 << R1)); |
| 1210 } else { | 1210 } else { |
| 1211 // Push null type arguments and kNoInstantiator. | 1211 // Push null type arguments and kNoInstantiator. |
| 1212 __ LoadImmediate(R1, Smi::RawValue(StubCode::kNoInstantiator)); | 1212 __ LoadImmediate(R1, Smi::RawValue(StubCode::kNoInstantiator)); |
| 1213 __ PushList((1 << R1) | (1 << R2)); | 1213 __ PushList((1 << R1) | (1 << R2)); |
| 1214 } | 1214 } |
| 1215 __ CallRuntime(kAllocateObjectRuntimeEntry); // Allocate object. | 1215 __ CallRuntime(kAllocateObjectRuntimeEntry, 3); // Allocate object. |
| 1216 __ Drop(3); // Pop arguments. | 1216 __ Drop(3); // Pop arguments. |
| 1217 __ Pop(R0); // Pop result (newly allocated object). | 1217 __ Pop(R0); // Pop result (newly allocated object). |
| 1218 // R0: new object | 1218 // R0: new object |
| 1219 // Restore the frame pointer. | 1219 // Restore the frame pointer. |
| 1220 __ LeaveStubFrame(true); | 1220 __ LeaveStubFrame(true); |
| 1221 __ Ret(); | 1221 __ Ret(); |
| 1222 } | 1222 } |
| 1223 | 1223 |
| 1224 | 1224 |
| 1225 // Called for inline allocation of closures. | 1225 // Called for inline allocation of closures. |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1338 __ ldr(R1, Address(FP, kReceiverFPOffset)); | 1338 __ ldr(R1, Address(FP, kReceiverFPOffset)); |
| 1339 __ Push(R1); // Receiver. | 1339 __ Push(R1); // Receiver. |
| 1340 } | 1340 } |
| 1341 // R0: raw null. | 1341 // R0: raw null. |
| 1342 if (has_type_arguments) { | 1342 if (has_type_arguments) { |
| 1343 __ ldr(R0, Address(FP, kTypeArgumentsFPOffset)); | 1343 __ ldr(R0, Address(FP, kTypeArgumentsFPOffset)); |
| 1344 } | 1344 } |
| 1345 __ Push(R0); // Push type arguments of closure to be allocated or null. | 1345 __ Push(R0); // Push type arguments of closure to be allocated or null. |
| 1346 | 1346 |
| 1347 if (is_implicit_instance_closure) { | 1347 if (is_implicit_instance_closure) { |
| 1348 __ CallRuntime(kAllocateImplicitInstanceClosureRuntimeEntry); | 1348 __ CallRuntime(kAllocateImplicitInstanceClosureRuntimeEntry, 3); |
| 1349 __ Drop(2); // Pop arguments (type arguments of object and receiver). | 1349 __ Drop(2); // Pop arguments (type arguments of object and receiver). |
| 1350 } else { | 1350 } else { |
| 1351 ASSERT(func.IsNonImplicitClosureFunction()); | 1351 ASSERT(func.IsNonImplicitClosureFunction()); |
| 1352 __ CallRuntime(kAllocateClosureRuntimeEntry); | 1352 __ CallRuntime(kAllocateClosureRuntimeEntry, 2); |
| 1353 __ Drop(1); // Pop argument (type arguments of object). | 1353 __ Drop(1); // Pop argument (type arguments of object). |
| 1354 } | 1354 } |
| 1355 __ Drop(1); // Pop function object. | 1355 __ Drop(1); // Pop function object. |
| 1356 __ Pop(R0); | 1356 __ Pop(R0); |
| 1357 // R0: new object | 1357 // R0: new object |
| 1358 // Restore the frame pointer. | 1358 // Restore the frame pointer. |
| 1359 __ LeaveStubFrame(true); | 1359 __ LeaveStubFrame(true); |
| 1360 __ Ret(); | 1360 __ Ret(); |
| 1361 } | 1361 } |
| 1362 | 1362 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1380 // Push space for the return value. | 1380 // Push space for the return value. |
| 1381 // Push the receiver. | 1381 // Push the receiver. |
| 1382 // Push IC data object. | 1382 // Push IC data object. |
| 1383 // Push arguments descriptor array. | 1383 // Push arguments descriptor array. |
| 1384 __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null())); | 1384 __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null())); |
| 1385 __ PushList((1 << R4) | (1 << R5) | (1 << R6) | (1 << IP)); | 1385 __ PushList((1 << R4) | (1 << R5) | (1 << R6) | (1 << IP)); |
| 1386 | 1386 |
| 1387 // R2: Smi-tagged arguments array length. | 1387 // R2: Smi-tagged arguments array length. |
| 1388 PushArgumentsArray(assembler); | 1388 PushArgumentsArray(assembler); |
| 1389 | 1389 |
| 1390 __ CallRuntime(kInvokeNoSuchMethodFunctionRuntimeEntry); | 1390 __ CallRuntime(kInvokeNoSuchMethodFunctionRuntimeEntry, 4); |
| 1391 // Remove arguments. | 1391 // Remove arguments. |
| 1392 __ Drop(4); | 1392 __ Drop(4); |
| 1393 __ Pop(R0); // Get result into R0. | 1393 __ Pop(R0); // Get result into R0. |
| 1394 __ LeaveStubFrame(); | 1394 __ LeaveStubFrame(); |
| 1395 __ Ret(); | 1395 __ Ret(); |
| 1396 } | 1396 } |
| 1397 | 1397 |
| 1398 | 1398 |
| 1399 // R6: function object. | 1399 // R6: function object. |
| 1400 // R5: inline cache data object. | 1400 // R5: inline cache data object. |
| 1401 // Cannot use function object from ICData as it may be the inlined | 1401 // Cannot use function object from ICData as it may be the inlined |
| 1402 // function and not the top-scope function. | 1402 // function and not the top-scope function. |
| 1403 void StubCode::GenerateOptimizedUsageCounterIncrement(Assembler* assembler) { | 1403 void StubCode::GenerateOptimizedUsageCounterIncrement(Assembler* assembler) { |
| 1404 Register ic_reg = R5; | 1404 Register ic_reg = R5; |
| 1405 Register func_reg = R6; | 1405 Register func_reg = R6; |
| 1406 if (FLAG_trace_optimized_ic_calls) { | 1406 if (FLAG_trace_optimized_ic_calls) { |
| 1407 __ EnterStubFrame(); | 1407 __ EnterStubFrame(); |
| 1408 __ PushList((1 << R5) | (1 << R6)); // Preserve. | 1408 __ PushList((1 << R5) | (1 << R6)); // Preserve. |
| 1409 __ Push(ic_reg); // Argument. | 1409 __ Push(ic_reg); // Argument. |
| 1410 __ Push(func_reg); // Argument. | 1410 __ Push(func_reg); // Argument. |
| 1411 __ CallRuntime(kTraceICCallRuntimeEntry); | 1411 __ CallRuntime(kTraceICCallRuntimeEntry, 2); |
| 1412 __ Drop(2); // Discard argument; | 1412 __ Drop(2); // Discard argument; |
| 1413 __ PopList((1 << R5) | (1 << R6)); // Restore. | 1413 __ PopList((1 << R5) | (1 << R6)); // Restore. |
| 1414 __ LeaveStubFrame(); | 1414 __ LeaveStubFrame(); |
| 1415 } | 1415 } |
| 1416 __ ldr(R7, FieldAddress(func_reg, Function::usage_counter_offset())); | 1416 __ ldr(R7, FieldAddress(func_reg, Function::usage_counter_offset())); |
| 1417 __ add(R7, R7, ShifterOperand(1)); | 1417 __ add(R7, R7, ShifterOperand(1)); |
| 1418 __ str(R7, FieldAddress(func_reg, Function::usage_counter_offset())); | 1418 __ str(R7, FieldAddress(func_reg, Function::usage_counter_offset())); |
| 1419 } | 1419 } |
| 1420 | 1420 |
| 1421 | 1421 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1460 #endif // DEBUG | 1460 #endif // DEBUG |
| 1461 | 1461 |
| 1462 // Check single stepping. | 1462 // Check single stepping. |
| 1463 Label not_stepping; | 1463 Label not_stepping; |
| 1464 __ ldr(R6, FieldAddress(CTX, Context::isolate_offset())); | 1464 __ ldr(R6, FieldAddress(CTX, Context::isolate_offset())); |
| 1465 __ ldrb(R6, Address(R6, Isolate::single_step_offset())); | 1465 __ ldrb(R6, Address(R6, Isolate::single_step_offset())); |
| 1466 __ CompareImmediate(R6, 0); | 1466 __ CompareImmediate(R6, 0); |
| 1467 __ b(¬_stepping, EQ); | 1467 __ b(¬_stepping, EQ); |
| 1468 __ EnterStubFrame(); | 1468 __ EnterStubFrame(); |
| 1469 __ Push(R5); // Preserve IC data. | 1469 __ Push(R5); // Preserve IC data. |
| 1470 __ CallRuntime(kSingleStepHandlerRuntimeEntry); | 1470 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); |
| 1471 __ Pop(R5); | 1471 __ Pop(R5); |
| 1472 __ LeaveStubFrame(); | 1472 __ LeaveStubFrame(); |
| 1473 __ Bind(¬_stepping); | 1473 __ Bind(¬_stepping); |
| 1474 | 1474 |
| 1475 // Load arguments descriptor into R4. | 1475 // Load arguments descriptor into R4. |
| 1476 __ ldr(R4, FieldAddress(R5, ICData::arguments_descriptor_offset())); | 1476 __ ldr(R4, FieldAddress(R5, ICData::arguments_descriptor_offset())); |
| 1477 // Preserve return address, since LR is needed for subroutine call. | 1477 // Preserve return address, since LR is needed for subroutine call. |
| 1478 __ mov(R8, ShifterOperand(LR)); | 1478 __ mov(R8, ShifterOperand(LR)); |
| 1479 // Loop that checks if there is an IC data match. | 1479 // Loop that checks if there is an IC data match. |
| 1480 Label loop, update, test, found, get_class_id_as_smi; | 1480 Label loop, update, test, found, get_class_id_as_smi; |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1545 // Preserve IC data object and arguments descriptor array and | 1545 // Preserve IC data object and arguments descriptor array and |
| 1546 // setup space on stack for result (target code object). | 1546 // setup space on stack for result (target code object). |
| 1547 __ PushList((1 << R0) | (1 << R4) | (1 << R5)); | 1547 __ PushList((1 << R0) | (1 << R4) | (1 << R5)); |
| 1548 // Push call arguments. | 1548 // Push call arguments. |
| 1549 for (intptr_t i = 0; i < num_args; i++) { | 1549 for (intptr_t i = 0; i < num_args; i++) { |
| 1550 __ LoadFromOffset(kWord, IP, R7, -i * kWordSize); | 1550 __ LoadFromOffset(kWord, IP, R7, -i * kWordSize); |
| 1551 __ Push(IP); | 1551 __ Push(IP); |
| 1552 } | 1552 } |
| 1553 // Pass IC data object. | 1553 // Pass IC data object. |
| 1554 __ Push(R5); | 1554 __ Push(R5); |
| 1555 __ CallRuntime(handle_ic_miss); | 1555 __ CallRuntime(handle_ic_miss, num_args + 1); |
| 1556 // Remove the call arguments pushed earlier, including the IC data object. | 1556 // Remove the call arguments pushed earlier, including the IC data object. |
| 1557 __ Drop(num_args + 1); | 1557 __ Drop(num_args + 1); |
| 1558 // Pop returned code object into R0 (null if not found). | 1558 // Pop returned code object into R0 (null if not found). |
| 1559 // Restore arguments descriptor array and IC data array. | 1559 // Restore arguments descriptor array and IC data array. |
| 1560 __ PopList((1 << R0) | (1 << R4) | (1 << R5)); | 1560 __ PopList((1 << R0) | (1 << R4) | (1 << R5)); |
| 1561 __ LeaveStubFrame(); | 1561 __ LeaveStubFrame(); |
| 1562 Label call_target_function; | 1562 Label call_target_function; |
| 1563 __ CompareImmediate(R0, reinterpret_cast<intptr_t>(Object::null())); | 1563 __ CompareImmediate(R0, reinterpret_cast<intptr_t>(Object::null())); |
| 1564 __ b(&call_target_function, NE); | 1564 __ b(&call_target_function, NE); |
| 1565 // NoSuchMethod or closure. | 1565 // NoSuchMethod or closure. |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1686 #endif // DEBUG | 1686 #endif // DEBUG |
| 1687 | 1687 |
| 1688 // Check single stepping. | 1688 // Check single stepping. |
| 1689 Label not_stepping; | 1689 Label not_stepping; |
| 1690 __ ldr(R6, FieldAddress(CTX, Context::isolate_offset())); | 1690 __ ldr(R6, FieldAddress(CTX, Context::isolate_offset())); |
| 1691 __ ldrb(R6, Address(R6, Isolate::single_step_offset())); | 1691 __ ldrb(R6, Address(R6, Isolate::single_step_offset())); |
| 1692 __ CompareImmediate(R6, 0); | 1692 __ CompareImmediate(R6, 0); |
| 1693 __ b(¬_stepping, EQ); | 1693 __ b(¬_stepping, EQ); |
| 1694 __ EnterStubFrame(); | 1694 __ EnterStubFrame(); |
| 1695 __ Push(R5); // Preserve IC data. | 1695 __ Push(R5); // Preserve IC data. |
| 1696 __ CallRuntime(kSingleStepHandlerRuntimeEntry); | 1696 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); |
| 1697 __ Pop(R5); | 1697 __ Pop(R5); |
| 1698 __ LeaveStubFrame(); | 1698 __ LeaveStubFrame(); |
| 1699 __ Bind(¬_stepping); | 1699 __ Bind(¬_stepping); |
| 1700 | 1700 |
| 1701 // R5: IC data object (preserved). | 1701 // R5: IC data object (preserved). |
| 1702 __ ldr(R6, FieldAddress(R5, ICData::ic_data_offset())); | 1702 __ ldr(R6, FieldAddress(R5, ICData::ic_data_offset())); |
| 1703 // R6: ic_data_array with entries: target functions and count. | 1703 // R6: ic_data_array with entries: target functions and count. |
| 1704 __ AddImmediate(R6, R6, Array::data_offset() - kHeapObjectTag); | 1704 __ AddImmediate(R6, R6, Array::data_offset() - kHeapObjectTag); |
| 1705 // R6: points directly to the first ic data array element. | 1705 // R6: points directly to the first ic data array element. |
| 1706 const intptr_t target_offset = ICData::TargetIndexFor(0) * kWordSize; | 1706 const intptr_t target_offset = ICData::TargetIndexFor(0) * kWordSize; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1721 __ LoadFromOffset(kWord, R1, R6, target_offset); | 1721 __ LoadFromOffset(kWord, R1, R6, target_offset); |
| 1722 __ ldr(R0, FieldAddress(R1, Function::code_offset())); | 1722 __ ldr(R0, FieldAddress(R1, Function::code_offset())); |
| 1723 __ CompareImmediate(R0, reinterpret_cast<intptr_t>(Object::null())); | 1723 __ CompareImmediate(R0, reinterpret_cast<intptr_t>(Object::null())); |
| 1724 __ b(&target_is_compiled, NE); | 1724 __ b(&target_is_compiled, NE); |
| 1725 // R1: function. | 1725 // R1: function. |
| 1726 | 1726 |
| 1727 __ EnterStubFrame(); | 1727 __ EnterStubFrame(); |
| 1728 // Preserve target function and IC data object. | 1728 // Preserve target function and IC data object. |
| 1729 __ PushList((1 << R1) | (1 << R5)); | 1729 __ PushList((1 << R1) | (1 << R5)); |
| 1730 __ Push(R1); // Pass function. | 1730 __ Push(R1); // Pass function. |
| 1731 __ CallRuntime(kCompileFunctionRuntimeEntry); | 1731 __ CallRuntime(kCompileFunctionRuntimeEntry, 1); |
| 1732 __ Drop(1); // Discard argument. | 1732 __ Drop(1); // Discard argument. |
| 1733 __ PopList((1 << R1) | (1 << R5)); // Restore function and IC data. | 1733 __ PopList((1 << R1) | (1 << R5)); // Restore function and IC data. |
| 1734 __ LeaveStubFrame(); | 1734 __ LeaveStubFrame(); |
| 1735 // R0: target function. | 1735 // R0: target function. |
| 1736 __ ldr(R0, FieldAddress(R1, Function::code_offset())); | 1736 __ ldr(R0, FieldAddress(R1, Function::code_offset())); |
| 1737 | 1737 |
| 1738 __ Bind(&target_is_compiled); | 1738 __ Bind(&target_is_compiled); |
| 1739 // R0: target code. | 1739 // R0: target code. |
| 1740 __ ldr(R0, FieldAddress(R0, Code::instructions_offset())); | 1740 __ ldr(R0, FieldAddress(R0, Code::instructions_offset())); |
| 1741 __ AddImmediate(R0, Instructions::HeaderSize() - kHeapObjectTag); | 1741 __ AddImmediate(R0, Instructions::HeaderSize() - kHeapObjectTag); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1759 | 1759 |
| 1760 // LR: return address (Dart code). | 1760 // LR: return address (Dart code). |
| 1761 // R5: IC data (unoptimized static call). | 1761 // R5: IC data (unoptimized static call). |
| 1762 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) { | 1762 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) { |
| 1763 // Create a stub frame as we are pushing some objects on the stack before | 1763 // Create a stub frame as we are pushing some objects on the stack before |
| 1764 // calling into the runtime. | 1764 // calling into the runtime. |
| 1765 __ EnterStubFrame(); | 1765 __ EnterStubFrame(); |
| 1766 __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null())); | 1766 __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null())); |
| 1767 // Preserve arguments descriptor and make room for result. | 1767 // Preserve arguments descriptor and make room for result. |
| 1768 __ PushList((1 << R0) | (1 << R5)); | 1768 __ PushList((1 << R0) | (1 << R5)); |
| 1769 __ CallRuntime(kBreakpointStaticHandlerRuntimeEntry); | 1769 __ CallRuntime(kBreakpointStaticHandlerRuntimeEntry, 0); |
| 1770 // Pop code object result and restore arguments descriptor. | 1770 // Pop code object result and restore arguments descriptor. |
| 1771 __ PopList((1 << R0) | (1 << R5)); | 1771 __ PopList((1 << R0) | (1 << R5)); |
| 1772 __ LeaveStubFrame(); | 1772 __ LeaveStubFrame(); |
| 1773 | 1773 |
| 1774 // Now call the static function. The breakpoint handler function | 1774 // Now call the static function. The breakpoint handler function |
| 1775 // ensures that the call target is compiled. | 1775 // ensures that the call target is compiled. |
| 1776 __ ldr(R0, FieldAddress(R0, Code::instructions_offset())); | 1776 __ ldr(R0, FieldAddress(R0, Code::instructions_offset())); |
| 1777 __ AddImmediate(R0, Instructions::HeaderSize() - kHeapObjectTag); | 1777 __ AddImmediate(R0, Instructions::HeaderSize() - kHeapObjectTag); |
| 1778 // Load arguments descriptor into R4. | 1778 // Load arguments descriptor into R4. |
| 1779 __ ldr(R4, FieldAddress(R5, ICData::arguments_descriptor_offset())); | 1779 __ ldr(R4, FieldAddress(R5, ICData::arguments_descriptor_offset())); |
| 1780 __ bx(R0); | 1780 __ bx(R0); |
| 1781 } | 1781 } |
| 1782 | 1782 |
| 1783 | 1783 |
| 1784 // R0: return value. | 1784 // R0: return value. |
| 1785 void StubCode::GenerateBreakpointReturnStub(Assembler* assembler) { | 1785 void StubCode::GenerateBreakpointReturnStub(Assembler* assembler) { |
| 1786 // Create a stub frame as we are pushing some objects on the stack before | 1786 // Create a stub frame as we are pushing some objects on the stack before |
| 1787 // calling into the runtime. | 1787 // calling into the runtime. |
| 1788 __ EnterStubFrame(); | 1788 __ EnterStubFrame(); |
| 1789 __ Push(R0); | 1789 __ Push(R0); |
| 1790 __ CallRuntime(kBreakpointReturnHandlerRuntimeEntry); | 1790 __ CallRuntime(kBreakpointReturnHandlerRuntimeEntry, 0); |
| 1791 __ Pop(R0); | 1791 __ Pop(R0); |
| 1792 __ LeaveStubFrame(); | 1792 __ LeaveStubFrame(); |
| 1793 | 1793 |
| 1794 // Instead of returning to the patched Dart function, emulate the | 1794 // Instead of returning to the patched Dart function, emulate the |
| 1795 // smashed return code pattern and return to the function's caller. | 1795 // smashed return code pattern and return to the function's caller. |
| 1796 __ LeaveDartFrame(); | 1796 __ LeaveDartFrame(); |
| 1797 __ Ret(); | 1797 __ Ret(); |
| 1798 } | 1798 } |
| 1799 | 1799 |
| 1800 | 1800 |
| 1801 // LR: return address (Dart code). | 1801 // LR: return address (Dart code). |
| 1802 // R5: inline cache data array. | 1802 // R5: inline cache data array. |
| 1803 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) { | 1803 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) { |
| 1804 // Create a stub frame as we are pushing some objects on the stack before | 1804 // Create a stub frame as we are pushing some objects on the stack before |
| 1805 // calling into the runtime. | 1805 // calling into the runtime. |
| 1806 __ EnterStubFrame(); | 1806 __ EnterStubFrame(); |
| 1807 __ Push(R5); | 1807 __ Push(R5); |
| 1808 __ CallRuntime(kBreakpointDynamicHandlerRuntimeEntry); | 1808 __ CallRuntime(kBreakpointDynamicHandlerRuntimeEntry, 0); |
| 1809 __ Pop(R5); | 1809 __ Pop(R5); |
| 1810 __ LeaveStubFrame(); | 1810 __ LeaveStubFrame(); |
| 1811 | 1811 |
| 1812 // Find out which dispatch stub to call. | 1812 // Find out which dispatch stub to call. |
| 1813 __ ldr(IP, FieldAddress(R5, ICData::num_args_tested_offset())); | 1813 __ ldr(IP, FieldAddress(R5, ICData::num_args_tested_offset())); |
| 1814 __ cmp(IP, ShifterOperand(1)); | 1814 __ cmp(IP, ShifterOperand(1)); |
| 1815 __ Branch(&StubCode::OneArgCheckInlineCacheLabel(), EQ); | 1815 __ Branch(&StubCode::OneArgCheckInlineCacheLabel(), EQ); |
| 1816 __ cmp(IP, ShifterOperand(2)); | 1816 __ cmp(IP, ShifterOperand(2)); |
| 1817 __ Branch(&StubCode::TwoArgsCheckInlineCacheLabel(), EQ); | 1817 __ Branch(&StubCode::TwoArgsCheckInlineCacheLabel(), EQ); |
| 1818 __ cmp(IP, ShifterOperand(3)); | 1818 __ cmp(IP, ShifterOperand(3)); |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2025 __ bx(LR, EQ); | 2025 __ bx(LR, EQ); |
| 2026 __ LoadClassId(R2, R2); | 2026 __ LoadClassId(R2, R2); |
| 2027 __ SmiTag(R2); | 2027 __ SmiTag(R2); |
| 2028 __ bx(LR); | 2028 __ bx(LR); |
| 2029 | 2029 |
| 2030 __ Bind(&update_ic_data); | 2030 __ Bind(&update_ic_data); |
| 2031 // R5: ICData | 2031 // R5: ICData |
| 2032 __ PushList((1 << R0) | (1 << R1)); | 2032 __ PushList((1 << R0) | (1 << R1)); |
| 2033 __ PushObject(Symbols::EqualOperator()); // Target's name. | 2033 __ PushObject(Symbols::EqualOperator()); // Target's name. |
| 2034 __ Push(R5); // ICData | 2034 __ Push(R5); // ICData |
| 2035 __ CallRuntime(kUpdateICDataTwoArgsRuntimeEntry); // Clobbers R4, R5. | 2035 __ CallRuntime(kUpdateICDataTwoArgsRuntimeEntry, 4); // Clobbers R4, R5. |
| 2036 __ Drop(2); | 2036 __ Drop(2); |
| 2037 __ PopList((1 << R0) | (1 << R1)); | 2037 __ PopList((1 << R0) | (1 << R1)); |
| 2038 __ b(&compute_result); | 2038 __ b(&compute_result); |
| 2039 } | 2039 } |
| 2040 | 2040 |
| 2041 | 2041 |
| 2042 // Calls to the runtime to optimize the given function. | 2042 // Calls to the runtime to optimize the given function. |
| 2043 // R6: function to be reoptimized. | 2043 // R6: function to be reoptimized. |
| 2044 // R4: argument descriptor (preserved). | 2044 // R4: argument descriptor (preserved). |
| 2045 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) { | 2045 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) { |
| 2046 __ EnterStubFrame(); | 2046 __ EnterStubFrame(); |
| 2047 __ Push(R4); | 2047 __ Push(R4); |
| 2048 __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null())); | 2048 __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null())); |
| 2049 __ Push(IP); // Setup space on stack for return value. | 2049 __ Push(IP); // Setup space on stack for return value. |
| 2050 __ Push(R6); | 2050 __ Push(R6); |
| 2051 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry); | 2051 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1); |
| 2052 __ Pop(R0); // Discard argument. | 2052 __ Pop(R0); // Discard argument. |
| 2053 __ Pop(R0); // Get Code object | 2053 __ Pop(R0); // Get Code object |
| 2054 __ Pop(R4); // Restore argument descriptor. | 2054 __ Pop(R4); // Restore argument descriptor. |
| 2055 __ ldr(R0, FieldAddress(R0, Code::instructions_offset())); | 2055 __ ldr(R0, FieldAddress(R0, Code::instructions_offset())); |
| 2056 __ AddImmediate(R0, Instructions::HeaderSize() - kHeapObjectTag); | 2056 __ AddImmediate(R0, Instructions::HeaderSize() - kHeapObjectTag); |
| 2057 __ LeaveStubFrame(); | 2057 __ LeaveStubFrame(); |
| 2058 __ bx(R0); | 2058 __ bx(R0); |
| 2059 __ bkpt(0); | 2059 __ bkpt(0); |
| 2060 } | 2060 } |
| 2061 | 2061 |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2115 __ b(&done); | 2115 __ b(&done); |
| 2116 | 2116 |
| 2117 __ Bind(&check_bigint); | 2117 __ Bind(&check_bigint); |
| 2118 __ CompareClassId(left, kBigintCid, temp); | 2118 __ CompareClassId(left, kBigintCid, temp); |
| 2119 __ b(&reference_compare, NE); | 2119 __ b(&reference_compare, NE); |
| 2120 __ CompareClassId(right, kBigintCid, temp); | 2120 __ CompareClassId(right, kBigintCid, temp); |
| 2121 __ b(&done, NE); | 2121 __ b(&done, NE); |
| 2122 __ EnterStubFrame(0); | 2122 __ EnterStubFrame(0); |
| 2123 __ ReserveAlignedFrameSpace(2 * kWordSize); | 2123 __ ReserveAlignedFrameSpace(2 * kWordSize); |
| 2124 __ stm(IA, SP, (1 << R0) | (1 << R1)); | 2124 __ stm(IA, SP, (1 << R0) | (1 << R1)); |
| 2125 __ CallRuntime(kBigintCompareRuntimeEntry); | 2125 __ CallRuntime(kBigintCompareRuntimeEntry, 2); |
| 2126 // Result in R0, 0 means equal. | 2126 // Result in R0, 0 means equal. |
| 2127 __ LeaveStubFrame(); | 2127 __ LeaveStubFrame(); |
| 2128 __ cmp(R0, ShifterOperand(0)); | 2128 __ cmp(R0, ShifterOperand(0)); |
| 2129 __ b(&done); | 2129 __ b(&done); |
| 2130 | 2130 |
| 2131 __ Bind(&reference_compare); | 2131 __ Bind(&reference_compare); |
| 2132 __ cmp(left, ShifterOperand(right)); | 2132 __ cmp(left, ShifterOperand(right)); |
| 2133 __ Bind(&done); | 2133 __ Bind(&done); |
| 2134 } | 2134 } |
| 2135 | 2135 |
| 2136 | 2136 |
| 2137 // Called only from unoptimized code. All relevant registers have been saved. | 2137 // Called only from unoptimized code. All relevant registers have been saved. |
| 2138 // LR: return address. | 2138 // LR: return address. |
| 2139 // SP + 4: left operand. | 2139 // SP + 4: left operand. |
| 2140 // SP + 0: right operand. | 2140 // SP + 0: right operand. |
| 2141 // Return Zero condition flag set if equal. | 2141 // Return Zero condition flag set if equal. |
| 2142 void StubCode::GenerateUnoptimizedIdenticalWithNumberCheckStub( | 2142 void StubCode::GenerateUnoptimizedIdenticalWithNumberCheckStub( |
| 2143 Assembler* assembler) { | 2143 Assembler* assembler) { |
| 2144 // Check single stepping. | 2144 // Check single stepping. |
| 2145 Label not_stepping; | 2145 Label not_stepping; |
| 2146 __ ldr(R1, FieldAddress(CTX, Context::isolate_offset())); | 2146 __ ldr(R1, FieldAddress(CTX, Context::isolate_offset())); |
| 2147 __ ldrb(R1, Address(R1, Isolate::single_step_offset())); | 2147 __ ldrb(R1, Address(R1, Isolate::single_step_offset())); |
| 2148 __ CompareImmediate(R1, 0); | 2148 __ CompareImmediate(R1, 0); |
| 2149 __ b(¬_stepping, EQ); | 2149 __ b(¬_stepping, EQ); |
| 2150 __ EnterStubFrame(); | 2150 __ EnterStubFrame(); |
| 2151 __ CallRuntime(kSingleStepHandlerRuntimeEntry); | 2151 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); |
| 2152 __ LeaveStubFrame(); | 2152 __ LeaveStubFrame(); |
| 2153 __ Bind(¬_stepping); | 2153 __ Bind(¬_stepping); |
| 2154 | 2154 |
| 2155 const Register temp = R2; | 2155 const Register temp = R2; |
| 2156 const Register left = R1; | 2156 const Register left = R1; |
| 2157 const Register right = R0; | 2157 const Register right = R0; |
| 2158 __ ldr(left, Address(SP, 1 * kWordSize)); | 2158 __ ldr(left, Address(SP, 1 * kWordSize)); |
| 2159 __ ldr(right, Address(SP, 0 * kWordSize)); | 2159 __ ldr(right, Address(SP, 0 * kWordSize)); |
| 2160 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); | 2160 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); |
| 2161 __ Ret(); | 2161 __ Ret(); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 2178 __ ldr(left, Address(SP, 4 * kWordSize)); | 2178 __ ldr(left, Address(SP, 4 * kWordSize)); |
| 2179 __ ldr(right, Address(SP, 3 * kWordSize)); | 2179 __ ldr(right, Address(SP, 3 * kWordSize)); |
| 2180 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); | 2180 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); |
| 2181 __ PopList((1 << R0) | (1 << R1) | (1 << R2)); | 2181 __ PopList((1 << R0) | (1 << R1) | (1 << R2)); |
| 2182 __ Ret(); | 2182 __ Ret(); |
| 2183 } | 2183 } |
| 2184 | 2184 |
| 2185 } // namespace dart | 2185 } // namespace dart |
| 2186 | 2186 |
| 2187 #endif // defined TARGET_ARCH_ARM | 2187 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |