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 2556 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2567 __ IncrementCounter(counters->call_global_inline_miss(), 1, r1, r3); | 2567 __ IncrementCounter(counters->call_global_inline_miss(), 1, r1, r3); |
2568 GenerateMissBranch(); | 2568 GenerateMissBranch(); |
2569 | 2569 |
2570 // Return the generated code. | 2570 // Return the generated code. |
2571 return GetCode(Code::NORMAL, name); | 2571 return GetCode(Code::NORMAL, name); |
2572 } | 2572 } |
2573 | 2573 |
2574 | 2574 |
2575 Handle<Code> StoreStubCompiler::CompileStoreCallback( | 2575 Handle<Code> StoreStubCompiler::CompileStoreCallback( |
2576 Handle<Name> name, | 2576 Handle<Name> name, |
2577 Handle<JSObject> receiver, | 2577 Handle<JSObject> object, |
2578 Handle<JSObject> holder, | 2578 Handle<JSObject> holder, |
2579 Handle<ExecutableAccessorInfo> callback) { | 2579 Handle<ExecutableAccessorInfo> callback) { |
2580 // ----------- S t a t e ------------- | |
2581 // -- r0 : value | |
2582 // -- r1 : receiver | |
2583 // -- r2 : name | |
2584 // -- lr : return address | |
2585 // ----------------------------------- | |
2586 Label miss; | 2580 Label miss; |
2587 // Check that the maps haven't changed. | 2581 // Check that the maps haven't changed. |
2588 __ JumpIfSmi(r1, &miss); | 2582 __ JumpIfSmi(receiver(), &miss); |
2589 CheckPrototypes(receiver, r1, holder, r3, r4, r5, name, &miss); | 2583 CheckPrototypes(object, receiver(), holder, |
| 2584 scratch1(), scratch2(), scratch3(), name, &miss); |
2590 | 2585 |
2591 // Stub never generated for non-global objects that require access checks. | 2586 // Stub never generated for non-global objects that require access checks. |
2592 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); | 2587 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); |
2593 | 2588 |
2594 __ push(r1); // receiver | 2589 __ push(receiver()); // receiver |
2595 __ mov(ip, Operand(callback)); // callback info | 2590 __ mov(ip, Operand(callback)); // callback info |
2596 __ Push(ip, r2, r0); | 2591 __ Push(ip, this->name(), value()); |
2597 | 2592 |
2598 // Do tail-call to the runtime system. | 2593 // Do tail-call to the runtime system. |
2599 ExternalReference store_callback_property = | 2594 ExternalReference store_callback_property = |
2600 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), | 2595 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), |
2601 masm()->isolate()); | 2596 masm()->isolate()); |
2602 __ TailCallExternalReference(store_callback_property, 4, 1); | 2597 __ TailCallExternalReference(store_callback_property, 4, 1); |
2603 | 2598 |
2604 // Handle store cache miss. | 2599 // Handle store cache miss. |
2605 __ bind(&miss); | 2600 __ bind(&miss); |
2606 TailCallBuiltin(masm(), MissBuiltin(kind())); | 2601 TailCallBuiltin(masm(), MissBuiltin(kind())); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2648 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2643 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
2649 } | 2644 } |
2650 __ Ret(); | 2645 __ Ret(); |
2651 } | 2646 } |
2652 | 2647 |
2653 | 2648 |
2654 #undef __ | 2649 #undef __ |
2655 #define __ ACCESS_MASM(masm()) | 2650 #define __ ACCESS_MASM(masm()) |
2656 | 2651 |
2657 | 2652 |
2658 Handle<Code> StoreStubCompiler::CompileStoreViaSetter( | |
2659 Handle<Name> name, | |
2660 Handle<JSObject> receiver, | |
2661 Handle<JSObject> holder, | |
2662 Handle<JSFunction> setter) { | |
2663 // ----------- S t a t e ------------- | |
2664 // -- r0 : value | |
2665 // -- r1 : receiver | |
2666 // -- r2 : name | |
2667 // -- lr : return address | |
2668 // ----------------------------------- | |
2669 Label miss; | |
2670 | |
2671 // Check that the maps haven't changed. | |
2672 __ JumpIfSmi(r1, &miss); | |
2673 CheckPrototypes(receiver, r1, holder, r3, r4, r5, name, &miss); | |
2674 | |
2675 GenerateStoreViaSetter(masm(), setter); | |
2676 | |
2677 __ bind(&miss); | |
2678 TailCallBuiltin(masm(), MissBuiltin(kind())); | |
2679 | |
2680 // Return the generated code. | |
2681 return GetICCode(kind(), Code::CALLBACKS, name); | |
2682 } | |
2683 | |
2684 | |
2685 Handle<Code> StoreStubCompiler::CompileStoreInterceptor( | 2653 Handle<Code> StoreStubCompiler::CompileStoreInterceptor( |
2686 Handle<JSObject> receiver, | 2654 Handle<JSObject> object, |
2687 Handle<Name> name) { | 2655 Handle<Name> name) { |
2688 // ----------- S t a t e ------------- | |
2689 // -- r0 : value | |
2690 // -- r1 : receiver | |
2691 // -- r2 : name | |
2692 // -- lr : return address | |
2693 // ----------------------------------- | |
2694 Label miss; | 2656 Label miss; |
2695 | 2657 |
2696 // Check that the map of the object hasn't changed. | 2658 // Check that the map of the object hasn't changed. |
2697 __ CheckMap(r1, r3, Handle<Map>(receiver->map()), &miss, | 2659 __ CheckMap(receiver(), scratch1(), Handle<Map>(object->map()), &miss, |
2698 DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS); | 2660 DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS); |
2699 | 2661 |
2700 // Perform global security token check if needed. | 2662 // Perform global security token check if needed. |
2701 if (receiver->IsJSGlobalProxy()) { | 2663 if (object->IsJSGlobalProxy()) { |
2702 __ CheckAccessGlobalProxy(r1, r3, &miss); | 2664 __ CheckAccessGlobalProxy(receiver(), scratch1(), &miss); |
2703 } | 2665 } |
2704 | 2666 |
2705 // Stub is never generated for non-global objects that require access | 2667 // Stub is never generated for non-global objects that require access |
2706 // checks. | 2668 // checks. |
2707 ASSERT(receiver->IsJSGlobalProxy() || !receiver->IsAccessCheckNeeded()); | 2669 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); |
2708 | 2670 |
2709 __ Push(r1, r2, r0); // Receiver, name, value. | 2671 __ Push(receiver(), this->name(), value()); |
2710 | 2672 |
2711 __ mov(r0, Operand(Smi::FromInt(strict_mode()))); | 2673 __ mov(scratch1(), Operand(Smi::FromInt(strict_mode()))); |
2712 __ push(r0); // strict mode | 2674 __ push(scratch1()); // strict mode |
2713 | 2675 |
2714 // Do tail-call to the runtime system. | 2676 // Do tail-call to the runtime system. |
2715 ExternalReference store_ic_property = | 2677 ExternalReference store_ic_property = |
2716 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), | 2678 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), |
2717 masm()->isolate()); | 2679 masm()->isolate()); |
2718 __ TailCallExternalReference(store_ic_property, 4, 1); | 2680 __ TailCallExternalReference(store_ic_property, 4, 1); |
2719 | 2681 |
2720 // Handle store cache miss. | 2682 // Handle store cache miss. |
2721 __ bind(&miss); | 2683 __ bind(&miss); |
2722 TailCallBuiltin(masm(), MissBuiltin(kind())); | 2684 TailCallBuiltin(masm(), MissBuiltin(kind())); |
2723 | 2685 |
2724 // Return the generated code. | 2686 // Return the generated code. |
2725 return GetICCode(kind(), Code::INTERCEPTOR, name); | 2687 return GetICCode(kind(), Code::INTERCEPTOR, name); |
2726 } | 2688 } |
2727 | 2689 |
2728 | 2690 |
2729 Handle<Code> StoreStubCompiler::CompileStoreGlobal( | 2691 Handle<Code> StoreStubCompiler::CompileStoreGlobal( |
2730 Handle<GlobalObject> object, | 2692 Handle<GlobalObject> object, |
2731 Handle<JSGlobalPropertyCell> cell, | 2693 Handle<JSGlobalPropertyCell> cell, |
2732 Handle<Name> name) { | 2694 Handle<Name> name) { |
2733 // ----------- S t a t e ------------- | |
2734 // -- r0 : value | |
2735 // -- r1 : receiver | |
2736 // -- r2 : name | |
2737 // -- lr : return address | |
2738 // ----------------------------------- | |
2739 Label miss; | 2695 Label miss; |
2740 | 2696 |
2741 // Check that the map of the global has not changed. | 2697 // Check that the map of the global has not changed. |
2742 __ ldr(r3, FieldMemOperand(r1, HeapObject::kMapOffset)); | 2698 __ ldr(scratch1(), FieldMemOperand(receiver(), HeapObject::kMapOffset)); |
2743 __ cmp(r3, Operand(Handle<Map>(object->map()))); | 2699 __ cmp(scratch1(), Operand(Handle<Map>(object->map()))); |
2744 __ b(ne, &miss); | 2700 __ b(ne, &miss); |
2745 | 2701 |
2746 // Check that the value in the cell is not the hole. If it is, this | 2702 // Check that the value in the cell is not the hole. If it is, this |
2747 // cell could have been deleted and reintroducing the global needs | 2703 // cell could have been deleted and reintroducing the global needs |
2748 // to update the property details in the property dictionary of the | 2704 // to update the property details in the property dictionary of the |
2749 // global object. We bail out to the runtime system to do that. | 2705 // global object. We bail out to the runtime system to do that. |
2750 __ mov(r4, Operand(cell)); | 2706 __ mov(scratch1(), Operand(cell)); |
2751 __ LoadRoot(r5, Heap::kTheHoleValueRootIndex); | 2707 __ LoadRoot(scratch2(), Heap::kTheHoleValueRootIndex); |
2752 __ ldr(r6, FieldMemOperand(r4, JSGlobalPropertyCell::kValueOffset)); | 2708 __ ldr(scratch3(), |
2753 __ cmp(r5, r6); | 2709 FieldMemOperand(scratch1(), JSGlobalPropertyCell::kValueOffset)); |
| 2710 __ cmp(scratch3(), scratch2()); |
2754 __ b(eq, &miss); | 2711 __ b(eq, &miss); |
2755 | 2712 |
2756 // Store the value in the cell. | 2713 // Store the value in the cell. |
2757 __ str(r0, FieldMemOperand(r4, JSGlobalPropertyCell::kValueOffset)); | 2714 __ str(value(), |
| 2715 FieldMemOperand(scratch1(), JSGlobalPropertyCell::kValueOffset)); |
2758 // Cells are always rescanned, so no write barrier here. | 2716 // Cells are always rescanned, so no write barrier here. |
2759 | 2717 |
2760 Counters* counters = masm()->isolate()->counters(); | 2718 Counters* counters = masm()->isolate()->counters(); |
2761 __ IncrementCounter(counters->named_store_global_inline(), 1, r4, r3); | 2719 __ IncrementCounter( |
| 2720 counters->named_store_global_inline(), 1, scratch1(), scratch2()); |
2762 __ Ret(); | 2721 __ Ret(); |
2763 | 2722 |
2764 // Handle store cache miss. | 2723 // Handle store cache miss. |
2765 __ bind(&miss); | 2724 __ bind(&miss); |
2766 __ IncrementCounter(counters->named_store_global_inline_miss(), 1, r4, r3); | 2725 __ IncrementCounter( |
| 2726 counters->named_store_global_inline_miss(), 1, scratch1(), scratch2()); |
2767 TailCallBuiltin(masm(), MissBuiltin(kind())); | 2727 TailCallBuiltin(masm(), MissBuiltin(kind())); |
2768 | 2728 |
2769 // Return the generated code. | 2729 // Return the generated code. |
2770 return GetICCode(kind(), Code::NORMAL, name); | 2730 return GetICCode(kind(), Code::NORMAL, name); |
2771 } | 2731 } |
2772 | 2732 |
2773 | 2733 |
2774 Handle<Code> LoadStubCompiler::CompileLoadNonexistent( | 2734 Handle<Code> LoadStubCompiler::CompileLoadNonexistent( |
2775 Handle<JSObject> object, | 2735 Handle<JSObject> object, |
2776 Handle<JSObject> last, | 2736 Handle<JSObject> last, |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2902 Counters* counters = masm()->isolate()->counters(); | 2862 Counters* counters = masm()->isolate()->counters(); |
2903 __ IncrementCounter(counters->named_load_global_stub(), 1, r1, r3); | 2863 __ IncrementCounter(counters->named_load_global_stub(), 1, r1, r3); |
2904 __ mov(r0, r4); | 2864 __ mov(r0, r4); |
2905 __ Ret(); | 2865 __ Ret(); |
2906 | 2866 |
2907 // Return the generated code. | 2867 // Return the generated code. |
2908 return GetICCode(kind(), Code::NORMAL, name); | 2868 return GetICCode(kind(), Code::NORMAL, name); |
2909 } | 2869 } |
2910 | 2870 |
2911 | 2871 |
2912 Handle<Code> KeyedLoadStubCompiler::CompileLoadElement( | |
2913 Handle<Map> receiver_map) { | |
2914 // ----------- S t a t e ------------- | |
2915 // -- lr : return address | |
2916 // -- r0 : key | |
2917 // -- r1 : receiver | |
2918 // ----------------------------------- | |
2919 ElementsKind elements_kind = receiver_map->elements_kind(); | |
2920 if (receiver_map->has_fast_elements() || | |
2921 receiver_map->has_external_array_elements()) { | |
2922 Handle<Code> stub = KeyedLoadFastElementStub( | |
2923 receiver_map->instance_type() == JS_ARRAY_TYPE, | |
2924 elements_kind).GetCode(isolate()); | |
2925 __ DispatchMap(r1, r2, receiver_map, stub, DO_SMI_CHECK); | |
2926 } else { | |
2927 Handle<Code> stub = | |
2928 KeyedLoadDictionaryElementStub().GetCode(isolate()); | |
2929 __ DispatchMap(r1, r2, receiver_map, stub, DO_SMI_CHECK); | |
2930 } | |
2931 | |
2932 TailCallBuiltin(masm(), MissBuiltin(kind())); | |
2933 | |
2934 // Return the generated code. | |
2935 return GetICCode(kind(), Code::NORMAL, factory()->empty_string()); | |
2936 } | |
2937 | |
2938 | |
2939 Handle<Code> BaseLoadStubCompiler::CompilePolymorphicIC( | 2872 Handle<Code> BaseLoadStubCompiler::CompilePolymorphicIC( |
2940 MapHandleList* receiver_maps, | 2873 MapHandleList* receiver_maps, |
2941 CodeHandleList* handlers, | 2874 CodeHandleList* handlers, |
2942 Handle<Name> name, | 2875 Handle<Name> name, |
2943 Code::StubType type, | 2876 Code::StubType type, |
2944 IcCheckType check) { | 2877 IcCheckType check) { |
2945 Label miss; | 2878 Label miss; |
2946 | 2879 |
2947 if (check == PROPERTY) { | 2880 if (check == PROPERTY) { |
2948 GenerateNameCheck(name, this->name(), &miss); | 2881 GenerateNameCheck(name, this->name(), &miss); |
(...skipping 13 matching lines...) Expand all Loading... |
2962 __ bind(&miss); | 2895 __ bind(&miss); |
2963 TailCallBuiltin(masm(), MissBuiltin(kind())); | 2896 TailCallBuiltin(masm(), MissBuiltin(kind())); |
2964 | 2897 |
2965 // Return the generated code. | 2898 // Return the generated code. |
2966 InlineCacheState state = | 2899 InlineCacheState state = |
2967 receiver_maps->length() > 1 ? POLYMORPHIC : MONOMORPHIC; | 2900 receiver_maps->length() > 1 ? POLYMORPHIC : MONOMORPHIC; |
2968 return GetICCode(kind(), type, name, state); | 2901 return GetICCode(kind(), type, name, state); |
2969 } | 2902 } |
2970 | 2903 |
2971 | 2904 |
2972 Handle<Code> KeyedStoreStubCompiler::CompileStoreElement( | |
2973 Handle<Map> receiver_map) { | |
2974 // ----------- S t a t e ------------- | |
2975 // -- r0 : value | |
2976 // -- r1 : key | |
2977 // -- r2 : receiver | |
2978 // -- lr : return address | |
2979 // -- r3 : scratch | |
2980 // ----------------------------------- | |
2981 ElementsKind elements_kind = receiver_map->elements_kind(); | |
2982 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE; | |
2983 Handle<Code> stub = | |
2984 KeyedStoreElementStub(is_js_array, | |
2985 elements_kind, | |
2986 store_mode_).GetCode(isolate()); | |
2987 | |
2988 __ DispatchMap(r2, r3, receiver_map, stub, DO_SMI_CHECK); | |
2989 | |
2990 TailCallBuiltin(masm(), MissBuiltin(kind())); | |
2991 | |
2992 // Return the generated code. | |
2993 return GetICCode(kind(), Code::NORMAL, factory()->empty_string()); | |
2994 } | |
2995 | |
2996 | |
2997 Handle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic( | 2905 Handle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic( |
2998 MapHandleList* receiver_maps, | 2906 MapHandleList* receiver_maps, |
2999 CodeHandleList* handler_stubs, | 2907 CodeHandleList* handler_stubs, |
3000 MapHandleList* transitioned_maps) { | 2908 MapHandleList* transitioned_maps) { |
3001 // ----------- S t a t e ------------- | |
3002 // -- r0 : value | |
3003 // -- r1 : key | |
3004 // -- r2 : receiver | |
3005 // -- lr : return address | |
3006 // -- r3 : scratch | |
3007 // ----------------------------------- | |
3008 Label miss; | 2909 Label miss; |
3009 __ JumpIfSmi(r2, &miss); | 2910 __ JumpIfSmi(receiver(), &miss); |
3010 | 2911 |
3011 int receiver_count = receiver_maps->length(); | 2912 int receiver_count = receiver_maps->length(); |
3012 __ ldr(r3, FieldMemOperand(r2, HeapObject::kMapOffset)); | 2913 __ ldr(scratch1(), FieldMemOperand(receiver(), HeapObject::kMapOffset)); |
3013 for (int i = 0; i < receiver_count; ++i) { | 2914 for (int i = 0; i < receiver_count; ++i) { |
3014 __ mov(ip, Operand(receiver_maps->at(i))); | 2915 __ mov(ip, Operand(receiver_maps->at(i))); |
3015 __ cmp(r3, ip); | 2916 __ cmp(scratch1(), ip); |
3016 if (transitioned_maps->at(i).is_null()) { | 2917 if (transitioned_maps->at(i).is_null()) { |
3017 __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET, eq); | 2918 __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET, eq); |
3018 } else { | 2919 } else { |
3019 Label next_map; | 2920 Label next_map; |
3020 __ b(ne, &next_map); | 2921 __ b(ne, &next_map); |
3021 __ mov(r3, Operand(transitioned_maps->at(i))); | 2922 __ mov(transition_map(), Operand(transitioned_maps->at(i))); |
3022 __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET, al); | 2923 __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET, al); |
3023 __ bind(&next_map); | 2924 __ bind(&next_map); |
3024 } | 2925 } |
3025 } | 2926 } |
3026 | 2927 |
3027 __ bind(&miss); | 2928 __ bind(&miss); |
3028 TailCallBuiltin(masm(), MissBuiltin(kind())); | 2929 TailCallBuiltin(masm(), MissBuiltin(kind())); |
3029 | 2930 |
3030 // Return the generated code. | 2931 // Return the generated code. |
3031 return GetICCode( | 2932 return GetICCode( |
(...skipping 916 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3948 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow); | 3849 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow); |
3949 } | 3850 } |
3950 } | 3851 } |
3951 | 3852 |
3952 | 3853 |
3953 #undef __ | 3854 #undef __ |
3954 | 3855 |
3955 } } // namespace v8::internal | 3856 } } // namespace v8::internal |
3956 | 3857 |
3957 #endif // V8_TARGET_ARCH_ARM | 3858 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |