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

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

Issue 8166017: Track elements_kind transitions in KeyedStoreICs. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: fix nits Created 9 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 | Annotate | Revision Log
« no previous file with comments | « src/arm/stub-cache-arm.cc ('k') | src/ic.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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 2741 matching lines...) Expand 10 before | Expand all | Expand 10 after
2752 DO_SMI_CHECK); 2752 DO_SMI_CHECK);
2753 2753
2754 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); 2754 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss();
2755 __ jmp(ic, RelocInfo::CODE_TARGET); 2755 __ jmp(ic, RelocInfo::CODE_TARGET);
2756 2756
2757 // Return the generated code. 2757 // Return the generated code.
2758 return GetCode(NORMAL, NULL); 2758 return GetCode(NORMAL, NULL);
2759 } 2759 }
2760 2760
2761 2761
2762 MaybeObject* KeyedStoreStubCompiler::CompileStoreElementWithTransition(
2763 Map* transitioned_map,
2764 Map* untransitioned_map_1,
2765 Map* untransitioned_map_2) {
2766 // ----------- S t a t e -------------
2767 // -- eax : value
2768 // -- ecx : key
2769 // -- edx : receiver
2770 // -- esp[0] : return address
2771 // -----------------------------------
2772
2773 // The order of map occurrences in the generated code below is important.
2774 // Both IC code and Crankshaft rely on |transitioned_map| being the first
2775 // map in the stub.
2776
2777 Code* notransition_stub;
2778 ElementsKind elements_kind = transitioned_map->elements_kind();
2779 bool is_jsarray = transitioned_map->instance_type() == JS_ARRAY_TYPE;
2780 MaybeObject* maybe_stub =
2781 KeyedStoreElementStub(is_jsarray, elements_kind).TryGetCode();
2782 if (!maybe_stub->To(&notransition_stub)) return maybe_stub;
2783
2784 Label just_store, miss;
2785 __ JumpIfSmi(edx, &miss, Label::kNear);
2786 __ mov(ebx, FieldOperand(edx, HeapObject::kMapOffset));
2787 // ebx: receiver->map().
2788 __ cmp(ebx, Handle<Map>(transitioned_map));
2789 __ j(equal, &just_store);
2790 ASSERT_NE(untransitioned_map_1, NULL);
2791 __ cmp(ebx, Handle<Map>(untransitioned_map_1));
2792 // TODO(jkummerow): When we have specialized code to do the transition,
2793 // call that code here, then jump to just_store when the call returns.
2794 // <temporary: just use the generic stub>
2795 Code* generic_stub = (strict_mode_ == kStrictMode)
2796 ? isolate()->builtins()->builtin(Builtins::kKeyedStoreIC_Generic_Strict)
2797 : isolate()->builtins()->builtin(Builtins::kKeyedStoreIC_Generic);
2798 __ j(equal, Handle<Code>(generic_stub));
2799 // </temporary>
2800 if (untransitioned_map_2 != NULL) {
2801 __ cmp(ebx, Handle<Map>(untransitioned_map_2));
2802 // <temporary: see above, same here>
2803 __ j(equal, Handle<Code>(generic_stub));
2804 // </temporary>
2805 }
2806 __ bind(&miss);
2807 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss();
2808 __ jmp(ic, RelocInfo::CODE_TARGET);
2809
2810 __ bind(&just_store);
2811 __ jmp(Handle<Code>(notransition_stub), RelocInfo::CODE_TARGET);
2812
2813 // Return the generated code.
2814 return GetCode(NORMAL, NULL, MEGAMORPHIC);
2815 }
2816
2817
2762 MaybeObject* KeyedStoreStubCompiler::CompileStoreMegamorphic( 2818 MaybeObject* KeyedStoreStubCompiler::CompileStoreMegamorphic(
2763 MapList* receiver_maps, 2819 MapList* receiver_maps,
2764 CodeList* handler_ics) { 2820 CodeList* handler_ics) {
2765 // ----------- S t a t e ------------- 2821 // ----------- S t a t e -------------
2766 // -- eax : value 2822 // -- eax : value
2767 // -- ecx : key 2823 // -- ecx : key
2768 // -- edx : receiver 2824 // -- edx : receiver
2769 // -- esp[0] : return address 2825 // -- esp[0] : return address
2770 // ----------------------------------- 2826 // -----------------------------------
2771 Label miss; 2827 Label miss;
(...skipping 1131 matching lines...) Expand 10 before | Expand all | Expand 10 after
3903 void KeyedStoreStubCompiler::GenerateStoreFastElement( 3959 void KeyedStoreStubCompiler::GenerateStoreFastElement(
3904 MacroAssembler* masm, 3960 MacroAssembler* masm,
3905 bool is_js_array, 3961 bool is_js_array,
3906 ElementsKind elements_kind) { 3962 ElementsKind elements_kind) {
3907 // ----------- S t a t e ------------- 3963 // ----------- S t a t e -------------
3908 // -- eax : value 3964 // -- eax : value
3909 // -- ecx : key 3965 // -- ecx : key
3910 // -- edx : receiver 3966 // -- edx : receiver
3911 // -- esp[0] : return address 3967 // -- esp[0] : return address
3912 // ----------------------------------- 3968 // -----------------------------------
3913 Label miss_force_generic; 3969 Label miss_force_generic, transition_elements_kind;
3914 3970
3915 // This stub is meant to be tail-jumped to, the receiver must already 3971 // This stub is meant to be tail-jumped to, the receiver must already
3916 // have been verified by the caller to not be a smi. 3972 // have been verified by the caller to not be a smi.
3917 3973
3918 // Check that the key is a smi. 3974 // Check that the key is a smi.
3919 __ JumpIfNotSmi(ecx, &miss_force_generic); 3975 __ JumpIfNotSmi(ecx, &miss_force_generic);
3920 3976
3921 // Get the elements array and make sure it is a fast element array, not 'cow'. 3977 // Get the elements array and make sure it is a fast element array, not 'cow'.
3922 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset)); 3978 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
3923 __ cmp(FieldOperand(edi, HeapObject::kMapOffset), 3979 __ cmp(FieldOperand(edi, HeapObject::kMapOffset),
3924 Immediate(masm->isolate()->factory()->fixed_array_map())); 3980 Immediate(masm->isolate()->factory()->fixed_array_map()));
3925 __ j(not_equal, &miss_force_generic); 3981 __ j(not_equal, &miss_force_generic);
3926 3982
3927 if (is_js_array) { 3983 if (is_js_array) {
3928 // Check that the key is within bounds. 3984 // Check that the key is within bounds.
3929 __ cmp(ecx, FieldOperand(edx, JSArray::kLengthOffset)); // smis. 3985 __ cmp(ecx, FieldOperand(edx, JSArray::kLengthOffset)); // smis.
3930 __ j(above_equal, &miss_force_generic); 3986 __ j(above_equal, &miss_force_generic);
3931 } else { 3987 } else {
3932 // Check that the key is within bounds. 3988 // Check that the key is within bounds.
3933 __ cmp(ecx, FieldOperand(edi, FixedArray::kLengthOffset)); // smis. 3989 __ cmp(ecx, FieldOperand(edi, FixedArray::kLengthOffset)); // smis.
3934 __ j(above_equal, &miss_force_generic); 3990 __ j(above_equal, &miss_force_generic);
3935 } 3991 }
3936 3992
3937 if (elements_kind == FAST_SMI_ONLY_ELEMENTS) { 3993 if (elements_kind == FAST_SMI_ONLY_ELEMENTS) {
3938 __ JumpIfNotSmi(eax, &miss_force_generic); 3994 __ JumpIfNotSmi(eax, &transition_elements_kind);
3939 // ecx is a smi, use times_half_pointer_size instead of 3995 // ecx is a smi, use times_half_pointer_size instead of
3940 // times_pointer_size 3996 // times_pointer_size
3941 __ mov(FieldOperand(edi, 3997 __ mov(FieldOperand(edi,
3942 ecx, 3998 ecx,
3943 times_half_pointer_size, 3999 times_half_pointer_size,
3944 FixedArray::kHeaderSize), eax); 4000 FixedArray::kHeaderSize), eax);
3945 } else { 4001 } else {
3946 ASSERT(elements_kind == FAST_ELEMENTS); 4002 ASSERT(elements_kind == FAST_ELEMENTS);
3947 // Do the store and update the write barrier. 4003 // Do the store and update the write barrier.
3948 // ecx is a smi, use times_half_pointer_size instead of 4004 // ecx is a smi, use times_half_pointer_size instead of
3949 // times_pointer_size 4005 // times_pointer_size
3950 __ lea(ecx, FieldOperand(edi, 4006 __ lea(ecx, FieldOperand(edi,
3951 ecx, 4007 ecx,
3952 times_half_pointer_size, 4008 times_half_pointer_size,
3953 FixedArray::kHeaderSize)); 4009 FixedArray::kHeaderSize));
3954 __ mov(Operand(ecx, 0), eax); 4010 __ mov(Operand(ecx, 0), eax);
3955 // Make sure to preserve the value in register eax. 4011 // Make sure to preserve the value in register eax.
3956 __ mov(edx, eax); 4012 __ mov(edx, eax);
3957 __ RecordWrite(edi, ecx, edx, kDontSaveFPRegs); 4013 __ RecordWrite(edi, ecx, edx, kDontSaveFPRegs);
3958 } 4014 }
3959 4015
3960 // Done. 4016 // Done.
3961 __ ret(0); 4017 __ ret(0);
3962 4018
3963 // Handle store cache miss, replacing the ic with the generic stub. 4019 // Handle store cache miss, replacing the ic with the generic stub.
3964 __ bind(&miss_force_generic); 4020 __ bind(&miss_force_generic);
3965 Handle<Code> ic_force_generic = 4021 Handle<Code> ic_force_generic =
3966 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); 4022 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric();
3967 __ jmp(ic_force_generic, RelocInfo::CODE_TARGET); 4023 __ jmp(ic_force_generic, RelocInfo::CODE_TARGET);
4024
4025 // Handle transition to other elements kinds without using the generic stub.
4026 __ bind(&transition_elements_kind);
4027 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss();
4028 __ jmp(ic_miss, RelocInfo::CODE_TARGET);
3968 } 4029 }
3969 4030
3970 4031
3971 void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement( 4032 void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement(
3972 MacroAssembler* masm, 4033 MacroAssembler* masm,
3973 bool is_js_array) { 4034 bool is_js_array) {
3974 // ----------- S t a t e ------------- 4035 // ----------- S t a t e -------------
3975 // -- eax : value 4036 // -- eax : value
3976 // -- ecx : key 4037 // -- ecx : key
3977 // -- edx : receiver 4038 // -- edx : receiver
3978 // -- esp[0] : return address 4039 // -- esp[0] : return address
3979 // ----------------------------------- 4040 // -----------------------------------
3980 Label miss_force_generic; 4041 Label miss_force_generic, transition_elements_kind;
3981 4042
3982 // This stub is meant to be tail-jumped to, the receiver must already 4043 // This stub is meant to be tail-jumped to, the receiver must already
3983 // have been verified by the caller to not be a smi. 4044 // have been verified by the caller to not be a smi.
3984 4045
3985 // Check that the key is a smi. 4046 // Check that the key is a smi.
3986 __ JumpIfNotSmi(ecx, &miss_force_generic); 4047 __ JumpIfNotSmi(ecx, &miss_force_generic);
3987 4048
3988 // Get the elements array. 4049 // Get the elements array.
3989 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset)); 4050 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
3990 __ AssertFastElements(edi); 4051 __ AssertFastElements(edi);
3991 4052
3992 if (is_js_array) { 4053 if (is_js_array) {
3993 // Check that the key is within bounds. 4054 // Check that the key is within bounds.
3994 __ cmp(ecx, FieldOperand(edx, JSArray::kLengthOffset)); // smis. 4055 __ cmp(ecx, FieldOperand(edx, JSArray::kLengthOffset)); // smis.
3995 } else { 4056 } else {
3996 // Check that the key is within bounds. 4057 // Check that the key is within bounds.
3997 __ cmp(ecx, FieldOperand(edi, FixedArray::kLengthOffset)); // smis. 4058 __ cmp(ecx, FieldOperand(edi, FixedArray::kLengthOffset)); // smis.
3998 } 4059 }
3999 __ j(above_equal, &miss_force_generic); 4060 __ j(above_equal, &miss_force_generic);
4000 4061
4001 __ StoreNumberToDoubleElements(eax, 4062 __ StoreNumberToDoubleElements(eax,
4002 edi, 4063 edi,
4003 ecx, 4064 ecx,
4004 edx, 4065 edx,
4005 xmm0, 4066 xmm0,
4006 &miss_force_generic, 4067 &transition_elements_kind,
4007 true); 4068 true);
4008 __ ret(0); 4069 __ ret(0);
4009 4070
4010 // Handle store cache miss, replacing the ic with the generic stub. 4071 // Handle store cache miss, replacing the ic with the generic stub.
4011 __ bind(&miss_force_generic); 4072 __ bind(&miss_force_generic);
4012 Handle<Code> ic_force_generic = 4073 Handle<Code> ic_force_generic =
4013 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); 4074 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric();
4014 __ jmp(ic_force_generic, RelocInfo::CODE_TARGET); 4075 __ jmp(ic_force_generic, RelocInfo::CODE_TARGET);
4076
4077 // Handle transition to other elements kinds without using the generic stub.
4078 __ bind(&transition_elements_kind);
4079 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss();
4080 __ jmp(ic_miss, RelocInfo::CODE_TARGET);
4015 } 4081 }
4016 4082
4017 4083
4018 #undef __ 4084 #undef __
4019 4085
4020 } } // namespace v8::internal 4086 } } // namespace v8::internal
4021 4087
4022 #endif // V8_TARGET_ARCH_IA32 4088 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/arm/stub-cache-arm.cc ('k') | src/ic.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698