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

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

Issue 12781004: Refactoring Store ICs. A first step towards polymorphic store ICs. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: space nits Created 7 years, 9 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
« no previous file with comments | « src/ia32/code-stubs-ia32.cc ('k') | src/log.h » ('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 // 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 351 matching lines...) Expand 10 before | Expand all | Expand 10 after
362 Register receiver, 362 Register receiver,
363 Register scratch1, 363 Register scratch1,
364 Register scratch2, 364 Register scratch2,
365 Label* miss_label) { 365 Label* miss_label) {
366 __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label); 366 __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label);
367 __ mov(eax, scratch1); 367 __ mov(eax, scratch1);
368 __ ret(0); 368 __ ret(0);
369 } 369 }
370 370
371 371
372 // Load a fast property out of a holder object (src). In-object properties
373 // are loaded directly otherwise the property is loaded from the properties
374 // fixed array.
375 void StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm,
376 Register dst,
377 Register src,
378 Handle<JSObject> holder,
379 PropertyIndex index) {
380 DoGenerateFastPropertyLoad(
381 masm, dst, src, index.is_inobject(holder), index.translate(holder));
382 }
383
384
385 void StubCompiler::DoGenerateFastPropertyLoad(MacroAssembler* masm, 372 void StubCompiler::DoGenerateFastPropertyLoad(MacroAssembler* masm,
386 Register dst, 373 Register dst,
387 Register src, 374 Register src,
388 bool inobject, 375 bool inobject,
389 int index) { 376 int index) {
390 int offset = index * kPointerSize; 377 int offset = index * kPointerSize;
391 if (!inobject) { 378 if (!inobject) {
392 // Calculate the offset into the properties array. 379 // Calculate the offset into the properties array.
393 offset = offset + FixedArray::kHeaderSize; 380 offset = offset + FixedArray::kHeaderSize;
394 __ mov(dst, FieldOperand(src, JSObject::kPropertiesOffset)); 381 __ mov(dst, FieldOperand(src, JSObject::kPropertiesOffset));
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after
722 __ j(not_equal, interceptor_succeeded); 709 __ j(not_equal, interceptor_succeeded);
723 } 710 }
724 711
725 StubCompiler* stub_compiler_; 712 StubCompiler* stub_compiler_;
726 const ParameterCount& arguments_; 713 const ParameterCount& arguments_;
727 Register name_; 714 Register name_;
728 Code::ExtraICState extra_state_; 715 Code::ExtraICState extra_state_;
729 }; 716 };
730 717
731 718
732 void StubCompiler::GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind) { 719 void BaseStoreStubCompiler::GenerateRestoreName(MacroAssembler* masm,
733 ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC); 720 Label* label,
734 Handle<Code> code = (kind == Code::LOAD_IC) 721 Handle<Name> name) {
735 ? masm->isolate()->builtins()->LoadIC_Miss() 722 if (!label->is_unused()) {
736 : masm->isolate()->builtins()->KeyedLoadIC_Miss(); 723 __ bind(label);
737 __ jmp(code, RelocInfo::CODE_TARGET); 724 __ mov(this->name(), Immediate(name));
725 }
738 } 726 }
739 727
740 728
741 void StubCompiler::GenerateStoreMiss(MacroAssembler* masm, Code::Kind kind) {
742 ASSERT(kind == Code::STORE_IC || kind == Code::KEYED_STORE_IC);
743 Handle<Code> code = (kind == Code::STORE_IC)
744 ? masm->isolate()->builtins()->StoreIC_Miss()
745 : masm->isolate()->builtins()->KeyedStoreIC_Miss();
746 __ jmp(code, RelocInfo::CODE_TARGET);
747 }
748
749
750 void StubCompiler::GenerateKeyedLoadMissForceGeneric(MacroAssembler* masm) {
751 Handle<Code> code =
752 masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric();
753 __ jmp(code, RelocInfo::CODE_TARGET);
754 }
755
756
757 // Both name_reg and receiver_reg are preserved on jumps to miss_label, 729 // Both name_reg and receiver_reg are preserved on jumps to miss_label,
758 // but may be destroyed if store is successful. 730 // but may be destroyed if store is successful.
759 void StubCompiler::GenerateStoreField(MacroAssembler* masm, 731 void StubCompiler::GenerateStoreField(MacroAssembler* masm,
760 Handle<JSObject> object, 732 Handle<JSObject> object,
761 int index, 733 int index,
762 Handle<Map> transition, 734 Handle<Map> transition,
763 Handle<Name> name, 735 Handle<Name> name,
764 Register receiver_reg, 736 Register receiver_reg,
765 Register name_reg, 737 Register name_reg,
738 Register value_reg,
766 Register scratch1, 739 Register scratch1,
767 Register scratch2, 740 Register scratch2,
768 Label* miss_label) { 741 Label* miss_label,
742 Label* miss_restore_name) {
769 LookupResult lookup(masm->isolate()); 743 LookupResult lookup(masm->isolate());
770 object->Lookup(*name, &lookup); 744 object->Lookup(*name, &lookup);
771 if (lookup.IsFound() && (lookup.IsReadOnly() || !lookup.IsCacheable())) { 745 if (lookup.IsFound() && (lookup.IsReadOnly() || !lookup.IsCacheable())) {
772 // In sloppy mode, we could just return the value and be done. However, we 746 // In sloppy mode, we could just return the value and be done. However, we
773 // might be in strict mode, where we have to throw. Since we cannot tell, 747 // might be in strict mode, where we have to throw. Since we cannot tell,
774 // go into slow case unconditionally. 748 // go into slow case unconditionally.
775 __ jmp(miss_label); 749 __ jmp(miss_label);
776 return; 750 return;
777 } 751 }
778 752
(...skipping 14 matching lines...) Expand all
793 if (lookup.IsFound()) { 767 if (lookup.IsFound()) {
794 holder = lookup.holder(); 768 holder = lookup.holder();
795 } else { 769 } else {
796 // Find the top object. 770 // Find the top object.
797 holder = *object; 771 holder = *object;
798 do { 772 do {
799 holder = JSObject::cast(holder->GetPrototype()); 773 holder = JSObject::cast(holder->GetPrototype());
800 } while (holder->GetPrototype()->IsJSObject()); 774 } while (holder->GetPrototype()->IsJSObject());
801 } 775 }
802 // We need an extra register, push 776 // We need an extra register, push
803 __ push(name_reg);
804 Label miss_pop, done_check;
805 CheckPrototypes(object, receiver_reg, Handle<JSObject>(holder), name_reg, 777 CheckPrototypes(object, receiver_reg, Handle<JSObject>(holder), name_reg,
806 scratch1, scratch2, name, &miss_pop); 778 scratch1, scratch2, name, miss_restore_name);
807 __ jmp(&done_check);
808 __ bind(&miss_pop);
809 __ pop(name_reg);
810 __ jmp(miss_label);
811 __ bind(&done_check);
812 __ pop(name_reg);
813 } 779 }
814 780
815 // Stub never generated for non-global objects that require access 781 // Stub never generated for non-global objects that require access
816 // checks. 782 // checks.
817 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); 783 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
818 784
819 // Perform map transition for the receiver if necessary. 785 // Perform map transition for the receiver if necessary.
820 if (!transition.is_null() && (object->map()->unused_property_fields() == 0)) { 786 if (!transition.is_null() && (object->map()->unused_property_fields() == 0)) {
821 // The properties must be extended before we can store the value. 787 // The properties must be extended before we can store the value.
822 // We jump to a runtime call that extends the properties array. 788 // We jump to a runtime call that extends the properties array.
(...skipping 27 matching lines...) Expand all
850 } 816 }
851 817
852 // Adjust for the number of properties stored in the object. Even in the 818 // Adjust for the number of properties stored in the object. Even in the
853 // face of a transition we can use the old map here because the size of the 819 // face of a transition we can use the old map here because the size of the
854 // object and the number of in-object properties is not going to change. 820 // object and the number of in-object properties is not going to change.
855 index -= object->map()->inobject_properties(); 821 index -= object->map()->inobject_properties();
856 822
857 if (index < 0) { 823 if (index < 0) {
858 // Set the property straight into the object. 824 // Set the property straight into the object.
859 int offset = object->map()->instance_size() + (index * kPointerSize); 825 int offset = object->map()->instance_size() + (index * kPointerSize);
860 __ mov(FieldOperand(receiver_reg, offset), eax); 826 __ mov(FieldOperand(receiver_reg, offset), value_reg);
861 827
862 // Update the write barrier for the array address. 828 // Update the write barrier for the array address.
863 // Pass the value being stored in the now unused name_reg. 829 // Pass the value being stored in the now unused name_reg.
864 __ mov(name_reg, eax); 830 __ mov(name_reg, value_reg);
865 __ RecordWriteField(receiver_reg, 831 __ RecordWriteField(receiver_reg,
866 offset, 832 offset,
867 name_reg, 833 name_reg,
868 scratch1, 834 scratch1,
869 kDontSaveFPRegs); 835 kDontSaveFPRegs);
870 } else { 836 } else {
871 // Write to the properties array. 837 // Write to the properties array.
872 int offset = index * kPointerSize + FixedArray::kHeaderSize; 838 int offset = index * kPointerSize + FixedArray::kHeaderSize;
873 // Get the properties array (optimistically). 839 // Get the properties array (optimistically).
874 __ mov(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset)); 840 __ mov(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset));
875 __ mov(FieldOperand(scratch1, offset), eax); 841 __ mov(FieldOperand(scratch1, offset), eax);
876 842
877 // Update the write barrier for the array address. 843 // Update the write barrier for the array address.
878 // Pass the value being stored in the now unused name_reg. 844 // Pass the value being stored in the now unused name_reg.
879 __ mov(name_reg, eax); 845 __ mov(name_reg, value_reg);
880 __ RecordWriteField(scratch1, 846 __ RecordWriteField(scratch1,
881 offset, 847 offset,
882 name_reg, 848 name_reg,
883 receiver_reg, 849 receiver_reg,
884 kDontSaveFPRegs); 850 kDontSaveFPRegs);
885 } 851 }
886 852
887 // Return the value (register eax). 853 // Return the value (register eax).
854 ASSERT(value_reg.is(eax));
888 __ ret(0); 855 __ ret(0);
889 } 856 }
890 857
891 858
892 // Generate code to check that a global property cell is empty. Create 859 // Generate code to check that a global property cell is empty. Create
893 // the property cell at compilation time if no cell exists for the 860 // the property cell at compilation time if no cell exists for the
894 // property. 861 // property.
895 static void GenerateCheckPropertyCell(MacroAssembler* masm, 862 static void GenerateCheckPropertyCell(MacroAssembler* masm,
896 Handle<GlobalObject> global, 863 Handle<GlobalObject> global,
897 Handle<Name> name, 864 Handle<Name> name,
(...skipping 28 matching lines...) Expand all
926 GenerateCheckPropertyCell(masm, 893 GenerateCheckPropertyCell(masm,
927 Handle<GlobalObject>::cast(current), 894 Handle<GlobalObject>::cast(current),
928 name, 895 name,
929 scratch, 896 scratch,
930 miss); 897 miss);
931 } 898 }
932 current = Handle<JSObject>(JSObject::cast(current->GetPrototype())); 899 current = Handle<JSObject>(JSObject::cast(current->GetPrototype()));
933 } 900 }
934 } 901 }
935 902
903
904 void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) {
905 __ jmp(code, RelocInfo::CODE_TARGET);
906 }
907
908
936 #undef __ 909 #undef __
937 #define __ ACCESS_MASM(masm()) 910 #define __ ACCESS_MASM(masm())
938 911
939 912
940 void StubCompiler::GenerateTailCall(Handle<Code> code) {
941 __ jmp(code, RelocInfo::CODE_TARGET);
942 }
943
944
945 Register StubCompiler::CheckPrototypes(Handle<JSObject> object, 913 Register StubCompiler::CheckPrototypes(Handle<JSObject> object,
946 Register object_reg, 914 Register object_reg,
947 Handle<JSObject> holder, 915 Handle<JSObject> holder,
948 Register holder_reg, 916 Register holder_reg,
949 Register scratch1, 917 Register scratch1,
950 Register scratch2, 918 Register scratch2,
951 Handle<Name> name, 919 Handle<Name> name,
952 int save_at_depth, 920 int save_at_depth,
953 Label* miss, 921 Label* miss,
954 PrototypeCheckType check) { 922 PrototypeCheckType check) {
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
1055 // Return the register containing the holder. 1023 // Return the register containing the holder.
1056 return reg; 1024 return reg;
1057 } 1025 }
1058 1026
1059 1027
1060 void BaseLoadStubCompiler::HandlerFrontendFooter(Label* success, 1028 void BaseLoadStubCompiler::HandlerFrontendFooter(Label* success,
1061 Label* miss) { 1029 Label* miss) {
1062 if (!miss->is_unused()) { 1030 if (!miss->is_unused()) {
1063 __ jmp(success); 1031 __ jmp(success);
1064 __ bind(miss); 1032 __ bind(miss);
1065 GenerateLoadMiss(masm(), kind()); 1033 TailCallBuiltin(masm(), MissBuiltin(kind()));
1066 } 1034 }
1067 } 1035 }
1068 1036
1069 1037
1070 Register BaseLoadStubCompiler::CallbackHandlerFrontend( 1038 Register BaseLoadStubCompiler::CallbackHandlerFrontend(
1071 Handle<JSObject> object, 1039 Handle<JSObject> object,
1072 Register object_reg, 1040 Register object_reg,
1073 Handle<JSObject> holder, 1041 Handle<JSObject> holder,
1074 Handle<Name> name, 1042 Handle<Name> name,
1075 Label* success, 1043 Label* success,
(...skipping 1498 matching lines...) Expand 10 before | Expand all | Expand 10 after
2574 // Handle call cache miss. 2542 // Handle call cache miss.
2575 __ bind(&miss); 2543 __ bind(&miss);
2576 __ IncrementCounter(counters->call_global_inline_miss(), 1); 2544 __ IncrementCounter(counters->call_global_inline_miss(), 1);
2577 GenerateMissBranch(); 2545 GenerateMissBranch();
2578 2546
2579 // Return the generated code. 2547 // Return the generated code.
2580 return GetCode(Code::NORMAL, name); 2548 return GetCode(Code::NORMAL, name);
2581 } 2549 }
2582 2550
2583 2551
2584 Handle<Code> StoreStubCompiler::CompileStoreField(Handle<JSObject> object,
2585 int index,
2586 Handle<Map> transition,
2587 Handle<Name> name) {
2588 // ----------- S t a t e -------------
2589 // -- eax : value
2590 // -- ecx : name
2591 // -- edx : receiver
2592 // -- esp[0] : return address
2593 // -----------------------------------
2594 Label miss;
2595
2596 // Generate store field code. Trashes the name register.
2597 GenerateStoreField(masm(),
2598 object,
2599 index,
2600 transition,
2601 name,
2602 edx, ecx, ebx, edi,
2603 &miss);
2604 // Handle store cache miss.
2605 __ bind(&miss);
2606 __ mov(ecx, Immediate(name)); // restore name
2607 Handle<Code> ic = isolate()->builtins()->StoreIC_Miss();
2608 __ jmp(ic, RelocInfo::CODE_TARGET);
2609
2610 // Return the generated code.
2611 return GetCode(transition.is_null()
2612 ? Code::FIELD
2613 : Code::MAP_TRANSITION, name);
2614 }
2615
2616
2617 Handle<Code> StoreStubCompiler::CompileStoreCallback( 2552 Handle<Code> StoreStubCompiler::CompileStoreCallback(
2618 Handle<Name> name, 2553 Handle<Name> name,
2619 Handle<JSObject> receiver, 2554 Handle<JSObject> receiver,
2620 Handle<JSObject> holder, 2555 Handle<JSObject> holder,
2621 Handle<ExecutableAccessorInfo> callback) { 2556 Handle<ExecutableAccessorInfo> callback) {
2622 // ----------- S t a t e ------------- 2557 // ----------- S t a t e -------------
2623 // -- eax : value 2558 // -- eax : value
2624 // -- ecx : name 2559 // -- ecx : name
2625 // -- edx : receiver 2560 // -- edx : receiver
2626 // -- esp[0] : return address 2561 // -- esp[0] : return address
(...skipping 16 matching lines...) Expand all
2643 __ push(ebx); // restore return address 2578 __ push(ebx); // restore return address
2644 2579
2645 // Do tail-call to the runtime system. 2580 // Do tail-call to the runtime system.
2646 ExternalReference store_callback_property = 2581 ExternalReference store_callback_property =
2647 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate()); 2582 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate());
2648 __ TailCallExternalReference(store_callback_property, 4, 1); 2583 __ TailCallExternalReference(store_callback_property, 4, 1);
2649 2584
2650 // Handle store cache miss. 2585 // Handle store cache miss.
2651 __ bind(&miss); 2586 __ bind(&miss);
2652 __ pop(eax); 2587 __ pop(eax);
2653 Handle<Code> ic = isolate()->builtins()->StoreIC_Miss(); 2588 TailCallBuiltin(masm(), MissBuiltin(kind()));
2654 __ jmp(ic, RelocInfo::CODE_TARGET);
2655 2589
2656 // Return the generated code. 2590 // Return the generated code.
2657 return GetCode(Code::CALLBACKS, name); 2591 return GetICCode(kind(), Code::CALLBACKS, name);
2658 } 2592 }
2659 2593
2660 2594
2661 #undef __ 2595 #undef __
2662 #define __ ACCESS_MASM(masm) 2596 #define __ ACCESS_MASM(masm)
2663 2597
2664 2598
2665 void StoreStubCompiler::GenerateStoreViaSetter( 2599 void StoreStubCompiler::GenerateStoreViaSetter(
2666 MacroAssembler* masm, 2600 MacroAssembler* masm,
2667 Handle<JSFunction> setter) { 2601 Handle<JSFunction> setter) {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
2720 // Check that the maps haven't changed, preserving the name register. 2654 // Check that the maps haven't changed, preserving the name register.
2721 __ push(ecx); 2655 __ push(ecx);
2722 __ JumpIfSmi(edx, &miss); 2656 __ JumpIfSmi(edx, &miss);
2723 CheckPrototypes(receiver, edx, holder, ebx, ecx, edi, name, &miss); 2657 CheckPrototypes(receiver, edx, holder, ebx, ecx, edi, name, &miss);
2724 __ pop(ecx); 2658 __ pop(ecx);
2725 2659
2726 GenerateStoreViaSetter(masm(), setter); 2660 GenerateStoreViaSetter(masm(), setter);
2727 2661
2728 __ bind(&miss); 2662 __ bind(&miss);
2729 __ pop(ecx); 2663 __ pop(ecx);
2730 Handle<Code> ic = isolate()->builtins()->StoreIC_Miss(); 2664 TailCallBuiltin(masm(), MissBuiltin(kind()));
2731 __ jmp(ic, RelocInfo::CODE_TARGET);
2732 2665
2733 // Return the generated code. 2666 // Return the generated code.
2734 return GetCode(Code::CALLBACKS, name); 2667 return GetICCode(kind(), Code::CALLBACKS, name);
2735 } 2668 }
2736 2669
2737 2670
2738 Handle<Code> StoreStubCompiler::CompileStoreInterceptor( 2671 Handle<Code> StoreStubCompiler::CompileStoreInterceptor(
2739 Handle<JSObject> receiver, 2672 Handle<JSObject> receiver,
2740 Handle<Name> name) { 2673 Handle<Name> name) {
2741 // ----------- S t a t e ------------- 2674 // ----------- S t a t e -------------
2742 // -- eax : value 2675 // -- eax : value
2743 // -- ecx : name 2676 // -- ecx : name
2744 // -- edx : receiver 2677 // -- edx : receiver
(...skipping 11 matching lines...) Expand all
2756 } 2689 }
2757 2690
2758 // Stub never generated for non-global objects that require access 2691 // Stub never generated for non-global objects that require access
2759 // checks. 2692 // checks.
2760 ASSERT(receiver->IsJSGlobalProxy() || !receiver->IsAccessCheckNeeded()); 2693 ASSERT(receiver->IsJSGlobalProxy() || !receiver->IsAccessCheckNeeded());
2761 2694
2762 __ pop(ebx); // remove the return address 2695 __ pop(ebx); // remove the return address
2763 __ push(edx); // receiver 2696 __ push(edx); // receiver
2764 __ push(ecx); // name 2697 __ push(ecx); // name
2765 __ push(eax); // value 2698 __ push(eax); // value
2766 __ push(Immediate(Smi::FromInt(strict_mode_))); 2699 __ push(Immediate(Smi::FromInt(strict_mode())));
2767 __ push(ebx); // restore return address 2700 __ push(ebx); // restore return address
2768 2701
2769 // Do tail-call to the runtime system. 2702 // Do tail-call to the runtime system.
2770 ExternalReference store_ic_property = 2703 ExternalReference store_ic_property =
2771 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), isolate()); 2704 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), isolate());
2772 __ TailCallExternalReference(store_ic_property, 4, 1); 2705 __ TailCallExternalReference(store_ic_property, 4, 1);
2773 2706
2774 // Handle store cache miss. 2707 // Handle store cache miss.
2775 __ bind(&miss); 2708 __ bind(&miss);
2776 Handle<Code> ic = isolate()->builtins()->StoreIC_Miss(); 2709 TailCallBuiltin(masm(), MissBuiltin(kind()));
2777 __ jmp(ic, RelocInfo::CODE_TARGET);
2778 2710
2779 // Return the generated code. 2711 // Return the generated code.
2780 return GetCode(Code::INTERCEPTOR, name); 2712 return GetICCode(kind(), Code::INTERCEPTOR, name);
2781 } 2713 }
2782 2714
2783 2715
2784 Handle<Code> StoreStubCompiler::CompileStoreGlobal( 2716 Handle<Code> StoreStubCompiler::CompileStoreGlobal(
2785 Handle<GlobalObject> object, 2717 Handle<GlobalObject> object,
2786 Handle<JSGlobalPropertyCell> cell, 2718 Handle<JSGlobalPropertyCell> cell,
2787 Handle<Name> name) { 2719 Handle<Name> name) {
2788 // ----------- S t a t e ------------- 2720 // ----------- S t a t e -------------
2789 // -- eax : value 2721 // -- eax : value
2790 // -- ecx : name 2722 // -- ecx : name
(...skipping 23 matching lines...) Expand all
2814 // No write barrier here, because cells are always rescanned. 2746 // No write barrier here, because cells are always rescanned.
2815 2747
2816 // Return the value (register eax). 2748 // Return the value (register eax).
2817 Counters* counters = isolate()->counters(); 2749 Counters* counters = isolate()->counters();
2818 __ IncrementCounter(counters->named_store_global_inline(), 1); 2750 __ IncrementCounter(counters->named_store_global_inline(), 1);
2819 __ ret(0); 2751 __ ret(0);
2820 2752
2821 // Handle store cache miss. 2753 // Handle store cache miss.
2822 __ bind(&miss); 2754 __ bind(&miss);
2823 __ IncrementCounter(counters->named_store_global_inline_miss(), 1); 2755 __ IncrementCounter(counters->named_store_global_inline_miss(), 1);
2824 Handle<Code> ic = isolate()->builtins()->StoreIC_Miss(); 2756 TailCallBuiltin(masm(), MissBuiltin(kind()));
2825 __ jmp(ic, RelocInfo::CODE_TARGET);
2826 2757
2827 // Return the generated code. 2758 // Return the generated code.
2828 return GetCode(Code::NORMAL, name); 2759 return GetICCode(kind(), Code::NORMAL, name);
2829 } 2760 }
2830 2761
2831 2762
2832 Handle<Code> KeyedStoreStubCompiler::CompileStoreField(Handle<JSObject> object,
2833 int index,
2834 Handle<Map> transition,
2835 Handle<Name> name) {
2836 // ----------- S t a t e -------------
2837 // -- eax : value
2838 // -- ecx : key
2839 // -- edx : receiver
2840 // -- esp[0] : return address
2841 // -----------------------------------
2842 Label miss;
2843
2844 Counters* counters = isolate()->counters();
2845 __ IncrementCounter(counters->keyed_store_field(), 1);
2846
2847 // Check that the name has not changed.
2848 __ cmp(ecx, Immediate(name));
2849 __ j(not_equal, &miss);
2850
2851 // Generate store field code. Trashes the name register.
2852 GenerateStoreField(masm(),
2853 object,
2854 index,
2855 transition,
2856 name,
2857 edx, ecx, ebx, edi,
2858 &miss);
2859
2860 // Handle store cache miss.
2861 __ bind(&miss);
2862 __ DecrementCounter(counters->keyed_store_field(), 1);
2863 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss();
2864 __ jmp(ic, RelocInfo::CODE_TARGET);
2865
2866 // Return the generated code.
2867 return GetCode(transition.is_null()
2868 ? Code::FIELD
2869 : Code::MAP_TRANSITION, name);
2870 }
2871
2872
2873 Handle<Code> KeyedStoreStubCompiler::CompileStoreElement( 2763 Handle<Code> KeyedStoreStubCompiler::CompileStoreElement(
2874 Handle<Map> receiver_map) { 2764 Handle<Map> receiver_map) {
2875 // ----------- S t a t e ------------- 2765 // ----------- S t a t e -------------
2876 // -- eax : value 2766 // -- eax : value
2877 // -- ecx : key 2767 // -- ecx : key
2878 // -- edx : receiver 2768 // -- edx : receiver
2879 // -- esp[0] : return address 2769 // -- esp[0] : return address
2880 // ----------------------------------- 2770 // -----------------------------------
2881 ElementsKind elements_kind = receiver_map->elements_kind(); 2771 ElementsKind elements_kind = receiver_map->elements_kind();
2882 bool is_jsarray = receiver_map->instance_type() == JS_ARRAY_TYPE; 2772 bool is_jsarray = receiver_map->instance_type() == JS_ARRAY_TYPE;
2883 Handle<Code> stub = 2773 Handle<Code> stub =
2884 KeyedStoreElementStub(is_jsarray, 2774 KeyedStoreElementStub(is_jsarray,
2885 elements_kind, 2775 elements_kind,
2886 store_mode_).GetCode(isolate()); 2776 store_mode_).GetCode(isolate());
2887 2777
2888 __ DispatchMap(edx, receiver_map, stub, DO_SMI_CHECK); 2778 __ DispatchMap(edx, receiver_map, stub, DO_SMI_CHECK);
2889 2779
2890 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); 2780 TailCallBuiltin(masm(), MissBuiltin(kind()));
2891 __ jmp(ic, RelocInfo::CODE_TARGET);
2892 2781
2893 // Return the generated code. 2782 // Return the generated code.
2894 return GetCode(Code::NORMAL, factory()->empty_string()); 2783 return GetICCode(kind(), Code::NORMAL, factory()->empty_string());
2895 } 2784 }
2896 2785
2897 2786
2898 Handle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic( 2787 Handle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic(
2899 MapHandleList* receiver_maps, 2788 MapHandleList* receiver_maps,
2900 CodeHandleList* handler_stubs, 2789 CodeHandleList* handler_stubs,
2901 MapHandleList* transitioned_maps) { 2790 MapHandleList* transitioned_maps) {
2902 // ----------- S t a t e ------------- 2791 // ----------- S t a t e -------------
2903 // -- eax : value 2792 // -- eax : value
2904 // -- ecx : key 2793 // -- ecx : key
(...skipping 10 matching lines...) Expand all
2915 __ j(equal, handler_stubs->at(i)); 2804 __ j(equal, handler_stubs->at(i));
2916 } else { 2805 } else {
2917 Label next_map; 2806 Label next_map;
2918 __ j(not_equal, &next_map, Label::kNear); 2807 __ j(not_equal, &next_map, Label::kNear);
2919 __ mov(ebx, Immediate(transitioned_maps->at(i))); 2808 __ mov(ebx, Immediate(transitioned_maps->at(i)));
2920 __ jmp(handler_stubs->at(i), RelocInfo::CODE_TARGET); 2809 __ jmp(handler_stubs->at(i), RelocInfo::CODE_TARGET);
2921 __ bind(&next_map); 2810 __ bind(&next_map);
2922 } 2811 }
2923 } 2812 }
2924 __ bind(&miss); 2813 __ bind(&miss);
2925 Handle<Code> miss_ic = isolate()->builtins()->KeyedStoreIC_Miss(); 2814 TailCallBuiltin(masm(), MissBuiltin(kind()));
2926 __ jmp(miss_ic, RelocInfo::CODE_TARGET);
2927 2815
2928 // Return the generated code. 2816 // Return the generated code.
2929 return GetCode(Code::NORMAL, factory()->empty_string(), POLYMORPHIC); 2817 return GetICCode(
2818 kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC);
2930 } 2819 }
2931 2820
2932 2821
2933 Handle<Code> LoadStubCompiler::CompileLoadNonexistent( 2822 Handle<Code> LoadStubCompiler::CompileLoadNonexistent(
2934 Handle<JSObject> object, 2823 Handle<JSObject> object,
2935 Handle<JSObject> last, 2824 Handle<JSObject> last,
2936 Handle<Name> name, 2825 Handle<Name> name,
2937 Handle<GlobalObject> global) { 2826 Handle<GlobalObject> global) {
2938 Label success; 2827 Label success;
2939 2828
(...skipping 17 matching lines...) Expand all
2957 } 2846 }
2958 2847
2959 2848
2960 Register* KeyedLoadStubCompiler::registers() { 2849 Register* KeyedLoadStubCompiler::registers() {
2961 // receiver, name, scratch1, scratch2, scratch3, scratch4. 2850 // receiver, name, scratch1, scratch2, scratch3, scratch4.
2962 static Register registers[] = { edx, ecx, ebx, eax, edi, no_reg }; 2851 static Register registers[] = { edx, ecx, ebx, eax, edi, no_reg };
2963 return registers; 2852 return registers;
2964 } 2853 }
2965 2854
2966 2855
2856 Register* StoreStubCompiler::registers() {
2857 // receiver, name, value, scratch1, scratch2, scratch3.
2858 static Register registers[] = { edx, ecx, eax, ebx, edi, no_reg };
2859 return registers;
2860 }
2861
2862
2863 Register* KeyedStoreStubCompiler::registers() {
2864 // receiver, name, value, scratch1, scratch2, scratch3.
2865 static Register registers[] = { edx, ecx, eax, ebx, edi, no_reg };
2866 return registers;
2867 }
2868
2869
2967 void KeyedLoadStubCompiler::GenerateNameCheck(Handle<Name> name, 2870 void KeyedLoadStubCompiler::GenerateNameCheck(Handle<Name> name,
2968 Register name_reg, 2871 Register name_reg,
2969 Label* miss) { 2872 Label* miss) {
2970 __ cmp(name_reg, Immediate(name)); 2873 __ cmp(name_reg, Immediate(name));
2971 __ j(not_equal, miss); 2874 __ j(not_equal, miss);
2972 } 2875 }
2973 2876
2974 2877
2878 void KeyedStoreStubCompiler::GenerateNameCheck(Handle<Name> name,
2879 Register name_reg,
2880 Label* miss) {
2881 __ cmp(name_reg, Immediate(name));
2882 __ j(not_equal, miss);
2883 }
2884
2885
2975 #undef __ 2886 #undef __
2976 #define __ ACCESS_MASM(masm) 2887 #define __ ACCESS_MASM(masm)
2977 2888
2978 2889
2979 void LoadStubCompiler::GenerateLoadViaGetter(MacroAssembler* masm, 2890 void LoadStubCompiler::GenerateLoadViaGetter(MacroAssembler* masm,
2980 Handle<JSFunction> getter) { 2891 Handle<JSFunction> getter) {
2981 // ----------- S t a t e ------------- 2892 // ----------- S t a t e -------------
2982 // -- ecx : name 2893 // -- ecx : name
2983 // -- edx : receiver 2894 // -- edx : receiver
2984 // -- esp[0] : return address 2895 // -- esp[0] : return address
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
3064 Handle<Code> stub = KeyedLoadFastElementStub( 2975 Handle<Code> stub = KeyedLoadFastElementStub(
3065 receiver_map->instance_type() == JS_ARRAY_TYPE, 2976 receiver_map->instance_type() == JS_ARRAY_TYPE,
3066 elements_kind).GetCode(isolate()); 2977 elements_kind).GetCode(isolate());
3067 __ DispatchMap(edx, receiver_map, stub, DO_SMI_CHECK); 2978 __ DispatchMap(edx, receiver_map, stub, DO_SMI_CHECK);
3068 } else { 2979 } else {
3069 Handle<Code> stub = 2980 Handle<Code> stub =
3070 KeyedLoadDictionaryElementStub().GetCode(isolate()); 2981 KeyedLoadDictionaryElementStub().GetCode(isolate());
3071 __ DispatchMap(edx, receiver_map, stub, DO_SMI_CHECK); 2982 __ DispatchMap(edx, receiver_map, stub, DO_SMI_CHECK);
3072 } 2983 }
3073 2984
3074 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 2985 TailCallBuiltin(masm(), Builtins::kKeyedLoadIC_Miss);
3075 2986
3076 // Return the generated code. 2987 // Return the generated code.
3077 return GetICCode(kind(), Code::NORMAL, factory()->empty_string()); 2988 return GetICCode(kind(), Code::NORMAL, factory()->empty_string());
3078 } 2989 }
3079 2990
3080 2991
3081 Handle<Code> BaseLoadStubCompiler::CompilePolymorphicIC( 2992 Handle<Code> BaseLoadStubCompiler::CompilePolymorphicIC(
3082 MapHandleList* receiver_maps, 2993 MapHandleList* receiver_maps,
3083 CodeHandleList* handlers, 2994 CodeHandleList* handlers,
3084 Handle<Name> name, 2995 Handle<Name> name,
3085 Code::StubType type, 2996 Code::StubType type,
3086 IcCheckType check) { 2997 IcCheckType check) {
3087 Label miss; 2998 Label miss;
3088 2999
3089 if (check == PROPERTY) { 3000 if (check == PROPERTY) {
3090 GenerateNameCheck(name, this->name(), &miss); 3001 GenerateNameCheck(name, this->name(), &miss);
3091 } 3002 }
3092 3003
3093 __ JumpIfSmi(receiver(), &miss); 3004 __ JumpIfSmi(receiver(), &miss);
3094 Register map_reg = scratch1(); 3005 Register map_reg = scratch1();
3095 __ mov(map_reg, FieldOperand(receiver(), HeapObject::kMapOffset)); 3006 __ mov(map_reg, FieldOperand(receiver(), HeapObject::kMapOffset));
3096 int receiver_count = receiver_maps->length(); 3007 int receiver_count = receiver_maps->length();
3097 for (int current = 0; current < receiver_count; ++current) { 3008 for (int current = 0; current < receiver_count; ++current) {
3098 __ cmp(map_reg, receiver_maps->at(current)); 3009 __ cmp(map_reg, receiver_maps->at(current));
3099 __ j(equal, handlers->at(current)); 3010 __ j(equal, handlers->at(current));
3100 } 3011 }
3101 3012
3102 __ bind(&miss); 3013 __ bind(&miss);
3103 GenerateLoadMiss(masm(), kind()); 3014 TailCallBuiltin(masm(), MissBuiltin(kind()));
3104 3015
3105 // Return the generated code. 3016 // Return the generated code.
3106 InlineCacheState state = 3017 InlineCacheState state =
3107 receiver_maps->length() > 1 ? POLYMORPHIC : MONOMORPHIC; 3018 receiver_maps->length() > 1 ? POLYMORPHIC : MONOMORPHIC;
3108 return GetICCode(kind(), type, name, state); 3019 return GetICCode(kind(), type, name, state);
3109 } 3020 }
3110 3021
3111 3022
3112 // Specialized stub for constructing objects from functions which only have only 3023 // Specialized stub for constructing objects from functions which only have only
3113 // simple assignments of the form this.x = ...; in their body. 3024 // simple assignments of the form this.x = ...; in their body.
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
3277 __ ret(0); 3188 __ ret(0);
3278 3189
3279 __ bind(&slow); 3190 __ bind(&slow);
3280 __ pop(edx); 3191 __ pop(edx);
3281 3192
3282 // ----------- S t a t e ------------- 3193 // ----------- S t a t e -------------
3283 // -- ecx : key 3194 // -- ecx : key
3284 // -- edx : receiver 3195 // -- edx : receiver
3285 // -- esp[0] : return address 3196 // -- esp[0] : return address
3286 // ----------------------------------- 3197 // -----------------------------------
3287 3198 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Slow);
3288 Handle<Code> slow_ic =
3289 masm->isolate()->builtins()->KeyedLoadIC_Slow();
3290 __ jmp(slow_ic, RelocInfo::CODE_TARGET);
3291 3199
3292 __ bind(&miss_force_generic); 3200 __ bind(&miss_force_generic);
3293 // ----------- S t a t e ------------- 3201 // ----------- S t a t e -------------
3294 // -- ecx : key 3202 // -- ecx : key
3295 // -- edx : receiver 3203 // -- edx : receiver
3296 // -- esp[0] : return address 3204 // -- esp[0] : return address
3297 // ----------------------------------- 3205 // -----------------------------------
3298 3206 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_MissForceGeneric);
3299 Handle<Code> miss_force_generic_ic =
3300 masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric();
3301 __ jmp(miss_force_generic_ic, RelocInfo::CODE_TARGET);
3302 } 3207 }
3303 3208
3304 3209
3305 static void GenerateSmiKeyCheck(MacroAssembler* masm, 3210 static void GenerateSmiKeyCheck(MacroAssembler* masm,
3306 Register key, 3211 Register key,
3307 Register scratch, 3212 Register scratch,
3308 XMMRegister xmm_scratch0, 3213 XMMRegister xmm_scratch0,
3309 XMMRegister xmm_scratch1, 3214 XMMRegister xmm_scratch1,
3310 Label* fail) { 3215 Label* fail) {
3311 // Check that key is a smi and if SSE2 is available a heap number 3216 // Check that key is a smi and if SSE2 is available a heap number
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
3509 __ bind(&slow); 3414 __ bind(&slow);
3510 Counters* counters = masm->isolate()->counters(); 3415 Counters* counters = masm->isolate()->counters();
3511 __ IncrementCounter(counters->keyed_store_external_array_slow(), 1); 3416 __ IncrementCounter(counters->keyed_store_external_array_slow(), 1);
3512 3417
3513 // ----------- S t a t e ------------- 3418 // ----------- S t a t e -------------
3514 // -- eax : value 3419 // -- eax : value
3515 // -- ecx : key 3420 // -- ecx : key
3516 // -- edx : receiver 3421 // -- edx : receiver
3517 // -- esp[0] : return address 3422 // -- esp[0] : return address
3518 // ----------------------------------- 3423 // -----------------------------------
3519 3424 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow);
3520 Handle<Code> ic = masm->isolate()->builtins()->KeyedStoreIC_Slow();
3521 __ jmp(ic, RelocInfo::CODE_TARGET);
3522 3425
3523 // ----------- S t a t e ------------- 3426 // ----------- S t a t e -------------
3524 // -- eax : value 3427 // -- eax : value
3525 // -- ecx : key 3428 // -- ecx : key
3526 // -- edx : receiver 3429 // -- edx : receiver
3527 // -- esp[0] : return address 3430 // -- esp[0] : return address
3528 // ----------------------------------- 3431 // -----------------------------------
3529 3432
3530 __ bind(&miss_force_generic); 3433 __ bind(&miss_force_generic);
3531 Handle<Code> miss_ic = 3434 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_MissForceGeneric);
3532 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric();
3533 __ jmp(miss_ic, RelocInfo::CODE_TARGET);
3534 } 3435 }
3535 3436
3536 3437
3537 void KeyedStoreStubCompiler::GenerateStoreFastElement( 3438 void KeyedStoreStubCompiler::GenerateStoreFastElement(
3538 MacroAssembler* masm, 3439 MacroAssembler* masm,
3539 bool is_js_array, 3440 bool is_js_array,
3540 ElementsKind elements_kind, 3441 ElementsKind elements_kind,
3541 KeyedAccessStoreMode store_mode) { 3442 KeyedAccessStoreMode store_mode) {
3542 // ----------- S t a t e ------------- 3443 // ----------- S t a t e -------------
3543 // -- eax : value 3444 // -- eax : value
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
3599 // Make sure to preserve the value in register eax. 3500 // Make sure to preserve the value in register eax.
3600 __ mov(ebx, eax); 3501 __ mov(ebx, eax);
3601 __ RecordWrite(edi, ecx, ebx, kDontSaveFPRegs); 3502 __ RecordWrite(edi, ecx, ebx, kDontSaveFPRegs);
3602 } 3503 }
3603 3504
3604 // Done. 3505 // Done.
3605 __ ret(0); 3506 __ ret(0);
3606 3507
3607 // Handle store cache miss, replacing the ic with the generic stub. 3508 // Handle store cache miss, replacing the ic with the generic stub.
3608 __ bind(&miss_force_generic); 3509 __ bind(&miss_force_generic);
3609 Handle<Code> ic_force_generic = 3510 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_MissForceGeneric);
3610 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric();
3611 __ jmp(ic_force_generic, RelocInfo::CODE_TARGET);
3612 3511
3613 // Handle transition to other elements kinds without using the generic stub. 3512 // Handle transition to other elements kinds without using the generic stub.
3614 __ bind(&transition_elements_kind); 3513 __ bind(&transition_elements_kind);
3615 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); 3514 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Miss);
3616 __ jmp(ic_miss, RelocInfo::CODE_TARGET);
3617 3515
3618 if (is_js_array && IsGrowStoreMode(store_mode)) { 3516 if (is_js_array && IsGrowStoreMode(store_mode)) {
3619 // Handle transition requiring the array to grow. 3517 // Handle transition requiring the array to grow.
3620 __ bind(&grow); 3518 __ bind(&grow);
3621 3519
3622 // Make sure the array is only growing by a single element, anything else 3520 // Make sure the array is only growing by a single element, anything else
3623 // must be handled by the runtime. Flags are already set by previous 3521 // must be handled by the runtime. Flags are already set by previous
3624 // compare. 3522 // compare.
3625 __ j(not_equal, &miss_force_generic); 3523 __ j(not_equal, &miss_force_generic);
3626 3524
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
3677 // Grow the array and finish the store. 3575 // Grow the array and finish the store.
3678 __ add(FieldOperand(edx, JSArray::kLengthOffset), 3576 __ add(FieldOperand(edx, JSArray::kLengthOffset),
3679 Immediate(Smi::FromInt(1))); 3577 Immediate(Smi::FromInt(1)));
3680 __ jmp(&finish_store); 3578 __ jmp(&finish_store);
3681 3579
3682 __ bind(&prepare_slow); 3580 __ bind(&prepare_slow);
3683 // Restore the key, which is known to be the array length. 3581 // Restore the key, which is known to be the array length.
3684 __ mov(ecx, Immediate(0)); 3582 __ mov(ecx, Immediate(0));
3685 3583
3686 __ bind(&slow); 3584 __ bind(&slow);
3687 Handle<Code> ic_slow = masm->isolate()->builtins()->KeyedStoreIC_Slow(); 3585 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow);
3688 __ jmp(ic_slow, RelocInfo::CODE_TARGET);
3689 } 3586 }
3690 } 3587 }
3691 3588
3692 3589
3693 void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement( 3590 void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement(
3694 MacroAssembler* masm, 3591 MacroAssembler* masm,
3695 bool is_js_array, 3592 bool is_js_array,
3696 KeyedAccessStoreMode store_mode) { 3593 KeyedAccessStoreMode store_mode) {
3697 // ----------- S t a t e ------------- 3594 // ----------- S t a t e -------------
3698 // -- eax : value 3595 // -- eax : value
(...skipping 28 matching lines...) Expand all
3727 __ j(above_equal, &miss_force_generic); 3624 __ j(above_equal, &miss_force_generic);
3728 } 3625 }
3729 3626
3730 __ bind(&finish_store); 3627 __ bind(&finish_store);
3731 __ StoreNumberToDoubleElements(eax, edi, ecx, edx, xmm0, 3628 __ StoreNumberToDoubleElements(eax, edi, ecx, edx, xmm0,
3732 &transition_elements_kind, true); 3629 &transition_elements_kind, true);
3733 __ ret(0); 3630 __ ret(0);
3734 3631
3735 // Handle store cache miss, replacing the ic with the generic stub. 3632 // Handle store cache miss, replacing the ic with the generic stub.
3736 __ bind(&miss_force_generic); 3633 __ bind(&miss_force_generic);
3737 Handle<Code> ic_force_generic = 3634 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_MissForceGeneric);
3738 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric();
3739 __ jmp(ic_force_generic, RelocInfo::CODE_TARGET);
3740 3635
3741 // Handle transition to other elements kinds without using the generic stub. 3636 // Handle transition to other elements kinds without using the generic stub.
3742 __ bind(&transition_elements_kind); 3637 __ bind(&transition_elements_kind);
3743 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); 3638 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Miss);
3744 __ jmp(ic_miss, RelocInfo::CODE_TARGET);
3745 3639
3746 if (is_js_array && IsGrowStoreMode(store_mode)) { 3640 if (is_js_array && IsGrowStoreMode(store_mode)) {
3747 // Handle transition requiring the array to grow. 3641 // Handle transition requiring the array to grow.
3748 __ bind(&grow); 3642 __ bind(&grow);
3749 3643
3750 // Make sure the array is only growing by a single element, anything else 3644 // Make sure the array is only growing by a single element, anything else
3751 // must be handled by the runtime. Flags are already set by previous 3645 // must be handled by the runtime. Flags are already set by previous
3752 // compare. 3646 // compare.
3753 __ j(not_equal, &miss_force_generic); 3647 __ j(not_equal, &miss_force_generic);
3754 3648
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
3815 // Grow the array and finish the store. 3709 // Grow the array and finish the store.
3816 __ add(FieldOperand(edx, JSArray::kLengthOffset), 3710 __ add(FieldOperand(edx, JSArray::kLengthOffset),
3817 Immediate(Smi::FromInt(1))); 3711 Immediate(Smi::FromInt(1)));
3818 __ jmp(&finish_store); 3712 __ jmp(&finish_store);
3819 3713
3820 __ bind(&prepare_slow); 3714 __ bind(&prepare_slow);
3821 // Restore the key, which is known to be the array length. 3715 // Restore the key, which is known to be the array length.
3822 __ mov(ecx, Immediate(0)); 3716 __ mov(ecx, Immediate(0));
3823 3717
3824 __ bind(&slow); 3718 __ bind(&slow);
3825 Handle<Code> ic_slow = masm->isolate()->builtins()->KeyedStoreIC_Slow(); 3719 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow);
3826 __ jmp(ic_slow, RelocInfo::CODE_TARGET);
3827 } 3720 }
3828 } 3721 }
3829 3722
3830 3723
3831 #undef __ 3724 #undef __
3832 3725
3833 } } // namespace v8::internal 3726 } } // namespace v8::internal
3834 3727
3835 #endif // V8_TARGET_ARCH_IA32 3728 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/code-stubs-ia32.cc ('k') | src/log.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698