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 2533 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2544 __ IncrementCounter(counters->call_global_inline_miss(), 1); | 2544 __ IncrementCounter(counters->call_global_inline_miss(), 1); |
2545 GenerateMissBranch(); | 2545 GenerateMissBranch(); |
2546 | 2546 |
2547 // Return the generated code. | 2547 // Return the generated code. |
2548 return GetCode(Code::NORMAL, name); | 2548 return GetCode(Code::NORMAL, name); |
2549 } | 2549 } |
2550 | 2550 |
2551 | 2551 |
2552 Handle<Code> StoreStubCompiler::CompileStoreCallback( | 2552 Handle<Code> StoreStubCompiler::CompileStoreCallback( |
2553 Handle<Name> name, | 2553 Handle<Name> name, |
2554 Handle<JSObject> receiver, | 2554 Handle<JSObject> object, |
2555 Handle<JSObject> holder, | 2555 Handle<JSObject> holder, |
2556 Handle<ExecutableAccessorInfo> callback) { | 2556 Handle<ExecutableAccessorInfo> callback) { |
2557 // ----------- S t a t e ------------- | 2557 Label miss, miss_restore_name; |
2558 // -- eax : value | |
2559 // -- ecx : name | |
2560 // -- edx : receiver | |
2561 // -- esp[0] : return address | |
2562 // ----------------------------------- | |
2563 Label miss; | |
2564 // Check that the maps haven't changed, preserving the value register. | 2558 // Check that the maps haven't changed, preserving the value register. |
2565 __ push(eax); | 2559 __ JumpIfSmi(receiver(), &miss); |
2566 __ JumpIfSmi(edx, &miss); | 2560 CheckPrototypes(object, receiver(), holder, |
2567 CheckPrototypes(receiver, edx, holder, ebx, eax, edi, name, &miss); | 2561 scratch1(), this->name(), scratch2(), |
2568 __ pop(eax); // restore value | 2562 name, &miss_restore_name); |
2569 | 2563 |
2570 // Stub never generated for non-global objects that require access checks. | 2564 // Stub never generated for non-global objects that require access checks. |
2571 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); | 2565 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); |
2572 | 2566 |
2573 __ pop(ebx); // remove the return address | 2567 __ pop(scratch1()); // remove the return address |
2574 __ push(edx); // receiver | 2568 __ push(receiver()); |
2575 __ push(Immediate(callback)); // callback info | 2569 __ Push(callback); |
2576 __ push(ecx); // name | 2570 __ Push(name); |
2577 __ push(eax); // value | 2571 __ push(value()); |
2578 __ push(ebx); // restore return address | 2572 __ push(scratch1()); // restore return address |
2579 | 2573 |
2580 // Do tail-call to the runtime system. | 2574 // Do tail-call to the runtime system. |
2581 ExternalReference store_callback_property = | 2575 ExternalReference store_callback_property = |
2582 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate()); | 2576 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate()); |
2583 __ TailCallExternalReference(store_callback_property, 4, 1); | 2577 __ TailCallExternalReference(store_callback_property, 4, 1); |
2584 | 2578 |
2585 // Handle store cache miss. | 2579 // Handle store cache miss. |
| 2580 GenerateRestoreName(masm(), &miss_restore_name, name); |
2586 __ bind(&miss); | 2581 __ bind(&miss); |
2587 __ pop(eax); | |
2588 TailCallBuiltin(masm(), MissBuiltin(kind())); | 2582 TailCallBuiltin(masm(), MissBuiltin(kind())); |
2589 | 2583 |
2590 // Return the generated code. | 2584 // Return the generated code. |
2591 return GetICCode(kind(), Code::CALLBACKS, name); | 2585 return GetICCode(kind(), Code::CALLBACKS, name); |
2592 } | 2586 } |
2593 | 2587 |
2594 | 2588 |
2595 #undef __ | 2589 #undef __ |
2596 #define __ ACCESS_MASM(masm) | 2590 #define __ ACCESS_MASM(masm) |
2597 | 2591 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2631 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 2625 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
2632 } | 2626 } |
2633 __ ret(0); | 2627 __ ret(0); |
2634 } | 2628 } |
2635 | 2629 |
2636 | 2630 |
2637 #undef __ | 2631 #undef __ |
2638 #define __ ACCESS_MASM(masm()) | 2632 #define __ ACCESS_MASM(masm()) |
2639 | 2633 |
2640 | 2634 |
2641 Handle<Code> StoreStubCompiler::CompileStoreViaSetter( | |
2642 Handle<Name> name, | |
2643 Handle<JSObject> receiver, | |
2644 Handle<JSObject> holder, | |
2645 Handle<JSFunction> setter) { | |
2646 // ----------- S t a t e ------------- | |
2647 // -- eax : value | |
2648 // -- ecx : name | |
2649 // -- edx : receiver | |
2650 // -- esp[0] : return address | |
2651 // ----------------------------------- | |
2652 Label miss; | |
2653 | |
2654 // Check that the maps haven't changed, preserving the name register. | |
2655 __ push(ecx); | |
2656 __ JumpIfSmi(edx, &miss); | |
2657 CheckPrototypes(receiver, edx, holder, ebx, ecx, edi, name, &miss); | |
2658 __ pop(ecx); | |
2659 | |
2660 GenerateStoreViaSetter(masm(), setter); | |
2661 | |
2662 __ bind(&miss); | |
2663 __ pop(ecx); | |
2664 TailCallBuiltin(masm(), MissBuiltin(kind())); | |
2665 | |
2666 // Return the generated code. | |
2667 return GetICCode(kind(), Code::CALLBACKS, name); | |
2668 } | |
2669 | |
2670 | |
2671 Handle<Code> StoreStubCompiler::CompileStoreInterceptor( | 2635 Handle<Code> StoreStubCompiler::CompileStoreInterceptor( |
2672 Handle<JSObject> receiver, | 2636 Handle<JSObject> object, |
2673 Handle<Name> name) { | 2637 Handle<Name> name) { |
2674 // ----------- S t a t e ------------- | |
2675 // -- eax : value | |
2676 // -- ecx : name | |
2677 // -- edx : receiver | |
2678 // -- esp[0] : return address | |
2679 // ----------------------------------- | |
2680 Label miss; | 2638 Label miss; |
2681 | 2639 |
2682 // Check that the map of the object hasn't changed. | 2640 // Check that the map of the object hasn't changed. |
2683 __ CheckMap(edx, Handle<Map>(receiver->map()), | 2641 __ CheckMap(receiver(), Handle<Map>(object->map()), |
2684 &miss, DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS); | 2642 &miss, DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS); |
2685 | 2643 |
2686 // Perform global security token check if needed. | 2644 // Perform global security token check if needed. |
2687 if (receiver->IsJSGlobalProxy()) { | 2645 if (object->IsJSGlobalProxy()) { |
2688 __ CheckAccessGlobalProxy(edx, ebx, &miss); | 2646 __ CheckAccessGlobalProxy(edx, ebx, &miss); |
2689 } | 2647 } |
2690 | 2648 |
2691 // Stub never generated for non-global objects that require access | 2649 // Stub never generated for non-global objects that require access |
2692 // checks. | 2650 // checks. |
2693 ASSERT(receiver->IsJSGlobalProxy() || !receiver->IsAccessCheckNeeded()); | 2651 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); |
2694 | 2652 |
2695 __ pop(ebx); // remove the return address | 2653 __ pop(scratch1()); // remove the return address |
2696 __ push(edx); // receiver | 2654 __ push(receiver()); |
2697 __ push(ecx); // name | 2655 __ push(this->name()); |
2698 __ push(eax); // value | 2656 __ push(value()); |
2699 __ push(Immediate(Smi::FromInt(strict_mode()))); | 2657 __ push(Immediate(Smi::FromInt(strict_mode()))); |
2700 __ push(ebx); // restore return address | 2658 __ push(scratch1()); // restore return address |
2701 | 2659 |
2702 // Do tail-call to the runtime system. | 2660 // Do tail-call to the runtime system. |
2703 ExternalReference store_ic_property = | 2661 ExternalReference store_ic_property = |
2704 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), isolate()); | 2662 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), isolate()); |
2705 __ TailCallExternalReference(store_ic_property, 4, 1); | 2663 __ TailCallExternalReference(store_ic_property, 4, 1); |
2706 | 2664 |
2707 // Handle store cache miss. | 2665 // Handle store cache miss. |
2708 __ bind(&miss); | 2666 __ bind(&miss); |
2709 TailCallBuiltin(masm(), MissBuiltin(kind())); | 2667 TailCallBuiltin(masm(), MissBuiltin(kind())); |
2710 | 2668 |
2711 // Return the generated code. | 2669 // Return the generated code. |
2712 return GetICCode(kind(), Code::INTERCEPTOR, name); | 2670 return GetICCode(kind(), Code::INTERCEPTOR, name); |
2713 } | 2671 } |
2714 | 2672 |
2715 | 2673 |
2716 Handle<Code> StoreStubCompiler::CompileStoreGlobal( | 2674 Handle<Code> StoreStubCompiler::CompileStoreGlobal( |
2717 Handle<GlobalObject> object, | 2675 Handle<GlobalObject> object, |
2718 Handle<JSGlobalPropertyCell> cell, | 2676 Handle<JSGlobalPropertyCell> cell, |
2719 Handle<Name> name) { | 2677 Handle<Name> name) { |
2720 // ----------- S t a t e ------------- | |
2721 // -- eax : value | |
2722 // -- ecx : name | |
2723 // -- edx : receiver | |
2724 // -- esp[0] : return address | |
2725 // ----------------------------------- | |
2726 Label miss; | 2678 Label miss; |
2727 | 2679 |
2728 // Check that the map of the global has not changed. | 2680 // Check that the map of the global has not changed. |
2729 __ cmp(FieldOperand(edx, HeapObject::kMapOffset), | 2681 __ cmp(FieldOperand(receiver(), HeapObject::kMapOffset), |
2730 Immediate(Handle<Map>(object->map()))); | 2682 Immediate(Handle<Map>(object->map()))); |
2731 __ j(not_equal, &miss); | 2683 __ j(not_equal, &miss); |
2732 | 2684 |
2733 // Compute the cell operand to use. | 2685 // Compute the cell operand to use. |
2734 __ mov(ebx, Immediate(cell)); | 2686 __ mov(scratch1(), Immediate(cell)); |
2735 Operand cell_operand = FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset); | 2687 Operand cell_operand = |
| 2688 FieldOperand(scratch1(), JSGlobalPropertyCell::kValueOffset); |
2736 | 2689 |
2737 // Check that the value in the cell is not the hole. If it is, this | 2690 // Check that the value in the cell is not the hole. If it is, this |
2738 // cell could have been deleted and reintroducing the global needs | 2691 // cell could have been deleted and reintroducing the global needs |
2739 // to update the property details in the property dictionary of the | 2692 // to update the property details in the property dictionary of the |
2740 // global object. We bail out to the runtime system to do that. | 2693 // global object. We bail out to the runtime system to do that. |
2741 __ cmp(cell_operand, factory()->the_hole_value()); | 2694 __ cmp(cell_operand, factory()->the_hole_value()); |
2742 __ j(equal, &miss); | 2695 __ j(equal, &miss); |
2743 | 2696 |
2744 // Store the value in the cell. | 2697 // Store the value in the cell. |
2745 __ mov(cell_operand, eax); | 2698 __ mov(cell_operand, value()); |
2746 // No write barrier here, because cells are always rescanned. | 2699 // No write barrier here, because cells are always rescanned. |
2747 | 2700 |
2748 // Return the value (register eax). | 2701 // Return the value (register eax). |
2749 Counters* counters = isolate()->counters(); | 2702 Counters* counters = isolate()->counters(); |
2750 __ IncrementCounter(counters->named_store_global_inline(), 1); | 2703 __ IncrementCounter(counters->named_store_global_inline(), 1); |
2751 __ ret(0); | 2704 __ ret(0); |
2752 | 2705 |
2753 // Handle store cache miss. | 2706 // Handle store cache miss. |
2754 __ bind(&miss); | 2707 __ bind(&miss); |
2755 __ IncrementCounter(counters->named_store_global_inline_miss(), 1); | 2708 __ IncrementCounter(counters->named_store_global_inline_miss(), 1); |
2756 TailCallBuiltin(masm(), MissBuiltin(kind())); | 2709 TailCallBuiltin(masm(), MissBuiltin(kind())); |
2757 | 2710 |
2758 // Return the generated code. | 2711 // Return the generated code. |
2759 return GetICCode(kind(), Code::NORMAL, name); | 2712 return GetICCode(kind(), Code::NORMAL, name); |
2760 } | 2713 } |
2761 | 2714 |
2762 | 2715 |
2763 Handle<Code> KeyedStoreStubCompiler::CompileStoreElement( | |
2764 Handle<Map> receiver_map) { | |
2765 // ----------- S t a t e ------------- | |
2766 // -- eax : value | |
2767 // -- ecx : key | |
2768 // -- edx : receiver | |
2769 // -- esp[0] : return address | |
2770 // ----------------------------------- | |
2771 ElementsKind elements_kind = receiver_map->elements_kind(); | |
2772 bool is_jsarray = receiver_map->instance_type() == JS_ARRAY_TYPE; | |
2773 Handle<Code> stub = | |
2774 KeyedStoreElementStub(is_jsarray, | |
2775 elements_kind, | |
2776 store_mode_).GetCode(isolate()); | |
2777 | |
2778 __ DispatchMap(edx, receiver_map, stub, DO_SMI_CHECK); | |
2779 | |
2780 TailCallBuiltin(masm(), MissBuiltin(kind())); | |
2781 | |
2782 // Return the generated code. | |
2783 return GetICCode(kind(), Code::NORMAL, factory()->empty_string()); | |
2784 } | |
2785 | |
2786 | |
2787 Handle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic( | 2716 Handle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic( |
2788 MapHandleList* receiver_maps, | 2717 MapHandleList* receiver_maps, |
2789 CodeHandleList* handler_stubs, | 2718 CodeHandleList* handler_stubs, |
2790 MapHandleList* transitioned_maps) { | 2719 MapHandleList* transitioned_maps) { |
2791 // ----------- S t a t e ------------- | |
2792 // -- eax : value | |
2793 // -- ecx : key | |
2794 // -- edx : receiver | |
2795 // -- esp[0] : return address | |
2796 // ----------------------------------- | |
2797 Label miss; | 2720 Label miss; |
2798 __ JumpIfSmi(edx, &miss, Label::kNear); | 2721 __ JumpIfSmi(receiver(), &miss, Label::kNear); |
2799 __ mov(edi, FieldOperand(edx, HeapObject::kMapOffset)); | 2722 __ mov(scratch1(), FieldOperand(receiver(), HeapObject::kMapOffset)); |
2800 // ebx: receiver->map(). | |
2801 for (int i = 0; i < receiver_maps->length(); ++i) { | 2723 for (int i = 0; i < receiver_maps->length(); ++i) { |
2802 __ cmp(edi, receiver_maps->at(i)); | 2724 __ cmp(scratch1(), receiver_maps->at(i)); |
2803 if (transitioned_maps->at(i).is_null()) { | 2725 if (transitioned_maps->at(i).is_null()) { |
2804 __ j(equal, handler_stubs->at(i)); | 2726 __ j(equal, handler_stubs->at(i)); |
2805 } else { | 2727 } else { |
2806 Label next_map; | 2728 Label next_map; |
2807 __ j(not_equal, &next_map, Label::kNear); | 2729 __ j(not_equal, &next_map, Label::kNear); |
2808 __ mov(ebx, Immediate(transitioned_maps->at(i))); | 2730 __ mov(transition_map(), Immediate(transitioned_maps->at(i))); |
2809 __ jmp(handler_stubs->at(i), RelocInfo::CODE_TARGET); | 2731 __ jmp(handler_stubs->at(i), RelocInfo::CODE_TARGET); |
2810 __ bind(&next_map); | 2732 __ bind(&next_map); |
2811 } | 2733 } |
2812 } | 2734 } |
2813 __ bind(&miss); | 2735 __ bind(&miss); |
2814 TailCallBuiltin(masm(), MissBuiltin(kind())); | 2736 TailCallBuiltin(masm(), MissBuiltin(kind())); |
2815 | 2737 |
2816 // Return the generated code. | 2738 // Return the generated code. |
2817 return GetICCode( | 2739 return GetICCode( |
2818 kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC); | 2740 kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC); |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2954 Counters* counters = isolate()->counters(); | 2876 Counters* counters = isolate()->counters(); |
2955 __ IncrementCounter(counters->named_load_global_stub(), 1); | 2877 __ IncrementCounter(counters->named_load_global_stub(), 1); |
2956 // The code above already loads the result into the return register. | 2878 // The code above already loads the result into the return register. |
2957 __ ret(0); | 2879 __ ret(0); |
2958 | 2880 |
2959 // Return the generated code. | 2881 // Return the generated code. |
2960 return GetICCode(kind(), Code::NORMAL, name); | 2882 return GetICCode(kind(), Code::NORMAL, name); |
2961 } | 2883 } |
2962 | 2884 |
2963 | 2885 |
2964 Handle<Code> KeyedLoadStubCompiler::CompileLoadElement( | |
2965 Handle<Map> receiver_map) { | |
2966 // ----------- S t a t e ------------- | |
2967 // -- ecx : key | |
2968 // -- edx : receiver | |
2969 // -- esp[0] : return address | |
2970 // ----------------------------------- | |
2971 | |
2972 ElementsKind elements_kind = receiver_map->elements_kind(); | |
2973 if (receiver_map->has_fast_elements() || | |
2974 receiver_map->has_external_array_elements()) { | |
2975 Handle<Code> stub = KeyedLoadFastElementStub( | |
2976 receiver_map->instance_type() == JS_ARRAY_TYPE, | |
2977 elements_kind).GetCode(isolate()); | |
2978 __ DispatchMap(edx, receiver_map, stub, DO_SMI_CHECK); | |
2979 } else { | |
2980 Handle<Code> stub = | |
2981 KeyedLoadDictionaryElementStub().GetCode(isolate()); | |
2982 __ DispatchMap(edx, receiver_map, stub, DO_SMI_CHECK); | |
2983 } | |
2984 | |
2985 TailCallBuiltin(masm(), Builtins::kKeyedLoadIC_Miss); | |
2986 | |
2987 // Return the generated code. | |
2988 return GetICCode(kind(), Code::NORMAL, factory()->empty_string()); | |
2989 } | |
2990 | |
2991 | |
2992 Handle<Code> BaseLoadStubCompiler::CompilePolymorphicIC( | 2886 Handle<Code> BaseLoadStubCompiler::CompilePolymorphicIC( |
2993 MapHandleList* receiver_maps, | 2887 MapHandleList* receiver_maps, |
2994 CodeHandleList* handlers, | 2888 CodeHandleList* handlers, |
2995 Handle<Name> name, | 2889 Handle<Name> name, |
2996 Code::StubType type, | 2890 Code::StubType type, |
2997 IcCheckType check) { | 2891 IcCheckType check) { |
2998 Label miss; | 2892 Label miss; |
2999 | 2893 |
3000 if (check == PROPERTY) { | 2894 if (check == PROPERTY) { |
3001 GenerateNameCheck(name, this->name(), &miss); | 2895 GenerateNameCheck(name, this->name(), &miss); |
(...skipping 717 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3719 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow); | 3613 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow); |
3720 } | 3614 } |
3721 } | 3615 } |
3722 | 3616 |
3723 | 3617 |
3724 #undef __ | 3618 #undef __ |
3725 | 3619 |
3726 } } // namespace v8::internal | 3620 } } // namespace v8::internal |
3727 | 3621 |
3728 #endif // V8_TARGET_ARCH_IA32 | 3622 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |