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

Side by Side Diff: src/x64/stub-cache-x64.cc

Issue 5188006: Push version 2.5.7 to trunk.... (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
Patch Set: Created 10 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/x64/macro-assembler-x64.cc ('k') | src/x64/virtual-frame-x64.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 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 479 matching lines...) Expand 10 before | Expand all | Expand 10 after
490 void StubCompiler::GenerateLoadFunctionPrototype(MacroAssembler* masm, 490 void StubCompiler::GenerateLoadFunctionPrototype(MacroAssembler* masm,
491 Register receiver, 491 Register receiver,
492 Register result, 492 Register result,
493 Register scratch, 493 Register scratch,
494 Label* miss_label) { 494 Label* miss_label) {
495 __ TryGetFunctionPrototype(receiver, result, miss_label); 495 __ TryGetFunctionPrototype(receiver, result, miss_label);
496 if (!result.is(rax)) __ movq(rax, result); 496 if (!result.is(rax)) __ movq(rax, result);
497 __ ret(0); 497 __ ret(0);
498 } 498 }
499 499
500 // Number of pointers to be reserved on stack for fast API call.
501 static const int kFastApiCallArguments = 3;
500 502
501 // Reserves space for the extra arguments to FastHandleApiCall in the 503 // Reserves space for the extra arguments to API function in the
502 // caller's frame. 504 // caller's frame.
503 // 505 //
504 // These arguments are set by CheckPrototypes and GenerateFastApiCall. 506 // These arguments are set by CheckPrototypes and GenerateFastApiCall.
505 static void ReserveSpaceForFastApiCall(MacroAssembler* masm, Register scratch) { 507 static void ReserveSpaceForFastApiCall(MacroAssembler* masm, Register scratch) {
506 // ----------- S t a t e ------------- 508 // ----------- S t a t e -------------
507 // -- rsp[0] : return address 509 // -- rsp[0] : return address
508 // -- rsp[8] : last argument in the internal frame of the caller 510 // -- rsp[8] : last argument in the internal frame of the caller
509 // ----------------------------------- 511 // -----------------------------------
510 __ movq(scratch, Operand(rsp, 0)); 512 __ movq(scratch, Operand(rsp, 0));
511 __ subq(rsp, Immediate(4 * kPointerSize)); 513 __ subq(rsp, Immediate(kFastApiCallArguments * kPointerSize));
512 __ movq(Operand(rsp, 0), scratch); 514 __ movq(Operand(rsp, 0), scratch);
513 __ Move(scratch, Smi::FromInt(0)); 515 __ Move(scratch, Smi::FromInt(0));
514 __ movq(Operand(rsp, 1 * kPointerSize), scratch); 516 for (int i = 1; i <= kFastApiCallArguments; i++) {
515 __ movq(Operand(rsp, 2 * kPointerSize), scratch); 517 __ movq(Operand(rsp, i * kPointerSize), scratch);
516 __ movq(Operand(rsp, 3 * kPointerSize), scratch); 518 }
517 __ movq(Operand(rsp, 4 * kPointerSize), scratch);
518 } 519 }
519 520
520 521
521 // Undoes the effects of ReserveSpaceForFastApiCall. 522 // Undoes the effects of ReserveSpaceForFastApiCall.
522 static void FreeSpaceForFastApiCall(MacroAssembler* masm, Register scratch) { 523 static void FreeSpaceForFastApiCall(MacroAssembler* masm, Register scratch) {
523 // ----------- S t a t e ------------- 524 // ----------- S t a t e -------------
524 // -- rsp[0] : return address 525 // -- rsp[0] : return address.
525 // -- rsp[8] : last fast api call extra argument 526 // -- rsp[8] : last fast api call extra argument.
526 // -- ... 527 // -- ...
527 // -- rsp[32] : first fast api call extra argument 528 // -- rsp[kFastApiCallArguments * 8] : first fast api call extra argument.
528 // -- rsp[40] : last argument in the internal frame 529 // -- rsp[kFastApiCallArguments * 8 + 8] : last argument in the internal
530 // frame.
529 // ----------------------------------- 531 // -----------------------------------
530 __ movq(scratch, Operand(rsp, 0)); 532 __ movq(scratch, Operand(rsp, 0));
531 __ movq(Operand(rsp, 4 * kPointerSize), scratch); 533 __ movq(Operand(rsp, kFastApiCallArguments * kPointerSize), scratch);
532 __ addq(rsp, Immediate(kPointerSize * 4)); 534 __ addq(rsp, Immediate(kPointerSize * kFastApiCallArguments));
533 } 535 }
534 536
535 537
536 // Generates call to FastHandleApiCall builtin. 538 // Generates call to API function.
537 static void GenerateFastApiCall(MacroAssembler* masm, 539 static bool GenerateFastApiCall(MacroAssembler* masm,
538 const CallOptimization& optimization, 540 const CallOptimization& optimization,
539 int argc) { 541 int argc,
542 Failure** failure) {
540 // ----------- S t a t e ------------- 543 // ----------- S t a t e -------------
541 // -- rsp[0] : return address 544 // -- rsp[0] : return address
542 // -- rsp[8] : object passing the type check 545 // -- rsp[8] : object passing the type check
543 // (last fast api call extra argument, 546 // (last fast api call extra argument,
544 // set by CheckPrototypes) 547 // set by CheckPrototypes)
545 // -- rsp[16] : api call data 548 // -- rsp[16] : api function
546 // -- rsp[24] : api callback
547 // -- rsp[32] : api function
548 // (first fast api call extra argument) 549 // (first fast api call extra argument)
549 // -- rsp[40] : last argument 550 // -- rsp[24] : api call data
551 // -- rsp[32] : last argument
550 // -- ... 552 // -- ...
551 // -- rsp[(argc + 5) * 8] : first argument 553 // -- rsp[(argc + 3) * 8] : first argument
552 // -- rsp[(argc + 6) * 8] : receiver 554 // -- rsp[(argc + 4) * 8] : receiver
553 // ----------------------------------- 555 // -----------------------------------
554 556
555 // Get the function and setup the context. 557 // Get the function and setup the context.
556 JSFunction* function = optimization.constant_function(); 558 JSFunction* function = optimization.constant_function();
557 __ Move(rdi, Handle<JSFunction>(function)); 559 __ Move(rdi, Handle<JSFunction>(function));
558 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); 560 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
559 561
560 // Pass the additional arguments FastHandleApiCall expects. 562 // Pass the additional arguments.
561 __ movq(Operand(rsp, 4 * kPointerSize), rdi); 563 __ movq(Operand(rsp, 2 * kPointerSize), rdi);
562 bool info_loaded = false; 564 Object* call_data = optimization.api_call_info()->data();
563 Object* callback = optimization.api_call_info()->callback(); 565 Handle<CallHandlerInfo> api_call_info_handle(optimization.api_call_info());
564 if (Heap::InNewSpace(callback)) { 566 if (Heap::InNewSpace(call_data)) {
565 info_loaded = true; 567 __ Move(rcx, api_call_info_handle);
566 __ Move(rcx, Handle<CallHandlerInfo>(optimization.api_call_info())); 568 __ movq(rbx, FieldOperand(rcx, CallHandlerInfo::kDataOffset));
567 __ movq(rbx, FieldOperand(rcx, CallHandlerInfo::kCallbackOffset));
568 __ movq(Operand(rsp, 3 * kPointerSize), rbx); 569 __ movq(Operand(rsp, 3 * kPointerSize), rbx);
569 } else { 570 } else {
570 __ Move(Operand(rsp, 3 * kPointerSize), Handle<Object>(callback)); 571 __ Move(Operand(rsp, 3 * kPointerSize), Handle<Object>(call_data));
571 }
572 Object* call_data = optimization.api_call_info()->data();
573 if (Heap::InNewSpace(call_data)) {
574 if (!info_loaded) {
575 __ Move(rcx, Handle<CallHandlerInfo>(optimization.api_call_info()));
576 }
577 __ movq(rbx, FieldOperand(rcx, CallHandlerInfo::kDataOffset));
578 __ movq(Operand(rsp, 2 * kPointerSize), rbx);
579 } else {
580 __ Move(Operand(rsp, 2 * kPointerSize), Handle<Object>(call_data));
581 } 572 }
582 573
583 // Set the number of arguments. 574 // Prepare arguments.
584 __ movq(rax, Immediate(argc + 4)); 575 __ lea(rbx, Operand(rsp, 3 * kPointerSize));
585 576
586 // Jump to the fast api call builtin (tail call). 577 Object* callback = optimization.api_call_info()->callback();
587 Handle<Code> code = Handle<Code>( 578 Address api_function_address = v8::ToCData<Address>(callback);
588 Builtins::builtin(Builtins::FastHandleApiCall)); 579 ApiFunction fun(api_function_address);
589 ParameterCount expected(0); 580
590 __ InvokeCode(code, expected, expected, 581 #ifdef _WIN64
591 RelocInfo::CODE_TARGET, JUMP_FUNCTION); 582 // Win64 uses first register--rcx--for returned value.
583 Register arguments_arg = rdx;
584 #else
585 Register arguments_arg = rdi;
586 #endif
587
588 // Allocate the v8::Arguments structure in the arguments' space since
589 // it's not controlled by GC.
590 const int kApiStackSpace = 4;
591
592 __ PrepareCallApiFunction(kApiStackSpace);
593
594 __ movq(StackSpaceOperand(0), rbx); // v8::Arguments::implicit_args_.
595 __ addq(rbx, Immediate(argc * kPointerSize));
596 __ movq(StackSpaceOperand(1), rbx); // v8::Arguments::values_.
597 __ Set(StackSpaceOperand(2), argc); // v8::Arguments::length_.
598 // v8::Arguments::is_construct_call_.
599 __ Set(StackSpaceOperand(3), 0);
600
601 // v8::InvocationCallback's argument.
602 __ lea(arguments_arg, StackSpaceOperand(0));
603 // Emitting a stub call may try to allocate (if the code is not
604 // already generated). Do not allow the assembler to perform a
605 // garbage collection but instead return the allocation failure
606 // object.
607 MaybeObject* result =
608 masm->TryCallApiFunctionAndReturn(&fun, argc + kFastApiCallArguments + 1);
609 if (result->IsFailure()) {
610 *failure = Failure::cast(result);
611 return false;
612 }
613 return true;
592 } 614 }
593 615
594 616
595 class CallInterceptorCompiler BASE_EMBEDDED { 617 class CallInterceptorCompiler BASE_EMBEDDED {
596 public: 618 public:
597 CallInterceptorCompiler(StubCompiler* stub_compiler, 619 CallInterceptorCompiler(StubCompiler* stub_compiler,
598 const ParameterCount& arguments, 620 const ParameterCount& arguments,
599 Register name) 621 Register name)
600 : stub_compiler_(stub_compiler), 622 : stub_compiler_(stub_compiler),
601 arguments_(arguments), 623 arguments_(arguments),
602 name_(name) {} 624 name_(name) {}
603 625
604 void Compile(MacroAssembler* masm, 626 bool Compile(MacroAssembler* masm,
605 JSObject* object, 627 JSObject* object,
606 JSObject* holder, 628 JSObject* holder,
607 String* name, 629 String* name,
608 LookupResult* lookup, 630 LookupResult* lookup,
609 Register receiver, 631 Register receiver,
610 Register scratch1, 632 Register scratch1,
611 Register scratch2, 633 Register scratch2,
612 Register scratch3, 634 Register scratch3,
613 Label* miss) { 635 Label* miss,
636 Failure** failure) {
614 ASSERT(holder->HasNamedInterceptor()); 637 ASSERT(holder->HasNamedInterceptor());
615 ASSERT(!holder->GetNamedInterceptor()->getter()->IsUndefined()); 638 ASSERT(!holder->GetNamedInterceptor()->getter()->IsUndefined());
616 639
617 // Check that the receiver isn't a smi. 640 // Check that the receiver isn't a smi.
618 __ JumpIfSmi(receiver, miss); 641 __ JumpIfSmi(receiver, miss);
619 642
620 CallOptimization optimization(lookup); 643 CallOptimization optimization(lookup);
621 644
622 if (optimization.is_constant_call()) { 645 if (optimization.is_constant_call()) {
623 CompileCacheable(masm, 646 return CompileCacheable(masm,
624 object, 647 object,
625 receiver, 648 receiver,
626 scratch1, 649 scratch1,
627 scratch2, 650 scratch2,
628 scratch3, 651 scratch3,
629 holder, 652 holder,
630 lookup, 653 lookup,
631 name, 654 name,
632 optimization, 655 optimization,
633 miss); 656 miss,
657 failure);
634 } else { 658 } else {
635 CompileRegular(masm, 659 CompileRegular(masm,
636 object, 660 object,
637 receiver, 661 receiver,
638 scratch1, 662 scratch1,
639 scratch2, 663 scratch2,
640 scratch3, 664 scratch3,
641 name, 665 name,
642 holder, 666 holder,
643 miss); 667 miss);
668 return true;
644 } 669 }
645 } 670 }
646 671
647 private: 672 private:
648 void CompileCacheable(MacroAssembler* masm, 673 bool CompileCacheable(MacroAssembler* masm,
649 JSObject* object, 674 JSObject* object,
650 Register receiver, 675 Register receiver,
651 Register scratch1, 676 Register scratch1,
652 Register scratch2, 677 Register scratch2,
653 Register scratch3, 678 Register scratch3,
654 JSObject* interceptor_holder, 679 JSObject* interceptor_holder,
655 LookupResult* lookup, 680 LookupResult* lookup,
656 String* name, 681 String* name,
657 const CallOptimization& optimization, 682 const CallOptimization& optimization,
658 Label* miss_label) { 683 Label* miss_label,
684 Failure** failure) {
659 ASSERT(optimization.is_constant_call()); 685 ASSERT(optimization.is_constant_call());
660 ASSERT(!lookup->holder()->IsGlobalObject()); 686 ASSERT(!lookup->holder()->IsGlobalObject());
661 687
662 int depth1 = kInvalidProtoDepth; 688 int depth1 = kInvalidProtoDepth;
663 int depth2 = kInvalidProtoDepth; 689 int depth2 = kInvalidProtoDepth;
664 bool can_do_fast_api_call = false; 690 bool can_do_fast_api_call = false;
665 if (optimization.is_simple_api_call() && 691 if (optimization.is_simple_api_call() &&
666 !lookup->holder()->IsGlobalObject()) { 692 !lookup->holder()->IsGlobalObject()) {
667 depth1 = 693 depth1 =
668 optimization.GetPrototypeDepthOfExpectedType(object, 694 optimization.GetPrototypeDepthOfExpectedType(object,
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
710 } else { 736 } else {
711 // CheckPrototypes has a side effect of fetching a 'holder' 737 // CheckPrototypes has a side effect of fetching a 'holder'
712 // for API (object which is instanceof for the signature). It's 738 // for API (object which is instanceof for the signature). It's
713 // safe to omit it here, as if present, it should be fetched 739 // safe to omit it here, as if present, it should be fetched
714 // by the previous CheckPrototypes. 740 // by the previous CheckPrototypes.
715 ASSERT(depth2 == kInvalidProtoDepth); 741 ASSERT(depth2 == kInvalidProtoDepth);
716 } 742 }
717 743
718 // Invoke function. 744 // Invoke function.
719 if (can_do_fast_api_call) { 745 if (can_do_fast_api_call) {
720 GenerateFastApiCall(masm, optimization, arguments_.immediate()); 746 bool success = GenerateFastApiCall(masm,
747 optimization,
748 arguments_.immediate(),
749 failure);
750 if (!success) {
751 return false;
752 }
721 } else { 753 } else {
722 __ InvokeFunction(optimization.constant_function(), arguments_, 754 __ InvokeFunction(optimization.constant_function(), arguments_,
723 JUMP_FUNCTION); 755 JUMP_FUNCTION);
724 } 756 }
725 757
726 // Deferred code for fast API call case---clean preallocated space. 758 // Deferred code for fast API call case---clean preallocated space.
727 if (can_do_fast_api_call) { 759 if (can_do_fast_api_call) {
728 __ bind(&miss_cleanup); 760 __ bind(&miss_cleanup);
729 FreeSpaceForFastApiCall(masm, scratch1); 761 FreeSpaceForFastApiCall(masm, scratch1);
730 __ jmp(miss_label); 762 __ jmp(miss_label);
731 } 763 }
732 764
733 // Invoke a regular function. 765 // Invoke a regular function.
734 __ bind(&regular_invoke); 766 __ bind(&regular_invoke);
735 if (can_do_fast_api_call) { 767 if (can_do_fast_api_call) {
736 FreeSpaceForFastApiCall(masm, scratch1); 768 FreeSpaceForFastApiCall(masm, scratch1);
737 } 769 }
770
771 return true;
738 } 772 }
739 773
740 void CompileRegular(MacroAssembler* masm, 774 void CompileRegular(MacroAssembler* masm,
741 JSObject* object, 775 JSObject* object,
742 Register receiver, 776 Register receiver,
743 Register scratch1, 777 Register scratch1,
744 Register scratch2, 778 Register scratch2,
745 Register scratch3, 779 Register scratch3,
746 String* name, 780 String* name,
747 JSObject* interceptor_holder, 781 JSObject* interceptor_holder,
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
951 case RECEIVER_MAP_CHECK: 985 case RECEIVER_MAP_CHECK:
952 __ IncrementCounter(&Counters::call_const, 1); 986 __ IncrementCounter(&Counters::call_const, 1);
953 987
954 if (optimization.is_simple_api_call() && !object->IsGlobalObject()) { 988 if (optimization.is_simple_api_call() && !object->IsGlobalObject()) {
955 depth = optimization.GetPrototypeDepthOfExpectedType( 989 depth = optimization.GetPrototypeDepthOfExpectedType(
956 JSObject::cast(object), holder); 990 JSObject::cast(object), holder);
957 } 991 }
958 992
959 if (depth != kInvalidProtoDepth) { 993 if (depth != kInvalidProtoDepth) {
960 __ IncrementCounter(&Counters::call_const_fast_api, 1); 994 __ IncrementCounter(&Counters::call_const_fast_api, 1);
961 ReserveSpaceForFastApiCall(masm(), rax); 995 // Allocate space for v8::Arguments implicit values. Must be initialized
996 // before to call any runtime function.
997 __ subq(rsp, Immediate(kFastApiCallArguments * kPointerSize));
962 } 998 }
963 999
964 // Check that the maps haven't changed. 1000 // Check that the maps haven't changed.
965 CheckPrototypes(JSObject::cast(object), rdx, holder, 1001 CheckPrototypes(JSObject::cast(object), rdx, holder,
966 rbx, rax, rdi, name, depth, &miss); 1002 rbx, rax, rdi, name, depth, &miss);
967 1003
968 // Patch the receiver on the stack with the global proxy if 1004 // Patch the receiver on the stack with the global proxy if
969 // necessary. 1005 // necessary.
970 if (object->IsGlobalObject()) { 1006 if (object->IsGlobalObject()) {
971 ASSERT(depth == kInvalidProtoDepth); 1007 ASSERT(depth == kInvalidProtoDepth);
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1029 rbx, rdx, rdi, name, &miss); 1065 rbx, rdx, rdi, name, &miss);
1030 } 1066 }
1031 break; 1067 break;
1032 } 1068 }
1033 1069
1034 default: 1070 default:
1035 UNREACHABLE(); 1071 UNREACHABLE();
1036 } 1072 }
1037 1073
1038 if (depth != kInvalidProtoDepth) { 1074 if (depth != kInvalidProtoDepth) {
1039 GenerateFastApiCall(masm(), optimization, argc); 1075 Failure* failure;
1076 // Move the return address on top of the stack.
1077 __ movq(rax, Operand(rsp, 3 * kPointerSize));
1078 __ movq(Operand(rsp, 0 * kPointerSize), rax);
1079
1080 // rsp[2 * kPointerSize] is uninitialized, rsp[3 * kPointerSize] contains
1081 // duplicate of return address and will be overwritten.
1082 bool success = GenerateFastApiCall(masm(), optimization, argc, &failure);
1083 if (!success) {
1084 return failure;
1085 }
1040 } else { 1086 } else {
1041 __ InvokeFunction(function, arguments(), JUMP_FUNCTION); 1087 __ InvokeFunction(function, arguments(), JUMP_FUNCTION);
1042 } 1088 }
1043 1089
1044 // Handle call cache miss. 1090 // Handle call cache miss.
1045 __ bind(&miss); 1091 __ bind(&miss);
1046 if (depth != kInvalidProtoDepth) { 1092 if (depth != kInvalidProtoDepth) {
1047 FreeSpaceForFastApiCall(masm(), rax); 1093 __ addq(rsp, Immediate(kFastApiCallArguments * kPointerSize));
1048 } 1094 }
1049 1095
1050 // Handle call cache miss. 1096 // Handle call cache miss.
1051 __ bind(&miss_in_smi_check); 1097 __ bind(&miss_in_smi_check);
1052 Object* obj; 1098 Object* obj;
1053 { MaybeObject* maybe_obj = GenerateMissBranch(); 1099 { MaybeObject* maybe_obj = GenerateMissBranch();
1054 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 1100 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
1055 } 1101 }
1056 1102
1057 // Return the generated code. 1103 // Return the generated code.
(...skipping 658 matching lines...) Expand 10 before | Expand all | Expand 10 after
1716 // Get the number of arguments. 1762 // Get the number of arguments.
1717 const int argc = arguments().immediate(); 1763 const int argc = arguments().immediate();
1718 1764
1719 LookupResult lookup; 1765 LookupResult lookup;
1720 LookupPostInterceptor(holder, name, &lookup); 1766 LookupPostInterceptor(holder, name, &lookup);
1721 1767
1722 // Get the receiver from the stack. 1768 // Get the receiver from the stack.
1723 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); 1769 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
1724 1770
1725 CallInterceptorCompiler compiler(this, arguments(), rcx); 1771 CallInterceptorCompiler compiler(this, arguments(), rcx);
1726 compiler.Compile(masm(), 1772 Failure* failure;
1727 object, 1773 bool success = compiler.Compile(masm(),
1728 holder, 1774 object,
1729 name, 1775 holder,
1730 &lookup, 1776 name,
1731 rdx, 1777 &lookup,
1732 rbx, 1778 rdx,
1733 rdi, 1779 rbx,
1734 rax, 1780 rdi,
1735 &miss); 1781 rax,
1782 &miss,
1783 &failure);
1784 if (!success) {
1785 return failure;
1786 }
1736 1787
1737 // Restore receiver. 1788 // Restore receiver.
1738 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); 1789 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
1739 1790
1740 // Check that the function really is a function. 1791 // Check that the function really is a function.
1741 __ JumpIfSmi(rax, &miss); 1792 __ JumpIfSmi(rax, &miss);
1742 __ CmpObjectType(rax, JS_FUNCTION_TYPE, rbx); 1793 __ CmpObjectType(rax, JS_FUNCTION_TYPE, rbx);
1743 __ j(not_equal, &miss); 1794 __ j(not_equal, &miss);
1744 1795
1745 // Patch the receiver on the stack with the global proxy if 1796 // Patch the receiver on the stack with the global proxy if
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
1837 JSObject* holder, 1888 JSObject* holder,
1838 AccessorInfo* callback) { 1889 AccessorInfo* callback) {
1839 // ----------- S t a t e ------------- 1890 // ----------- S t a t e -------------
1840 // -- rax : receiver 1891 // -- rax : receiver
1841 // -- rcx : name 1892 // -- rcx : name
1842 // -- rsp[0] : return address 1893 // -- rsp[0] : return address
1843 // ----------------------------------- 1894 // -----------------------------------
1844 Label miss; 1895 Label miss;
1845 1896
1846 Failure* failure = Failure::InternalError(); 1897 Failure* failure = Failure::InternalError();
1847 bool success = GenerateLoadCallback(object, holder, rax, rcx, rbx, rdx, rdi, 1898 bool success = GenerateLoadCallback(object, holder, rax, rcx, rdx, rbx, rdi,
1848 callback, name, &miss, &failure); 1899 callback, name, &miss, &failure);
1849 if (!success) { 1900 if (!success) {
1850 miss.Unuse(); 1901 miss.Unuse();
1851 return failure; 1902 return failure;
1852 } 1903 }
1853 1904
1854 __ bind(&miss); 1905 __ bind(&miss);
1855 GenerateLoadMiss(masm(), Code::LOAD_IC); 1906 GenerateLoadMiss(masm(), Code::LOAD_IC);
1856 1907
1857 // Return the generated code. 1908 // Return the generated code.
(...skipping 720 matching lines...) Expand 10 before | Expand all | Expand 10 after
2578 // Check that the receiver isn't a smi. 2629 // Check that the receiver isn't a smi.
2579 __ JumpIfSmi(receiver, miss); 2630 __ JumpIfSmi(receiver, miss);
2580 2631
2581 // Check that the maps haven't changed. 2632 // Check that the maps haven't changed.
2582 Register reg = 2633 Register reg =
2583 CheckPrototypes(object, receiver, holder, scratch1, 2634 CheckPrototypes(object, receiver, holder, scratch1,
2584 scratch2, scratch3, name, miss); 2635 scratch2, scratch3, name, miss);
2585 2636
2586 Handle<AccessorInfo> callback_handle(callback); 2637 Handle<AccessorInfo> callback_handle(callback);
2587 2638
2588 __ EnterInternalFrame(); 2639 // Insert additional parameters into the stack frame above return address.
2589 // Push the stack address where the list of arguments ends. 2640 ASSERT(!scratch2.is(reg));
2590 __ movq(scratch2, rsp); 2641 __ pop(scratch2); // Get return address to place it below.
2591 __ subq(scratch2, Immediate(2 * kPointerSize)); 2642
2592 __ push(scratch2);
2593 __ push(receiver); // receiver 2643 __ push(receiver); // receiver
2594 __ push(reg); // holder 2644 __ push(reg); // holder
2595 if (Heap::InNewSpace(callback_handle->data())) { 2645 if (Heap::InNewSpace(callback_handle->data())) {
2596 __ Move(scratch2, callback_handle); 2646 __ Move(scratch1, callback_handle);
2597 __ push(FieldOperand(scratch2, AccessorInfo::kDataOffset)); // data 2647 __ push(FieldOperand(scratch1, AccessorInfo::kDataOffset)); // data
2598 } else { 2648 } else {
2599 __ Push(Handle<Object>(callback_handle->data())); 2649 __ Push(Handle<Object>(callback_handle->data()));
2600 } 2650 }
2601 __ push(name_reg); // name 2651 __ push(name_reg); // name
2602 // Save a pointer to where we pushed the arguments pointer. 2652 // Save a pointer to where we pushed the arguments pointer.
2603 // This will be passed as the const AccessorInfo& to the C++ callback. 2653 // This will be passed as the const AccessorInfo& to the C++ callback.
2604 2654
2605 #ifdef _WIN64 2655 #ifdef _WIN64
2606 // Win64 uses first register--rcx--for returned value. 2656 // Win64 uses first register--rcx--for returned value.
2607 Register accessor_info_arg = r8; 2657 Register accessor_info_arg = r8;
2608 Register name_arg = rdx; 2658 Register name_arg = rdx;
2609 #else 2659 #else
2610 Register accessor_info_arg = rdx; // temporary, copied to rsi by the stub. 2660 Register accessor_info_arg = rsi;
2611 Register name_arg = rdi; 2661 Register name_arg = rdi;
2612 #endif 2662 #endif
2613 2663
2614 __ movq(accessor_info_arg, rsp); 2664 ASSERT(!name_arg.is(scratch2));
2615 __ addq(accessor_info_arg, Immediate(4 * kPointerSize));
2616 __ movq(name_arg, rsp); 2665 __ movq(name_arg, rsp);
2666 __ push(scratch2); // Restore return address.
2617 2667
2618 // Do call through the api. 2668 // Do call through the api.
2619 ASSERT_EQ(5, ApiGetterEntryStub::kStackSpace);
2620 Address getter_address = v8::ToCData<Address>(callback->getter()); 2669 Address getter_address = v8::ToCData<Address>(callback->getter());
2621 ApiFunction fun(getter_address); 2670 ApiFunction fun(getter_address);
2622 ApiGetterEntryStub stub(callback_handle, &fun); 2671
2623 #ifdef _WIN64 2672 // 3 elements array for v8::Agruments::values_ and handler for name.
2624 // We need to prepare a slot for result handle on stack and put 2673 const int kStackSpace = 4;
2625 // a pointer to it into 1st arg register. 2674
2626 __ push(Immediate(0)); 2675 // Allocate v8::AccessorInfo in non-GCed stack space.
2627 __ movq(rcx, rsp); 2676 const int kArgStackSpace = 1;
2628 #endif 2677
2678 __ PrepareCallApiFunction(kArgStackSpace);
2679 __ lea(rax, Operand(name_arg, 3 * kPointerSize));
2680
2681 // v8::AccessorInfo::args_.
2682 __ movq(StackSpaceOperand(0), rax);
2683
2684 // The context register (rsi) has been saved in PrepareCallApiFunction and
2685 // could be used to pass arguments.
2686 __ lea(accessor_info_arg, StackSpaceOperand(0));
2687
2629 // Emitting a stub call may try to allocate (if the code is not 2688 // Emitting a stub call may try to allocate (if the code is not
2630 // already generated). Do not allow the assembler to perform a 2689 // already generated). Do not allow the assembler to perform a
2631 // garbage collection but instead return the allocation failure 2690 // garbage collection but instead return the allocation failure
2632 // object. 2691 // object.
2633 MaybeObject* result = masm()->TryCallStub(&stub); 2692 MaybeObject* result = masm()->TryCallApiFunctionAndReturn(&fun, kStackSpace);
2634 if (result->IsFailure()) { 2693 if (result->IsFailure()) {
2635 *failure = Failure::cast(result); 2694 *failure = Failure::cast(result);
2636 return false; 2695 return false;
2637 } 2696 }
2638 #ifdef _WIN64
2639 // Discard allocated slot.
2640 __ addq(rsp, Immediate(kPointerSize));
2641 #endif
2642 __ LeaveInternalFrame();
2643
2644 __ ret(0);
2645
2646 return true; 2697 return true;
2647 } 2698 }
2648 2699
2649 2700
2650 Register StubCompiler::CheckPrototypes(JSObject* object, 2701 Register StubCompiler::CheckPrototypes(JSObject* object,
2651 Register object_reg, 2702 Register object_reg,
2652 JSObject* holder, 2703 JSObject* holder,
2653 Register holder_reg, 2704 Register holder_reg,
2654 Register scratch1, 2705 Register scratch1,
2655 Register scratch2, 2706 Register scratch2,
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after
2965 // Return the generated code. 3016 // Return the generated code.
2966 return GetCode(); 3017 return GetCode();
2967 } 3018 }
2968 3019
2969 3020
2970 #undef __ 3021 #undef __
2971 3022
2972 } } // namespace v8::internal 3023 } } // namespace v8::internal
2973 3024
2974 #endif // V8_TARGET_ARCH_X64 3025 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/macro-assembler-x64.cc ('k') | src/x64/virtual-frame-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698