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

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

Issue 63093003: Fix for issue 14790 - Crash when using dartium devtools (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 1 month 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/stack_frame_x64.h ('k') | runtime/vm/stub_code_x64_test.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_X64) 6 #if defined(TARGET_ARCH_X64)
7 7
8 #include "vm/assembler.h" 8 #include "vm/assembler.h"
9 #include "vm/compiler.h" 9 #include "vm/compiler.h"
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 // R10: arguments descriptor array. 253 // R10: arguments descriptor array.
254 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { 254 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) {
255 __ EnterStubFrame(); 255 __ EnterStubFrame();
256 __ pushq(R10); // Preserve arguments descriptor array. 256 __ pushq(R10); // Preserve arguments descriptor array.
257 // Setup space on stack for return value. 257 // Setup space on stack for return value.
258 __ PushObject(Object::null_object(), PP); 258 __ PushObject(Object::null_object(), PP);
259 __ CallRuntime(kPatchStaticCallRuntimeEntry, 0); 259 __ CallRuntime(kPatchStaticCallRuntimeEntry, 0);
260 __ popq(RAX); // Get Code object result. 260 __ popq(RAX); // Get Code object result.
261 __ popq(R10); // Restore arguments descriptor array. 261 __ popq(R10); // Restore arguments descriptor array.
262 // Remove the stub frame as we are about to jump to the dart function. 262 // Remove the stub frame as we are about to jump to the dart function.
263 __ LeaveFrame(); 263 __ LeaveStubFrame();
264 264
265 __ movq(RBX, FieldAddress(RAX, Code::instructions_offset())); 265 __ movq(RBX, FieldAddress(RAX, Code::instructions_offset()));
266 __ addq(RBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); 266 __ addq(RBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
267 __ jmp(RBX); 267 __ jmp(RBX);
268 } 268 }
269 269
270 270
271 // Called from a static call only when an invalid code has been entered 271 // Called from a static call only when an invalid code has been entered
272 // (invalid because its function was optimized or deoptimized). 272 // (invalid because its function was optimized or deoptimized).
273 // R10: arguments descriptor array. 273 // R10: arguments descriptor array.
274 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) { 274 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) {
275 __ EnterStubFrame(); 275 __ EnterStubFrame();
276 __ pushq(R10); // Preserve arguments descriptor array. 276 __ pushq(R10); // Preserve arguments descriptor array.
277 // Setup space on stack for return value. 277 // Setup space on stack for return value.
278 __ PushObject(Object::null_object(), PP); 278 __ PushObject(Object::null_object(), PP);
279 __ CallRuntime(kFixCallersTargetRuntimeEntry, 0); 279 __ CallRuntime(kFixCallersTargetRuntimeEntry, 0);
280 __ popq(RAX); // Get Code object. 280 __ popq(RAX); // Get Code object.
281 __ popq(R10); // Restore arguments descriptor array. 281 __ popq(R10); // Restore arguments descriptor array.
282 __ movq(RAX, FieldAddress(RAX, Code::instructions_offset())); 282 __ movq(RAX, FieldAddress(RAX, Code::instructions_offset()));
283 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); 283 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
284 __ LeaveFrame(); 284 __ LeaveStubFrame();
285 __ jmp(RAX); 285 __ jmp(RAX);
286 __ int3(); 286 __ int3();
287 } 287 }
288 288
289 289
290 // Input parameters: 290 // Input parameters:
291 // R10: smi-tagged argument count, may be zero. 291 // R10: smi-tagged argument count, may be zero.
292 // RBP[kParamEndSlotFromFp + 1]: last argument. 292 // RBP[kParamEndSlotFromFp + 1]: last argument.
293 static void PushArgumentsArray(Assembler* assembler) { 293 static void PushArgumentsArray(Assembler* assembler) {
294 __ LoadObject(R12, Object::null_object(), PP); 294 __ LoadObject(R12, Object::null_object(), PP);
(...skipping 21 matching lines...) Expand all
316 } 316 }
317 317
318 318
319 // Input parameters: 319 // Input parameters:
320 // RBX: ic-data. 320 // RBX: ic-data.
321 // R10: arguments descriptor array. 321 // R10: arguments descriptor array.
322 // Note: The receiver object is the first argument to the function being 322 // Note: The receiver object is the first argument to the function being
323 // called, the stub accesses the receiver from this location directly 323 // called, the stub accesses the receiver from this location directly
324 // when trying to resolve the call. 324 // when trying to resolve the call.
325 void StubCode::GenerateInstanceFunctionLookupStub(Assembler* assembler) { 325 void StubCode::GenerateInstanceFunctionLookupStub(Assembler* assembler) {
326 __ EnterStubFrameWithPP(); 326 __ EnterStubFrame();
327 __ PushObject(Object::null_object(), PP); // Space for the return value. 327 __ PushObject(Object::null_object(), PP); // Space for the return value.
328 328
329 // Push the receiver as an argument. Load the smi-tagged argument 329 // Push the receiver as an argument. Load the smi-tagged argument
330 // count into R13 to index the receiver in the stack. There are 330 // count into R13 to index the receiver in the stack. There are
331 // four words (null, stub's pc marker, saved pp, saved fp) above the return 331 // four words (null, stub's pc marker, saved pp, saved fp) above the return
332 // address. 332 // address.
333 __ movq(R13, FieldAddress(R10, ArgumentsDescriptor::count_offset())); 333 __ movq(R13, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
334 __ pushq(Address(RSP, R13, TIMES_4, (4 * kWordSize))); 334 __ pushq(Address(RSP, R13, TIMES_4, (4 * kWordSize)));
335 335
336 __ pushq(RBX); // Pass IC data object. 336 __ pushq(RBX); // Pass IC data object.
337 __ pushq(R10); // Pass arguments descriptor array. 337 __ pushq(R10); // Pass arguments descriptor array.
338 338
339 // Pass the call's arguments array. 339 // Pass the call's arguments array.
340 __ movq(R10, R13); // Smi-tagged arguments array length. 340 __ movq(R10, R13); // Smi-tagged arguments array length.
341 PushArgumentsArray(assembler); 341 PushArgumentsArray(assembler);
342 342
343 __ CallRuntime(kInstanceFunctionLookupRuntimeEntry, 4); 343 __ CallRuntime(kInstanceFunctionLookupRuntimeEntry, 4);
344 344
345 // Remove arguments. 345 // Remove arguments.
346 __ Drop(4); 346 __ Drop(4);
347 __ popq(RAX); // Get result into RAX. 347 __ popq(RAX); // Get result into RAX.
348 __ LeaveFrameWithPP(); 348 __ LeaveStubFrame();
349 __ ret(); 349 __ ret();
350 } 350 }
351 351
352 352
353 DECLARE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame, 353 DECLARE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame,
354 intptr_t deopt_reason, 354 intptr_t deopt_reason,
355 uword saved_registers_address); 355 uword saved_registers_address);
356 356
357 DECLARE_LEAF_RUNTIME_ENTRY(void, DeoptimizeFillFrame, uword last_fp); 357 DECLARE_LEAF_RUNTIME_ENTRY(void, DeoptimizeFillFrame, uword last_fp);
358 358
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
411 __ movq(RDI, RSP); // Pass address of saved registers block. 411 __ movq(RDI, RSP); // Pass address of saved registers block.
412 __ ReserveAlignedFrameSpace(0); 412 __ ReserveAlignedFrameSpace(0);
413 __ CallRuntime(kDeoptimizeCopyFrameRuntimeEntry, 1); 413 __ CallRuntime(kDeoptimizeCopyFrameRuntimeEntry, 1);
414 // Result (RAX) is stack-size (FP - SP) in bytes. 414 // Result (RAX) is stack-size (FP - SP) in bytes.
415 415
416 if (preserve_result) { 416 if (preserve_result) {
417 // Restore result into RBX temporarily. 417 // Restore result into RBX temporarily.
418 __ movq(RBX, Address(RBP, saved_result_slot_from_fp * kWordSize)); 418 __ movq(RBX, Address(RBP, saved_result_slot_from_fp * kWordSize));
419 } 419 }
420 420
421 // There is a Dart Frame on the stack. We just need the PP. 421 // There is a Dart Frame on the stack. We must restore PP and leave frame.
422 __ movq(PP, Address(RBP, -2 * kWordSize)); 422 __ LeaveDartFrame();
423 __ LeaveFrame();
424 423
425 __ popq(RCX); // Preserve return address. 424 __ popq(RCX); // Preserve return address.
426 __ movq(RSP, RBP); // Discard optimized frame. 425 __ movq(RSP, RBP); // Discard optimized frame.
427 __ subq(RSP, RAX); // Reserve space for deoptimized frame. 426 __ subq(RSP, RAX); // Reserve space for deoptimized frame.
428 __ pushq(RCX); // Restore return address. 427 __ pushq(RCX); // Restore return address.
429 428
430 // DeoptimizeFillFrame expects a Dart frame, i.e. EnterDartFrame(0), but there 429 // DeoptimizeFillFrame expects a Dart frame, i.e. EnterDartFrame(0), but there
431 // is no need to set the correct PC marker or load PP, since they get patched. 430 // is no need to set the correct PC marker or load PP, since they get patched.
432 __ EnterFrame(0); 431 __ EnterFrame(0);
433 __ pushq(Immediate(0)); 432 __ pushq(Immediate(0));
434 __ pushq(PP); 433 __ pushq(PP);
435 434
436 if (preserve_result) { 435 if (preserve_result) {
437 __ pushq(RBX); // Preserve result as first local. 436 __ pushq(RBX); // Preserve result as first local.
438 } 437 }
439 __ ReserveAlignedFrameSpace(0); 438 __ ReserveAlignedFrameSpace(0);
440 __ movq(RDI, RBP); // Pass last FP as parameter in RDI. 439 __ movq(RDI, RBP); // Pass last FP as parameter in RDI.
441 __ CallRuntime(kDeoptimizeFillFrameRuntimeEntry, 1); 440 __ CallRuntime(kDeoptimizeFillFrameRuntimeEntry, 1);
442 if (preserve_result) { 441 if (preserve_result) {
443 // Restore result into RBX. 442 // Restore result into RBX.
444 __ movq(RBX, Address(RBP, kFirstLocalSlotFromFp * kWordSize)); 443 __ movq(RBX, Address(RBP, kFirstLocalSlotFromFp * kWordSize));
445 } 444 }
446 // Code above cannot cause GC. 445 // Code above cannot cause GC.
447 // There is a Dart Frame on the stack. We just need the PP. 446 // There is a Dart Frame on the stack. We must restore PP and leave frame.
448 __ movq(PP, Address(RBP, -2 * kWordSize)); 447 __ LeaveDartFrame();
449 __ LeaveFrame();
450 448
451 // Frame is fully rewritten at this point and it is safe to perform a GC. 449 // Frame is fully rewritten at this point and it is safe to perform a GC.
452 // Materialize any objects that were deferred by FillFrame because they 450 // Materialize any objects that were deferred by FillFrame because they
453 // require allocation. 451 // require allocation.
454 __ EnterStubFrame(); 452 __ EnterStubFrame();
455 if (preserve_result) { 453 if (preserve_result) {
456 __ pushq(Immediate(0)); // Workaround for dropped stack slot during GC. 454 __ pushq(Immediate(0)); // Workaround for dropped stack slot during GC.
457 __ pushq(RBX); // Preserve result, it will be GC-d here. 455 __ pushq(RBX); // Preserve result, it will be GC-d here.
458 } 456 }
459 __ pushq(Immediate(Smi::RawValue(0))); // Space for the result. 457 __ pushq(Immediate(Smi::RawValue(0))); // Space for the result.
460 __ CallRuntime(kDeoptimizeMaterializeRuntimeEntry, 0); 458 __ CallRuntime(kDeoptimizeMaterializeRuntimeEntry, 0);
461 // Result tells stub how many bytes to remove from the expression stack 459 // Result tells stub how many bytes to remove from the expression stack
462 // of the bottom-most frame. They were used as materialization arguments. 460 // of the bottom-most frame. They were used as materialization arguments.
463 __ popq(RBX); 461 __ popq(RBX);
464 __ SmiUntag(RBX); 462 __ SmiUntag(RBX);
465 if (preserve_result) { 463 if (preserve_result) {
466 __ popq(RAX); // Restore result. 464 __ popq(RAX); // Restore result.
467 __ Drop(1); // Workaround for dropped stack slot during GC. 465 __ Drop(1); // Workaround for dropped stack slot during GC.
468 } 466 }
469 __ LeaveFrame(); 467 __ LeaveStubFrame();
470 468
471 __ popq(RCX); // Pop return address. 469 __ popq(RCX); // Pop return address.
472 __ addq(RSP, RBX); // Remove materialization arguments. 470 __ addq(RSP, RBX); // Remove materialization arguments.
473 __ pushq(RCX); // Push return address. 471 __ pushq(RCX); // Push return address.
474 __ ret(); 472 __ ret();
475 } 473 }
476 474
477 475
478 // TOS: return address + call-instruction-size (5 bytes). 476 // TOS: return address + call-instruction-size (5 bytes).
479 // RAX: result, must be preserved 477 // RAX: result, must be preserved
480 void StubCode::GenerateDeoptimizeLazyStub(Assembler* assembler) { 478 void StubCode::GenerateDeoptimizeLazyStub(Assembler* assembler) {
481 // Correct return address to point just after the call that is being 479 // Correct return address to point just after the call that is being
482 // deoptimized. 480 // deoptimized.
483 __ popq(RBX); 481 __ popq(RBX);
484 __ subq(RBX, Immediate(ShortCallPattern::InstructionLength())); 482 __ subq(RBX, Immediate(ShortCallPattern::InstructionLength()));
485 __ pushq(RBX); 483 __ pushq(RBX);
486 GenerateDeoptimizationSequence(assembler, true); // Preserve RAX. 484 GenerateDeoptimizationSequence(assembler, true); // Preserve RAX.
487 } 485 }
488 486
489 487
490 void StubCode::GenerateDeoptimizeStub(Assembler* assembler) { 488 void StubCode::GenerateDeoptimizeStub(Assembler* assembler) {
491 GenerateDeoptimizationSequence(assembler, false); // Don't preserve RAX. 489 GenerateDeoptimizationSequence(assembler, false); // Don't preserve RAX.
492 } 490 }
493 491
494 492
495 void StubCode::GenerateMegamorphicMissStub(Assembler* assembler) { 493 void StubCode::GenerateMegamorphicMissStub(Assembler* assembler) {
496 __ EnterStubFrameWithPP(); 494 __ EnterStubFrame();
497 // Load the receiver into RAX. The argument count in the arguments 495 // Load the receiver into RAX. The argument count in the arguments
498 // descriptor in R10 is a smi. 496 // descriptor in R10 is a smi.
499 __ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset())); 497 __ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
500 // Three words (saved pp, saved fp, stub's pc marker) 498 // Three words (saved pp, saved fp, stub's pc marker)
501 // in the stack above the return address. 499 // in the stack above the return address.
502 __ movq(RAX, Address(RSP, RAX, TIMES_4, 500 __ movq(RAX, Address(RSP, RAX, TIMES_4,
503 kSavedAboveReturnAddress * kWordSize)); 501 kSavedAboveReturnAddress * kWordSize));
504 // Preserve IC data and arguments descriptor. 502 // Preserve IC data and arguments descriptor.
505 __ pushq(RBX); 503 __ pushq(RBX);
506 __ pushq(R10); 504 __ pushq(R10);
507 505
508 // Space for the result of the runtime call. 506 // Space for the result of the runtime call.
509 __ PushObject(Object::null_object(), PP); 507 __ PushObject(Object::null_object(), PP);
510 __ pushq(RAX); // Receiver. 508 __ pushq(RAX); // Receiver.
511 __ pushq(RBX); // IC data. 509 __ pushq(RBX); // IC data.
512 __ pushq(R10); // Arguments descriptor. 510 __ pushq(R10); // Arguments descriptor.
513 __ CallRuntime(kMegamorphicCacheMissHandlerRuntimeEntry, 3); 511 __ CallRuntime(kMegamorphicCacheMissHandlerRuntimeEntry, 3);
514 // Discard arguments. 512 // Discard arguments.
515 __ popq(RAX); 513 __ popq(RAX);
516 __ popq(RAX); 514 __ popq(RAX);
517 __ popq(RAX); 515 __ popq(RAX);
518 __ popq(RAX); // Return value from the runtime call (instructions). 516 __ popq(RAX); // Return value from the runtime call (instructions).
519 __ popq(R10); // Restore arguments descriptor. 517 __ popq(R10); // Restore arguments descriptor.
520 __ popq(RBX); // Restore IC data. 518 __ popq(RBX); // Restore IC data.
521 __ LeaveFrameWithPP(); 519 __ LeaveStubFrame();
522 520
523 Label lookup; 521 Label lookup;
524 __ CompareObject(RAX, Object::null_object(), PP); 522 __ CompareObject(RAX, Object::null_object(), PP);
525 __ j(EQUAL, &lookup, Assembler::kNearJump); 523 __ j(EQUAL, &lookup, Assembler::kNearJump);
526 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); 524 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
527 __ jmp(RAX); 525 __ jmp(RAX);
528 526
529 __ Bind(&lookup); 527 __ Bind(&lookup);
530 __ jmp(&StubCode::InstanceFunctionLookupLabel()); 528 __ jmp(&StubCode::InstanceFunctionLookupLabel());
531 } 529 }
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
652 // calling into the runtime. 650 // calling into the runtime.
653 __ EnterStubFrame(); 651 __ EnterStubFrame();
654 // Setup space on stack for return value. 652 // Setup space on stack for return value.
655 __ PushObject(Object::null_object(), PP); 653 __ PushObject(Object::null_object(), PP);
656 __ pushq(R10); // Array length as Smi. 654 __ pushq(R10); // Array length as Smi.
657 __ pushq(RBX); // Element type. 655 __ pushq(RBX); // Element type.
658 __ CallRuntime(kAllocateArrayRuntimeEntry, 2); 656 __ CallRuntime(kAllocateArrayRuntimeEntry, 2);
659 __ popq(RAX); // Pop element type argument. 657 __ popq(RAX); // Pop element type argument.
660 __ popq(R10); // Pop array length argument. 658 __ popq(R10); // Pop array length argument.
661 __ popq(RAX); // Pop return value from return slot. 659 __ popq(RAX); // Pop return value from return slot.
662 __ LeaveFrame(); 660 __ LeaveStubFrame();
663 __ ret(); 661 __ ret();
664 } 662 }
665 663
666 664
667 // Input parameters: 665 // Input parameters:
668 // R10: Arguments descriptor array. 666 // R10: Arguments descriptor array.
669 // Note: The closure object is the first argument to the function being 667 // Note: The closure object is the first argument to the function being
670 // called, the stub accesses the closure from this location directly 668 // called, the stub accesses the closure from this location directly
671 // when trying to resolve the call. 669 // when trying to resolve the call.
672 void StubCode::GenerateCallClosureFunctionStub(Assembler* assembler) { 670 void StubCode::GenerateCallClosureFunctionStub(Assembler* assembler) {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
710 708
711 __ pushq(R10); // Preserve arguments descriptor array. 709 __ pushq(R10); // Preserve arguments descriptor array.
712 __ pushq(RBX); // Preserve read-only function object argument. 710 __ pushq(RBX); // Preserve read-only function object argument.
713 __ CallRuntime(kCompileFunctionRuntimeEntry, 1); 711 __ CallRuntime(kCompileFunctionRuntimeEntry, 1);
714 __ popq(RBX); // Restore read-only function object argument in RBX. 712 __ popq(RBX); // Restore read-only function object argument in RBX.
715 __ popq(R10); // Restore arguments descriptor array. 713 __ popq(R10); // Restore arguments descriptor array.
716 // Restore RAX. 714 // Restore RAX.
717 __ movq(RAX, FieldAddress(RBX, Function::code_offset())); 715 __ movq(RAX, FieldAddress(RBX, Function::code_offset()));
718 716
719 // Remove the stub frame as we are about to jump to the closure function. 717 // Remove the stub frame as we are about to jump to the closure function.
720 __ LeaveFrame(); 718 __ LeaveStubFrame();
721 719
722 __ Bind(&function_compiled); 720 __ Bind(&function_compiled);
723 // RAX: Code. 721 // RAX: Code.
724 // RBX: Function. 722 // RBX: Function.
725 // R10: Arguments descriptor array. 723 // R10: Arguments descriptor array.
726 724
727 __ movq(RBX, FieldAddress(RAX, Code::instructions_offset())); 725 __ movq(RBX, FieldAddress(RAX, Code::instructions_offset()));
728 __ addq(RBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); 726 __ addq(RBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
729 __ jmp(RBX); 727 __ jmp(RBX);
730 728
(...skipping 15 matching lines...) Expand all
746 __ movq(R10, FieldAddress(R10, ArgumentsDescriptor::count_offset())); 744 __ movq(R10, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
747 PushArgumentsArray(assembler); 745 PushArgumentsArray(assembler);
748 746
749 __ CallRuntime(kInvokeNonClosureRuntimeEntry, 2); 747 __ CallRuntime(kInvokeNonClosureRuntimeEntry, 2);
750 748
751 // Remove arguments. 749 // Remove arguments.
752 __ Drop(2); 750 __ Drop(2);
753 __ popq(RAX); // Get result into RAX. 751 __ popq(RAX); // Get result into RAX.
754 752
755 // Remove the stub frame as we are about to return. 753 // Remove the stub frame as we are about to return.
756 __ LeaveFrame(); 754 __ LeaveStubFrame();
757 __ ret(); 755 __ ret();
758 } 756 }
759 757
760 758
761 // Called when invoking Dart code from C++ (VM code). 759 // Called when invoking Dart code from C++ (VM code).
762 // Input parameters: 760 // Input parameters:
763 // RSP : points to return address. 761 // RSP : points to return address.
764 // RDI : entrypoint of the Dart function to call. 762 // RDI : entrypoint of the Dart function to call.
765 // RSI : arguments descriptor array. 763 // RSI : arguments descriptor array.
766 // RDX : arguments array. 764 // RDX : arguments array.
767 // RCX : new context containing the current isolate pointer. 765 // RCX : new context containing the current isolate pointer.
768 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) { 766 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) {
769 // Save frame pointer coming in. 767 // Save frame pointer coming in.
770 __ EnterStubFrameWithPP(); 768 __ EnterFrame(0);
771 769
772 // At this point, the stack looks like: 770 // At this point, the stack looks like:
773 // | saved RC15/PP | <-- RSP / TOS
774 // | "saved PC area" = 0 |
775 // | saved RBP | <-- RBP 771 // | saved RBP | <-- RBP
776 // | saved PC (return to DartEntry::InvokeFunction) | 772 // | saved PC (return to DartEntry::InvokeFunction) |
777 773
778 // The old frame pointer, the return address, the old R15 (for PP). 774 const intptr_t kInitialOffset = 1;
779 const intptr_t kInitialOffset = 3;
780 // Save arguments descriptor array and new context. 775 // Save arguments descriptor array and new context.
781 const intptr_t kArgumentsDescOffset = -(kInitialOffset) * kWordSize; 776 const intptr_t kArgumentsDescOffset = -(kInitialOffset) * kWordSize;
782 __ pushq(RSI); 777 __ pushq(RSI);
783 const intptr_t kNewContextOffset = -(kInitialOffset + 1) * kWordSize; 778 const intptr_t kNewContextOffset = -(kInitialOffset + 1) * kWordSize;
784 __ pushq(RCX); 779 __ pushq(RCX);
785 780
786 // Save C++ ABI callee-saved registers. 781 // Save C++ ABI callee-saved registers.
787 __ pushq(RBX); 782 __ pushq(RBX);
788 __ pushq(R12); 783 __ pushq(R12);
789 __ pushq(R13); 784 __ pushq(R13);
790 __ pushq(R14); 785 __ pushq(R14);
791 // R15 is already saved above by EnterStubFrameWithPP. 786 __ pushq(R15);
787
788 // We now load the pool pointer(PP) as we are about to invoke dart code and we
789 // could potentially invoke some intrinsic functions which need the PP to be
790 // set up.
791 __ LoadPoolPointer(PP);
792 792
793 // If any additional (or fewer) values are pushed, the offsets in 793 // If any additional (or fewer) values are pushed, the offsets in
794 // kExitLinkSlotFromEntryFp and kSavedContextSlotFromEntryFp will need to be 794 // kExitLinkSlotFromEntryFp and kSavedContextSlotFromEntryFp will need to be
795 // changed. 795 // changed.
796 796
797 // The new Context structure contains a pointer to the current Isolate 797 // The new Context structure contains a pointer to the current Isolate
798 // structure. Cache the Context pointer in the CTX register so that it is 798 // structure. Cache the Context pointer in the CTX register so that it is
799 // available in generated code and calls to Isolate::Current() need not be 799 // available in generated code and calls to Isolate::Current() need not be
800 // done. The assumption is that this register will never be clobbered by 800 // done. The assumption is that this register will never be clobbered by
801 // compiled or runtime stub code. 801 // compiled or runtime stub code.
802 802
803 // Cache the new Context pointer into CTX while executing Dart code. 803 // Cache the new Context pointer into CTX while executing Dart code.
804 __ movq(CTX, Address(RCX, VMHandles::kOffsetOfRawPtrInHandle)); 804 __ movq(CTX, Address(RCX, VMHandles::kOffsetOfRawPtrInHandle));
805 805
806 // Load Isolate pointer from Context structure into R8. 806 // Load Isolate pointer from Context structure into R8.
807 __ movq(R8, FieldAddress(CTX, Context::isolate_offset())); 807 __ movq(R8, FieldAddress(CTX, Context::isolate_offset()));
808 808
809 // Save the top exit frame info. Use RAX as a temporary register. 809 // Save the top exit frame info. Use RAX as a temporary register.
810 // StackFrameIterator reads the top exit frame info saved in this frame. 810 // StackFrameIterator reads the top exit frame info saved in this frame.
811 // The constant kExitLinkSlotFromEntryFp must be kept in sync with the 811 // The constant kExitLinkSlotFromEntryFp must be kept in sync with the
812 // code below. 812 // code below.
813 ASSERT(kExitLinkSlotFromEntryFp == -9); 813 ASSERT(kExitLinkSlotFromEntryFp == -8);
814 __ movq(RAX, Address(R8, Isolate::top_exit_frame_info_offset())); 814 __ movq(RAX, Address(R8, Isolate::top_exit_frame_info_offset()));
815 __ pushq(RAX); 815 __ pushq(RAX);
816 __ movq(Address(R8, Isolate::top_exit_frame_info_offset()), Immediate(0)); 816 __ movq(Address(R8, Isolate::top_exit_frame_info_offset()), Immediate(0));
817 817
818 // Save the old Context pointer. Use RAX as a temporary register. 818 // Save the old Context pointer. Use RAX as a temporary register.
819 // Note that VisitObjectPointers will find this saved Context pointer during 819 // Note that VisitObjectPointers will find this saved Context pointer during
820 // GC marking, since it traverses any information between SP and 820 // GC marking, since it traverses any information between SP and
821 // FP - kExitLinkSlotFromEntryFp * kWordSize. 821 // FP - kExitLinkSlotFromEntryFp * kWordSize.
822 // EntryFrame::SavedContext reads the context saved in this frame. 822 // EntryFrame::SavedContext reads the context saved in this frame.
823 // The constant kSavedContextSlotFromEntryFp must be kept in sync with 823 // The constant kSavedContextSlotFromEntryFp must be kept in sync with
824 // the code below. 824 // the code below.
825 ASSERT(kSavedContextSlotFromEntryFp == -10); 825 ASSERT(kSavedContextSlotFromEntryFp == -9);
826 __ movq(RAX, Address(R8, Isolate::top_context_offset())); 826 __ movq(RAX, Address(R8, Isolate::top_context_offset()));
827 __ pushq(RAX); 827 __ pushq(RAX);
828 828
829 // Load arguments descriptor array into R10, which is passed to Dart code. 829 // Load arguments descriptor array into R10, which is passed to Dart code.
830 __ movq(R10, Address(RSI, VMHandles::kOffsetOfRawPtrInHandle)); 830 __ movq(R10, Address(RSI, VMHandles::kOffsetOfRawPtrInHandle));
831 831
832 // Load number of arguments into RBX. 832 // Load number of arguments into RBX.
833 __ movq(RBX, FieldAddress(R10, ArgumentsDescriptor::count_offset())); 833 __ movq(RBX, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
834 __ SmiUntag(RBX); 834 __ SmiUntag(RBX);
835 835
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
873 // Uses RCX as a temporary register for this. 873 // Uses RCX as a temporary register for this.
874 __ popq(RCX); 874 __ popq(RCX);
875 __ movq(Address(CTX, Isolate::top_context_offset()), RCX); 875 __ movq(Address(CTX, Isolate::top_context_offset()), RCX);
876 876
877 // Restore the saved top exit frame info back into the Isolate structure. 877 // Restore the saved top exit frame info back into the Isolate structure.
878 // Uses RDX as a temporary register for this. 878 // Uses RDX as a temporary register for this.
879 __ popq(RDX); 879 __ popq(RDX);
880 __ movq(Address(CTX, Isolate::top_exit_frame_info_offset()), RDX); 880 __ movq(Address(CTX, Isolate::top_exit_frame_info_offset()), RDX);
881 881
882 // Restore C++ ABI callee-saved registers. 882 // Restore C++ ABI callee-saved registers.
883 // R15 will be restored below by LeaveFrameWithPP. 883 __ popq(R15);
884 __ popq(R14); 884 __ popq(R14);
885 __ popq(R13); 885 __ popq(R13);
886 __ popq(R12); 886 __ popq(R12);
887 __ popq(RBX); 887 __ popq(RBX);
888 888
889 // Restore the frame pointer. 889 // Restore the frame pointer.
890 __ LeaveFrameWithPP(); 890 __ LeaveFrame();
891 891
892 __ ret(); 892 __ ret();
893 } 893 }
894 894
895 895
896 // Called for inline allocation of contexts. 896 // Called for inline allocation of contexts.
897 // Input: 897 // Input:
898 // R10: number of context variables. 898 // R10: number of context variables.
899 // Output: 899 // Output:
900 // RAX: new allocated RawContext object. 900 // RAX: new allocated RawContext object.
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
1004 // Create a stub frame. 1004 // Create a stub frame.
1005 __ EnterStubFrame(); 1005 __ EnterStubFrame();
1006 __ pushq(R12); // Setup space on stack for the return value. 1006 __ pushq(R12); // Setup space on stack for the return value.
1007 __ SmiTag(R10); 1007 __ SmiTag(R10);
1008 __ pushq(R10); // Push number of context variables. 1008 __ pushq(R10); // Push number of context variables.
1009 __ CallRuntime(kAllocateContextRuntimeEntry, 1); // Allocate context. 1009 __ CallRuntime(kAllocateContextRuntimeEntry, 1); // Allocate context.
1010 __ popq(RAX); // Pop number of context variables argument. 1010 __ popq(RAX); // Pop number of context variables argument.
1011 __ popq(RAX); // Pop the new context object. 1011 __ popq(RAX); // Pop the new context object.
1012 // RAX: new object 1012 // RAX: new object
1013 // Restore the frame pointer. 1013 // Restore the frame pointer.
1014 __ LeaveFrame(); 1014 __ LeaveStubFrame();
1015 __ ret(); 1015 __ ret();
1016 } 1016 }
1017 1017
1018 1018
1019 DECLARE_LEAF_RUNTIME_ENTRY(void, StoreBufferBlockProcess, Isolate* isolate); 1019 DECLARE_LEAF_RUNTIME_ENTRY(void, StoreBufferBlockProcess, Isolate* isolate);
1020 1020
1021 // Helper stub to implement Assembler::StoreIntoObject. 1021 // Helper stub to implement Assembler::StoreIntoObject.
1022 // Input parameters: 1022 // Input parameters:
1023 // RAX: Address being stored 1023 // RAX: Address being stored
1024 void StubCode::GenerateUpdateStoreBufferStub(Assembler* assembler) { 1024 void StubCode::GenerateUpdateStoreBufferStub(Assembler* assembler) {
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
1221 __ addq(RAX, Immediate(kHeapObjectTag)); 1221 __ addq(RAX, Immediate(kHeapObjectTag));
1222 __ ret(); 1222 __ ret();
1223 1223
1224 __ Bind(&slow_case); 1224 __ Bind(&slow_case);
1225 } 1225 }
1226 if (is_cls_parameterized) { 1226 if (is_cls_parameterized) {
1227 __ movq(RAX, Address(RSP, kObjectTypeArgumentsOffset)); 1227 __ movq(RAX, Address(RSP, kObjectTypeArgumentsOffset));
1228 __ movq(RDX, Address(RSP, kInstantiatorTypeArgumentsOffset)); 1228 __ movq(RDX, Address(RSP, kInstantiatorTypeArgumentsOffset));
1229 } 1229 }
1230 // Create a stub frame. 1230 // Create a stub frame.
1231 __ EnterStubFrameWithPP(); 1231 __ EnterStubFrame(true); // Uses PP to access class object.
1232 __ pushq(R12); // Setup space on stack for return value. 1232 __ pushq(R12); // Setup space on stack for return value.
1233 __ PushObject(cls, PP); // Push class of object to be allocated. 1233 __ PushObject(cls, PP); // Push class of object to be allocated.
1234 if (is_cls_parameterized) { 1234 if (is_cls_parameterized) {
1235 __ pushq(RAX); // Push type arguments of object to be allocated. 1235 __ pushq(RAX); // Push type arguments of object to be allocated.
1236 __ pushq(RDX); // Push type arguments of instantiator. 1236 __ pushq(RDX); // Push type arguments of instantiator.
1237 } else { 1237 } else {
1238 __ pushq(R12); // Push null type arguments. 1238 __ pushq(R12); // Push null type arguments.
1239 __ pushq(Immediate(Smi::RawValue(StubCode::kNoInstantiator))); 1239 __ pushq(Immediate(Smi::RawValue(StubCode::kNoInstantiator)));
1240 } 1240 }
1241 __ CallRuntime(kAllocateObjectRuntimeEntry, 3); // Allocate object. 1241 __ CallRuntime(kAllocateObjectRuntimeEntry, 3); // Allocate object.
1242 __ popq(RAX); // Pop argument (instantiator). 1242 __ popq(RAX); // Pop argument (instantiator).
1243 __ popq(RAX); // Pop argument (type arguments of object). 1243 __ popq(RAX); // Pop argument (type arguments of object).
1244 __ popq(RAX); // Pop argument (class of object). 1244 __ popq(RAX); // Pop argument (class of object).
1245 __ popq(RAX); // Pop result (newly allocated object). 1245 __ popq(RAX); // Pop result (newly allocated object).
1246 // RAX: new object 1246 // RAX: new object
1247 // Restore the frame pointer. 1247 // Restore the frame pointer.
1248 __ LeaveFrameWithPP(); 1248 __ LeaveStubFrame();
1249 __ ret(); 1249 __ ret();
1250 } 1250 }
1251 1251
1252 1252
1253 // Called for inline allocation of closures. 1253 // Called for inline allocation of closures.
1254 // Input parameters: 1254 // Input parameters:
1255 // RSP + 16 : receiver (null if not an implicit instance closure). 1255 // RSP + 16 : receiver (null if not an implicit instance closure).
1256 // RSP + 8 : type arguments object (null if class is not parameterized). 1256 // RSP + 8 : type arguments object (null if class is not parameterized).
1257 // RSP : points to return address. 1257 // RSP : points to return address.
1258 void StubCode::GenerateAllocationStubForClosure(Assembler* assembler, 1258 void StubCode::GenerateAllocationStubForClosure(Assembler* assembler,
1259 const Function& func) { 1259 const Function& func) {
1260 ASSERT(func.IsClosureFunction()); 1260 ASSERT(func.IsClosureFunction());
1261 ASSERT(!func.IsImplicitStaticClosureFunction()); 1261 ASSERT(!func.IsImplicitStaticClosureFunction());
1262 const bool is_implicit_instance_closure = 1262 const bool is_implicit_instance_closure =
1263 func.IsImplicitInstanceClosureFunction(); 1263 func.IsImplicitInstanceClosureFunction();
1264 const Class& cls = Class::ZoneHandle(func.signature_class()); 1264 const Class& cls = Class::ZoneHandle(func.signature_class());
1265 const bool has_type_arguments = cls.NumTypeArguments() > 0; 1265 const bool has_type_arguments = cls.NumTypeArguments() > 0;
1266 1266
1267 __ EnterStubFrameWithPP(); // Uses pool pointer to refer to function. 1267 __ EnterStubFrame(true); // Uses pool pointer to refer to function.
1268 __ LoadObject(R12, Object::null_object(), PP); 1268 __ LoadObject(R12, Object::null_object(), PP);
1269 const intptr_t kTypeArgumentsOffset = 4 * kWordSize; 1269 const intptr_t kTypeArgumentsOffset = 4 * kWordSize;
1270 const intptr_t kReceiverOffset = 5 * kWordSize; 1270 const intptr_t kReceiverOffset = 5 * kWordSize;
1271 const intptr_t closure_size = Closure::InstanceSize(); 1271 const intptr_t closure_size = Closure::InstanceSize();
1272 const intptr_t context_size = Context::InstanceSize(1); // Captured receiver. 1272 const intptr_t context_size = Context::InstanceSize(1); // Captured receiver.
1273 if (FLAG_inline_alloc && 1273 if (FLAG_inline_alloc &&
1274 Heap::IsAllocatableInNewSpace(closure_size + context_size)) { 1274 Heap::IsAllocatableInNewSpace(closure_size + context_size)) {
1275 Label slow_case; 1275 Label slow_case;
1276 Heap* heap = Isolate::Current()->heap(); 1276 Heap* heap = Isolate::Current()->heap();
1277 __ movq(RAX, Immediate(heap->TopAddress())); 1277 __ movq(RAX, Immediate(heap->TopAddress()));
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
1346 __ movq(Address(RAX, Closure::context_offset()), CTX); 1346 __ movq(Address(RAX, Closure::context_offset()), CTX);
1347 } 1347 }
1348 1348
1349 // Set the type arguments field in the newly allocated closure. 1349 // Set the type arguments field in the newly allocated closure.
1350 __ movq(R10, Address(RSP, kTypeArgumentsOffset)); 1350 __ movq(R10, Address(RSP, kTypeArgumentsOffset));
1351 __ movq(Address(RAX, Closure::type_arguments_offset()), R10); 1351 __ movq(Address(RAX, Closure::type_arguments_offset()), R10);
1352 1352
1353 // Done allocating and initializing the instance. 1353 // Done allocating and initializing the instance.
1354 // RAX: new object. 1354 // RAX: new object.
1355 __ addq(RAX, Immediate(kHeapObjectTag)); 1355 __ addq(RAX, Immediate(kHeapObjectTag));
1356 __ LeaveFrameWithPP(); 1356 __ LeaveStubFrame();
1357 __ ret(); 1357 __ ret();
1358 1358
1359 __ Bind(&slow_case); 1359 __ Bind(&slow_case);
1360 } 1360 }
1361 if (has_type_arguments) { 1361 if (has_type_arguments) {
1362 __ movq(RCX, Address(RSP, kTypeArgumentsOffset)); 1362 __ movq(RCX, Address(RSP, kTypeArgumentsOffset));
1363 } 1363 }
1364 if (is_implicit_instance_closure) { 1364 if (is_implicit_instance_closure) {
1365 __ movq(RAX, Address(RSP, kReceiverOffset)); 1365 __ movq(RAX, Address(RSP, kReceiverOffset));
1366 } 1366 }
(...skipping 14 matching lines...) Expand all
1381 __ popq(RAX); // Pop receiver. 1381 __ popq(RAX); // Pop receiver.
1382 } else { 1382 } else {
1383 ASSERT(func.IsNonImplicitClosureFunction()); 1383 ASSERT(func.IsNonImplicitClosureFunction());
1384 __ CallRuntime(kAllocateClosureRuntimeEntry, 2); 1384 __ CallRuntime(kAllocateClosureRuntimeEntry, 2);
1385 __ popq(RAX); // Pop type arguments. 1385 __ popq(RAX); // Pop type arguments.
1386 } 1386 }
1387 __ popq(RAX); // Pop the function object. 1387 __ popq(RAX); // Pop the function object.
1388 __ popq(RAX); // Pop the result. 1388 __ popq(RAX); // Pop the result.
1389 // RAX: New closure object. 1389 // RAX: New closure object.
1390 // Restore the calling frame. 1390 // Restore the calling frame.
1391 __ LeaveFrameWithPP(); 1391 __ LeaveStubFrame();
1392 __ ret(); 1392 __ ret();
1393 } 1393 }
1394 1394
1395 1395
1396 // Called for invoking "dynamic noSuchMethod(Invocation invocation)" function 1396 // Called for invoking "dynamic noSuchMethod(Invocation invocation)" function
1397 // from the entry code of a dart function after an error in passed argument 1397 // from the entry code of a dart function after an error in passed argument
1398 // name or number is detected. 1398 // name or number is detected.
1399 // Input parameters: 1399 // Input parameters:
1400 // RSP : points to return address. 1400 // RSP : points to return address.
1401 // RSP + 8 : address of last argument. 1401 // RSP + 8 : address of last argument.
(...skipping 15 matching lines...) Expand all
1417 __ movq(R10, R13); // Smi-tagged arguments array length. 1417 __ movq(R10, R13); // Smi-tagged arguments array length.
1418 PushArgumentsArray(assembler); 1418 PushArgumentsArray(assembler);
1419 1419
1420 __ CallRuntime(kInvokeNoSuchMethodFunctionRuntimeEntry, 4); 1420 __ CallRuntime(kInvokeNoSuchMethodFunctionRuntimeEntry, 4);
1421 1421
1422 // Remove arguments. 1422 // Remove arguments.
1423 __ Drop(4); 1423 __ Drop(4);
1424 __ popq(RAX); // Get result into RAX. 1424 __ popq(RAX); // Get result into RAX.
1425 1425
1426 // Remove the stub frame as we are about to return. 1426 // Remove the stub frame as we are about to return.
1427 __ LeaveFrame(); 1427 __ LeaveStubFrame();
1428 __ ret(); 1428 __ ret();
1429 } 1429 }
1430 1430
1431 1431
1432 // Cannot use function object from ICData as it may be the inlined 1432 // Cannot use function object from ICData as it may be the inlined
1433 // function and not the top-scope function. 1433 // function and not the top-scope function.
1434 void StubCode::GenerateOptimizedUsageCounterIncrement(Assembler* assembler) { 1434 void StubCode::GenerateOptimizedUsageCounterIncrement(Assembler* assembler) {
1435 Register ic_reg = RBX; 1435 Register ic_reg = RBX;
1436 Register func_reg = RDI; 1436 Register func_reg = RDI;
1437 if (FLAG_trace_optimized_ic_calls) { 1437 if (FLAG_trace_optimized_ic_calls) {
1438 __ EnterStubFrame(); 1438 __ EnterStubFrame();
1439 __ pushq(func_reg); // Preserve 1439 __ pushq(func_reg); // Preserve
1440 __ pushq(ic_reg); // Preserve. 1440 __ pushq(ic_reg); // Preserve.
1441 __ pushq(ic_reg); // Argument. 1441 __ pushq(ic_reg); // Argument.
1442 __ pushq(func_reg); // Argument. 1442 __ pushq(func_reg); // Argument.
1443 __ CallRuntime(kTraceICCallRuntimeEntry, 2); 1443 __ CallRuntime(kTraceICCallRuntimeEntry, 2);
1444 __ popq(RAX); // Discard argument; 1444 __ popq(RAX); // Discard argument;
1445 __ popq(RAX); // Discard argument; 1445 __ popq(RAX); // Discard argument;
1446 __ popq(ic_reg); // Restore. 1446 __ popq(ic_reg); // Restore.
1447 __ popq(func_reg); // Restore. 1447 __ popq(func_reg); // Restore.
1448 __ LeaveFrame(); 1448 __ LeaveStubFrame();
1449 } 1449 }
1450 __ incq(FieldAddress(func_reg, Function::usage_counter_offset())); 1450 __ incq(FieldAddress(func_reg, Function::usage_counter_offset()));
1451 } 1451 }
1452 1452
1453 1453
1454 // Loads function into 'temp_reg', preserves 'ic_reg'. 1454 // Loads function into 'temp_reg', preserves 'ic_reg'.
1455 void StubCode::GenerateUsageCounterIncrement(Assembler* assembler, 1455 void StubCode::GenerateUsageCounterIncrement(Assembler* assembler,
1456 Register temp_reg) { 1456 Register temp_reg) {
1457 Register ic_reg = RBX; 1457 Register ic_reg = RBX;
1458 Register func_reg = temp_reg; 1458 Register func_reg = temp_reg;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1492 // Check single stepping. 1492 // Check single stepping.
1493 Label not_stepping; 1493 Label not_stepping;
1494 __ movq(RAX, FieldAddress(CTX, Context::isolate_offset())); 1494 __ movq(RAX, FieldAddress(CTX, Context::isolate_offset()));
1495 __ movzxb(RAX, Address(RAX, Isolate::single_step_offset())); 1495 __ movzxb(RAX, Address(RAX, Isolate::single_step_offset()));
1496 __ cmpq(RAX, Immediate(0)); 1496 __ cmpq(RAX, Immediate(0));
1497 __ j(EQUAL, &not_stepping, Assembler::kNearJump); 1497 __ j(EQUAL, &not_stepping, Assembler::kNearJump);
1498 __ EnterStubFrame(); 1498 __ EnterStubFrame();
1499 __ pushq(RBX); 1499 __ pushq(RBX);
1500 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); 1500 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0);
1501 __ popq(RBX); 1501 __ popq(RBX);
1502 __ LeaveFrame(); 1502 __ LeaveStubFrame();
1503 __ Bind(&not_stepping); 1503 __ Bind(&not_stepping);
1504 1504
1505 // Load arguments descriptor into R10. 1505 // Load arguments descriptor into R10.
1506 __ movq(R10, FieldAddress(RBX, ICData::arguments_descriptor_offset())); 1506 __ movq(R10, FieldAddress(RBX, ICData::arguments_descriptor_offset()));
1507 // Loop that checks if there is an IC data match. 1507 // Loop that checks if there is an IC data match.
1508 Label loop, update, test, found, get_class_id_as_smi; 1508 Label loop, update, test, found, get_class_id_as_smi;
1509 // RBX: IC data object (preserved). 1509 // RBX: IC data object (preserved).
1510 __ movq(R12, FieldAddress(RBX, ICData::ic_data_offset())); 1510 __ movq(R12, FieldAddress(RBX, ICData::ic_data_offset()));
1511 // R12: ic_data_array with check entries: classes and target functions. 1511 // R12: ic_data_array with check entries: classes and target functions.
1512 __ leaq(R12, FieldAddress(R12, Array::data_offset())); 1512 __ leaq(R12, FieldAddress(R12, Array::data_offset()));
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1573 } 1573 }
1574 __ pushq(RBX); // Pass IC data object. 1574 __ pushq(RBX); // Pass IC data object.
1575 __ CallRuntime(handle_ic_miss, num_args + 1); 1575 __ CallRuntime(handle_ic_miss, num_args + 1);
1576 // Remove the call arguments pushed earlier, including the IC data object. 1576 // Remove the call arguments pushed earlier, including the IC data object.
1577 for (intptr_t i = 0; i < num_args + 1; i++) { 1577 for (intptr_t i = 0; i < num_args + 1; i++) {
1578 __ popq(RAX); 1578 __ popq(RAX);
1579 } 1579 }
1580 __ popq(RAX); // Pop returned code object into RAX (null if not found). 1580 __ popq(RAX); // Pop returned code object into RAX (null if not found).
1581 __ popq(RBX); // Restore IC data array. 1581 __ popq(RBX); // Restore IC data array.
1582 __ popq(R10); // Restore arguments descriptor array. 1582 __ popq(R10); // Restore arguments descriptor array.
1583 __ LeaveFrame(); 1583 __ LeaveStubFrame();
1584 Label call_target_function; 1584 Label call_target_function;
1585 __ cmpq(RAX, R12); 1585 __ cmpq(RAX, R12);
1586 __ j(NOT_EQUAL, &call_target_function, Assembler::kNearJump); 1586 __ j(NOT_EQUAL, &call_target_function, Assembler::kNearJump);
1587 // NoSuchMethod or closure. 1587 // NoSuchMethod or closure.
1588 // Mark IC call that it may be a closure call that does not collect 1588 // Mark IC call that it may be a closure call that does not collect
1589 // type feedback. 1589 // type feedback.
1590 __ movb(FieldAddress(RBX, ICData::is_closure_call_offset()), Immediate(1)); 1590 __ movb(FieldAddress(RBX, ICData::is_closure_call_offset()), Immediate(1));
1591 __ jmp(&StubCode::InstanceFunctionLookupLabel()); 1591 __ jmp(&StubCode::InstanceFunctionLookupLabel());
1592 1592
1593 __ Bind(&found); 1593 __ Bind(&found);
(...skipping 15 matching lines...) Expand all
1609 __ CompareObject(RCX, Object::null_object(), PP); 1609 __ CompareObject(RCX, Object::null_object(), PP);
1610 __ j(NOT_EQUAL, &is_compiled, Assembler::kNearJump); 1610 __ j(NOT_EQUAL, &is_compiled, Assembler::kNearJump);
1611 __ EnterStubFrame(); 1611 __ EnterStubFrame();
1612 __ pushq(R10); // Preserve arguments descriptor array. 1612 __ pushq(R10); // Preserve arguments descriptor array.
1613 __ pushq(RBX); // Preserve IC data object. 1613 __ pushq(RBX); // Preserve IC data object.
1614 __ pushq(RAX); // Pass function. 1614 __ pushq(RAX); // Pass function.
1615 __ CallRuntime(kCompileFunctionRuntimeEntry, 1); 1615 __ CallRuntime(kCompileFunctionRuntimeEntry, 1);
1616 __ popq(RAX); // Restore function. 1616 __ popq(RAX); // Restore function.
1617 __ popq(RBX); // Restore IC data array. 1617 __ popq(RBX); // Restore IC data array.
1618 __ popq(R10); // Restore arguments descriptor array. 1618 __ popq(R10); // Restore arguments descriptor array.
1619 __ LeaveFrame(); 1619 __ LeaveStubFrame();
1620 __ movq(RCX, FieldAddress(RAX, Function::code_offset())); 1620 __ movq(RCX, FieldAddress(RAX, Function::code_offset()));
1621 __ Bind(&is_compiled); 1621 __ Bind(&is_compiled);
1622 } 1622 }
1623 __ movq(RAX, FieldAddress(RCX, Code::instructions_offset())); 1623 __ movq(RAX, FieldAddress(RCX, Code::instructions_offset()));
1624 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); 1624 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
1625 __ jmp(RAX); 1625 __ jmp(RAX);
1626 1626
1627 __ Bind(&get_class_id_as_smi); 1627 __ Bind(&get_class_id_as_smi);
1628 Label not_smi; 1628 Label not_smi;
1629 // Test if Smi -> load Smi class for comparison. 1629 // Test if Smi -> load Smi class for comparison.
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
1739 // Check single stepping. 1739 // Check single stepping.
1740 Label not_stepping; 1740 Label not_stepping;
1741 __ movq(RAX, FieldAddress(CTX, Context::isolate_offset())); 1741 __ movq(RAX, FieldAddress(CTX, Context::isolate_offset()));
1742 __ movzxb(RAX, Address(RAX, Isolate::single_step_offset())); 1742 __ movzxb(RAX, Address(RAX, Isolate::single_step_offset()));
1743 __ cmpq(RAX, Immediate(0)); 1743 __ cmpq(RAX, Immediate(0));
1744 __ j(EQUAL, &not_stepping, Assembler::kNearJump); 1744 __ j(EQUAL, &not_stepping, Assembler::kNearJump);
1745 __ EnterStubFrame(); 1745 __ EnterStubFrame();
1746 __ pushq(RBX); // Preserve IC data object. 1746 __ pushq(RBX); // Preserve IC data object.
1747 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); 1747 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0);
1748 __ popq(RBX); 1748 __ popq(RBX);
1749 __ LeaveFrame(); 1749 __ LeaveStubFrame();
1750 __ Bind(&not_stepping); 1750 __ Bind(&not_stepping);
1751 1751
1752 // RBX: IC data object (preserved). 1752 // RBX: IC data object (preserved).
1753 __ movq(R12, FieldAddress(RBX, ICData::ic_data_offset())); 1753 __ movq(R12, FieldAddress(RBX, ICData::ic_data_offset()));
1754 // R12: ic_data_array with entries: target functions and count. 1754 // R12: ic_data_array with entries: target functions and count.
1755 __ leaq(R12, FieldAddress(R12, Array::data_offset())); 1755 __ leaq(R12, FieldAddress(R12, Array::data_offset()));
1756 // R12: points directly to the first ic data array element. 1756 // R12: points directly to the first ic data array element.
1757 const intptr_t target_offset = ICData::TargetIndexFor(0) * kWordSize; 1757 const intptr_t target_offset = ICData::TargetIndexFor(0) * kWordSize;
1758 const intptr_t count_offset = ICData::CountIndexFor(0) * kWordSize; 1758 const intptr_t count_offset = ICData::CountIndexFor(0) * kWordSize;
1759 1759
(...skipping 14 matching lines...) Expand all
1774 __ j(NOT_EQUAL, &target_is_compiled, Assembler::kNearJump); 1774 __ j(NOT_EQUAL, &target_is_compiled, Assembler::kNearJump);
1775 1775
1776 __ EnterStubFrame(); 1776 __ EnterStubFrame();
1777 __ pushq(R13); // Preserve target function. 1777 __ pushq(R13); // Preserve target function.
1778 __ pushq(RBX); // Preserve IC data object. 1778 __ pushq(RBX); // Preserve IC data object.
1779 __ pushq(R13); // Pass function. 1779 __ pushq(R13); // Pass function.
1780 __ CallRuntime(kCompileFunctionRuntimeEntry, 1); 1780 __ CallRuntime(kCompileFunctionRuntimeEntry, 1);
1781 __ popq(RAX); // Discard argument. 1781 __ popq(RAX); // Discard argument.
1782 __ popq(RBX); // Restore IC data object. 1782 __ popq(RBX); // Restore IC data object.
1783 __ popq(R13); // Restore target function. 1783 __ popq(R13); // Restore target function.
1784 __ LeaveFrame(); 1784 __ LeaveStubFrame();
1785 __ movq(RAX, FieldAddress(R13, Function::code_offset())); 1785 __ movq(RAX, FieldAddress(R13, Function::code_offset()));
1786 1786
1787 __ Bind(&target_is_compiled); 1787 __ Bind(&target_is_compiled);
1788 // RAX: Target code. 1788 // RAX: Target code.
1789 __ movq(RAX, FieldAddress(RAX, Code::instructions_offset())); 1789 __ movq(RAX, FieldAddress(RAX, Code::instructions_offset()));
1790 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); 1790 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
1791 // Load arguments descriptor into R10. 1791 // Load arguments descriptor into R10.
1792 __ movq(R10, FieldAddress(RBX, ICData::arguments_descriptor_offset())); 1792 __ movq(R10, FieldAddress(RBX, ICData::arguments_descriptor_offset()));
1793 __ jmp(RAX); 1793 __ jmp(RAX);
1794 } 1794 }
(...skipping 12 matching lines...) Expand all
1807 // RAX: Function. 1807 // RAX: Function.
1808 void StubCode::GenerateCompileFunctionRuntimeCallStub(Assembler* assembler) { 1808 void StubCode::GenerateCompileFunctionRuntimeCallStub(Assembler* assembler) {
1809 __ EnterStubFrame(); 1809 __ EnterStubFrame();
1810 __ pushq(RDX); // Preserve arguments descriptor array. 1810 __ pushq(RDX); // Preserve arguments descriptor array.
1811 __ pushq(RCX); // Preserve IC data object. 1811 __ pushq(RCX); // Preserve IC data object.
1812 __ pushq(RAX); // Pass function. 1812 __ pushq(RAX); // Pass function.
1813 __ CallRuntime(kCompileFunctionRuntimeEntry, 1); 1813 __ CallRuntime(kCompileFunctionRuntimeEntry, 1);
1814 __ popq(RAX); // Restore function. 1814 __ popq(RAX); // Restore function.
1815 __ popq(RCX); // Restore IC data array. 1815 __ popq(RCX); // Restore IC data array.
1816 __ popq(RDX); // Restore arguments descriptor array. 1816 __ popq(RDX); // Restore arguments descriptor array.
1817 __ LeaveFrame(); 1817 __ LeaveStubFrame();
1818 __ ret(); 1818 __ ret();
1819 } 1819 }
1820 1820
1821 1821
1822 // RBX, R10: May contain arguments to runtime stub. 1822 // RBX, R10: May contain arguments to runtime stub.
1823 // TOS(0): return address (Dart code). 1823 // TOS(0): return address (Dart code).
1824 void StubCode::GenerateBreakpointRuntimeStub(Assembler* assembler) { 1824 void StubCode::GenerateBreakpointRuntimeStub(Assembler* assembler) {
1825 __ EnterStubFrameWithPP(); 1825 __ EnterStubFrame();
1826 // Preserve runtime args. 1826 // Preserve runtime args.
1827 __ pushq(RBX); 1827 __ pushq(RBX);
1828 __ pushq(R10); 1828 __ pushq(R10);
1829 // Room for result. Debugger stub returns address of the 1829 // Room for result. Debugger stub returns address of the
1830 // unpatched runtime stub. 1830 // unpatched runtime stub.
1831 __ LoadObject(R12, Object::null_object(), PP); 1831 __ LoadObject(R12, Object::null_object(), PP);
1832 __ pushq(R12); // Room for result. 1832 __ pushq(R12); // Room for result.
1833 __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0); 1833 __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0);
1834 __ popq(RAX); // Address of original. 1834 __ popq(RAX); // Address of original.
1835 __ popq(R10); // Restore arguments. 1835 __ popq(R10); // Restore arguments.
1836 __ popq(RBX); 1836 __ popq(RBX);
1837 __ LeaveFrameWithPP(); 1837 __ LeaveStubFrame();
1838 __ jmp(RAX); // Jump to original stub. 1838 __ jmp(RAX); // Jump to original stub.
1839 } 1839 }
1840 1840
1841 1841
1842 // RBX: ICData (unoptimized static call) 1842 // RBX: ICData (unoptimized static call)
1843 // TOS(0): return address (Dart code). 1843 // TOS(0): return address (Dart code).
1844 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) { 1844 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) {
1845 __ EnterStubFrame(); 1845 __ EnterStubFrame();
1846 __ LoadObject(R12, Object::null_object(), PP); 1846 __ LoadObject(R12, Object::null_object(), PP);
1847 __ pushq(RBX); // Preserve IC data for unoptimized call. 1847 __ pushq(RBX); // Preserve IC data for unoptimized call.
1848 __ pushq(R12); // Room for result. 1848 __ pushq(R12); // Room for result.
1849 __ CallRuntime(kBreakpointStaticHandlerRuntimeEntry, 0); 1849 __ CallRuntime(kBreakpointStaticHandlerRuntimeEntry, 0);
1850 __ popq(RAX); // Code object. 1850 __ popq(RAX); // Code object.
1851 __ popq(RBX); // Restore IC data. 1851 __ popq(RBX); // Restore IC data.
1852 __ LeaveFrame(); 1852 __ LeaveStubFrame();
1853 1853
1854 // Load arguments descriptor into R10. 1854 // Load arguments descriptor into R10.
1855 __ movq(R10, FieldAddress(RBX, ICData::arguments_descriptor_offset())); 1855 __ movq(R10, FieldAddress(RBX, ICData::arguments_descriptor_offset()));
1856 // Now call the static function. The breakpoint handler function 1856 // Now call the static function. The breakpoint handler function
1857 // ensures that the call target is compiled. 1857 // ensures that the call target is compiled.
1858 __ movq(RBX, FieldAddress(RAX, Code::instructions_offset())); 1858 __ movq(RBX, FieldAddress(RAX, Code::instructions_offset()));
1859 __ addq(RBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); 1859 __ addq(RBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
1860 __ jmp(RBX); 1860 __ jmp(RBX);
1861 } 1861 }
1862 1862
1863 1863
1864 // TOS(0): return address (Dart code). 1864 // TOS(0): return address (Dart code).
1865 void StubCode::GenerateBreakpointReturnStub(Assembler* assembler) { 1865 void StubCode::GenerateBreakpointReturnStub(Assembler* assembler) {
1866 __ EnterStubFrameWithPP(); 1866 __ EnterStubFrame();
1867 __ pushq(RAX); 1867 __ pushq(RAX);
1868 __ CallRuntime(kBreakpointReturnHandlerRuntimeEntry, 0); 1868 __ CallRuntime(kBreakpointReturnHandlerRuntimeEntry, 0);
1869 __ popq(RAX); 1869 __ popq(RAX);
1870 __ LeaveFrameWithPP(); 1870 __ LeaveStubFrame();
1871
1872 __ popq(R11); // discard return address of call to this stub. 1871 __ popq(R11); // discard return address of call to this stub.
1873 __ LeaveFrameWithPP(); 1872 __ LeaveDartFrame();
1874 __ ret(); 1873 __ ret();
1875 } 1874 }
1876 1875
1877 1876
1878 // RBX: Inline cache data array. 1877 // RBX: Inline cache data array.
1879 // TOS(0): return address (Dart code). 1878 // TOS(0): return address (Dart code).
1880 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) { 1879 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) {
1881 __ EnterStubFrame(); 1880 __ EnterStubFrame();
1882 __ pushq(RBX); 1881 __ pushq(RBX);
1883 __ CallRuntime(kBreakpointDynamicHandlerRuntimeEntry, 0); 1882 __ CallRuntime(kBreakpointDynamicHandlerRuntimeEntry, 0);
1884 __ popq(RBX); 1883 __ popq(RBX);
1885 __ LeaveFrame(); 1884 __ LeaveStubFrame();
1886 1885
1887 // Find out which dispatch stub to call. 1886 // Find out which dispatch stub to call.
1888 Label test_two, test_three, test_four; 1887 Label test_two, test_three, test_four;
1889 __ movq(RCX, FieldAddress(RBX, ICData::num_args_tested_offset())); 1888 __ movq(RCX, FieldAddress(RBX, ICData::num_args_tested_offset()));
1890 __ cmpq(RCX, Immediate(1)); 1889 __ cmpq(RCX, Immediate(1));
1891 __ j(NOT_EQUAL, &test_two, Assembler::kNearJump); 1890 __ j(NOT_EQUAL, &test_two, Assembler::kNearJump);
1892 __ jmp(&StubCode::OneArgCheckInlineCacheLabel()); 1891 __ jmp(&StubCode::OneArgCheckInlineCacheLabel());
1893 __ Bind(&test_two); 1892 __ Bind(&test_two);
1894 __ cmpl(RCX, Immediate(2)); 1893 __ cmpl(RCX, Immediate(2));
1895 __ j(NOT_EQUAL, &test_three, Assembler::kNearJump); 1894 __ j(NOT_EQUAL, &test_three, Assembler::kNearJump);
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
2037 __ movq(kExceptionObjectReg, RCX); // exception object. 2036 __ movq(kExceptionObjectReg, RCX); // exception object.
2038 __ movq(RSP, RSI); // target stack_pointer. 2037 __ movq(RSP, RSI); // target stack_pointer.
2039 __ jmp(RDI); // Jump to the exception handler code. 2038 __ jmp(RDI); // Jump to the exception handler code.
2040 } 2039 }
2041 2040
2042 2041
2043 // Calls to the runtime to optimize the given function. 2042 // Calls to the runtime to optimize the given function.
2044 // RDI: function to be reoptimized. 2043 // RDI: function to be reoptimized.
2045 // R10: argument descriptor (preserved). 2044 // R10: argument descriptor (preserved).
2046 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) { 2045 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) {
2047 __ EnterStubFrameWithPP(); 2046 __ EnterStubFrame();
2048 __ LoadObject(R12, Object::null_object(), PP); 2047 __ LoadObject(R12, Object::null_object(), PP);
2049 __ pushq(R10); 2048 __ pushq(R10);
2050 __ pushq(R12); // Setup space on stack for return value. 2049 __ pushq(R12); // Setup space on stack for return value.
2051 __ pushq(RDI); 2050 __ pushq(RDI);
2052 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1); 2051 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1);
2053 __ popq(RAX); // Disard argument. 2052 __ popq(RAX); // Disard argument.
2054 __ popq(RAX); // Get Code object. 2053 __ popq(RAX); // Get Code object.
2055 __ popq(R10); // Restore argument descriptor. 2054 __ popq(R10); // Restore argument descriptor.
2056 __ movq(RAX, FieldAddress(RAX, Code::instructions_offset())); 2055 __ movq(RAX, FieldAddress(RAX, Code::instructions_offset()));
2057 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); 2056 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
2058 __ LeaveFrameWithPP(); 2057 __ LeaveStubFrame();
2059 __ jmp(RAX); 2058 __ jmp(RAX);
2060 __ int3(); 2059 __ int3();
2061 } 2060 }
2062 2061
2063 2062
2064 DECLARE_LEAF_RUNTIME_ENTRY(intptr_t, 2063 DECLARE_LEAF_RUNTIME_ENTRY(intptr_t,
2065 BigintCompare, 2064 BigintCompare,
2066 RawBigint* left, 2065 RawBigint* left,
2067 RawBigint* right); 2066 RawBigint* right);
2068 2067
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
2134 void StubCode::GenerateUnoptimizedIdenticalWithNumberCheckStub( 2133 void StubCode::GenerateUnoptimizedIdenticalWithNumberCheckStub(
2135 Assembler* assembler) { 2134 Assembler* assembler) {
2136 // Check single stepping. 2135 // Check single stepping.
2137 Label not_stepping; 2136 Label not_stepping;
2138 __ movq(RAX, FieldAddress(CTX, Context::isolate_offset())); 2137 __ movq(RAX, FieldAddress(CTX, Context::isolate_offset()));
2139 __ movzxb(RAX, Address(RAX, Isolate::single_step_offset())); 2138 __ movzxb(RAX, Address(RAX, Isolate::single_step_offset()));
2140 __ cmpq(RAX, Immediate(0)); 2139 __ cmpq(RAX, Immediate(0));
2141 __ j(EQUAL, &not_stepping, Assembler::kNearJump); 2140 __ j(EQUAL, &not_stepping, Assembler::kNearJump);
2142 __ EnterStubFrame(); 2141 __ EnterStubFrame();
2143 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); 2142 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0);
2144 __ LeaveFrame(); 2143 __ LeaveStubFrame();
2145 __ Bind(&not_stepping); 2144 __ Bind(&not_stepping);
2146 2145
2147 const Register left = RAX; 2146 const Register left = RAX;
2148 const Register right = RDX; 2147 const Register right = RDX;
2149 2148
2150 __ movq(left, Address(RSP, 2 * kWordSize)); 2149 __ movq(left, Address(RSP, 2 * kWordSize));
2151 __ movq(right, Address(RSP, 1 * kWordSize)); 2150 __ movq(right, Address(RSP, 1 * kWordSize));
2152 GenerateIdenticalWithNumberCheckStub(assembler, left, right); 2151 GenerateIdenticalWithNumberCheckStub(assembler, left, right);
2153 __ ret(); 2152 __ ret();
2154 } 2153 }
(...skipping 11 matching lines...) Expand all
2166 2165
2167 __ movq(left, Address(RSP, 2 * kWordSize)); 2166 __ movq(left, Address(RSP, 2 * kWordSize));
2168 __ movq(right, Address(RSP, 1 * kWordSize)); 2167 __ movq(right, Address(RSP, 1 * kWordSize));
2169 GenerateIdenticalWithNumberCheckStub(assembler, left, right); 2168 GenerateIdenticalWithNumberCheckStub(assembler, left, right);
2170 __ ret(); 2169 __ ret();
2171 } 2170 }
2172 2171
2173 } // namespace dart 2172 } // namespace dart
2174 2173
2175 #endif // defined TARGET_ARCH_X64 2174 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/stack_frame_x64.h ('k') | runtime/vm/stub_code_x64_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698