| 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 |