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

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

Issue 22825023: Uses an object pool on x64 (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« runtime/vm/assembler_x64.cc ('K') | « runtime/vm/stack_frame_x64.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/globals.h" 5 #include "vm/globals.h"
6 #if defined(TARGET_ARCH_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 312 matching lines...) Expand 10 before | Expand all | Expand 10 after
323 } 323 }
324 324
325 325
326 // Input parameters: 326 // Input parameters:
327 // RBX: ic-data. 327 // RBX: ic-data.
328 // R10: arguments descriptor array. 328 // R10: arguments descriptor array.
329 // Note: The receiver object is the first argument to the function being 329 // Note: The receiver object is the first argument to the function being
330 // called, the stub accesses the receiver from this location directly 330 // called, the stub accesses the receiver from this location directly
331 // when trying to resolve the call. 331 // when trying to resolve the call.
332 void StubCode::GenerateInstanceFunctionLookupStub(Assembler* assembler) { 332 void StubCode::GenerateInstanceFunctionLookupStub(Assembler* assembler) {
333 __ EnterStubFrame(); 333 __ EnterStubFrame(true);
334 334
335 const Immediate& raw_null = 335 const Immediate& raw_null =
336 Immediate(reinterpret_cast<intptr_t>(Object::null())); 336 Immediate(reinterpret_cast<intptr_t>(Object::null()));
337 __ pushq(raw_null); // Space for the return value. 337 __ pushq(raw_null); // Space for the return value.
338 338
339 // Push the receiver as an argument. Load the smi-tagged argument 339 // Push the receiver as an argument. Load the smi-tagged argument
340 // count into R13 to index the receiver in the stack. There are 340 // count into R13 to index the receiver in the stack. There are
341 // three words (null, stub's pc marker, saved fp) above the return 341 // four words (null, stub's pc marker, saved pp, saved fp) above the return
342 // address. 342 // address.
343 __ movq(R13, FieldAddress(R10, ArgumentsDescriptor::count_offset())); 343 __ movq(R13, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
344 __ pushq(Address(RSP, R13, TIMES_4, (3 * kWordSize))); 344 __ pushq(Address(RSP, R13, TIMES_4, (4 * kWordSize)));
345 345
346 __ pushq(RBX); // Pass IC data object. 346 __ pushq(RBX); // Pass IC data object.
347 __ pushq(R10); // Pass arguments descriptor array. 347 __ pushq(R10); // Pass arguments descriptor array.
348 348
349 // Pass the call's arguments array. 349 // Pass the call's arguments array.
350 __ movq(R10, R13); // Smi-tagged arguments array length. 350 __ movq(R10, R13); // Smi-tagged arguments array length.
351 PushArgumentsArray(assembler); 351 PushArgumentsArray(assembler);
352 352
353 __ CallRuntime(kInstanceFunctionLookupRuntimeEntry); 353 __ CallRuntime(kInstanceFunctionLookupRuntimeEntry);
354 354
355 // Remove arguments. 355 // Remove arguments.
356 __ Drop(4); 356 __ Drop(4);
357 __ popq(RAX); // Get result into RAX. 357 __ popq(RAX); // Get result into RAX.
358 __ LeaveFrame(); 358 __ LeaveFrame(true);
359 __ ret(); 359 __ ret();
360 } 360 }
361 361
362 362
363 DECLARE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame, 363 DECLARE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame,
364 intptr_t deopt_reason, 364 intptr_t deopt_reason,
365 uword saved_registers_address); 365 uword saved_registers_address);
366 366
367 DECLARE_LEAF_RUNTIME_ENTRY(void, DeoptimizeFillFrame, uword last_fp); 367 DECLARE_LEAF_RUNTIME_ENTRY(void, DeoptimizeFillFrame, uword last_fp);
368 368
369 369
370 // Used by eager and lazy deoptimization. Preserve result in RAX if necessary. 370 // Used by eager and lazy deoptimization. Preserve result in RAX if necessary.
371 // This stub translates optimized frame into unoptimized frame. The optimized 371 // This stub translates optimized frame into unoptimized frame. The optimized
372 // frame can contain values in registers and on stack, the unoptimized 372 // frame can contain values in registers and on stack, the unoptimized
373 // frame contains all values on stack. 373 // frame contains all values on stack.
374 // Deoptimization occurs in following steps: 374 // Deoptimization occurs in following steps:
375 // - Push all registers that can contain values. 375 // - Push all registers that can contain values.
376 // - Call C routine to copy the stack and saved registers into temporary buffer. 376 // - Call C routine to copy the stack and saved registers into temporary buffer.
377 // - Adjust caller's frame to correct unoptimized frame size. 377 // - Adjust caller's frame to correct unoptimized frame size.
378 // - Fill the unoptimized frame. 378 // - Fill the unoptimized frame.
379 // - Materialize objects that require allocation (e.g. Double instances). 379 // - Materialize objects that require allocation (e.g. Double instances).
380 // GC can occur only after frame is fully rewritten. 380 // GC can occur only after frame is fully rewritten.
381 // Stack after EnterDartFrame(0) below: 381 // Stack after EnterDartFrame(0) below:
382 // +------------------+ 382 // +------------------+
383 // | Saved PP | <- PP
384 // +------------------+
383 // | PC marker | <- TOS 385 // | PC marker | <- TOS
384 // +------------------+ 386 // +------------------+
385 // | Saved FP | <- FP of stub 387 // | Saved FP | <- FP of stub
386 // +------------------+ 388 // +------------------+
387 // | return-address | (deoptimization point) 389 // | return-address | (deoptimization point)
388 // +------------------+ 390 // +------------------+
389 // | ... | <- SP of optimized frame 391 // | ... | <- SP of optimized frame
390 // 392 //
391 // Parts of the code cannot GC, part of the code can GC. 393 // Parts of the code cannot GC, part of the code can GC.
392 static void GenerateDeoptimizationSequence(Assembler* assembler, 394 static void GenerateDeoptimizationSequence(Assembler* assembler,
393 bool preserve_result) { 395 bool preserve_result) {
394 // Leaf runtime function DeoptimizeCopyFrame expects a Dart frame. 396 // DeoptimizeCopyFrame expects a Dart frame, i.e. EnterDartFrame(0), but there
395 __ EnterDartFrame(0); 397 // is no need to set the correct PC marker or load PP, since they get patched.
398 __ EnterFrame(0);
399 __ pushq(Immediate(0));
400 __ pushq(PP);
401
396 // The code in this frame may not cause GC. kDeoptimizeCopyFrameRuntimeEntry 402 // The code in this frame may not cause GC. kDeoptimizeCopyFrameRuntimeEntry
397 // and kDeoptimizeFillFrameRuntimeEntry are leaf runtime calls. 403 // and kDeoptimizeFillFrameRuntimeEntry are leaf runtime calls.
398 const intptr_t saved_result_slot_from_fp = 404 const intptr_t saved_result_slot_from_fp =
399 kFirstLocalSlotFromFp + 1 - (kNumberOfCpuRegisters - RAX); 405 kFirstLocalSlotFromFp + 1 - (kNumberOfCpuRegisters - RAX);
400 // Result in RAX is preserved as part of pushing all registers below. 406 // Result in RAX is preserved as part of pushing all registers below.
401 407
402 // Push registers in their enumeration order: lowest register number at 408 // Push registers in their enumeration order: lowest register number at
403 // lowest address. 409 // lowest address.
404 for (intptr_t i = kNumberOfCpuRegisters - 1; i >= 0; i--) { 410 for (intptr_t i = kNumberOfCpuRegisters - 1; i >= 0; i--) {
405 __ pushq(static_cast<Register>(i)); 411 __ pushq(static_cast<Register>(i));
406 } 412 }
407 __ subq(RSP, Immediate(kNumberOfXmmRegisters * kFpuRegisterSize)); 413 __ subq(RSP, Immediate(kNumberOfXmmRegisters * kFpuRegisterSize));
408 intptr_t offset = 0; 414 intptr_t offset = 0;
409 for (intptr_t reg_idx = 0; reg_idx < kNumberOfXmmRegisters; ++reg_idx) { 415 for (intptr_t reg_idx = 0; reg_idx < kNumberOfXmmRegisters; ++reg_idx) {
410 XmmRegister xmm_reg = static_cast<XmmRegister>(reg_idx); 416 XmmRegister xmm_reg = static_cast<XmmRegister>(reg_idx);
411 __ movups(Address(RSP, offset), xmm_reg); 417 __ movups(Address(RSP, offset), xmm_reg);
412 offset += kFpuRegisterSize; 418 offset += kFpuRegisterSize;
413 } 419 }
414 420
415 __ movq(RDI, RSP); // Pass address of saved registers block. 421 __ movq(RDI, RSP); // Pass address of saved registers block.
416 __ ReserveAlignedFrameSpace(0); 422 __ ReserveAlignedFrameSpace(0);
417 __ CallRuntime(kDeoptimizeCopyFrameRuntimeEntry); 423 __ CallRuntime(kDeoptimizeCopyFrameRuntimeEntry);
418 // Result (RAX) is stack-size (FP - SP) in bytes. 424 // Result (RAX) is stack-size (FP - SP) in bytes.
419 425
420 if (preserve_result) { 426 if (preserve_result) {
421 // Restore result into RBX temporarily. 427 // Restore result into RBX temporarily.
422 __ movq(RBX, Address(RBP, saved_result_slot_from_fp * kWordSize)); 428 __ movq(RBX, Address(RBP, saved_result_slot_from_fp * kWordSize));
423 } 429 }
424 430
425 __ LeaveFrame(); 431 __ LeaveFrame(true);
426 __ popq(RCX); // Preserve return address. 432 __ popq(RCX); // Preserve return address.
427 __ movq(RSP, RBP); // Discard optimized frame. 433 __ movq(RSP, RBP); // Discard optimized frame.
428 __ subq(RSP, RAX); // Reserve space for deoptimized frame. 434 __ subq(RSP, RAX); // Reserve space for deoptimized frame.
429 __ pushq(RCX); // Restore return address. 435 __ pushq(RCX); // Restore return address.
430 436
431 // Leaf runtime function DeoptimizeFillFrame expects a Dart frame. 437 // DeoptimizeFillFrame expects a Dart frame, i.e. EnterDartFrame(0), but there
432 __ EnterDartFrame(0); 438 // is no need to set the correct PC marker or load PP, since they get patched.
439 __ EnterFrame(0);
440 __ pushq(Immediate(0));
441 __ pushq(PP);
442
433 if (preserve_result) { 443 if (preserve_result) {
434 __ pushq(RBX); // Preserve result as first local. 444 __ pushq(RBX); // Preserve result as first local.
435 } 445 }
436 __ ReserveAlignedFrameSpace(0); 446 __ ReserveAlignedFrameSpace(0);
437 __ movq(RDI, RBP); // Pass last FP as parameter in RDI. 447 __ movq(RDI, RBP); // Pass last FP as parameter in RDI.
438 __ CallRuntime(kDeoptimizeFillFrameRuntimeEntry); 448 __ CallRuntime(kDeoptimizeFillFrameRuntimeEntry);
439 if (preserve_result) { 449 if (preserve_result) {
440 // Restore result into RBX. 450 // Restore result into RBX.
441 __ movq(RBX, Address(RBP, kFirstLocalSlotFromFp * kWordSize)); 451 __ movq(RBX, Address(RBP, kFirstLocalSlotFromFp * kWordSize));
442 } 452 }
443 // Code above cannot cause GC. 453 // Code above cannot cause GC.
444 __ LeaveFrame(); 454 __ LeaveFrame(true);
445 455
446 // Frame is fully rewritten at this point and it is safe to perform a GC. 456 // Frame is fully rewritten at this point and it is safe to perform a GC.
447 // Materialize any objects that were deferred by FillFrame because they 457 // Materialize any objects that were deferred by FillFrame because they
448 // require allocation. 458 // require allocation.
449 __ EnterStubFrame(); 459 __ EnterStubFrame();
450 if (preserve_result) { 460 if (preserve_result) {
451 __ pushq(RBX); // Preserve result, it will be GC-d here. 461 __ pushq(RBX); // Preserve result, it will be GC-d here.
452 } 462 }
453 __ pushq(Immediate(Smi::RawValue(0))); // Space for the result. 463 __ pushq(Immediate(Smi::RawValue(0))); // Space for the result.
454 __ CallRuntime(kDeoptimizeMaterializeRuntimeEntry); 464 __ CallRuntime(kDeoptimizeMaterializeRuntimeEntry);
(...skipping 24 matching lines...) Expand all
479 GenerateDeoptimizationSequence(assembler, true); // Preserve RAX. 489 GenerateDeoptimizationSequence(assembler, true); // Preserve RAX.
480 } 490 }
481 491
482 492
483 void StubCode::GenerateDeoptimizeStub(Assembler* assembler) { 493 void StubCode::GenerateDeoptimizeStub(Assembler* assembler) {
484 GenerateDeoptimizationSequence(assembler, false); // Don't preserve RAX. 494 GenerateDeoptimizationSequence(assembler, false); // Don't preserve RAX.
485 } 495 }
486 496
487 497
488 void StubCode::GenerateMegamorphicMissStub(Assembler* assembler) { 498 void StubCode::GenerateMegamorphicMissStub(Assembler* assembler) {
489 __ EnterStubFrame(); 499 __ EnterStubFrame(true);
490 // Load the receiver into RAX. The argument count in the arguments 500 // Load the receiver into RAX. The argument count in the arguments
491 // descriptor in R10 is a smi. 501 // descriptor in R10 is a smi.
492 __ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset())); 502 __ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
493 // Two words (saved fp, stub's pc marker) in the stack above the return 503 // Three words (saved pp, saved fp, stub's pc marker)
494 // address. 504 // in the stack above the return address.
495 __ movq(RAX, Address(RSP, RAX, TIMES_4, 2 * kWordSize)); 505 __ movq(RAX, Address(RSP, RAX, TIMES_4,
506 kSavedAboveReturnAddress * kWordSize));
496 // Preserve IC data and arguments descriptor. 507 // Preserve IC data and arguments descriptor.
497 __ pushq(RBX); 508 __ pushq(RBX);
498 __ pushq(R10); 509 __ pushq(R10);
499 510
500 const Immediate& raw_null = 511 const Immediate& raw_null =
501 Immediate(reinterpret_cast<intptr_t>(Instructions::null())); 512 Immediate(reinterpret_cast<intptr_t>(Instructions::null()));
502 __ pushq(raw_null); // Space for the result of the runtime call. 513 __ pushq(raw_null); // Space for the result of the runtime call.
503 __ pushq(RAX); // Receiver. 514 __ pushq(RAX); // Receiver.
504 __ pushq(RBX); // IC data. 515 __ pushq(RBX); // IC data.
505 __ pushq(R10); // Arguments descriptor. 516 __ pushq(R10); // Arguments descriptor.
506 __ CallRuntime(kMegamorphicCacheMissHandlerRuntimeEntry); 517 __ CallRuntime(kMegamorphicCacheMissHandlerRuntimeEntry);
507 // Discard arguments. 518 // Discard arguments.
508 __ popq(RAX); 519 __ popq(RAX);
509 __ popq(RAX); 520 __ popq(RAX);
510 __ popq(RAX); 521 __ popq(RAX);
511 __ popq(RAX); // Return value from the runtime call (instructions). 522 __ popq(RAX); // Return value from the runtime call (instructions).
512 __ popq(R10); // Restore arguments descriptor. 523 __ popq(R10); // Restore arguments descriptor.
513 __ popq(RBX); // Restore IC data. 524 __ popq(RBX); // Restore IC data.
514 __ LeaveFrame(); 525 __ LeaveFrame(true);
515 526
516 Label lookup; 527 Label lookup;
517 __ cmpq(RAX, raw_null); 528 __ cmpq(RAX, raw_null);
518 __ j(EQUAL, &lookup, Assembler::kNearJump); 529 __ j(EQUAL, &lookup, Assembler::kNearJump);
519 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); 530 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
520 __ jmp(RAX); 531 __ jmp(RAX);
521 532
522 __ Bind(&lookup); 533 __ Bind(&lookup);
523 __ jmp(&StubCode::InstanceFunctionLookupLabel()); 534 __ jmp(&StubCode::InstanceFunctionLookupLabel());
524 } 535 }
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
754 765
755 // Called when invoking Dart code from C++ (VM code). 766 // Called when invoking Dart code from C++ (VM code).
756 // Input parameters: 767 // Input parameters:
757 // RSP : points to return address. 768 // RSP : points to return address.
758 // RDI : entrypoint of the Dart function to call. 769 // RDI : entrypoint of the Dart function to call.
759 // RSI : arguments descriptor array. 770 // RSI : arguments descriptor array.
760 // RDX : arguments array. 771 // RDX : arguments array.
761 // RCX : new context containing the current isolate pointer. 772 // RCX : new context containing the current isolate pointer.
762 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) { 773 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) {
763 // Save frame pointer coming in. 774 // Save frame pointer coming in.
764 __ EnterFrame(0); 775 __ EnterStubFrame();
765 776
766 // Save arguments descriptor array and new context. 777 // Save arguments descriptor array and new context.
767 const intptr_t kArgumentsDescOffset = -1 * kWordSize; 778 const intptr_t kArgumentsDescOffset = -2 * kWordSize;
768 __ pushq(RSI); 779 __ pushq(RSI);
769 const intptr_t kNewContextOffset = -2 * kWordSize; 780 const intptr_t kNewContextOffset = -3 * kWordSize;
770 __ pushq(RCX); 781 __ pushq(RCX);
771 782
772 // Save C++ ABI callee-saved registers. 783 // Save C++ ABI callee-saved registers.
773 __ pushq(RBX); 784 __ pushq(RBX);
774 __ pushq(R12); 785 __ pushq(R12);
775 __ pushq(R13); 786 __ pushq(R13);
776 __ pushq(R14); 787 __ pushq(R14);
777 __ pushq(R15); 788 __ pushq(R15);
778 789
779 // The new Context structure contains a pointer to the current Isolate 790 // The new Context structure contains a pointer to the current Isolate
780 // structure. Cache the Context pointer in the CTX register so that it is 791 // structure. Cache the Context pointer in the CTX register so that it is
781 // available in generated code and calls to Isolate::Current() need not be 792 // available in generated code and calls to Isolate::Current() need not be
782 // done. The assumption is that this register will never be clobbered by 793 // done. The assumption is that this register will never be clobbered by
783 // compiled or runtime stub code. 794 // compiled or runtime stub code.
784 795
785 // Cache the new Context pointer into CTX while executing Dart code. 796 // Cache the new Context pointer into CTX while executing Dart code.
786 __ movq(CTX, Address(RCX, VMHandles::kOffsetOfRawPtrInHandle)); 797 __ movq(CTX, Address(RCX, VMHandles::kOffsetOfRawPtrInHandle));
787 798
788 // Load Isolate pointer from Context structure into R8. 799 // Load Isolate pointer from Context structure into R8.
789 __ movq(R8, FieldAddress(CTX, Context::isolate_offset())); 800 __ movq(R8, FieldAddress(CTX, Context::isolate_offset()));
790 801
791 // Save the top exit frame info. Use RAX as a temporary register. 802 // Save the top exit frame info. Use RAX as a temporary register.
792 // StackFrameIterator reads the top exit frame info saved in this frame. 803 // StackFrameIterator reads the top exit frame info saved in this frame.
793 // The constant kExitLinkSlotFromEntryFp must be kept in sync with the 804 // The constant kExitLinkSlotFromEntryFp must be kept in sync with the
794 // code below. 805 // code below.
795 ASSERT(kExitLinkSlotFromEntryFp == -8); 806 ASSERT(kExitLinkSlotFromEntryFp == -9);
796 __ movq(RAX, Address(R8, Isolate::top_exit_frame_info_offset())); 807 __ movq(RAX, Address(R8, Isolate::top_exit_frame_info_offset()));
797 __ pushq(RAX); 808 __ pushq(RAX);
798 __ movq(Address(R8, Isolate::top_exit_frame_info_offset()), Immediate(0)); 809 __ movq(Address(R8, Isolate::top_exit_frame_info_offset()), Immediate(0));
799 810
800 // Save the old Context pointer. Use RAX as a temporary register. 811 // Save the old Context pointer. Use RAX as a temporary register.
801 // Note that VisitObjectPointers will find this saved Context pointer during 812 // Note that VisitObjectPointers will find this saved Context pointer during
802 // GC marking, since it traverses any information between SP and 813 // GC marking, since it traverses any information between SP and
803 // FP - kExitLinkSlotFromEntryFp * kWordSize. 814 // FP - kExitLinkSlotFromEntryFp * kWordSize.
804 // EntryFrame::SavedContext reads the context saved in this frame. 815 // EntryFrame::SavedContext reads the context saved in this frame.
805 // The constant kSavedContextSlotFromEntryFp must be kept in sync with 816 // The constant kSavedContextSlotFromEntryFp must be kept in sync with
806 // the code below. 817 // the code below.
807 ASSERT(kSavedContextSlotFromEntryFp == -9); 818 ASSERT(kSavedContextSlotFromEntryFp == -10);
808 __ movq(RAX, Address(R8, Isolate::top_context_offset())); 819 __ movq(RAX, Address(R8, Isolate::top_context_offset()));
809 __ pushq(RAX); 820 __ pushq(RAX);
810 821
811 // Load arguments descriptor array into R10, which is passed to Dart code. 822 // Load arguments descriptor array into R10, which is passed to Dart code.
812 __ movq(R10, Address(RSI, VMHandles::kOffsetOfRawPtrInHandle)); 823 __ movq(R10, Address(RSI, VMHandles::kOffsetOfRawPtrInHandle));
813 824
814 // Load number of arguments into RBX. 825 // Load number of arguments into RBX.
815 __ movq(RBX, FieldAddress(R10, ArgumentsDescriptor::count_offset())); 826 __ movq(RBX, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
816 __ SmiUntag(RBX); 827 __ SmiUntag(RBX);
817 828
(...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after
1210 __ addq(RAX, Immediate(kHeapObjectTag)); 1221 __ addq(RAX, Immediate(kHeapObjectTag));
1211 __ ret(); 1222 __ ret();
1212 1223
1213 __ Bind(&slow_case); 1224 __ Bind(&slow_case);
1214 } 1225 }
1215 if (is_cls_parameterized) { 1226 if (is_cls_parameterized) {
1216 __ movq(RAX, Address(RSP, kObjectTypeArgumentsOffset)); 1227 __ movq(RAX, Address(RSP, kObjectTypeArgumentsOffset));
1217 __ movq(RDX, Address(RSP, kInstantiatorTypeArgumentsOffset)); 1228 __ movq(RDX, Address(RSP, kInstantiatorTypeArgumentsOffset));
1218 } 1229 }
1219 // Create a stub frame. 1230 // Create a stub frame.
1220 __ EnterStubFrame(); 1231 __ EnterStubFrame(true);
1221 __ pushq(raw_null); // Setup space on stack for return value. 1232 __ pushq(raw_null); // Setup space on stack for return value.
1222 __ PushObject(cls); // Push class of object to be allocated. 1233 __ PushObject(cls); // Push class of object to be allocated.
1223 if (is_cls_parameterized) { 1234 if (is_cls_parameterized) {
1224 __ pushq(RAX); // Push type arguments of object to be allocated. 1235 __ pushq(RAX); // Push type arguments of object to be allocated.
1225 __ pushq(RDX); // Push type arguments of instantiator. 1236 __ pushq(RDX); // Push type arguments of instantiator.
1226 } else { 1237 } else {
1227 __ pushq(raw_null); // Push null type arguments. 1238 __ pushq(raw_null); // Push null type arguments.
1228 __ pushq(Immediate(Smi::RawValue(StubCode::kNoInstantiator))); 1239 __ pushq(Immediate(Smi::RawValue(StubCode::kNoInstantiator)));
1229 } 1240 }
1230 __ CallRuntime(kAllocateObjectRuntimeEntry); // Allocate object. 1241 __ CallRuntime(kAllocateObjectRuntimeEntry); // Allocate object.
1231 __ popq(RAX); // Pop argument (instantiator). 1242 __ popq(RAX); // Pop argument (instantiator).
1232 __ popq(RAX); // Pop argument (type arguments of object). 1243 __ popq(RAX); // Pop argument (type arguments of object).
1233 __ popq(RAX); // Pop argument (class of object). 1244 __ popq(RAX); // Pop argument (class of object).
1234 __ popq(RAX); // Pop result (newly allocated object). 1245 __ popq(RAX); // Pop result (newly allocated object).
1235 // RAX: new object 1246 // RAX: new object
1236 // Restore the frame pointer. 1247 // Restore the frame pointer.
1237 __ LeaveFrame(); 1248 __ LeaveFrame(true);
1238 __ ret(); 1249 __ ret();
1239 } 1250 }
1240 1251
1241 1252
1242 // Called for inline allocation of closures. 1253 // Called for inline allocation of closures.
1243 // Input parameters: 1254 // Input parameters:
1244 // RSP + 16 : receiver (null if not an implicit instance closure). 1255 // RSP + 16 : receiver (null if not an implicit instance closure).
1245 // RSP + 8 : type arguments object (null if class is not parameterized). 1256 // RSP + 8 : type arguments object (null if class is not parameterized).
1246 // RSP : points to return address. 1257 // RSP : points to return address.
1247 void StubCode::GenerateAllocationStubForClosure(Assembler* assembler, 1258 void StubCode::GenerateAllocationStubForClosure(Assembler* assembler,
1248 const Function& func) { 1259 const Function& func) {
1249 const Immediate& raw_null = 1260 const Immediate& raw_null =
1250 Immediate(reinterpret_cast<intptr_t>(Object::null())); 1261 Immediate(reinterpret_cast<intptr_t>(Object::null()));
1251 ASSERT(func.IsClosureFunction()); 1262 ASSERT(func.IsClosureFunction());
1252 ASSERT(!func.IsImplicitStaticClosureFunction()); 1263 ASSERT(!func.IsImplicitStaticClosureFunction());
1253 const bool is_implicit_instance_closure = 1264 const bool is_implicit_instance_closure =
1254 func.IsImplicitInstanceClosureFunction(); 1265 func.IsImplicitInstanceClosureFunction();
1255 const Class& cls = Class::ZoneHandle(func.signature_class()); 1266 const Class& cls = Class::ZoneHandle(func.signature_class());
1256 const bool has_type_arguments = cls.HasTypeArguments(); 1267 const bool has_type_arguments = cls.HasTypeArguments();
1257 const intptr_t kTypeArgumentsOffset = 1 * kWordSize; 1268
1258 const intptr_t kReceiverOffset = 2 * kWordSize; 1269 __ EnterStubFrame(true); // Uses pool pointer to refer to function.
1270 const intptr_t kTypeArgumentsOffset = 4 * kWordSize;
1271 const intptr_t kReceiverOffset = 5 * kWordSize;
1259 const intptr_t closure_size = Closure::InstanceSize(); 1272 const intptr_t closure_size = Closure::InstanceSize();
1260 const intptr_t context_size = Context::InstanceSize(1); // Captured receiver. 1273 const intptr_t context_size = Context::InstanceSize(1); // Captured receiver.
1261 if (FLAG_inline_alloc && 1274 if (FLAG_inline_alloc &&
1262 Heap::IsAllocatableInNewSpace(closure_size + context_size)) { 1275 Heap::IsAllocatableInNewSpace(closure_size + context_size)) {
1263 Label slow_case; 1276 Label slow_case;
1264 Heap* heap = Isolate::Current()->heap(); 1277 Heap* heap = Isolate::Current()->heap();
1265 __ movq(RAX, Immediate(heap->TopAddress())); 1278 __ movq(RAX, Immediate(heap->TopAddress()));
1266 __ movq(RAX, Address(RAX, 0)); 1279 __ movq(RAX, Address(RAX, 0));
1267 __ leaq(R13, Address(RAX, closure_size)); 1280 __ leaq(R13, Address(RAX, closure_size));
1268 if (is_implicit_instance_closure) { 1281 if (is_implicit_instance_closure) {
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1333 __ movq(Address(RAX, Closure::context_offset()), CTX); 1346 __ movq(Address(RAX, Closure::context_offset()), CTX);
1334 } 1347 }
1335 1348
1336 // Set the type arguments field in the newly allocated closure. 1349 // Set the type arguments field in the newly allocated closure.
1337 __ movq(R10, Address(RSP, kTypeArgumentsOffset)); 1350 __ movq(R10, Address(RSP, kTypeArgumentsOffset));
1338 __ movq(Address(RAX, Closure::type_arguments_offset()), R10); 1351 __ movq(Address(RAX, Closure::type_arguments_offset()), R10);
1339 1352
1340 // Done allocating and initializing the instance. 1353 // Done allocating and initializing the instance.
1341 // RAX: new object. 1354 // RAX: new object.
1342 __ addq(RAX, Immediate(kHeapObjectTag)); 1355 __ addq(RAX, Immediate(kHeapObjectTag));
1356 __ LeaveFrame(true);
1343 __ ret(); 1357 __ ret();
1344 1358
1345 __ Bind(&slow_case); 1359 __ Bind(&slow_case);
1346 } 1360 }
1347 if (has_type_arguments) { 1361 if (has_type_arguments) {
1348 __ movq(RCX, Address(RSP, kTypeArgumentsOffset)); 1362 __ movq(RCX, Address(RSP, kTypeArgumentsOffset));
1349 } 1363 }
1350 if (is_implicit_instance_closure) { 1364 if (is_implicit_instance_closure) {
1351 __ movq(RAX, Address(RSP, kReceiverOffset)); 1365 __ movq(RAX, Address(RSP, kReceiverOffset));
1352 } 1366 }
1353 // Create the stub frame. 1367
1354 __ EnterStubFrame();
1355 __ pushq(raw_null); // Setup space on stack for the return value. 1368 __ pushq(raw_null); // Setup space on stack for the return value.
1356 __ PushObject(func); 1369 __ PushObject(func);
1357 if (is_implicit_instance_closure) { 1370 if (is_implicit_instance_closure) {
1358 __ pushq(RAX); // Receiver. 1371 __ pushq(RAX); // Receiver.
1359 } 1372 }
1360 if (has_type_arguments) { 1373 if (has_type_arguments) {
1361 __ pushq(RCX); // Push type arguments of closure to be allocated. 1374 __ pushq(RCX); // Push type arguments of closure to be allocated.
1362 } else { 1375 } else {
1363 __ pushq(raw_null); // Push null type arguments. 1376 __ pushq(raw_null); // Push null type arguments.
1364 } 1377 }
1365 if (is_implicit_instance_closure) { 1378 if (is_implicit_instance_closure) {
1366 __ CallRuntime(kAllocateImplicitInstanceClosureRuntimeEntry); 1379 __ CallRuntime(kAllocateImplicitInstanceClosureRuntimeEntry);
1367 __ popq(RAX); // Pop type arguments. 1380 __ popq(RAX); // Pop type arguments.
1368 __ popq(RAX); // Pop receiver. 1381 __ popq(RAX); // Pop receiver.
1369 } else { 1382 } else {
1370 ASSERT(func.IsNonImplicitClosureFunction()); 1383 ASSERT(func.IsNonImplicitClosureFunction());
1371 __ CallRuntime(kAllocateClosureRuntimeEntry); 1384 __ CallRuntime(kAllocateClosureRuntimeEntry);
1372 __ popq(RAX); // Pop type arguments. 1385 __ popq(RAX); // Pop type arguments.
1373 } 1386 }
1374 __ popq(RAX); // Pop the function object. 1387 __ popq(RAX); // Pop the function object.
1375 __ popq(RAX); // Pop the result. 1388 __ popq(RAX); // Pop the result.
1376 // RAX: New closure object. 1389 // RAX: New closure object.
1377 // Restore the calling frame. 1390 // Restore the calling frame.
1378 __ LeaveFrame(); 1391 __ LeaveFrame(true);
1379 __ ret(); 1392 __ ret();
1380 } 1393 }
1381 1394
1382 1395
1383 // Called for invoking "dynamic noSuchMethod(Invocation invocation)" function 1396 // Called for invoking "dynamic noSuchMethod(Invocation invocation)" function
1384 // 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
1385 // name or number is detected. 1398 // name or number is detected.
1386 // Input parameters: 1399 // Input parameters:
1387 // RSP : points to return address. 1400 // RSP : points to return address.
1388 // RSP + 8 : address of last argument. 1401 // RSP + 8 : address of last argument.
(...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after
1820 1833
1821 // TOS(0): return address (Dart code). 1834 // TOS(0): return address (Dart code).
1822 void StubCode::GenerateBreakpointReturnStub(Assembler* assembler) { 1835 void StubCode::GenerateBreakpointReturnStub(Assembler* assembler) {
1823 __ EnterStubFrame(); 1836 __ EnterStubFrame();
1824 __ pushq(RAX); 1837 __ pushq(RAX);
1825 __ CallRuntime(kBreakpointReturnHandlerRuntimeEntry); 1838 __ CallRuntime(kBreakpointReturnHandlerRuntimeEntry);
1826 __ popq(RAX); 1839 __ popq(RAX);
1827 __ LeaveFrame(); 1840 __ LeaveFrame();
1828 1841
1829 __ popq(R11); // discard return address of call to this stub. 1842 __ popq(R11); // discard return address of call to this stub.
1830 __ LeaveFrame(); 1843 __ LeaveFrame(true);
1831 __ ret(); 1844 __ ret();
1832 } 1845 }
1833 1846
1834 1847
1835 // RBX: Inline cache data array. 1848 // RBX: Inline cache data array.
1836 // TOS(0): return address (Dart code). 1849 // TOS(0): return address (Dart code).
1837 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) { 1850 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) {
1838 __ EnterStubFrame(); 1851 __ EnterStubFrame();
1839 __ pushq(RBX); 1852 __ pushq(RBX);
1840 __ CallRuntime(kBreakpointDynamicHandlerRuntimeEntry); 1853 __ CallRuntime(kBreakpointDynamicHandlerRuntimeEntry);
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
2074 __ movq(RAX, Immediate(Smi::RawValue(kSmiCid))); 2087 __ movq(RAX, Immediate(Smi::RawValue(kSmiCid)));
2075 __ ret(); 2088 __ ret();
2076 2089
2077 __ Bind(&not_smi); 2090 __ Bind(&not_smi);
2078 __ LoadClassId(RAX, RAX); 2091 __ LoadClassId(RAX, RAX);
2079 __ SmiTag(RAX); 2092 __ SmiTag(RAX);
2080 __ ret(); 2093 __ ret();
2081 2094
2082 __ Bind(&update_ic_data); 2095 __ Bind(&update_ic_data);
2083 2096
2084 // RCX: ICData 2097 // RBX: ICData
2085 __ movq(RAX, Address(RSP, 1 * kWordSize)); 2098 __ movq(RAX, Address(RSP, 1 * kWordSize));
2086 __ movq(R13, Address(RSP, 2 * kWordSize)); 2099 __ movq(R13, Address(RSP, 2 * kWordSize));
2087 __ EnterStubFrame(); 2100 __ EnterStubFrame();
2088 __ pushq(R13); // arg 0 2101 __ pushq(R13); // arg 0
2089 __ pushq(RAX); // arg 1 2102 __ pushq(RAX); // arg 1
2090 __ PushObject(Symbols::EqualOperator()); // Target's name. 2103 __ PushObject(Symbols::EqualOperator()); // Target's name.
2091 __ pushq(RBX); // ICData 2104 __ pushq(RBX); // ICData
2092 __ CallRuntime(kUpdateICDataTwoArgsRuntimeEntry); 2105 __ CallRuntime(kUpdateICDataTwoArgsRuntimeEntry);
2093 __ Drop(4); 2106 __ Drop(4);
2094 __ LeaveFrame(); 2107 __ LeaveFrame();
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
2228 __ movq(right, Address(RSP, 3 * kWordSize)); 2241 __ movq(right, Address(RSP, 3 * kWordSize));
2229 GenerateIdenticalWithNumberCheckStub(assembler, left, right); 2242 GenerateIdenticalWithNumberCheckStub(assembler, left, right);
2230 __ popq(right); 2243 __ popq(right);
2231 __ popq(left); 2244 __ popq(left);
2232 __ ret(); 2245 __ ret();
2233 } 2246 }
2234 2247
2235 } // namespace dart 2248 } // namespace dart
2236 2249
2237 #endif // defined TARGET_ARCH_X64 2250 #endif // defined TARGET_ARCH_X64
OLDNEW
« runtime/vm/assembler_x64.cc ('K') | « runtime/vm/stack_frame_x64.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698