OLD | NEW |
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 2586 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2597 __ IncrementCounter(counters->call_global_inline_miss(), 1, a1, a3); | 2597 __ IncrementCounter(counters->call_global_inline_miss(), 1, a1, a3); |
2598 GenerateMissBranch(); | 2598 GenerateMissBranch(); |
2599 | 2599 |
2600 // Return the generated code. | 2600 // Return the generated code. |
2601 return GetCode(Code::NORMAL, name); | 2601 return GetCode(Code::NORMAL, name); |
2602 } | 2602 } |
2603 | 2603 |
2604 | 2604 |
2605 Handle<Code> StoreStubCompiler::CompileStoreCallback( | 2605 Handle<Code> StoreStubCompiler::CompileStoreCallback( |
2606 Handle<Name> name, | 2606 Handle<Name> name, |
2607 Handle<JSObject> receiver, | 2607 Handle<JSObject> object, |
2608 Handle<JSObject> holder, | 2608 Handle<JSObject> holder, |
2609 Handle<ExecutableAccessorInfo> callback) { | 2609 Handle<ExecutableAccessorInfo> callback) { |
2610 // ----------- S t a t e ------------- | |
2611 // -- a0 : value | |
2612 // -- a1 : receiver | |
2613 // -- a2 : name | |
2614 // -- ra : return address | |
2615 // ----------------------------------- | |
2616 Label miss; | 2610 Label miss; |
2617 // Check that the maps haven't changed. | 2611 // Check that the maps haven't changed. |
2618 __ JumpIfSmi(a1, &miss, a3); | 2612 __ JumpIfSmi(receiver(), &miss); |
2619 CheckPrototypes(receiver, a1, holder, a3, t0, t1, name, &miss); | 2613 CheckPrototypes(object, receiver(), holder, |
| 2614 scratch1(), scratch2(), scratch3(), name, &miss); |
2620 | 2615 |
2621 // Stub never generated for non-global objects that require access | 2616 // Stub never generated for non-global objects that require access |
2622 // checks. | 2617 // checks. |
2623 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); | 2618 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); |
2624 | 2619 |
2625 __ push(a1); // Receiver. | 2620 __ push(receiver()); // Receiver. |
2626 __ li(a3, Operand(callback)); // Callback info. | 2621 __ li(at, Operand(callback)); // Callback info. |
2627 __ Push(a3, a2, a0); | 2622 __ Push(at, this->name(), value()); |
2628 | 2623 |
2629 // Do tail-call to the runtime system. | 2624 // Do tail-call to the runtime system. |
2630 ExternalReference store_callback_property = | 2625 ExternalReference store_callback_property = |
2631 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), | 2626 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), |
2632 masm()->isolate()); | 2627 masm()->isolate()); |
2633 __ TailCallExternalReference(store_callback_property, 4, 1); | 2628 __ TailCallExternalReference(store_callback_property, 4, 1); |
2634 | 2629 |
2635 // Handle store cache miss. | 2630 // Handle store cache miss. |
2636 __ bind(&miss); | 2631 __ bind(&miss); |
2637 TailCallBuiltin(masm(), MissBuiltin(kind())); | 2632 TailCallBuiltin(masm(), MissBuiltin(kind())); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2680 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2675 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
2681 } | 2676 } |
2682 __ Ret(); | 2677 __ Ret(); |
2683 } | 2678 } |
2684 | 2679 |
2685 | 2680 |
2686 #undef __ | 2681 #undef __ |
2687 #define __ ACCESS_MASM(masm()) | 2682 #define __ ACCESS_MASM(masm()) |
2688 | 2683 |
2689 | 2684 |
2690 Handle<Code> StoreStubCompiler::CompileStoreViaSetter( | |
2691 Handle<Name> name, | |
2692 Handle<JSObject> receiver, | |
2693 Handle<JSObject> holder, | |
2694 Handle<JSFunction> setter) { | |
2695 // ----------- S t a t e ------------- | |
2696 // -- a0 : value | |
2697 // -- a1 : receiver | |
2698 // -- a2 : name | |
2699 // -- ra : return address | |
2700 // ----------------------------------- | |
2701 Label miss; | |
2702 | |
2703 // Check that the maps haven't changed. | |
2704 __ JumpIfSmi(a1, &miss); | |
2705 CheckPrototypes(receiver, a1, holder, a3, t0, t1, name, &miss); | |
2706 | |
2707 GenerateStoreViaSetter(masm(), setter); | |
2708 | |
2709 __ bind(&miss); | |
2710 TailCallBuiltin(masm(), MissBuiltin(kind())); | |
2711 | |
2712 // Return the generated code. | |
2713 return GetICCode(kind(), Code::CALLBACKS, name); | |
2714 } | |
2715 | |
2716 | |
2717 Handle<Code> StoreStubCompiler::CompileStoreInterceptor( | 2685 Handle<Code> StoreStubCompiler::CompileStoreInterceptor( |
2718 Handle<JSObject> receiver, | 2686 Handle<JSObject> object, |
2719 Handle<Name> name) { | 2687 Handle<Name> name) { |
2720 // ----------- S t a t e ------------- | |
2721 // -- a0 : value | |
2722 // -- a1 : receiver | |
2723 // -- a2 : name | |
2724 // -- ra : return address | |
2725 // ----------------------------------- | |
2726 Label miss; | 2688 Label miss; |
2727 | 2689 |
2728 // Check that the map of the object hasn't changed. | 2690 // Check that the map of the object hasn't changed. |
2729 __ CheckMap(a1, a3, Handle<Map>(receiver->map()), &miss, | 2691 __ CheckMap(receiver(), scratch1(), Handle<Map>(object->map()), &miss, |
2730 DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS); | 2692 DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS); |
2731 | 2693 |
2732 // Perform global security token check if needed. | 2694 // Perform global security token check if needed. |
2733 if (receiver->IsJSGlobalProxy()) { | 2695 if (object->IsJSGlobalProxy()) { |
2734 __ CheckAccessGlobalProxy(a1, a3, &miss); | 2696 __ CheckAccessGlobalProxy(receiver(), scratch1(), &miss); |
2735 } | 2697 } |
2736 | 2698 |
2737 // Stub is never generated for non-global objects that require access | 2699 // Stub is never generated for non-global objects that require access |
2738 // checks. | 2700 // checks. |
2739 ASSERT(receiver->IsJSGlobalProxy() || !receiver->IsAccessCheckNeeded()); | 2701 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); |
2740 | 2702 |
2741 __ Push(a1, a2, a0); // Receiver, name, value. | 2703 __ Push(receiver(), this->name(), value()); |
2742 | 2704 |
2743 __ li(a0, Operand(Smi::FromInt(strict_mode()))); | 2705 __ li(scratch1(), Operand(Smi::FromInt(strict_mode()))); |
2744 __ push(a0); // Strict mode. | 2706 __ push(scratch1()); // strict mode |
2745 | 2707 |
2746 // Do tail-call to the runtime system. | 2708 // Do tail-call to the runtime system. |
2747 ExternalReference store_ic_property = | 2709 ExternalReference store_ic_property = |
2748 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), | 2710 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), |
2749 masm()->isolate()); | 2711 masm()->isolate()); |
2750 __ TailCallExternalReference(store_ic_property, 4, 1); | 2712 __ TailCallExternalReference(store_ic_property, 4, 1); |
2751 | 2713 |
2752 // Handle store cache miss. | 2714 // Handle store cache miss. |
2753 __ bind(&miss); | 2715 __ bind(&miss); |
2754 TailCallBuiltin(masm(), MissBuiltin(kind())); | 2716 TailCallBuiltin(masm(), MissBuiltin(kind())); |
2755 | 2717 |
2756 // Return the generated code. | 2718 // Return the generated code. |
2757 return GetICCode(kind(), Code::INTERCEPTOR, name); | 2719 return GetICCode(kind(), Code::INTERCEPTOR, name); |
2758 } | 2720 } |
2759 | 2721 |
2760 | 2722 |
2761 Handle<Code> StoreStubCompiler::CompileStoreGlobal( | 2723 Handle<Code> StoreStubCompiler::CompileStoreGlobal( |
2762 Handle<GlobalObject> object, | 2724 Handle<GlobalObject> object, |
2763 Handle<JSGlobalPropertyCell> cell, | 2725 Handle<JSGlobalPropertyCell> cell, |
2764 Handle<Name> name) { | 2726 Handle<Name> name) { |
2765 // ----------- S t a t e ------------- | |
2766 // -- a0 : value | |
2767 // -- a1 : receiver | |
2768 // -- a2 : name | |
2769 // -- ra : return address | |
2770 // ----------------------------------- | |
2771 Label miss; | 2727 Label miss; |
2772 | 2728 |
2773 // Check that the map of the global has not changed. | 2729 // Check that the map of the global has not changed. |
2774 __ lw(a3, FieldMemOperand(a1, HeapObject::kMapOffset)); | 2730 __ lw(scratch1(), FieldMemOperand(receiver(), HeapObject::kMapOffset)); |
2775 __ Branch(&miss, ne, a3, Operand(Handle<Map>(object->map()))); | 2731 __ Branch(&miss, ne, scratch1(), Operand(Handle<Map>(object->map()))); |
2776 | 2732 |
2777 // Check that the value in the cell is not the hole. If it is, this | 2733 // Check that the value in the cell is not the hole. If it is, this |
2778 // cell could have been deleted and reintroducing the global needs | 2734 // cell could have been deleted and reintroducing the global needs |
2779 // to update the property details in the property dictionary of the | 2735 // to update the property details in the property dictionary of the |
2780 // global object. We bail out to the runtime system to do that. | 2736 // global object. We bail out to the runtime system to do that. |
2781 __ li(t0, Operand(cell)); | 2737 __ li(scratch1(), Operand(cell)); |
2782 __ LoadRoot(t1, Heap::kTheHoleValueRootIndex); | 2738 __ LoadRoot(scratch2(), Heap::kTheHoleValueRootIndex); |
2783 __ lw(t2, FieldMemOperand(t0, JSGlobalPropertyCell::kValueOffset)); | 2739 __ lw(scratch3(), |
2784 __ Branch(&miss, eq, t1, Operand(t2)); | 2740 FieldMemOperand(scratch1(), JSGlobalPropertyCell::kValueOffset)); |
| 2741 __ Branch(&miss, eq, scratch3(), Operand(scratch2())); |
2785 | 2742 |
2786 // Store the value in the cell. | 2743 // Store the value in the cell. |
2787 __ sw(a0, FieldMemOperand(t0, JSGlobalPropertyCell::kValueOffset)); | 2744 __ sw(value(), |
| 2745 FieldMemOperand(scratch1(), JSGlobalPropertyCell::kValueOffset)); |
2788 __ mov(v0, a0); // Stored value must be returned in v0. | 2746 __ mov(v0, a0); // Stored value must be returned in v0. |
2789 // Cells are always rescanned, so no write barrier here. | 2747 // Cells are always rescanned, so no write barrier here. |
2790 | 2748 |
2791 Counters* counters = masm()->isolate()->counters(); | 2749 Counters* counters = masm()->isolate()->counters(); |
2792 __ IncrementCounter(counters->named_store_global_inline(), 1, a1, a3); | 2750 __ IncrementCounter( |
| 2751 counters->named_store_global_inline(), 1, scratch1(), scratch2()); |
2793 __ Ret(); | 2752 __ Ret(); |
2794 | 2753 |
2795 // Handle store cache miss. | 2754 // Handle store cache miss. |
2796 __ bind(&miss); | 2755 __ bind(&miss); |
2797 __ IncrementCounter(counters->named_store_global_inline_miss(), 1, a1, a3); | 2756 __ IncrementCounter( |
| 2757 counters->named_store_global_inline_miss(), 1, scratch1(), scratch2()); |
2798 TailCallBuiltin(masm(), MissBuiltin(kind())); | 2758 TailCallBuiltin(masm(), MissBuiltin(kind())); |
2799 | 2759 |
2800 // Return the generated code. | 2760 // Return the generated code. |
2801 return GetICCode(kind(), Code::NORMAL, name); | 2761 return GetICCode(kind(), Code::NORMAL, name); |
2802 } | 2762 } |
2803 | 2763 |
2804 | 2764 |
2805 Handle<Code> LoadStubCompiler::CompileLoadNonexistent( | 2765 Handle<Code> LoadStubCompiler::CompileLoadNonexistent( |
2806 Handle<JSObject> object, | 2766 Handle<JSObject> object, |
2807 Handle<JSObject> last, | 2767 Handle<JSObject> last, |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2929 Counters* counters = masm()->isolate()->counters(); | 2889 Counters* counters = masm()->isolate()->counters(); |
2930 __ IncrementCounter(counters->named_load_global_stub(), 1, a1, a3); | 2890 __ IncrementCounter(counters->named_load_global_stub(), 1, a1, a3); |
2931 __ mov(v0, t0); | 2891 __ mov(v0, t0); |
2932 __ Ret(); | 2892 __ Ret(); |
2933 | 2893 |
2934 // Return the generated code. | 2894 // Return the generated code. |
2935 return GetICCode(kind(), Code::NORMAL, name); | 2895 return GetICCode(kind(), Code::NORMAL, name); |
2936 } | 2896 } |
2937 | 2897 |
2938 | 2898 |
2939 Handle<Code> KeyedLoadStubCompiler::CompileLoadElement( | |
2940 Handle<Map> receiver_map) { | |
2941 // ----------- S t a t e ------------- | |
2942 // -- ra : return address | |
2943 // -- a0 : key | |
2944 // -- a1 : receiver | |
2945 // ----------------------------------- | |
2946 ElementsKind elements_kind = receiver_map->elements_kind(); | |
2947 if (receiver_map->has_fast_elements() || | |
2948 receiver_map->has_external_array_elements()) { | |
2949 Handle<Code> stub = KeyedLoadFastElementStub( | |
2950 receiver_map->instance_type() == JS_ARRAY_TYPE, | |
2951 elements_kind).GetCode(isolate()); | |
2952 __ DispatchMap(a1, a2, receiver_map, stub, DO_SMI_CHECK); | |
2953 } else { | |
2954 Handle<Code> stub = | |
2955 KeyedLoadDictionaryElementStub().GetCode(isolate()); | |
2956 __ DispatchMap(a1, a2, receiver_map, stub, DO_SMI_CHECK); | |
2957 } | |
2958 | |
2959 TailCallBuiltin(masm(), MissBuiltin(kind())); | |
2960 | |
2961 // Return the generated code. | |
2962 return GetICCode(kind(), Code::NORMAL, factory()->empty_string()); | |
2963 } | |
2964 | |
2965 | |
2966 Handle<Code> BaseLoadStubCompiler::CompilePolymorphicIC( | 2899 Handle<Code> BaseLoadStubCompiler::CompilePolymorphicIC( |
2967 MapHandleList* receiver_maps, | 2900 MapHandleList* receiver_maps, |
2968 CodeHandleList* handlers, | 2901 CodeHandleList* handlers, |
2969 Handle<Name> name, | 2902 Handle<Name> name, |
2970 Code::StubType type, | 2903 Code::StubType type, |
2971 IcCheckType check) { | 2904 IcCheckType check) { |
2972 Label miss; | 2905 Label miss; |
2973 | 2906 |
2974 if (check == PROPERTY) { | 2907 if (check == PROPERTY) { |
2975 GenerateNameCheck(name, this->name(), &miss); | 2908 GenerateNameCheck(name, this->name(), &miss); |
(...skipping 12 matching lines...) Expand all Loading... |
2988 __ bind(&miss); | 2921 __ bind(&miss); |
2989 TailCallBuiltin(masm(), MissBuiltin(kind())); | 2922 TailCallBuiltin(masm(), MissBuiltin(kind())); |
2990 | 2923 |
2991 // Return the generated code. | 2924 // Return the generated code. |
2992 InlineCacheState state = | 2925 InlineCacheState state = |
2993 receiver_maps->length() > 1 ? POLYMORPHIC : MONOMORPHIC; | 2926 receiver_maps->length() > 1 ? POLYMORPHIC : MONOMORPHIC; |
2994 return GetICCode(kind(), type, name, state); | 2927 return GetICCode(kind(), type, name, state); |
2995 } | 2928 } |
2996 | 2929 |
2997 | 2930 |
2998 Handle<Code> KeyedStoreStubCompiler::CompileStoreElement( | |
2999 Handle<Map> receiver_map) { | |
3000 // ----------- S t a t e ------------- | |
3001 // -- a0 : value | |
3002 // -- a1 : key | |
3003 // -- a2 : receiver | |
3004 // -- ra : return address | |
3005 // -- a3 : scratch | |
3006 // ----------------------------------- | |
3007 ElementsKind elements_kind = receiver_map->elements_kind(); | |
3008 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE; | |
3009 Handle<Code> stub = | |
3010 KeyedStoreElementStub(is_js_array, | |
3011 elements_kind, | |
3012 store_mode_).GetCode(isolate()); | |
3013 | |
3014 __ DispatchMap(a2, a3, receiver_map, stub, DO_SMI_CHECK); | |
3015 | |
3016 TailCallBuiltin(masm(), MissBuiltin(kind())); | |
3017 | |
3018 // Return the generated code. | |
3019 return GetICCode(kind(), Code::NORMAL, factory()->empty_string()); | |
3020 } | |
3021 | |
3022 | |
3023 Handle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic( | 2931 Handle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic( |
3024 MapHandleList* receiver_maps, | 2932 MapHandleList* receiver_maps, |
3025 CodeHandleList* handler_stubs, | 2933 CodeHandleList* handler_stubs, |
3026 MapHandleList* transitioned_maps) { | 2934 MapHandleList* transitioned_maps) { |
3027 // ----------- S t a t e ------------- | |
3028 // -- a0 : value | |
3029 // -- a1 : key | |
3030 // -- a2 : receiver | |
3031 // -- ra : return address | |
3032 // -- a3 : scratch | |
3033 // ----------------------------------- | |
3034 Label miss; | 2935 Label miss; |
3035 __ JumpIfSmi(a2, &miss); | 2936 __ JumpIfSmi(receiver(), &miss); |
3036 | 2937 |
3037 int receiver_count = receiver_maps->length(); | 2938 int receiver_count = receiver_maps->length(); |
3038 __ lw(a3, FieldMemOperand(a2, HeapObject::kMapOffset)); | 2939 __ lw(scratch1(), FieldMemOperand(receiver(), HeapObject::kMapOffset)); |
3039 for (int i = 0; i < receiver_count; ++i) { | 2940 for (int i = 0; i < receiver_count; ++i) { |
3040 if (transitioned_maps->at(i).is_null()) { | 2941 if (transitioned_maps->at(i).is_null()) { |
3041 __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET, eq, | 2942 __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET, eq, |
3042 a3, Operand(receiver_maps->at(i))); | 2943 scratch1(), Operand(receiver_maps->at(i))); |
3043 } else { | 2944 } else { |
3044 Label next_map; | 2945 Label next_map; |
3045 __ Branch(&next_map, ne, a3, Operand(receiver_maps->at(i))); | 2946 __ Branch(&next_map, ne, scratch1(), Operand(receiver_maps->at(i))); |
3046 __ li(a3, Operand(transitioned_maps->at(i))); | 2947 __ li(transition_map(), Operand(transitioned_maps->at(i))); |
3047 __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET); | 2948 __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET); |
3048 __ bind(&next_map); | 2949 __ bind(&next_map); |
3049 } | 2950 } |
3050 } | 2951 } |
3051 | 2952 |
3052 __ bind(&miss); | 2953 __ bind(&miss); |
3053 TailCallBuiltin(masm(), MissBuiltin(kind())); | 2954 TailCallBuiltin(masm(), MissBuiltin(kind())); |
3054 | 2955 |
3055 // Return the generated code. | 2956 // Return the generated code. |
3056 return GetICCode( | 2957 return GetICCode( |
(...skipping 982 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4039 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow); | 3940 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow); |
4040 } | 3941 } |
4041 } | 3942 } |
4042 | 3943 |
4043 | 3944 |
4044 #undef __ | 3945 #undef __ |
4045 | 3946 |
4046 } } // namespace v8::internal | 3947 } } // namespace v8::internal |
4047 | 3948 |
4048 #endif // V8_TARGET_ARCH_MIPS | 3949 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |