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