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