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

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
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 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 __ movq(CTX, R8); 245 __ movq(CTX, R8);
246 246
247 __ LeaveFrame(); 247 __ LeaveFrame();
248 __ ret(); 248 __ ret();
249 } 249 }
250 250
251 251
252 // Input parameters: 252 // Input parameters:
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(true); // Uses PP to access null object.
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(true); // Uses PP to access null object.
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(true); // Uses PP to access null object.
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(RBX); // Preserve result, it will be GC-d here. 454 __ pushq(RBX); // Preserve result, it will be GC-d here.
457 } 455 }
458 __ pushq(Immediate(Smi::RawValue(0))); // Space for the result. 456 __ pushq(Immediate(Smi::RawValue(0))); // Space for the result.
459 __ CallRuntime(kDeoptimizeMaterializeRuntimeEntry, 0); 457 __ CallRuntime(kDeoptimizeMaterializeRuntimeEntry, 0);
460 // Result tells stub how many bytes to remove from the expression stack 458 // Result tells stub how many bytes to remove from the expression stack
461 // of the bottom-most frame. They were used as materialization arguments. 459 // of the bottom-most frame. They were used as materialization arguments.
462 __ popq(RBX); 460 __ popq(RBX);
463 __ SmiUntag(RBX); 461 __ SmiUntag(RBX);
464 if (preserve_result) { 462 if (preserve_result) {
465 __ popq(RAX); // Restore result. 463 __ popq(RAX); // Restore result.
466 } 464 }
467 __ LeaveFrame(); 465 __ LeaveStubFrame();
468 466
469 __ popq(RCX); // Pop return address. 467 __ popq(RCX); // Pop return address.
470 __ addq(RSP, RBX); // Remove materialization arguments. 468 __ addq(RSP, RBX); // Remove materialization arguments.
471 __ pushq(RCX); // Push return address. 469 __ pushq(RCX); // Push return address.
472 __ ret(); 470 __ ret();
473 } 471 }
474 472
475 473
476 // TOS: return address + call-instruction-size (5 bytes). 474 // TOS: return address + call-instruction-size (5 bytes).
477 // RAX: result, must be preserved 475 // RAX: result, must be preserved
478 void StubCode::GenerateDeoptimizeLazyStub(Assembler* assembler) { 476 void StubCode::GenerateDeoptimizeLazyStub(Assembler* assembler) {
479 // Correct return address to point just after the call that is being 477 // Correct return address to point just after the call that is being
480 // deoptimized. 478 // deoptimized.
481 __ popq(RBX); 479 __ popq(RBX);
482 __ subq(RBX, Immediate(ShortCallPattern::InstructionLength())); 480 __ subq(RBX, Immediate(ShortCallPattern::InstructionLength()));
483 __ pushq(RBX); 481 __ pushq(RBX);
484 GenerateDeoptimizationSequence(assembler, true); // Preserve RAX. 482 GenerateDeoptimizationSequence(assembler, true); // Preserve RAX.
485 } 483 }
486 484
487 485
488 void StubCode::GenerateDeoptimizeStub(Assembler* assembler) { 486 void StubCode::GenerateDeoptimizeStub(Assembler* assembler) {
489 GenerateDeoptimizationSequence(assembler, false); // Don't preserve RAX. 487 GenerateDeoptimizationSequence(assembler, false); // Don't preserve RAX.
490 } 488 }
491 489
492 490
493 void StubCode::GenerateMegamorphicMissStub(Assembler* assembler) { 491 void StubCode::GenerateMegamorphicMissStub(Assembler* assembler) {
494 __ EnterStubFrameWithPP(); 492 __ EnterStubFrame(true); // Uses PP to access null object.
495 // Load the receiver into RAX. The argument count in the arguments 493 // Load the receiver into RAX. The argument count in the arguments
496 // descriptor in R10 is a smi. 494 // descriptor in R10 is a smi.
497 __ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset())); 495 __ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
498 // Three words (saved pp, saved fp, stub's pc marker) 496 // Three words (saved pp, saved fp, stub's pc marker)
499 // in the stack above the return address. 497 // in the stack above the return address.
500 __ movq(RAX, Address(RSP, RAX, TIMES_4, 498 __ movq(RAX, Address(RSP, RAX, TIMES_4,
501 kSavedAboveReturnAddress * kWordSize)); 499 kSavedAboveReturnAddress * kWordSize));
502 // Preserve IC data and arguments descriptor. 500 // Preserve IC data and arguments descriptor.
503 __ pushq(RBX); 501 __ pushq(RBX);
504 __ pushq(R10); 502 __ pushq(R10);
505 503
506 // Space for the result of the runtime call. 504 // Space for the result of the runtime call.
507 __ PushObject(Object::null_object(), PP); 505 __ PushObject(Object::null_object(), PP);
508 __ pushq(RAX); // Receiver. 506 __ pushq(RAX); // Receiver.
509 __ pushq(RBX); // IC data. 507 __ pushq(RBX); // IC data.
510 __ pushq(R10); // Arguments descriptor. 508 __ pushq(R10); // Arguments descriptor.
511 __ CallRuntime(kMegamorphicCacheMissHandlerRuntimeEntry, 3); 509 __ CallRuntime(kMegamorphicCacheMissHandlerRuntimeEntry, 3);
512 // Discard arguments. 510 // Discard arguments.
513 __ popq(RAX); 511 __ popq(RAX);
514 __ popq(RAX); 512 __ popq(RAX);
515 __ popq(RAX); 513 __ popq(RAX);
516 __ popq(RAX); // Return value from the runtime call (instructions). 514 __ popq(RAX); // Return value from the runtime call (instructions).
517 __ popq(R10); // Restore arguments descriptor. 515 __ popq(R10); // Restore arguments descriptor.
518 __ popq(RBX); // Restore IC data. 516 __ popq(RBX); // Restore IC data.
519 __ LeaveFrameWithPP(); 517 __ LeaveStubFrame();
520 518
521 Label lookup; 519 Label lookup;
522 __ CompareObject(RAX, Object::null_object(), PP); 520 __ CompareObject(RAX, Object::null_object(), PP);
523 __ j(EQUAL, &lookup, Assembler::kNearJump); 521 __ j(EQUAL, &lookup, Assembler::kNearJump);
524 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); 522 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
525 __ jmp(RAX); 523 __ jmp(RAX);
526 524
527 __ Bind(&lookup); 525 __ Bind(&lookup);
528 __ jmp(&StubCode::InstanceFunctionLookupLabel()); 526 __ jmp(&StubCode::InstanceFunctionLookupLabel());
529 } 527 }
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
641 // RAX: new object. 639 // RAX: new object.
642 // R10: Array length as Smi (preserved for the caller.) 640 // R10: Array length as Smi (preserved for the caller.)
643 __ ret(); 641 __ ret();
644 } 642 }
645 643
646 // Unable to allocate the array using the fast inline code, just call 644 // Unable to allocate the array using the fast inline code, just call
647 // into the runtime. 645 // into the runtime.
648 __ Bind(&slow_case); 646 __ Bind(&slow_case);
649 // Create a stub frame as we are pushing some objects on the stack before 647 // Create a stub frame as we are pushing some objects on the stack before
650 // calling into the runtime. 648 // calling into the runtime.
651 __ EnterStubFrame(); 649 __ EnterStubFrame(true); // Uses PP to access null object.
Ivan Posva 2013/11/07 22:11:58 Where PP is only used to access null we do not nee
siva 2013/11/07 23:08:19 Done.
652 // Setup space on stack for return value. 650 // Setup space on stack for return value.
653 __ PushObject(Object::null_object(), PP); 651 __ PushObject(Object::null_object(), PP);
654 __ pushq(R10); // Array length as Smi. 652 __ pushq(R10); // Array length as Smi.
655 __ pushq(RBX); // Element type. 653 __ pushq(RBX); // Element type.
656 __ CallRuntime(kAllocateArrayRuntimeEntry, 2); 654 __ CallRuntime(kAllocateArrayRuntimeEntry, 2);
657 __ popq(RAX); // Pop element type argument. 655 __ popq(RAX); // Pop element type argument.
658 __ popq(R10); // Pop array length argument. 656 __ popq(R10); // Pop array length argument.
659 __ popq(RAX); // Pop return value from return slot. 657 __ popq(RAX); // Pop return value from return slot.
660 __ LeaveFrame(); 658 __ LeaveStubFrame();
661 __ ret(); 659 __ ret();
662 } 660 }
663 661
664 662
665 // Input parameters: 663 // Input parameters:
666 // R10: Arguments descriptor array. 664 // R10: Arguments descriptor array.
667 // Note: The closure object is the first argument to the function being 665 // Note: The closure object is the first argument to the function being
668 // called, the stub accesses the closure from this location directly 666 // called, the stub accesses the closure from this location directly
669 // when trying to resolve the call. 667 // when trying to resolve the call.
670 void StubCode::GenerateCallClosureFunctionStub(Assembler* assembler) { 668 void StubCode::GenerateCallClosureFunctionStub(Assembler* assembler) {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
708 706
709 __ pushq(R10); // Preserve arguments descriptor array. 707 __ pushq(R10); // Preserve arguments descriptor array.
710 __ pushq(RBX); // Preserve read-only function object argument. 708 __ pushq(RBX); // Preserve read-only function object argument.
711 __ CallRuntime(kCompileFunctionRuntimeEntry, 1); 709 __ CallRuntime(kCompileFunctionRuntimeEntry, 1);
712 __ popq(RBX); // Restore read-only function object argument in RBX. 710 __ popq(RBX); // Restore read-only function object argument in RBX.
713 __ popq(R10); // Restore arguments descriptor array. 711 __ popq(R10); // Restore arguments descriptor array.
714 // Restore RAX. 712 // Restore RAX.
715 __ movq(RAX, FieldAddress(RBX, Function::code_offset())); 713 __ movq(RAX, FieldAddress(RBX, Function::code_offset()));
716 714
717 // Remove the stub frame as we are about to jump to the closure function. 715 // Remove the stub frame as we are about to jump to the closure function.
718 __ LeaveFrame(); 716 __ LeaveStubFrame();
719 717
720 __ Bind(&function_compiled); 718 __ Bind(&function_compiled);
721 // RAX: Code. 719 // RAX: Code.
722 // RBX: Function. 720 // RBX: Function.
723 // R10: Arguments descriptor array. 721 // R10: Arguments descriptor array.
724 722
725 __ movq(RBX, FieldAddress(RAX, Code::instructions_offset())); 723 __ movq(RBX, FieldAddress(RAX, Code::instructions_offset()));
726 __ addq(RBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); 724 __ addq(RBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
727 __ jmp(RBX); 725 __ jmp(RBX);
728 726
(...skipping 15 matching lines...) Expand all
744 __ movq(R10, FieldAddress(R10, ArgumentsDescriptor::count_offset())); 742 __ movq(R10, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
745 PushArgumentsArray(assembler); 743 PushArgumentsArray(assembler);
746 744
747 __ CallRuntime(kInvokeNonClosureRuntimeEntry, 2); 745 __ CallRuntime(kInvokeNonClosureRuntimeEntry, 2);
748 746
749 // Remove arguments. 747 // Remove arguments.
750 __ Drop(2); 748 __ Drop(2);
751 __ popq(RAX); // Get result into RAX. 749 __ popq(RAX); // Get result into RAX.
752 750
753 // Remove the stub frame as we are about to return. 751 // Remove the stub frame as we are about to return.
754 __ LeaveFrame(); 752 __ LeaveStubFrame();
755 __ ret(); 753 __ ret();
756 } 754 }
757 755
758 756
759 // Called when invoking Dart code from C++ (VM code). 757 // Called when invoking Dart code from C++ (VM code).
760 // Input parameters: 758 // Input parameters:
761 // RSP : points to return address. 759 // RSP : points to return address.
762 // RDI : entrypoint of the Dart function to call. 760 // RDI : entrypoint of the Dart function to call.
763 // RSI : arguments descriptor array. 761 // RSI : arguments descriptor array.
764 // RDX : arguments array. 762 // RDX : arguments array.
765 // RCX : new context containing the current isolate pointer. 763 // RCX : new context containing the current isolate pointer.
766 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) { 764 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) {
767 // Save frame pointer coming in. 765 // Save frame pointer coming in.
768 __ EnterStubFrameWithPP(); 766 __ EnterFrame(0);
769 767
770 // At this point, the stack looks like: 768 // At this point, the stack looks like:
771 // | saved RC15/PP | <-- RSP / TOS
772 // | "saved PC area" = 0 |
773 // | saved RBP | <-- RBP 769 // | saved RBP | <-- RBP
774 // | saved PC (return to DartEntry::InvokeFunction) | 770 // | saved PC (return to DartEntry::InvokeFunction) |
775 771
776 // The old frame pointer, the return address, the old R15 (for PP). 772 const intptr_t kInitialOffset = 1;
777 const intptr_t kInitialOffset = 3;
778 // Save arguments descriptor array and new context. 773 // Save arguments descriptor array and new context.
779 const intptr_t kArgumentsDescOffset = -(kInitialOffset) * kWordSize; 774 const intptr_t kArgumentsDescOffset = -(kInitialOffset) * kWordSize;
780 __ pushq(RSI); 775 __ pushq(RSI);
781 const intptr_t kNewContextOffset = -(kInitialOffset + 1) * kWordSize; 776 const intptr_t kNewContextOffset = -(kInitialOffset + 1) * kWordSize;
782 __ pushq(RCX); 777 __ pushq(RCX);
783 778
784 // Save C++ ABI callee-saved registers. 779 // Save C++ ABI callee-saved registers.
785 __ pushq(RBX); 780 __ pushq(RBX);
786 __ pushq(R12); 781 __ pushq(R12);
787 __ pushq(R13); 782 __ pushq(R13);
788 __ pushq(R14); 783 __ pushq(R14);
789 // R15 is already saved above by EnterStubFrameWithPP. 784 __ pushq(R15);
785
786 // We now load the pool pointer(PP) as we are about to invoke dart code and we
787 // could potentially invoke some intrinsic functions which need the PP to be
788 // set up.
789 __ LoadPoolPointer(PP);
790 790
791 // If any additional (or fewer) values are pushed, the offsets in 791 // If any additional (or fewer) values are pushed, the offsets in
792 // kExitLinkSlotFromEntryFp and kSavedContextSlotFromEntryFp will need to be 792 // kExitLinkSlotFromEntryFp and kSavedContextSlotFromEntryFp will need to be
793 // changed. 793 // changed.
794 794
795 // The new Context structure contains a pointer to the current Isolate 795 // The new Context structure contains a pointer to the current Isolate
796 // structure. Cache the Context pointer in the CTX register so that it is 796 // structure. Cache the Context pointer in the CTX register so that it is
797 // available in generated code and calls to Isolate::Current() need not be 797 // available in generated code and calls to Isolate::Current() need not be
798 // done. The assumption is that this register will never be clobbered by 798 // done. The assumption is that this register will never be clobbered by
799 // compiled or runtime stub code. 799 // compiled or runtime stub code.
800 800
801 // Cache the new Context pointer into CTX while executing Dart code. 801 // Cache the new Context pointer into CTX while executing Dart code.
802 __ movq(CTX, Address(RCX, VMHandles::kOffsetOfRawPtrInHandle)); 802 __ movq(CTX, Address(RCX, VMHandles::kOffsetOfRawPtrInHandle));
803 803
804 // Load Isolate pointer from Context structure into R8. 804 // Load Isolate pointer from Context structure into R8.
805 __ movq(R8, FieldAddress(CTX, Context::isolate_offset())); 805 __ movq(R8, FieldAddress(CTX, Context::isolate_offset()));
806 806
807 // Save the top exit frame info. Use RAX as a temporary register. 807 // Save the top exit frame info. Use RAX as a temporary register.
808 // StackFrameIterator reads the top exit frame info saved in this frame. 808 // StackFrameIterator reads the top exit frame info saved in this frame.
809 // The constant kExitLinkSlotFromEntryFp must be kept in sync with the 809 // The constant kExitLinkSlotFromEntryFp must be kept in sync with the
810 // code below. 810 // code below.
811 ASSERT(kExitLinkSlotFromEntryFp == -9); 811 ASSERT(kExitLinkSlotFromEntryFp == -8);
812 __ movq(RAX, Address(R8, Isolate::top_exit_frame_info_offset())); 812 __ movq(RAX, Address(R8, Isolate::top_exit_frame_info_offset()));
813 __ pushq(RAX); 813 __ pushq(RAX);
814 __ movq(Address(R8, Isolate::top_exit_frame_info_offset()), Immediate(0)); 814 __ movq(Address(R8, Isolate::top_exit_frame_info_offset()), Immediate(0));
815 815
816 // Save the old Context pointer. Use RAX as a temporary register. 816 // Save the old Context pointer. Use RAX as a temporary register.
817 // Note that VisitObjectPointers will find this saved Context pointer during 817 // Note that VisitObjectPointers will find this saved Context pointer during
818 // GC marking, since it traverses any information between SP and 818 // GC marking, since it traverses any information between SP and
819 // FP - kExitLinkSlotFromEntryFp * kWordSize. 819 // FP - kExitLinkSlotFromEntryFp * kWordSize.
820 // EntryFrame::SavedContext reads the context saved in this frame. 820 // EntryFrame::SavedContext reads the context saved in this frame.
821 // The constant kSavedContextSlotFromEntryFp must be kept in sync with 821 // The constant kSavedContextSlotFromEntryFp must be kept in sync with
822 // the code below. 822 // the code below.
823 ASSERT(kSavedContextSlotFromEntryFp == -10); 823 ASSERT(kSavedContextSlotFromEntryFp == -9);
824 __ movq(RAX, Address(R8, Isolate::top_context_offset())); 824 __ movq(RAX, Address(R8, Isolate::top_context_offset()));
825 __ pushq(RAX); 825 __ pushq(RAX);
826 826
827 // Load arguments descriptor array into R10, which is passed to Dart code. 827 // Load arguments descriptor array into R10, which is passed to Dart code.
828 __ movq(R10, Address(RSI, VMHandles::kOffsetOfRawPtrInHandle)); 828 __ movq(R10, Address(RSI, VMHandles::kOffsetOfRawPtrInHandle));
829 829
830 // Load number of arguments into RBX. 830 // Load number of arguments into RBX.
831 __ movq(RBX, FieldAddress(R10, ArgumentsDescriptor::count_offset())); 831 __ movq(RBX, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
832 __ SmiUntag(RBX); 832 __ SmiUntag(RBX);
833 833
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
871 // Uses RCX as a temporary register for this. 871 // Uses RCX as a temporary register for this.
872 __ popq(RCX); 872 __ popq(RCX);
873 __ movq(Address(CTX, Isolate::top_context_offset()), RCX); 873 __ movq(Address(CTX, Isolate::top_context_offset()), RCX);
874 874
875 // Restore the saved top exit frame info back into the Isolate structure. 875 // Restore the saved top exit frame info back into the Isolate structure.
876 // Uses RDX as a temporary register for this. 876 // Uses RDX as a temporary register for this.
877 __ popq(RDX); 877 __ popq(RDX);
878 __ movq(Address(CTX, Isolate::top_exit_frame_info_offset()), RDX); 878 __ movq(Address(CTX, Isolate::top_exit_frame_info_offset()), RDX);
879 879
880 // Restore C++ ABI callee-saved registers. 880 // Restore C++ ABI callee-saved registers.
881 // R15 will be restored below by LeaveFrameWithPP. 881 __ popq(R15);
882 __ popq(R14); 882 __ popq(R14);
883 __ popq(R13); 883 __ popq(R13);
884 __ popq(R12); 884 __ popq(R12);
885 __ popq(RBX); 885 __ popq(RBX);
886 886
887 // Restore the frame pointer. 887 // Restore the frame pointer.
888 __ LeaveFrameWithPP(); 888 __ LeaveFrame();
889 889
890 __ ret(); 890 __ ret();
891 } 891 }
892 892
893 893
894 // Called for inline allocation of contexts. 894 // Called for inline allocation of contexts.
895 // Input: 895 // Input:
896 // R10: number of context variables. 896 // R10: number of context variables.
897 // Output: 897 // Output:
898 // RAX: new allocated RawContext object. 898 // RAX: new allocated RawContext object.
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
1002 // Create a stub frame. 1002 // Create a stub frame.
1003 __ EnterStubFrame(); 1003 __ EnterStubFrame();
1004 __ pushq(R12); // Setup space on stack for the return value. 1004 __ pushq(R12); // Setup space on stack for the return value.
1005 __ SmiTag(R10); 1005 __ SmiTag(R10);
1006 __ pushq(R10); // Push number of context variables. 1006 __ pushq(R10); // Push number of context variables.
1007 __ CallRuntime(kAllocateContextRuntimeEntry, 1); // Allocate context. 1007 __ CallRuntime(kAllocateContextRuntimeEntry, 1); // Allocate context.
1008 __ popq(RAX); // Pop number of context variables argument. 1008 __ popq(RAX); // Pop number of context variables argument.
1009 __ popq(RAX); // Pop the new context object. 1009 __ popq(RAX); // Pop the new context object.
1010 // RAX: new object 1010 // RAX: new object
1011 // Restore the frame pointer. 1011 // Restore the frame pointer.
1012 __ LeaveFrame(); 1012 __ LeaveStubFrame();
1013 __ ret(); 1013 __ ret();
1014 } 1014 }
1015 1015
1016 1016
1017 DECLARE_LEAF_RUNTIME_ENTRY(void, StoreBufferBlockProcess, Isolate* isolate); 1017 DECLARE_LEAF_RUNTIME_ENTRY(void, StoreBufferBlockProcess, Isolate* isolate);
1018 1018
1019 // Helper stub to implement Assembler::StoreIntoObject. 1019 // Helper stub to implement Assembler::StoreIntoObject.
1020 // Input parameters: 1020 // Input parameters:
1021 // RAX: Address being stored 1021 // RAX: Address being stored
1022 void StubCode::GenerateUpdateStoreBufferStub(Assembler* assembler) { 1022 void StubCode::GenerateUpdateStoreBufferStub(Assembler* assembler) {
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
1219 __ addq(RAX, Immediate(kHeapObjectTag)); 1219 __ addq(RAX, Immediate(kHeapObjectTag));
1220 __ ret(); 1220 __ ret();
1221 1221
1222 __ Bind(&slow_case); 1222 __ Bind(&slow_case);
1223 } 1223 }
1224 if (is_cls_parameterized) { 1224 if (is_cls_parameterized) {
1225 __ movq(RAX, Address(RSP, kObjectTypeArgumentsOffset)); 1225 __ movq(RAX, Address(RSP, kObjectTypeArgumentsOffset));
1226 __ movq(RDX, Address(RSP, kInstantiatorTypeArgumentsOffset)); 1226 __ movq(RDX, Address(RSP, kInstantiatorTypeArgumentsOffset));
1227 } 1227 }
1228 // Create a stub frame. 1228 // Create a stub frame.
1229 __ EnterStubFrameWithPP(); 1229 __ EnterStubFrame(true); // Uses PP to access class object.
1230 __ pushq(R12); // Setup space on stack for return value. 1230 __ pushq(R12); // Setup space on stack for return value.
1231 __ PushObject(cls, PP); // Push class of object to be allocated. 1231 __ PushObject(cls, PP); // Push class of object to be allocated.
1232 if (is_cls_parameterized) { 1232 if (is_cls_parameterized) {
1233 __ pushq(RAX); // Push type arguments of object to be allocated. 1233 __ pushq(RAX); // Push type arguments of object to be allocated.
1234 __ pushq(RDX); // Push type arguments of instantiator. 1234 __ pushq(RDX); // Push type arguments of instantiator.
1235 } else { 1235 } else {
1236 __ pushq(R12); // Push null type arguments. 1236 __ pushq(R12); // Push null type arguments.
1237 __ pushq(Immediate(Smi::RawValue(StubCode::kNoInstantiator))); 1237 __ pushq(Immediate(Smi::RawValue(StubCode::kNoInstantiator)));
1238 } 1238 }
1239 __ CallRuntime(kAllocateObjectRuntimeEntry, 3); // Allocate object. 1239 __ CallRuntime(kAllocateObjectRuntimeEntry, 3); // Allocate object.
1240 __ popq(RAX); // Pop argument (instantiator). 1240 __ popq(RAX); // Pop argument (instantiator).
1241 __ popq(RAX); // Pop argument (type arguments of object). 1241 __ popq(RAX); // Pop argument (type arguments of object).
1242 __ popq(RAX); // Pop argument (class of object). 1242 __ popq(RAX); // Pop argument (class of object).
1243 __ popq(RAX); // Pop result (newly allocated object). 1243 __ popq(RAX); // Pop result (newly allocated object).
1244 // RAX: new object 1244 // RAX: new object
1245 // Restore the frame pointer. 1245 // Restore the frame pointer.
1246 __ LeaveFrameWithPP(); 1246 __ LeaveStubFrame();
1247 __ ret(); 1247 __ ret();
1248 } 1248 }
1249 1249
1250 1250
1251 // Called for inline allocation of closures. 1251 // Called for inline allocation of closures.
1252 // Input parameters: 1252 // Input parameters:
1253 // RSP + 16 : receiver (null if not an implicit instance closure). 1253 // RSP + 16 : receiver (null if not an implicit instance closure).
1254 // RSP + 8 : type arguments object (null if class is not parameterized). 1254 // RSP + 8 : type arguments object (null if class is not parameterized).
1255 // RSP : points to return address. 1255 // RSP : points to return address.
1256 void StubCode::GenerateAllocationStubForClosure(Assembler* assembler, 1256 void StubCode::GenerateAllocationStubForClosure(Assembler* assembler,
1257 const Function& func) { 1257 const Function& func) {
1258 ASSERT(func.IsClosureFunction()); 1258 ASSERT(func.IsClosureFunction());
1259 ASSERT(!func.IsImplicitStaticClosureFunction()); 1259 ASSERT(!func.IsImplicitStaticClosureFunction());
1260 const bool is_implicit_instance_closure = 1260 const bool is_implicit_instance_closure =
1261 func.IsImplicitInstanceClosureFunction(); 1261 func.IsImplicitInstanceClosureFunction();
1262 const Class& cls = Class::ZoneHandle(func.signature_class()); 1262 const Class& cls = Class::ZoneHandle(func.signature_class());
1263 const bool has_type_arguments = cls.NumTypeArguments() > 0; 1263 const bool has_type_arguments = cls.NumTypeArguments() > 0;
1264 1264
1265 __ EnterStubFrameWithPP(); // Uses pool pointer to refer to function. 1265 __ EnterStubFrame(true); // Uses pool pointer to refer to function.
1266 __ LoadObject(R12, Object::null_object(), PP); 1266 __ LoadObject(R12, Object::null_object(), PP);
1267 const intptr_t kTypeArgumentsOffset = 4 * kWordSize; 1267 const intptr_t kTypeArgumentsOffset = 4 * kWordSize;
1268 const intptr_t kReceiverOffset = 5 * kWordSize; 1268 const intptr_t kReceiverOffset = 5 * kWordSize;
1269 const intptr_t closure_size = Closure::InstanceSize(); 1269 const intptr_t closure_size = Closure::InstanceSize();
1270 const intptr_t context_size = Context::InstanceSize(1); // Captured receiver. 1270 const intptr_t context_size = Context::InstanceSize(1); // Captured receiver.
1271 if (FLAG_inline_alloc && 1271 if (FLAG_inline_alloc &&
1272 Heap::IsAllocatableInNewSpace(closure_size + context_size)) { 1272 Heap::IsAllocatableInNewSpace(closure_size + context_size)) {
1273 Label slow_case; 1273 Label slow_case;
1274 Heap* heap = Isolate::Current()->heap(); 1274 Heap* heap = Isolate::Current()->heap();
1275 __ movq(RAX, Immediate(heap->TopAddress())); 1275 __ movq(RAX, Immediate(heap->TopAddress()));
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
1344 __ movq(Address(RAX, Closure::context_offset()), CTX); 1344 __ movq(Address(RAX, Closure::context_offset()), CTX);
1345 } 1345 }
1346 1346
1347 // Set the type arguments field in the newly allocated closure. 1347 // Set the type arguments field in the newly allocated closure.
1348 __ movq(R10, Address(RSP, kTypeArgumentsOffset)); 1348 __ movq(R10, Address(RSP, kTypeArgumentsOffset));
1349 __ movq(Address(RAX, Closure::type_arguments_offset()), R10); 1349 __ movq(Address(RAX, Closure::type_arguments_offset()), R10);
1350 1350
1351 // Done allocating and initializing the instance. 1351 // Done allocating and initializing the instance.
1352 // RAX: new object. 1352 // RAX: new object.
1353 __ addq(RAX, Immediate(kHeapObjectTag)); 1353 __ addq(RAX, Immediate(kHeapObjectTag));
1354 __ LeaveFrameWithPP(); 1354 __ LeaveStubFrame();
1355 __ ret(); 1355 __ ret();
1356 1356
1357 __ Bind(&slow_case); 1357 __ Bind(&slow_case);
1358 } 1358 }
1359 if (has_type_arguments) { 1359 if (has_type_arguments) {
1360 __ movq(RCX, Address(RSP, kTypeArgumentsOffset)); 1360 __ movq(RCX, Address(RSP, kTypeArgumentsOffset));
1361 } 1361 }
1362 if (is_implicit_instance_closure) { 1362 if (is_implicit_instance_closure) {
1363 __ movq(RAX, Address(RSP, kReceiverOffset)); 1363 __ movq(RAX, Address(RSP, kReceiverOffset));
1364 } 1364 }
(...skipping 14 matching lines...) Expand all
1379 __ popq(RAX); // Pop receiver. 1379 __ popq(RAX); // Pop receiver.
1380 } else { 1380 } else {
1381 ASSERT(func.IsNonImplicitClosureFunction()); 1381 ASSERT(func.IsNonImplicitClosureFunction());
1382 __ CallRuntime(kAllocateClosureRuntimeEntry, 2); 1382 __ CallRuntime(kAllocateClosureRuntimeEntry, 2);
1383 __ popq(RAX); // Pop type arguments. 1383 __ popq(RAX); // Pop type arguments.
1384 } 1384 }
1385 __ popq(RAX); // Pop the function object. 1385 __ popq(RAX); // Pop the function object.
1386 __ popq(RAX); // Pop the result. 1386 __ popq(RAX); // Pop the result.
1387 // RAX: New closure object. 1387 // RAX: New closure object.
1388 // Restore the calling frame. 1388 // Restore the calling frame.
1389 __ LeaveFrameWithPP(); 1389 __ LeaveStubFrame();
1390 __ ret(); 1390 __ ret();
1391 } 1391 }
1392 1392
1393 1393
1394 // Called for invoking "dynamic noSuchMethod(Invocation invocation)" function 1394 // Called for invoking "dynamic noSuchMethod(Invocation invocation)" function
1395 // from the entry code of a dart function after an error in passed argument 1395 // from the entry code of a dart function after an error in passed argument
1396 // name or number is detected. 1396 // name or number is detected.
1397 // Input parameters: 1397 // Input parameters:
1398 // RSP : points to return address. 1398 // RSP : points to return address.
1399 // RSP + 8 : address of last argument. 1399 // RSP + 8 : address of last argument.
1400 // RBX : ic-data. 1400 // RBX : ic-data.
1401 // R10 : arguments descriptor array. 1401 // R10 : arguments descriptor array.
1402 void StubCode::GenerateCallNoSuchMethodFunctionStub(Assembler* assembler) { 1402 void StubCode::GenerateCallNoSuchMethodFunctionStub(Assembler* assembler) {
1403 __ EnterStubFrame(); 1403 __ EnterStubFrame(true); // Uses PP to access null object.
1404 1404
1405 // Load the receiver. 1405 // Load the receiver.
1406 __ movq(R13, FieldAddress(R10, ArgumentsDescriptor::count_offset())); 1406 __ movq(R13, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
1407 __ movq(RAX, Address(RBP, R13, TIMES_4, kParamEndSlotFromFp * kWordSize)); 1407 __ movq(RAX, Address(RBP, R13, TIMES_4, kParamEndSlotFromFp * kWordSize));
1408 1408
1409 __ LoadObject(R12, Object::null_object(), PP); 1409 __ LoadObject(R12, Object::null_object(), PP);
1410 __ pushq(R12); // Setup space on stack for result from noSuchMethod. 1410 __ pushq(R12); // Setup space on stack for result from noSuchMethod.
1411 __ pushq(RAX); // Receiver. 1411 __ pushq(RAX); // Receiver.
1412 __ pushq(RBX); // IC data array. 1412 __ pushq(RBX); // IC data array.
1413 __ pushq(R10); // Arguments descriptor array. 1413 __ pushq(R10); // Arguments descriptor array.
1414 1414
1415 __ movq(R10, R13); // Smi-tagged arguments array length. 1415 __ movq(R10, R13); // Smi-tagged arguments array length.
1416 PushArgumentsArray(assembler); 1416 PushArgumentsArray(assembler);
1417 1417
1418 __ CallRuntime(kInvokeNoSuchMethodFunctionRuntimeEntry, 4); 1418 __ CallRuntime(kInvokeNoSuchMethodFunctionRuntimeEntry, 4);
1419 1419
1420 // Remove arguments. 1420 // Remove arguments.
1421 __ Drop(4); 1421 __ Drop(4);
1422 __ popq(RAX); // Get result into RAX. 1422 __ popq(RAX); // Get result into RAX.
1423 1423
1424 // Remove the stub frame as we are about to return. 1424 // Remove the stub frame as we are about to return.
1425 __ LeaveFrame(); 1425 __ LeaveStubFrame();
1426 __ ret(); 1426 __ ret();
1427 } 1427 }
1428 1428
1429 1429
1430 // Cannot use function object from ICData as it may be the inlined 1430 // Cannot use function object from ICData as it may be the inlined
1431 // function and not the top-scope function. 1431 // function and not the top-scope function.
1432 void StubCode::GenerateOptimizedUsageCounterIncrement(Assembler* assembler) { 1432 void StubCode::GenerateOptimizedUsageCounterIncrement(Assembler* assembler) {
1433 Register ic_reg = RBX; 1433 Register ic_reg = RBX;
1434 Register func_reg = RDI; 1434 Register func_reg = RDI;
1435 if (FLAG_trace_optimized_ic_calls) { 1435 if (FLAG_trace_optimized_ic_calls) {
1436 __ EnterStubFrame(); 1436 __ EnterStubFrame();
1437 __ pushq(func_reg); // Preserve 1437 __ pushq(func_reg); // Preserve
1438 __ pushq(ic_reg); // Preserve. 1438 __ pushq(ic_reg); // Preserve.
1439 __ pushq(ic_reg); // Argument. 1439 __ pushq(ic_reg); // Argument.
1440 __ pushq(func_reg); // Argument. 1440 __ pushq(func_reg); // Argument.
1441 __ CallRuntime(kTraceICCallRuntimeEntry, 2); 1441 __ CallRuntime(kTraceICCallRuntimeEntry, 2);
1442 __ popq(RAX); // Discard argument; 1442 __ popq(RAX); // Discard argument;
1443 __ popq(RAX); // Discard argument; 1443 __ popq(RAX); // Discard argument;
1444 __ popq(ic_reg); // Restore. 1444 __ popq(ic_reg); // Restore.
1445 __ popq(func_reg); // Restore. 1445 __ popq(func_reg); // Restore.
1446 __ LeaveFrame(); 1446 __ LeaveStubFrame();
1447 } 1447 }
1448 __ incq(FieldAddress(func_reg, Function::usage_counter_offset())); 1448 __ incq(FieldAddress(func_reg, Function::usage_counter_offset()));
1449 } 1449 }
1450 1450
1451 1451
1452 // Loads function into 'temp_reg', preserves 'ic_reg'. 1452 // Loads function into 'temp_reg', preserves 'ic_reg'.
1453 void StubCode::GenerateUsageCounterIncrement(Assembler* assembler, 1453 void StubCode::GenerateUsageCounterIncrement(Assembler* assembler,
1454 Register temp_reg) { 1454 Register temp_reg) {
1455 Register ic_reg = RBX; 1455 Register ic_reg = RBX;
1456 Register func_reg = temp_reg; 1456 Register func_reg = temp_reg;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1490 // Check single stepping. 1490 // Check single stepping.
1491 Label not_stepping; 1491 Label not_stepping;
1492 __ movq(RAX, FieldAddress(CTX, Context::isolate_offset())); 1492 __ movq(RAX, FieldAddress(CTX, Context::isolate_offset()));
1493 __ movzxb(RAX, Address(RAX, Isolate::single_step_offset())); 1493 __ movzxb(RAX, Address(RAX, Isolate::single_step_offset()));
1494 __ cmpq(RAX, Immediate(0)); 1494 __ cmpq(RAX, Immediate(0));
1495 __ j(EQUAL, &not_stepping, Assembler::kNearJump); 1495 __ j(EQUAL, &not_stepping, Assembler::kNearJump);
1496 __ EnterStubFrame(); 1496 __ EnterStubFrame();
1497 __ pushq(RBX); 1497 __ pushq(RBX);
1498 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); 1498 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0);
1499 __ popq(RBX); 1499 __ popq(RBX);
1500 __ LeaveFrame(); 1500 __ LeaveStubFrame();
1501 __ Bind(&not_stepping); 1501 __ Bind(&not_stepping);
1502 1502
1503 // Load arguments descriptor into R10. 1503 // Load arguments descriptor into R10.
1504 __ movq(R10, FieldAddress(RBX, ICData::arguments_descriptor_offset())); 1504 __ movq(R10, FieldAddress(RBX, ICData::arguments_descriptor_offset()));
1505 // Loop that checks if there is an IC data match. 1505 // Loop that checks if there is an IC data match.
1506 Label loop, update, test, found, get_class_id_as_smi; 1506 Label loop, update, test, found, get_class_id_as_smi;
1507 // RBX: IC data object (preserved). 1507 // RBX: IC data object (preserved).
1508 __ movq(R12, FieldAddress(RBX, ICData::ic_data_offset())); 1508 __ movq(R12, FieldAddress(RBX, ICData::ic_data_offset()));
1509 // R12: ic_data_array with check entries: classes and target functions. 1509 // R12: ic_data_array with check entries: classes and target functions.
1510 __ leaq(R12, FieldAddress(R12, Array::data_offset())); 1510 __ leaq(R12, FieldAddress(R12, Array::data_offset()));
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1571 } 1571 }
1572 __ pushq(RBX); // Pass IC data object. 1572 __ pushq(RBX); // Pass IC data object.
1573 __ CallRuntime(handle_ic_miss, num_args + 1); 1573 __ CallRuntime(handle_ic_miss, num_args + 1);
1574 // Remove the call arguments pushed earlier, including the IC data object. 1574 // Remove the call arguments pushed earlier, including the IC data object.
1575 for (intptr_t i = 0; i < num_args + 1; i++) { 1575 for (intptr_t i = 0; i < num_args + 1; i++) {
1576 __ popq(RAX); 1576 __ popq(RAX);
1577 } 1577 }
1578 __ popq(RAX); // Pop returned code object into RAX (null if not found). 1578 __ popq(RAX); // Pop returned code object into RAX (null if not found).
1579 __ popq(RBX); // Restore IC data array. 1579 __ popq(RBX); // Restore IC data array.
1580 __ popq(R10); // Restore arguments descriptor array. 1580 __ popq(R10); // Restore arguments descriptor array.
1581 __ LeaveFrame(); 1581 __ LeaveStubFrame();
1582 Label call_target_function; 1582 Label call_target_function;
1583 __ cmpq(RAX, R12); 1583 __ cmpq(RAX, R12);
1584 __ j(NOT_EQUAL, &call_target_function, Assembler::kNearJump); 1584 __ j(NOT_EQUAL, &call_target_function, Assembler::kNearJump);
1585 // NoSuchMethod or closure. 1585 // NoSuchMethod or closure.
1586 // Mark IC call that it may be a closure call that does not collect 1586 // Mark IC call that it may be a closure call that does not collect
1587 // type feedback. 1587 // type feedback.
1588 __ movb(FieldAddress(RBX, ICData::is_closure_call_offset()), Immediate(1)); 1588 __ movb(FieldAddress(RBX, ICData::is_closure_call_offset()), Immediate(1));
1589 __ jmp(&StubCode::InstanceFunctionLookupLabel()); 1589 __ jmp(&StubCode::InstanceFunctionLookupLabel());
1590 1590
1591 __ Bind(&found); 1591 __ Bind(&found);
(...skipping 15 matching lines...) Expand all
1607 __ CompareObject(RCX, Object::null_object(), PP); 1607 __ CompareObject(RCX, Object::null_object(), PP);
1608 __ j(NOT_EQUAL, &is_compiled, Assembler::kNearJump); 1608 __ j(NOT_EQUAL, &is_compiled, Assembler::kNearJump);
1609 __ EnterStubFrame(); 1609 __ EnterStubFrame();
1610 __ pushq(R10); // Preserve arguments descriptor array. 1610 __ pushq(R10); // Preserve arguments descriptor array.
1611 __ pushq(RBX); // Preserve IC data object. 1611 __ pushq(RBX); // Preserve IC data object.
1612 __ pushq(RAX); // Pass function. 1612 __ pushq(RAX); // Pass function.
1613 __ CallRuntime(kCompileFunctionRuntimeEntry, 1); 1613 __ CallRuntime(kCompileFunctionRuntimeEntry, 1);
1614 __ popq(RAX); // Restore function. 1614 __ popq(RAX); // Restore function.
1615 __ popq(RBX); // Restore IC data array. 1615 __ popq(RBX); // Restore IC data array.
1616 __ popq(R10); // Restore arguments descriptor array. 1616 __ popq(R10); // Restore arguments descriptor array.
1617 __ LeaveFrame(); 1617 __ LeaveStubFrame();
1618 __ movq(RCX, FieldAddress(RAX, Function::code_offset())); 1618 __ movq(RCX, FieldAddress(RAX, Function::code_offset()));
1619 __ Bind(&is_compiled); 1619 __ Bind(&is_compiled);
1620 } 1620 }
1621 __ movq(RAX, FieldAddress(RCX, Code::instructions_offset())); 1621 __ movq(RAX, FieldAddress(RCX, Code::instructions_offset()));
1622 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); 1622 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
1623 __ jmp(RAX); 1623 __ jmp(RAX);
1624 1624
1625 __ Bind(&get_class_id_as_smi); 1625 __ Bind(&get_class_id_as_smi);
1626 Label not_smi; 1626 Label not_smi;
1627 // Test if Smi -> load Smi class for comparison. 1627 // Test if Smi -> load Smi class for comparison.
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
1737 // Check single stepping. 1737 // Check single stepping.
1738 Label not_stepping; 1738 Label not_stepping;
1739 __ movq(RAX, FieldAddress(CTX, Context::isolate_offset())); 1739 __ movq(RAX, FieldAddress(CTX, Context::isolate_offset()));
1740 __ movzxb(RAX, Address(RAX, Isolate::single_step_offset())); 1740 __ movzxb(RAX, Address(RAX, Isolate::single_step_offset()));
1741 __ cmpq(RAX, Immediate(0)); 1741 __ cmpq(RAX, Immediate(0));
1742 __ j(EQUAL, &not_stepping, Assembler::kNearJump); 1742 __ j(EQUAL, &not_stepping, Assembler::kNearJump);
1743 __ EnterStubFrame(); 1743 __ EnterStubFrame();
1744 __ pushq(RBX); // Preserve IC data object. 1744 __ pushq(RBX); // Preserve IC data object.
1745 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); 1745 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0);
1746 __ popq(RBX); 1746 __ popq(RBX);
1747 __ LeaveFrame(); 1747 __ LeaveStubFrame();
1748 __ Bind(&not_stepping); 1748 __ Bind(&not_stepping);
1749 1749
1750 // RBX: IC data object (preserved). 1750 // RBX: IC data object (preserved).
1751 __ movq(R12, FieldAddress(RBX, ICData::ic_data_offset())); 1751 __ movq(R12, FieldAddress(RBX, ICData::ic_data_offset()));
1752 // R12: ic_data_array with entries: target functions and count. 1752 // R12: ic_data_array with entries: target functions and count.
1753 __ leaq(R12, FieldAddress(R12, Array::data_offset())); 1753 __ leaq(R12, FieldAddress(R12, Array::data_offset()));
1754 // R12: points directly to the first ic data array element. 1754 // R12: points directly to the first ic data array element.
1755 const intptr_t target_offset = ICData::TargetIndexFor(0) * kWordSize; 1755 const intptr_t target_offset = ICData::TargetIndexFor(0) * kWordSize;
1756 const intptr_t count_offset = ICData::CountIndexFor(0) * kWordSize; 1756 const intptr_t count_offset = ICData::CountIndexFor(0) * kWordSize;
1757 1757
(...skipping 14 matching lines...) Expand all
1772 __ j(NOT_EQUAL, &target_is_compiled, Assembler::kNearJump); 1772 __ j(NOT_EQUAL, &target_is_compiled, Assembler::kNearJump);
1773 1773
1774 __ EnterStubFrame(); 1774 __ EnterStubFrame();
1775 __ pushq(R13); // Preserve target function. 1775 __ pushq(R13); // Preserve target function.
1776 __ pushq(RBX); // Preserve IC data object. 1776 __ pushq(RBX); // Preserve IC data object.
1777 __ pushq(R13); // Pass function. 1777 __ pushq(R13); // Pass function.
1778 __ CallRuntime(kCompileFunctionRuntimeEntry, 1); 1778 __ CallRuntime(kCompileFunctionRuntimeEntry, 1);
1779 __ popq(RAX); // Discard argument. 1779 __ popq(RAX); // Discard argument.
1780 __ popq(RBX); // Restore IC data object. 1780 __ popq(RBX); // Restore IC data object.
1781 __ popq(R13); // Restore target function. 1781 __ popq(R13); // Restore target function.
1782 __ LeaveFrame(); 1782 __ LeaveStubFrame();
1783 __ movq(RAX, FieldAddress(R13, Function::code_offset())); 1783 __ movq(RAX, FieldAddress(R13, Function::code_offset()));
1784 1784
1785 __ Bind(&target_is_compiled); 1785 __ Bind(&target_is_compiled);
1786 // RAX: Target code. 1786 // RAX: Target code.
1787 __ movq(RAX, FieldAddress(RAX, Code::instructions_offset())); 1787 __ movq(RAX, FieldAddress(RAX, Code::instructions_offset()));
1788 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); 1788 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
1789 // Load arguments descriptor into R10. 1789 // Load arguments descriptor into R10.
1790 __ movq(R10, FieldAddress(RBX, ICData::arguments_descriptor_offset())); 1790 __ movq(R10, FieldAddress(RBX, ICData::arguments_descriptor_offset()));
1791 __ jmp(RAX); 1791 __ jmp(RAX);
1792 } 1792 }
(...skipping 12 matching lines...) Expand all
1805 // RAX: Function. 1805 // RAX: Function.
1806 void StubCode::GenerateCompileFunctionRuntimeCallStub(Assembler* assembler) { 1806 void StubCode::GenerateCompileFunctionRuntimeCallStub(Assembler* assembler) {
1807 __ EnterStubFrame(); 1807 __ EnterStubFrame();
1808 __ pushq(RDX); // Preserve arguments descriptor array. 1808 __ pushq(RDX); // Preserve arguments descriptor array.
1809 __ pushq(RCX); // Preserve IC data object. 1809 __ pushq(RCX); // Preserve IC data object.
1810 __ pushq(RAX); // Pass function. 1810 __ pushq(RAX); // Pass function.
1811 __ CallRuntime(kCompileFunctionRuntimeEntry, 1); 1811 __ CallRuntime(kCompileFunctionRuntimeEntry, 1);
1812 __ popq(RAX); // Restore function. 1812 __ popq(RAX); // Restore function.
1813 __ popq(RCX); // Restore IC data array. 1813 __ popq(RCX); // Restore IC data array.
1814 __ popq(RDX); // Restore arguments descriptor array. 1814 __ popq(RDX); // Restore arguments descriptor array.
1815 __ LeaveFrame(); 1815 __ LeaveStubFrame();
1816 __ ret(); 1816 __ ret();
1817 } 1817 }
1818 1818
1819 1819
1820 // RBX, R10: May contain arguments to runtime stub. 1820 // RBX, R10: May contain arguments to runtime stub.
1821 // TOS(0): return address (Dart code). 1821 // TOS(0): return address (Dart code).
1822 void StubCode::GenerateBreakpointRuntimeStub(Assembler* assembler) { 1822 void StubCode::GenerateBreakpointRuntimeStub(Assembler* assembler) {
1823 __ EnterStubFrame(); 1823 __ EnterStubFrame(true); // Uses PP to access null object.
1824 // Preserve runtime args. 1824 // Preserve runtime args.
1825 __ pushq(RBX); 1825 __ pushq(RBX);
1826 __ pushq(R10); 1826 __ pushq(R10);
1827 // Room for result. Debugger stub returns address of the 1827 // Room for result. Debugger stub returns address of the
1828 // unpatched runtime stub. 1828 // unpatched runtime stub.
1829 __ LoadObject(R12, Object::null_object(), PP); 1829 __ LoadObject(R12, Object::null_object(), PP);
1830 __ pushq(R12); // Room for result. 1830 __ pushq(R12); // Room for result.
1831 __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0); 1831 __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0);
1832 __ popq(RAX); // Address of original. 1832 __ popq(RAX); // Address of original.
1833 __ popq(R10); // Restore arguments. 1833 __ popq(R10); // Restore arguments.
1834 __ popq(RBX); 1834 __ popq(RBX);
1835 __ LeaveFrame(); 1835 __ LeaveStubFrame();
1836 __ jmp(RAX); // Jump to original stub. 1836 __ jmp(RAX); // Jump to original stub.
1837 } 1837 }
1838 1838
1839 1839
1840 // RBX: ICData (unoptimized static call) 1840 // RBX: ICData (unoptimized static call)
1841 // TOS(0): return address (Dart code). 1841 // TOS(0): return address (Dart code).
1842 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) { 1842 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) {
1843 __ EnterStubFrame(); 1843 __ EnterStubFrame(true); // Uses PP to access null object.
1844 __ LoadObject(R12, Object::null_object(), PP); 1844 __ LoadObject(R12, Object::null_object(), PP);
1845 __ pushq(RBX); // Preserve IC data for unoptimized call. 1845 __ pushq(RBX); // Preserve IC data for unoptimized call.
1846 __ pushq(R12); // Room for result. 1846 __ pushq(R12); // Room for result.
1847 __ CallRuntime(kBreakpointStaticHandlerRuntimeEntry, 0); 1847 __ CallRuntime(kBreakpointStaticHandlerRuntimeEntry, 0);
1848 __ popq(RAX); // Code object. 1848 __ popq(RAX); // Code object.
1849 __ popq(RBX); // Restore IC data. 1849 __ popq(RBX); // Restore IC data.
1850 __ LeaveFrame(); 1850 __ LeaveStubFrame();
1851 1851
1852 // Load arguments descriptor into R10. 1852 // Load arguments descriptor into R10.
1853 __ movq(R10, FieldAddress(RBX, ICData::arguments_descriptor_offset())); 1853 __ movq(R10, FieldAddress(RBX, ICData::arguments_descriptor_offset()));
1854 // Now call the static function. The breakpoint handler function 1854 // Now call the static function. The breakpoint handler function
1855 // ensures that the call target is compiled. 1855 // ensures that the call target is compiled.
1856 __ movq(RBX, FieldAddress(RAX, Code::instructions_offset())); 1856 __ movq(RBX, FieldAddress(RAX, Code::instructions_offset()));
1857 __ addq(RBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); 1857 __ addq(RBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
1858 __ jmp(RBX); 1858 __ jmp(RBX);
1859 } 1859 }
1860 1860
1861 1861
1862 // TOS(0): return address (Dart code). 1862 // TOS(0): return address (Dart code).
1863 void StubCode::GenerateBreakpointReturnStub(Assembler* assembler) { 1863 void StubCode::GenerateBreakpointReturnStub(Assembler* assembler) {
1864 __ EnterStubFrame(); 1864 __ EnterStubFrame();
1865 __ pushq(RAX); 1865 __ pushq(RAX);
1866 __ CallRuntime(kBreakpointReturnHandlerRuntimeEntry, 0); 1866 __ CallRuntime(kBreakpointReturnHandlerRuntimeEntry, 0);
1867 __ popq(RAX); 1867 __ popq(RAX);
1868 __ LeaveFrame(); 1868 __ LeaveStubFrame();
1869 1869
1870 __ popq(R11); // discard return address of call to this stub. 1870 __ popq(R11); // discard return address of call to this stub.
1871 __ LeaveFrameWithPP(); 1871 __ LeaveDartFrame();
1872 __ ret(); 1872 __ ret();
1873 } 1873 }
1874 1874
1875 1875
1876 // RBX: Inline cache data array. 1876 // RBX: Inline cache data array.
1877 // TOS(0): return address (Dart code). 1877 // TOS(0): return address (Dart code).
1878 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) { 1878 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) {
1879 __ EnterStubFrame(); 1879 __ EnterStubFrame();
1880 __ pushq(RBX); 1880 __ pushq(RBX);
1881 __ CallRuntime(kBreakpointDynamicHandlerRuntimeEntry, 0); 1881 __ CallRuntime(kBreakpointDynamicHandlerRuntimeEntry, 0);
1882 __ popq(RBX); 1882 __ popq(RBX);
1883 __ LeaveFrame(); 1883 __ LeaveStubFrame();
1884 1884
1885 // Find out which dispatch stub to call. 1885 // Find out which dispatch stub to call.
1886 Label test_two, test_three, test_four; 1886 Label test_two, test_three, test_four;
1887 __ movq(RCX, FieldAddress(RBX, ICData::num_args_tested_offset())); 1887 __ movq(RCX, FieldAddress(RBX, ICData::num_args_tested_offset()));
1888 __ cmpq(RCX, Immediate(1)); 1888 __ cmpq(RCX, Immediate(1));
1889 __ j(NOT_EQUAL, &test_two, Assembler::kNearJump); 1889 __ j(NOT_EQUAL, &test_two, Assembler::kNearJump);
1890 __ jmp(&StubCode::OneArgCheckInlineCacheLabel()); 1890 __ jmp(&StubCode::OneArgCheckInlineCacheLabel());
1891 __ Bind(&test_two); 1891 __ Bind(&test_two);
1892 __ cmpl(RCX, Immediate(2)); 1892 __ cmpl(RCX, Immediate(2));
1893 __ j(NOT_EQUAL, &test_three, Assembler::kNearJump); 1893 __ j(NOT_EQUAL, &test_three, Assembler::kNearJump);
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
2035 __ movq(kExceptionObjectReg, RCX); // exception object. 2035 __ movq(kExceptionObjectReg, RCX); // exception object.
2036 __ movq(RSP, RSI); // target stack_pointer. 2036 __ movq(RSP, RSI); // target stack_pointer.
2037 __ jmp(RDI); // Jump to the exception handler code. 2037 __ jmp(RDI); // Jump to the exception handler code.
2038 } 2038 }
2039 2039
2040 2040
2041 // Calls to the runtime to optimize the given function. 2041 // Calls to the runtime to optimize the given function.
2042 // RDI: function to be reoptimized. 2042 // RDI: function to be reoptimized.
2043 // R10: argument descriptor (preserved). 2043 // R10: argument descriptor (preserved).
2044 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) { 2044 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) {
2045 __ EnterStubFrameWithPP(); 2045 __ EnterStubFrame(true); // Uses PP to access null object.
2046 __ LoadObject(R12, Object::null_object(), PP); 2046 __ LoadObject(R12, Object::null_object(), PP);
2047 __ pushq(R10); 2047 __ pushq(R10);
2048 __ pushq(R12); // Setup space on stack for return value. 2048 __ pushq(R12); // Setup space on stack for return value.
2049 __ pushq(RDI); 2049 __ pushq(RDI);
2050 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1); 2050 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1);
2051 __ popq(RAX); // Disard argument. 2051 __ popq(RAX); // Disard argument.
2052 __ popq(RAX); // Get Code object. 2052 __ popq(RAX); // Get Code object.
2053 __ popq(R10); // Restore argument descriptor. 2053 __ popq(R10); // Restore argument descriptor.
2054 __ movq(RAX, FieldAddress(RAX, Code::instructions_offset())); 2054 __ movq(RAX, FieldAddress(RAX, Code::instructions_offset()));
2055 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); 2055 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
2056 __ LeaveFrameWithPP(); 2056 __ LeaveStubFrame();
2057 __ jmp(RAX); 2057 __ jmp(RAX);
2058 __ int3(); 2058 __ int3();
2059 } 2059 }
2060 2060
2061 2061
2062 DECLARE_LEAF_RUNTIME_ENTRY(intptr_t, 2062 DECLARE_LEAF_RUNTIME_ENTRY(intptr_t,
2063 BigintCompare, 2063 BigintCompare,
2064 RawBigint* left, 2064 RawBigint* left,
2065 RawBigint* right); 2065 RawBigint* right);
2066 2066
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
2132 void StubCode::GenerateUnoptimizedIdenticalWithNumberCheckStub( 2132 void StubCode::GenerateUnoptimizedIdenticalWithNumberCheckStub(
2133 Assembler* assembler) { 2133 Assembler* assembler) {
2134 // Check single stepping. 2134 // Check single stepping.
2135 Label not_stepping; 2135 Label not_stepping;
2136 __ movq(RAX, FieldAddress(CTX, Context::isolate_offset())); 2136 __ movq(RAX, FieldAddress(CTX, Context::isolate_offset()));
2137 __ movzxb(RAX, Address(RAX, Isolate::single_step_offset())); 2137 __ movzxb(RAX, Address(RAX, Isolate::single_step_offset()));
2138 __ cmpq(RAX, Immediate(0)); 2138 __ cmpq(RAX, Immediate(0));
2139 __ j(EQUAL, &not_stepping, Assembler::kNearJump); 2139 __ j(EQUAL, &not_stepping, Assembler::kNearJump);
2140 __ EnterStubFrame(); 2140 __ EnterStubFrame();
2141 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); 2141 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0);
2142 __ LeaveFrame(); 2142 __ LeaveStubFrame();
2143 __ Bind(&not_stepping); 2143 __ Bind(&not_stepping);
2144 2144
2145 const Register left = RAX; 2145 const Register left = RAX;
2146 const Register right = RDX; 2146 const Register right = RDX;
2147 2147
2148 __ movq(left, Address(RSP, 2 * kWordSize)); 2148 __ movq(left, Address(RSP, 2 * kWordSize));
2149 __ movq(right, Address(RSP, 1 * kWordSize)); 2149 __ movq(right, Address(RSP, 1 * kWordSize));
2150 GenerateIdenticalWithNumberCheckStub(assembler, left, right); 2150 GenerateIdenticalWithNumberCheckStub(assembler, left, right);
2151 __ ret(); 2151 __ ret();
2152 } 2152 }
(...skipping 16 matching lines...) Expand all
2169 __ movq(right, Address(RSP, 3 * kWordSize)); 2169 __ movq(right, Address(RSP, 3 * kWordSize));
2170 GenerateIdenticalWithNumberCheckStub(assembler, left, right); 2170 GenerateIdenticalWithNumberCheckStub(assembler, left, right);
2171 __ popq(right); 2171 __ popq(right);
2172 __ popq(left); 2172 __ popq(left);
2173 __ ret(); 2173 __ ret();
2174 } 2174 }
2175 2175
2176 } // namespace dart 2176 } // namespace dart
2177 2177
2178 #endif // defined TARGET_ARCH_X64 2178 #endif // defined TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698