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

Side by Side Diff: src/x87/code-stubs-x87.cc

Issue 1368873002: X87: [turbofan] Call ArgumentsAccessStub to materialize arguments. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 2 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
« no previous file with comments | « src/full-codegen/x87/full-codegen-x87.cc ('k') | src/x87/interface-descriptors-x87.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #if V8_TARGET_ARCH_X87 5 #if V8_TARGET_ARCH_X87
6 6
7 #include "src/base/bits.h" 7 #include "src/base/bits.h"
8 #include "src/bootstrapper.h" 8 #include "src/bootstrapper.h"
9 #include "src/code-stubs.h" 9 #include "src/code-stubs.h"
10 #include "src/codegen.h" 10 #include "src/codegen.h"
(...skipping 475 matching lines...) Expand 10 before | Expand all | Expand 10 after
486 // by calling the runtime system. 486 // by calling the runtime system.
487 __ bind(&slow); 487 __ bind(&slow);
488 __ pop(ebx); // Return address. 488 __ pop(ebx); // Return address.
489 __ push(edx); 489 __ push(edx);
490 __ push(ebx); 490 __ push(ebx);
491 __ TailCallRuntime(Runtime::kArguments, 1, 1); 491 __ TailCallRuntime(Runtime::kArguments, 1, 1);
492 } 492 }
493 493
494 494
495 void ArgumentsAccessStub::GenerateNewSloppySlow(MacroAssembler* masm) { 495 void ArgumentsAccessStub::GenerateNewSloppySlow(MacroAssembler* masm) {
496 // ecx : number of parameters (tagged)
497 // edx : parameters pointer
498 // edi : function
496 // esp[0] : return address 499 // esp[0] : return address
497 // esp[4] : number of parameters 500
498 // esp[8] : receiver displacement 501 DCHECK(edi.is(ArgumentsAccessNewDescriptor::function()));
499 // esp[12] : function 502 DCHECK(ecx.is(ArgumentsAccessNewDescriptor::parameter_count()));
503 DCHECK(edx.is(ArgumentsAccessNewDescriptor::parameter_pointer()));
500 504
501 // Check if the calling frame is an arguments adaptor frame. 505 // Check if the calling frame is an arguments adaptor frame.
502 Label runtime; 506 Label runtime;
503 __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); 507 __ mov(ebx, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
504 __ mov(ecx, Operand(edx, StandardFrameConstants::kContextOffset)); 508 __ mov(eax, Operand(ebx, StandardFrameConstants::kContextOffset));
505 __ cmp(ecx, Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); 509 __ cmp(eax, Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
506 __ j(not_equal, &runtime, Label::kNear); 510 __ j(not_equal, &runtime, Label::kNear);
507 511
508 // Patch the arguments.length and the parameters pointer. 512 // Patch the arguments.length and the parameters pointer.
509 __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset)); 513 __ mov(ecx, Operand(ebx, ArgumentsAdaptorFrameConstants::kLengthOffset));
510 __ mov(Operand(esp, 1 * kPointerSize), ecx); 514 __ lea(edx,
511 __ lea(edx, Operand(edx, ecx, times_2, 515 Operand(ebx, ecx, times_2, StandardFrameConstants::kCallerSPOffset));
512 StandardFrameConstants::kCallerSPOffset));
513 __ mov(Operand(esp, 2 * kPointerSize), edx);
514 516
515 __ bind(&runtime); 517 __ bind(&runtime);
518 __ pop(eax); // Pop return address.
519 __ push(edi); // Push function.
520 __ push(edx); // Push parameters pointer.
521 __ push(ecx); // Push parameter count.
522 __ push(eax); // Push return address.
516 __ TailCallRuntime(Runtime::kNewSloppyArguments, 3, 1); 523 __ TailCallRuntime(Runtime::kNewSloppyArguments, 3, 1);
517 } 524 }
518 525
519 526
520 void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) { 527 void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) {
528 // ecx : number of parameters (tagged)
529 // edx : parameters pointer
530 // edi : function
521 // esp[0] : return address 531 // esp[0] : return address
522 // esp[4] : number of parameters (tagged)
523 // esp[8] : receiver displacement
524 // esp[12] : function
525 532
526 // ebx = parameter count (tagged) 533 DCHECK(edi.is(ArgumentsAccessNewDescriptor::function()));
527 __ mov(ebx, Operand(esp, 1 * kPointerSize)); 534 DCHECK(ecx.is(ArgumentsAccessNewDescriptor::parameter_count()));
535 DCHECK(edx.is(ArgumentsAccessNewDescriptor::parameter_pointer()));
528 536
529 // Check if the calling frame is an arguments adaptor frame. 537 // Check if the calling frame is an arguments adaptor frame.
530 // TODO(rossberg): Factor out some of the bits that are shared with the other 538 Label adaptor_frame, try_allocate, runtime;
531 // Generate* functions. 539 __ mov(ebx, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
532 Label runtime; 540 __ mov(eax, Operand(ebx, StandardFrameConstants::kContextOffset));
533 Label adaptor_frame, try_allocate; 541 __ cmp(eax, Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
534 __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
535 __ mov(ecx, Operand(edx, StandardFrameConstants::kContextOffset));
536 __ cmp(ecx, Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
537 __ j(equal, &adaptor_frame, Label::kNear); 542 __ j(equal, &adaptor_frame, Label::kNear);
538 543
539 // No adaptor, parameter count = argument count. 544 // No adaptor, parameter count = argument count.
540 __ mov(ecx, ebx); 545 __ mov(ebx, ecx);
546 __ push(ecx);
541 __ jmp(&try_allocate, Label::kNear); 547 __ jmp(&try_allocate, Label::kNear);
542 548
543 // We have an adaptor frame. Patch the parameters pointer. 549 // We have an adaptor frame. Patch the parameters pointer.
544 __ bind(&adaptor_frame); 550 __ bind(&adaptor_frame);
551 __ mov(ebx, ecx);
552 __ push(ecx);
553 __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
545 __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset)); 554 __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset));
546 __ lea(edx, Operand(edx, ecx, times_2, 555 __ lea(edx, Operand(edx, ecx, times_2,
547 StandardFrameConstants::kCallerSPOffset)); 556 StandardFrameConstants::kCallerSPOffset));
548 __ mov(Operand(esp, 2 * kPointerSize), edx);
549 557
550 // ebx = parameter count (tagged) 558 // ebx = parameter count (tagged)
551 // ecx = argument count (smi-tagged) 559 // ecx = argument count (smi-tagged)
552 // esp[4] = parameter count (tagged)
553 // esp[8] = address of receiver argument
554 // Compute the mapped parameter count = min(ebx, ecx) in ebx. 560 // Compute the mapped parameter count = min(ebx, ecx) in ebx.
555 __ cmp(ebx, ecx); 561 __ cmp(ebx, ecx);
556 __ j(less_equal, &try_allocate, Label::kNear); 562 __ j(less_equal, &try_allocate, Label::kNear);
557 __ mov(ebx, ecx); 563 __ mov(ebx, ecx);
558 564
565 // Save mapped parameter count and function.
559 __ bind(&try_allocate); 566 __ bind(&try_allocate);
560 567 __ push(edi);
561 // Save mapped parameter count.
562 __ push(ebx); 568 __ push(ebx);
563 569
564 // Compute the sizes of backing store, parameter map, and arguments object. 570 // Compute the sizes of backing store, parameter map, and arguments object.
565 // 1. Parameter map, has 2 extra words containing context and backing store. 571 // 1. Parameter map, has 2 extra words containing context and backing store.
566 const int kParameterMapHeaderSize = 572 const int kParameterMapHeaderSize =
567 FixedArray::kHeaderSize + 2 * kPointerSize; 573 FixedArray::kHeaderSize + 2 * kPointerSize;
568 Label no_parameter_map; 574 Label no_parameter_map;
569 __ test(ebx, ebx); 575 __ test(ebx, ebx);
570 __ j(zero, &no_parameter_map, Label::kNear); 576 __ j(zero, &no_parameter_map, Label::kNear);
571 __ lea(ebx, Operand(ebx, times_2, kParameterMapHeaderSize)); 577 __ lea(ebx, Operand(ebx, times_2, kParameterMapHeaderSize));
572 __ bind(&no_parameter_map); 578 __ bind(&no_parameter_map);
573 579
574 // 2. Backing store. 580 // 2. Backing store.
575 __ lea(ebx, Operand(ebx, ecx, times_2, FixedArray::kHeaderSize)); 581 __ lea(ebx, Operand(ebx, ecx, times_2, FixedArray::kHeaderSize));
576 582
577 // 3. Arguments object. 583 // 3. Arguments object.
578 __ add(ebx, Immediate(Heap::kSloppyArgumentsObjectSize)); 584 __ add(ebx, Immediate(Heap::kSloppyArgumentsObjectSize));
579 585
580 // Do the allocation of all three objects in one go. 586 // Do the allocation of all three objects in one go.
581 __ Allocate(ebx, eax, edx, edi, &runtime, TAG_OBJECT); 587 __ Allocate(ebx, eax, edi, no_reg, &runtime, TAG_OBJECT);
582 588
583 // eax = address of new object(s) (tagged) 589 // eax = address of new object(s) (tagged)
584 // ecx = argument count (smi-tagged) 590 // ecx = argument count (smi-tagged)
585 // esp[0] = mapped parameter count (tagged) 591 // esp[0] = mapped parameter count (tagged)
592 // esp[4] = function
586 // esp[8] = parameter count (tagged) 593 // esp[8] = parameter count (tagged)
587 // esp[12] = address of receiver argument
588 // Get the arguments map from the current native context into edi. 594 // Get the arguments map from the current native context into edi.
589 Label has_mapped_parameters, instantiate; 595 Label has_mapped_parameters, instantiate;
590 __ mov(edi, Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); 596 __ mov(edi, Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
591 __ mov(edi, FieldOperand(edi, GlobalObject::kNativeContextOffset)); 597 __ mov(edi, FieldOperand(edi, GlobalObject::kNativeContextOffset));
592 __ mov(ebx, Operand(esp, 0 * kPointerSize)); 598 __ mov(ebx, Operand(esp, 0 * kPointerSize));
593 __ test(ebx, ebx); 599 __ test(ebx, ebx);
594 __ j(not_zero, &has_mapped_parameters, Label::kNear); 600 __ j(not_zero, &has_mapped_parameters, Label::kNear);
595 __ mov( 601 __ mov(
596 edi, 602 edi,
597 Operand(edi, Context::SlotOffset(Context::SLOPPY_ARGUMENTS_MAP_INDEX))); 603 Operand(edi, Context::SlotOffset(Context::SLOPPY_ARGUMENTS_MAP_INDEX)));
598 __ jmp(&instantiate, Label::kNear); 604 __ jmp(&instantiate, Label::kNear);
599 605
600 __ bind(&has_mapped_parameters); 606 __ bind(&has_mapped_parameters);
601 __ mov(edi, Operand(edi, Context::SlotOffset( 607 __ mov(edi, Operand(edi, Context::SlotOffset(
602 Context::FAST_ALIASED_ARGUMENTS_MAP_INDEX))); 608 Context::FAST_ALIASED_ARGUMENTS_MAP_INDEX)));
603 __ bind(&instantiate); 609 __ bind(&instantiate);
604 610
605 // eax = address of new object (tagged) 611 // eax = address of new object (tagged)
606 // ebx = mapped parameter count (tagged) 612 // ebx = mapped parameter count (tagged)
607 // ecx = argument count (smi-tagged) 613 // ecx = argument count (smi-tagged)
608 // edi = address of arguments map (tagged) 614 // edi = address of arguments map (tagged)
609 // esp[0] = mapped parameter count (tagged) 615 // esp[0] = mapped parameter count (tagged)
616 // esp[4] = function
610 // esp[8] = parameter count (tagged) 617 // esp[8] = parameter count (tagged)
611 // esp[12] = address of receiver argument
612 // Copy the JS object part. 618 // Copy the JS object part.
613 __ mov(FieldOperand(eax, JSObject::kMapOffset), edi); 619 __ mov(FieldOperand(eax, JSObject::kMapOffset), edi);
614 __ mov(FieldOperand(eax, JSObject::kPropertiesOffset), 620 __ mov(FieldOperand(eax, JSObject::kPropertiesOffset),
615 masm->isolate()->factory()->empty_fixed_array()); 621 masm->isolate()->factory()->empty_fixed_array());
616 __ mov(FieldOperand(eax, JSObject::kElementsOffset), 622 __ mov(FieldOperand(eax, JSObject::kElementsOffset),
617 masm->isolate()->factory()->empty_fixed_array()); 623 masm->isolate()->factory()->empty_fixed_array());
618 624
619 // Set up the callee in-object property. 625 // Set up the callee in-object property.
620 STATIC_ASSERT(Heap::kArgumentsCalleeIndex == 1); 626 STATIC_ASSERT(Heap::kArgumentsCalleeIndex == 1);
621 __ mov(edx, Operand(esp, 4 * kPointerSize)); 627 __ mov(edi, Operand(esp, 1 * kPointerSize));
622 __ AssertNotSmi(edx); 628 __ AssertNotSmi(edi);
623 __ mov(FieldOperand(eax, JSObject::kHeaderSize + 629 __ mov(FieldOperand(eax, JSObject::kHeaderSize +
624 Heap::kArgumentsCalleeIndex * kPointerSize), 630 Heap::kArgumentsCalleeIndex * kPointerSize),
625 edx); 631 edi);
626 632
627 // Use the length (smi tagged) and set that as an in-object property too. 633 // Use the length (smi tagged) and set that as an in-object property too.
628 __ AssertSmi(ecx); 634 __ AssertSmi(ecx);
629 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0); 635 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0);
630 __ mov(FieldOperand(eax, JSObject::kHeaderSize + 636 __ mov(FieldOperand(eax, JSObject::kHeaderSize +
631 Heap::kArgumentsLengthIndex * kPointerSize), 637 Heap::kArgumentsLengthIndex * kPointerSize),
632 ecx); 638 ecx);
633 639
634 // Set up the elements pointer in the allocated arguments object. 640 // Set up the elements pointer in the allocated arguments object.
635 // If we allocated a parameter map, edi will point there, otherwise to the 641 // If we allocated a parameter map, edi will point there, otherwise to the
636 // backing store. 642 // backing store.
637 __ lea(edi, Operand(eax, Heap::kSloppyArgumentsObjectSize)); 643 __ lea(edi, Operand(eax, Heap::kSloppyArgumentsObjectSize));
638 __ mov(FieldOperand(eax, JSObject::kElementsOffset), edi); 644 __ mov(FieldOperand(eax, JSObject::kElementsOffset), edi);
639 645
640 // eax = address of new object (tagged) 646 // eax = address of new object (tagged)
641 // ebx = mapped parameter count (tagged) 647 // ebx = mapped parameter count (tagged)
642 // ecx = argument count (tagged) 648 // ecx = argument count (tagged)
649 // edx = address of receiver argument
643 // edi = address of parameter map or backing store (tagged) 650 // edi = address of parameter map or backing store (tagged)
644 // esp[0] = mapped parameter count (tagged) 651 // esp[0] = mapped parameter count (tagged)
652 // esp[4] = function
645 // esp[8] = parameter count (tagged) 653 // esp[8] = parameter count (tagged)
646 // esp[12] = address of receiver argument 654 // Free two registers.
647 // Free a register. 655 __ push(edx);
648 __ push(eax); 656 __ push(eax);
649 657
650 // Initialize parameter map. If there are no mapped arguments, we're done. 658 // Initialize parameter map. If there are no mapped arguments, we're done.
651 Label skip_parameter_map; 659 Label skip_parameter_map;
652 __ test(ebx, ebx); 660 __ test(ebx, ebx);
653 __ j(zero, &skip_parameter_map); 661 __ j(zero, &skip_parameter_map);
654 662
655 __ mov(FieldOperand(edi, FixedArray::kMapOffset), 663 __ mov(FieldOperand(edi, FixedArray::kMapOffset),
656 Immediate(isolate()->factory()->sloppy_arguments_elements_map())); 664 Immediate(isolate()->factory()->sloppy_arguments_elements_map()));
657 __ lea(eax, Operand(ebx, reinterpret_cast<intptr_t>(Smi::FromInt(2)))); 665 __ lea(eax, Operand(ebx, reinterpret_cast<intptr_t>(Smi::FromInt(2))));
658 __ mov(FieldOperand(edi, FixedArray::kLengthOffset), eax); 666 __ mov(FieldOperand(edi, FixedArray::kLengthOffset), eax);
659 __ mov(FieldOperand(edi, FixedArray::kHeaderSize + 0 * kPointerSize), esi); 667 __ mov(FieldOperand(edi, FixedArray::kHeaderSize + 0 * kPointerSize), esi);
660 __ lea(eax, Operand(edi, ebx, times_2, kParameterMapHeaderSize)); 668 __ lea(eax, Operand(edi, ebx, times_2, kParameterMapHeaderSize));
661 __ mov(FieldOperand(edi, FixedArray::kHeaderSize + 1 * kPointerSize), eax); 669 __ mov(FieldOperand(edi, FixedArray::kHeaderSize + 1 * kPointerSize), eax);
662 670
663 // Copy the parameter slots and the holes in the arguments. 671 // Copy the parameter slots and the holes in the arguments.
664 // We need to fill in mapped_parameter_count slots. They index the context, 672 // We need to fill in mapped_parameter_count slots. They index the context,
665 // where parameters are stored in reverse order, at 673 // where parameters are stored in reverse order, at
666 // MIN_CONTEXT_SLOTS .. MIN_CONTEXT_SLOTS+parameter_count-1 674 // MIN_CONTEXT_SLOTS .. MIN_CONTEXT_SLOTS+parameter_count-1
667 // The mapped parameter thus need to get indices 675 // The mapped parameter thus need to get indices
668 // MIN_CONTEXT_SLOTS+parameter_count-1 .. 676 // MIN_CONTEXT_SLOTS+parameter_count-1 ..
669 // MIN_CONTEXT_SLOTS+parameter_count-mapped_parameter_count 677 // MIN_CONTEXT_SLOTS+parameter_count-mapped_parameter_count
670 // We loop from right to left. 678 // We loop from right to left.
671 Label parameters_loop, parameters_test; 679 Label parameters_loop, parameters_test;
672 __ push(ecx); 680 __ push(ecx);
673 __ mov(eax, Operand(esp, 2 * kPointerSize)); 681 __ mov(eax, Operand(esp, 3 * kPointerSize));
674 __ mov(ebx, Immediate(Smi::FromInt(Context::MIN_CONTEXT_SLOTS))); 682 __ mov(ebx, Immediate(Smi::FromInt(Context::MIN_CONTEXT_SLOTS)));
675 __ add(ebx, Operand(esp, 4 * kPointerSize)); 683 __ add(ebx, Operand(esp, 5 * kPointerSize));
676 __ sub(ebx, eax); 684 __ sub(ebx, eax);
677 __ mov(ecx, isolate()->factory()->the_hole_value()); 685 __ mov(ecx, isolate()->factory()->the_hole_value());
678 __ mov(edx, edi); 686 __ mov(edx, edi);
679 __ lea(edi, Operand(edi, eax, times_2, kParameterMapHeaderSize)); 687 __ lea(edi, Operand(edi, eax, times_2, kParameterMapHeaderSize));
680 // eax = loop variable (tagged) 688 // eax = loop variable (tagged)
681 // ebx = mapping index (tagged) 689 // ebx = mapping index (tagged)
682 // ecx = the hole value 690 // ecx = the hole value
683 // edx = address of parameter map (tagged) 691 // edx = address of parameter map (tagged)
684 // edi = address of backing store (tagged) 692 // edi = address of backing store (tagged)
685 // esp[0] = argument count (tagged) 693 // esp[0] = argument count (tagged)
686 // esp[4] = address of new object (tagged) 694 // esp[4] = address of new object (tagged)
687 // esp[8] = mapped parameter count (tagged) 695 // esp[8] = address of receiver argument
688 // esp[16] = parameter count (tagged) 696 // esp[12] = mapped parameter count (tagged)
689 // esp[20] = address of receiver argument 697 // esp[16] = function
698 // esp[20] = parameter count (tagged)
690 __ jmp(&parameters_test, Label::kNear); 699 __ jmp(&parameters_test, Label::kNear);
691 700
692 __ bind(&parameters_loop); 701 __ bind(&parameters_loop);
693 __ sub(eax, Immediate(Smi::FromInt(1))); 702 __ sub(eax, Immediate(Smi::FromInt(1)));
694 __ mov(FieldOperand(edx, eax, times_2, kParameterMapHeaderSize), ebx); 703 __ mov(FieldOperand(edx, eax, times_2, kParameterMapHeaderSize), ebx);
695 __ mov(FieldOperand(edi, eax, times_2, FixedArray::kHeaderSize), ecx); 704 __ mov(FieldOperand(edi, eax, times_2, FixedArray::kHeaderSize), ecx);
696 __ add(ebx, Immediate(Smi::FromInt(1))); 705 __ add(ebx, Immediate(Smi::FromInt(1)));
697 __ bind(&parameters_test); 706 __ bind(&parameters_test);
698 __ test(eax, eax); 707 __ test(eax, eax);
699 __ j(not_zero, &parameters_loop, Label::kNear); 708 __ j(not_zero, &parameters_loop, Label::kNear);
700 __ pop(ecx); 709 __ pop(ecx);
701 710
702 __ bind(&skip_parameter_map); 711 __ bind(&skip_parameter_map);
703 712
704 // ecx = argument count (tagged) 713 // ecx = argument count (tagged)
705 // edi = address of backing store (tagged) 714 // edi = address of backing store (tagged)
706 // esp[0] = address of new object (tagged) 715 // esp[0] = address of new object (tagged)
707 // esp[4] = mapped parameter count (tagged) 716 // esp[4] = address of receiver argument
708 // esp[12] = parameter count (tagged) 717 // esp[8] = mapped parameter count (tagged)
709 // esp[16] = address of receiver argument 718 // esp[12] = function
719 // esp[16] = parameter count (tagged)
710 // Copy arguments header and remaining slots (if there are any). 720 // Copy arguments header and remaining slots (if there are any).
711 __ mov(FieldOperand(edi, FixedArray::kMapOffset), 721 __ mov(FieldOperand(edi, FixedArray::kMapOffset),
712 Immediate(isolate()->factory()->fixed_array_map())); 722 Immediate(isolate()->factory()->fixed_array_map()));
713 __ mov(FieldOperand(edi, FixedArray::kLengthOffset), ecx); 723 __ mov(FieldOperand(edi, FixedArray::kLengthOffset), ecx);
714 724
715 Label arguments_loop, arguments_test; 725 Label arguments_loop, arguments_test;
716 __ mov(ebx, Operand(esp, 1 * kPointerSize)); 726 __ mov(ebx, Operand(esp, 2 * kPointerSize));
717 __ mov(edx, Operand(esp, 4 * kPointerSize)); 727 __ mov(edx, Operand(esp, 1 * kPointerSize));
718 __ sub(edx, ebx); // Is there a smarter way to do negative scaling? 728 __ sub(edx, ebx); // Is there a smarter way to do negative scaling?
719 __ sub(edx, ebx); 729 __ sub(edx, ebx);
720 __ jmp(&arguments_test, Label::kNear); 730 __ jmp(&arguments_test, Label::kNear);
721 731
722 __ bind(&arguments_loop); 732 __ bind(&arguments_loop);
723 __ sub(edx, Immediate(kPointerSize)); 733 __ sub(edx, Immediate(kPointerSize));
724 __ mov(eax, Operand(edx, 0)); 734 __ mov(eax, Operand(edx, 0));
725 __ mov(FieldOperand(edi, ebx, times_2, FixedArray::kHeaderSize), eax); 735 __ mov(FieldOperand(edi, ebx, times_2, FixedArray::kHeaderSize), eax);
726 __ add(ebx, Immediate(Smi::FromInt(1))); 736 __ add(ebx, Immediate(Smi::FromInt(1)));
727 737
728 __ bind(&arguments_test); 738 __ bind(&arguments_test);
729 __ cmp(ebx, ecx); 739 __ cmp(ebx, ecx);
730 __ j(less, &arguments_loop, Label::kNear); 740 __ j(less, &arguments_loop, Label::kNear);
731 741
732 // Restore. 742 // Restore.
733 __ pop(eax); // Address of arguments object. 743 __ pop(eax); // Address of arguments object.
734 __ pop(ebx); // Parameter count. 744 __ Drop(4);
735 745
736 // Return and remove the on-stack parameters. 746 // Return.
737 __ ret(3 * kPointerSize); 747 __ ret(0);
738 748
739 // Do the runtime call to allocate the arguments object. 749 // Do the runtime call to allocate the arguments object.
740 __ bind(&runtime); 750 __ bind(&runtime);
741 __ pop(eax); // Remove saved parameter count. 751 __ pop(eax); // Remove saved mapped parameter count.
742 __ mov(Operand(esp, 1 * kPointerSize), ecx); // Patch argument count. 752 __ pop(edi); // Pop saved function.
753 __ pop(eax); // Remove saved parameter count.
754 __ pop(eax); // Pop return address.
755 __ push(edi); // Push function.
756 __ push(edx); // Push parameters pointer.
757 __ push(ecx); // Push parameter count.
758 __ push(eax); // Push return address.
743 __ TailCallRuntime(Runtime::kNewSloppyArguments, 3, 1); 759 __ TailCallRuntime(Runtime::kNewSloppyArguments, 3, 1);
744 } 760 }
745 761
746 762
747 void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) { 763 void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) {
764 // ecx : number of parameters (tagged)
765 // edx : parameters pointer
766 // edi : function
748 // esp[0] : return address 767 // esp[0] : return address
749 // esp[4] : number of parameters 768
750 // esp[8] : receiver displacement 769 DCHECK(edi.is(ArgumentsAccessNewDescriptor::function()));
751 // esp[12] : function 770 DCHECK(ecx.is(ArgumentsAccessNewDescriptor::parameter_count()));
771 DCHECK(edx.is(ArgumentsAccessNewDescriptor::parameter_pointer()));
752 772
753 // Check if the calling frame is an arguments adaptor frame. 773 // Check if the calling frame is an arguments adaptor frame.
754 Label adaptor_frame, try_allocate, runtime; 774 Label try_allocate, runtime;
755 __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); 775 __ mov(ebx, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
756 __ mov(ecx, Operand(edx, StandardFrameConstants::kContextOffset)); 776 __ mov(eax, Operand(ebx, StandardFrameConstants::kContextOffset));
757 __ cmp(ecx, Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); 777 __ cmp(eax, Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
758 __ j(equal, &adaptor_frame, Label::kNear); 778 __ j(not_equal, &try_allocate, Label::kNear);
759
760 // Get the length from the frame.
761 __ mov(ecx, Operand(esp, 1 * kPointerSize));
762 __ jmp(&try_allocate, Label::kNear);
763 779
764 // Patch the arguments.length and the parameters pointer. 780 // Patch the arguments.length and the parameters pointer.
765 __ bind(&adaptor_frame); 781 __ mov(ecx, Operand(ebx, ArgumentsAdaptorFrameConstants::kLengthOffset));
766 __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset)); 782 __ lea(edx,
767 783 Operand(ebx, ecx, times_2, StandardFrameConstants::kCallerSPOffset));
768 __ lea(edx, Operand(edx, ecx, times_2,
769 StandardFrameConstants::kCallerSPOffset));
770 __ mov(Operand(esp, 1 * kPointerSize), ecx);
771 __ mov(Operand(esp, 2 * kPointerSize), edx);
772 784
773 // Try the new space allocation. Start out with computing the size of 785 // Try the new space allocation. Start out with computing the size of
774 // the arguments object and the elements array. 786 // the arguments object and the elements array.
775 Label add_arguments_object; 787 Label add_arguments_object;
776 __ bind(&try_allocate); 788 __ bind(&try_allocate);
777 __ test(ecx, ecx); 789 __ mov(eax, ecx);
790 __ test(eax, eax);
778 __ j(zero, &add_arguments_object, Label::kNear); 791 __ j(zero, &add_arguments_object, Label::kNear);
779 __ lea(ecx, Operand(ecx, times_2, FixedArray::kHeaderSize)); 792 __ lea(eax, Operand(eax, times_2, FixedArray::kHeaderSize));
780 __ bind(&add_arguments_object); 793 __ bind(&add_arguments_object);
781 __ add(ecx, Immediate(Heap::kStrictArgumentsObjectSize)); 794 __ add(eax, Immediate(Heap::kStrictArgumentsObjectSize));
782 795
783 // Do the allocation of both objects in one go. 796 // Do the allocation of both objects in one go.
784 __ Allocate(ecx, eax, edx, ebx, &runtime, TAG_OBJECT); 797 __ Allocate(eax, eax, ebx, no_reg, &runtime, TAG_OBJECT);
785 798
786 // Get the arguments map from the current native context. 799 // Get the arguments map from the current native context.
787 __ mov(edi, Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); 800 __ mov(edi, Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
788 __ mov(edi, FieldOperand(edi, GlobalObject::kNativeContextOffset)); 801 __ mov(edi, FieldOperand(edi, GlobalObject::kNativeContextOffset));
789 const int offset = Context::SlotOffset(Context::STRICT_ARGUMENTS_MAP_INDEX); 802 const int offset = Context::SlotOffset(Context::STRICT_ARGUMENTS_MAP_INDEX);
790 __ mov(edi, Operand(edi, offset)); 803 __ mov(edi, Operand(edi, offset));
791 804
792 __ mov(FieldOperand(eax, JSObject::kMapOffset), edi); 805 __ mov(FieldOperand(eax, JSObject::kMapOffset), edi);
793 __ mov(FieldOperand(eax, JSObject::kPropertiesOffset), 806 __ mov(FieldOperand(eax, JSObject::kPropertiesOffset),
794 masm->isolate()->factory()->empty_fixed_array()); 807 masm->isolate()->factory()->empty_fixed_array());
795 __ mov(FieldOperand(eax, JSObject::kElementsOffset), 808 __ mov(FieldOperand(eax, JSObject::kElementsOffset),
796 masm->isolate()->factory()->empty_fixed_array()); 809 masm->isolate()->factory()->empty_fixed_array());
797 810
798 // Get the length (smi tagged) and set that as an in-object property too. 811 // Get the length (smi tagged) and set that as an in-object property too.
799 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0); 812 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0);
800 __ mov(ecx, Operand(esp, 1 * kPointerSize));
801 __ AssertSmi(ecx); 813 __ AssertSmi(ecx);
802 __ mov(FieldOperand(eax, JSObject::kHeaderSize + 814 __ mov(FieldOperand(eax, JSObject::kHeaderSize +
803 Heap::kArgumentsLengthIndex * kPointerSize), 815 Heap::kArgumentsLengthIndex * kPointerSize),
804 ecx); 816 ecx);
805 817
806 // If there are no actual arguments, we're done. 818 // If there are no actual arguments, we're done.
807 Label done; 819 Label done;
808 __ test(ecx, ecx); 820 __ test(ecx, ecx);
809 __ j(zero, &done, Label::kNear); 821 __ j(zero, &done, Label::kNear);
810 822
811 // Get the parameters pointer from the stack.
812 __ mov(edx, Operand(esp, 2 * kPointerSize));
813
814 // Set up the elements pointer in the allocated arguments object and 823 // Set up the elements pointer in the allocated arguments object and
815 // initialize the header in the elements fixed array. 824 // initialize the header in the elements fixed array.
816 __ lea(edi, Operand(eax, Heap::kStrictArgumentsObjectSize)); 825 __ lea(edi, Operand(eax, Heap::kStrictArgumentsObjectSize));
817 __ mov(FieldOperand(eax, JSObject::kElementsOffset), edi); 826 __ mov(FieldOperand(eax, JSObject::kElementsOffset), edi);
818 __ mov(FieldOperand(edi, FixedArray::kMapOffset), 827 __ mov(FieldOperand(edi, FixedArray::kMapOffset),
819 Immediate(isolate()->factory()->fixed_array_map())); 828 Immediate(isolate()->factory()->fixed_array_map()));
829 __ mov(FieldOperand(edi, FixedArray::kLengthOffset), ecx);
820 830
821 __ mov(FieldOperand(edi, FixedArray::kLengthOffset), ecx);
822 // Untag the length for the loop below. 831 // Untag the length for the loop below.
823 __ SmiUntag(ecx); 832 __ SmiUntag(ecx);
824 833
825 // Copy the fixed array slots. 834 // Copy the fixed array slots.
826 Label loop; 835 Label loop;
827 __ bind(&loop); 836 __ bind(&loop);
828 __ mov(ebx, Operand(edx, -1 * kPointerSize)); // Skip receiver. 837 __ mov(ebx, Operand(edx, -1 * kPointerSize)); // Skip receiver.
829 __ mov(FieldOperand(edi, FixedArray::kHeaderSize), ebx); 838 __ mov(FieldOperand(edi, FixedArray::kHeaderSize), ebx);
830 __ add(edi, Immediate(kPointerSize)); 839 __ add(edi, Immediate(kPointerSize));
831 __ sub(edx, Immediate(kPointerSize)); 840 __ sub(edx, Immediate(kPointerSize));
832 __ dec(ecx); 841 __ dec(ecx);
833 __ j(not_zero, &loop); 842 __ j(not_zero, &loop);
834 843
835 // Return and remove the on-stack parameters. 844 // Return.
836 __ bind(&done); 845 __ bind(&done);
837 __ ret(3 * kPointerSize); 846 __ ret(0);
838 847
839 // Do the runtime call to allocate the arguments object. 848 // Do the runtime call to allocate the arguments object.
840 __ bind(&runtime); 849 __ bind(&runtime);
850 __ pop(eax); // Pop return address.
851 __ push(edi); // Push function.
852 __ push(edx); // Push parameters pointer.
853 __ push(ecx); // Push parameter count.
854 __ push(eax); // Push return address.
841 __ TailCallRuntime(Runtime::kNewStrictArguments, 3, 1); 855 __ TailCallRuntime(Runtime::kNewStrictArguments, 3, 1);
842 } 856 }
843 857
844 858
845 void RegExpExecStub::Generate(MacroAssembler* masm) { 859 void RegExpExecStub::Generate(MacroAssembler* masm) {
846 // Just jump directly to runtime if native RegExp is not selected at compile 860 // Just jump directly to runtime if native RegExp is not selected at compile
847 // time or if regexp entry in generated code is turned off runtime switch or 861 // time or if regexp entry in generated code is turned off runtime switch or
848 // at compilation. 862 // at compilation.
849 #ifdef V8_INTERPRETED_REGEXP 863 #ifdef V8_INTERPRETED_REGEXP
850 __ TailCallRuntime(Runtime::kRegExpExec, 4, 1); 864 __ TailCallRuntime(Runtime::kRegExpExec, 4, 1);
(...skipping 4638 matching lines...) Expand 10 before | Expand all | Expand 10 after
5489 Operand(ebp, 7 * kPointerSize), NULL); 5503 Operand(ebp, 7 * kPointerSize), NULL);
5490 } 5504 }
5491 5505
5492 5506
5493 #undef __ 5507 #undef __
5494 5508
5495 } // namespace internal 5509 } // namespace internal
5496 } // namespace v8 5510 } // namespace v8
5497 5511
5498 #endif // V8_TARGET_ARCH_X87 5512 #endif // V8_TARGET_ARCH_X87
OLDNEW
« no previous file with comments | « src/full-codegen/x87/full-codegen-x87.cc ('k') | src/x87/interface-descriptors-x87.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698