| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/debug/liveedit.h" | 5 #include "src/debug/liveedit.h" |
| 6 | 6 |
| 7 #include "src/ast/scopes.h" | 7 #include "src/ast/scopes.h" |
| 8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" |
| 9 #include "src/compilation-cache.h" | 9 #include "src/compilation-cache.h" |
| 10 #include "src/compiler.h" | 10 #include "src/compiler.h" |
| (...skipping 724 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 735 if (obj->IsJSFunction()) { | 735 if (obj->IsJSFunction()) { |
| 736 JSFunction* fun = JSFunction::cast(obj); | 736 JSFunction* fun = JSFunction::cast(obj); |
| 737 if (fun->code() == *original) fun->ReplaceCode(*substitution); | 737 if (fun->code() == *original) fun->ReplaceCode(*substitution); |
| 738 } else if (obj->IsSharedFunctionInfo()) { | 738 } else if (obj->IsSharedFunctionInfo()) { |
| 739 SharedFunctionInfo* info = SharedFunctionInfo::cast(obj); | 739 SharedFunctionInfo* info = SharedFunctionInfo::cast(obj); |
| 740 if (info->code() == *original) info->set_code(*substitution); | 740 if (info->code() == *original) info->set_code(*substitution); |
| 741 } | 741 } |
| 742 } | 742 } |
| 743 } | 743 } |
| 744 | 744 |
| 745 // Patch function feedback vector. |
| 746 // The feedback vector is a cache for complex object boilerplates and for a |
| 747 // native context. We must clean cached values, or if the structure of the |
| 748 // vector itself changes we need to allocate a new one. |
| 749 class FeedbackVectorFixer { |
| 750 public: |
| 751 static void PatchFeedbackVector(FunctionInfoWrapper* compile_info_wrapper, |
| 752 Handle<SharedFunctionInfo> shared_info, |
| 753 Isolate* isolate) { |
| 754 int new_literal_count = compile_info_wrapper->GetLiteralCount(); |
| 745 | 755 |
| 746 // Patch function literals. | 756 // When feedback metadata changes, we have to create new array instances. |
| 747 // Name 'literals' is a misnomer. Rather it's a cache for complex object | 757 // Since we cannot create instances when iterating heap, we should first |
| 748 // boilerplates and for a native context. We must clean cached values. | 758 // collect all functions and fix their literal arrays. |
| 749 // Additionally we may need to allocate a new array if number of literals | 759 Handle<FixedArray> function_instances = |
| 750 // changed. | 760 CollectJSFunctions(shared_info, isolate); |
| 751 class LiteralFixer { | 761 Handle<TypeFeedbackMetadata> feedback_metadata( |
| 752 public: | 762 shared_info->feedback_metadata()); |
| 753 static void PatchLiterals(FunctionInfoWrapper* compile_info_wrapper, | |
| 754 Handle<SharedFunctionInfo> shared_info, | |
| 755 bool feedback_metadata_changed, Isolate* isolate) { | |
| 756 int new_literal_count = compile_info_wrapper->GetLiteralCount(); | |
| 757 int old_literal_count = shared_info->num_literals(); | |
| 758 | 763 |
| 759 if (old_literal_count == new_literal_count && !feedback_metadata_changed) { | 764 for (int i = 0; i < function_instances->length(); i++) { |
| 760 // If literal count didn't change, simply go over all functions | 765 Handle<JSFunction> fun(JSFunction::cast(function_instances->get(i))); |
| 761 // and clear literal arrays. | 766 Handle<TypeFeedbackVector> vector = |
| 762 ClearValuesVisitor visitor; | 767 TypeFeedbackVector::New(isolate, feedback_metadata); |
| 763 IterateJSFunctions(shared_info, &visitor); | 768 fun->feedback_vector_cell()->set_value(*vector); |
| 764 } else { | |
| 765 // When literal count changes, we have to create new array instances. | |
| 766 // Since we cannot create instances when iterating heap, we should first | |
| 767 // collect all functions and fix their literal arrays. | |
| 768 Handle<FixedArray> function_instances = | |
| 769 CollectJSFunctions(shared_info, isolate); | |
| 770 Handle<TypeFeedbackMetadata> feedback_metadata( | |
| 771 shared_info->feedback_metadata()); | |
| 772 | |
| 773 for (int i = 0; i < function_instances->length(); i++) { | |
| 774 Handle<JSFunction> fun(JSFunction::cast(function_instances->get(i))); | |
| 775 Handle<TypeFeedbackVector> vector = | |
| 776 TypeFeedbackVector::New(isolate, feedback_metadata); | |
| 777 fun->set_feedback_vector(*vector); | |
| 778 } | 769 } |
| 779 | 770 |
| 780 shared_info->set_num_literals(new_literal_count); | 771 shared_info->set_num_literals(new_literal_count); |
| 781 } | |
| 782 } | 772 } |
| 783 | 773 |
| 784 private: | 774 private: |
| 785 // Iterates all function instances in the HEAP that refers to the | 775 // Iterates all function instances in the HEAP that refers to the |
| 786 // provided shared_info. | 776 // provided shared_info. |
| 787 template<typename Visitor> | 777 template<typename Visitor> |
| 788 static void IterateJSFunctions(Handle<SharedFunctionInfo> shared_info, | 778 static void IterateJSFunctions(Handle<SharedFunctionInfo> shared_info, |
| 789 Visitor* visitor) { | 779 Visitor* visitor) { |
| 790 HeapIterator iterator(shared_info->GetHeap()); | 780 HeapIterator iterator(shared_info->GetHeap()); |
| 791 for (HeapObject* obj = iterator.next(); obj != NULL; | 781 for (HeapObject* obj = iterator.next(); obj != NULL; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 809 int size = count_visitor.count; | 799 int size = count_visitor.count; |
| 810 | 800 |
| 811 Handle<FixedArray> result = isolate->factory()->NewFixedArray(size); | 801 Handle<FixedArray> result = isolate->factory()->NewFixedArray(size); |
| 812 if (size > 0) { | 802 if (size > 0) { |
| 813 CollectVisitor collect_visitor(result); | 803 CollectVisitor collect_visitor(result); |
| 814 IterateJSFunctions(shared_info, &collect_visitor); | 804 IterateJSFunctions(shared_info, &collect_visitor); |
| 815 } | 805 } |
| 816 return result; | 806 return result; |
| 817 } | 807 } |
| 818 | 808 |
| 819 class ClearValuesVisitor { | |
| 820 public: | |
| 821 void visit(JSFunction* fun) { | |
| 822 TypeFeedbackVector* vector = fun->feedback_vector(); | |
| 823 vector->ClearSlots(fun->shared()); | |
| 824 } | |
| 825 }; | |
| 826 | |
| 827 class CountVisitor { | 809 class CountVisitor { |
| 828 public: | 810 public: |
| 829 void visit(JSFunction* fun) { | 811 void visit(JSFunction* fun) { |
| 830 count++; | 812 count++; |
| 831 } | 813 } |
| 832 int count; | 814 int count; |
| 833 }; | 815 }; |
| 834 | 816 |
| 835 class CollectVisitor { | 817 class CollectVisitor { |
| 836 public: | 818 public: |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 889 Handle<JSArray> new_compile_info_array, | 871 Handle<JSArray> new_compile_info_array, |
| 890 Handle<JSArray> shared_info_array) { | 872 Handle<JSArray> shared_info_array) { |
| 891 Isolate* isolate = new_compile_info_array->GetIsolate(); | 873 Isolate* isolate = new_compile_info_array->GetIsolate(); |
| 892 | 874 |
| 893 FunctionInfoWrapper compile_info_wrapper(new_compile_info_array); | 875 FunctionInfoWrapper compile_info_wrapper(new_compile_info_array); |
| 894 SharedInfoWrapper shared_info_wrapper(shared_info_array); | 876 SharedInfoWrapper shared_info_wrapper(shared_info_array); |
| 895 | 877 |
| 896 Handle<SharedFunctionInfo> shared_info = shared_info_wrapper.GetInfo(); | 878 Handle<SharedFunctionInfo> shared_info = shared_info_wrapper.GetInfo(); |
| 897 Handle<SharedFunctionInfo> new_shared_info = | 879 Handle<SharedFunctionInfo> new_shared_info = |
| 898 compile_info_wrapper.GetSharedFunctionInfo(); | 880 compile_info_wrapper.GetSharedFunctionInfo(); |
| 899 bool feedback_metadata_changed = false; | |
| 900 | 881 |
| 901 if (shared_info->is_compiled()) { | 882 if (shared_info->is_compiled()) { |
| 902 // Take whatever code we can get from the new shared function info. We | 883 // Take whatever code we can get from the new shared function info. We |
| 903 // expect activations of neither the old bytecode nor old FCG code, since | 884 // expect activations of neither the old bytecode nor old FCG code, since |
| 904 // the lowest activation is going to be restarted. | 885 // the lowest activation is going to be restarted. |
| 905 Handle<Code> old_code(shared_info->code()); | 886 Handle<Code> old_code(shared_info->code()); |
| 906 Handle<Code> new_code(new_shared_info->code()); | 887 Handle<Code> new_code(new_shared_info->code()); |
| 907 // Clear old bytecode. This will trigger self-healing if we do not install | 888 // Clear old bytecode. This will trigger self-healing if we do not install |
| 908 // new bytecode. | 889 // new bytecode. |
| 909 shared_info->ClearBytecodeArray(); | 890 shared_info->ClearBytecodeArray(); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 936 // Existing break points will be re-applied. Reset the debug info here. | 917 // Existing break points will be re-applied. Reset the debug info here. |
| 937 isolate->debug()->RemoveDebugInfoAndClearFromShared( | 918 isolate->debug()->RemoveDebugInfoAndClearFromShared( |
| 938 handle(shared_info->GetDebugInfo())); | 919 handle(shared_info->GetDebugInfo())); |
| 939 } | 920 } |
| 940 shared_info->set_scope_info(new_shared_info->scope_info()); | 921 shared_info->set_scope_info(new_shared_info->scope_info()); |
| 941 shared_info->set_outer_scope_info(new_shared_info->outer_scope_info()); | 922 shared_info->set_outer_scope_info(new_shared_info->outer_scope_info()); |
| 942 shared_info->DisableOptimization(kLiveEdit); | 923 shared_info->DisableOptimization(kLiveEdit); |
| 943 // Update the type feedback vector, if needed. | 924 // Update the type feedback vector, if needed. |
| 944 Handle<TypeFeedbackMetadata> new_feedback_metadata( | 925 Handle<TypeFeedbackMetadata> new_feedback_metadata( |
| 945 new_shared_info->feedback_metadata()); | 926 new_shared_info->feedback_metadata()); |
| 946 feedback_metadata_changed = | |
| 947 new_feedback_metadata->DiffersFrom(shared_info->feedback_metadata()); | |
| 948 shared_info->set_feedback_metadata(*new_feedback_metadata); | 927 shared_info->set_feedback_metadata(*new_feedback_metadata); |
| 949 } | 928 } |
| 950 | 929 |
| 951 int start_position = compile_info_wrapper.GetStartPosition(); | 930 int start_position = compile_info_wrapper.GetStartPosition(); |
| 952 int end_position = compile_info_wrapper.GetEndPosition(); | 931 int end_position = compile_info_wrapper.GetEndPosition(); |
| 953 shared_info->set_start_position(start_position); | 932 shared_info->set_start_position(start_position); |
| 954 shared_info->set_end_position(end_position); | 933 shared_info->set_end_position(end_position); |
| 955 | 934 |
| 956 LiteralFixer::PatchLiterals(&compile_info_wrapper, shared_info, | 935 FeedbackVectorFixer::PatchFeedbackVector(&compile_info_wrapper, shared_info, |
| 957 feedback_metadata_changed, isolate); | 936 isolate); |
| 958 | 937 |
| 959 DeoptimizeDependentFunctions(*shared_info); | 938 DeoptimizeDependentFunctions(*shared_info); |
| 960 isolate->compilation_cache()->Remove(shared_info); | 939 isolate->compilation_cache()->Remove(shared_info); |
| 961 } | 940 } |
| 962 | 941 |
| 963 void LiveEdit::FunctionSourceUpdated(Handle<JSArray> shared_info_array, | 942 void LiveEdit::FunctionSourceUpdated(Handle<JSArray> shared_info_array, |
| 964 int new_function_literal_id) { | 943 int new_function_literal_id) { |
| 965 SharedInfoWrapper shared_info_wrapper(shared_info_array); | 944 SharedInfoWrapper shared_info_wrapper(shared_info_array); |
| 966 Handle<SharedFunctionInfo> shared_info = shared_info_wrapper.GetInfo(); | 945 Handle<SharedFunctionInfo> shared_info = shared_info_wrapper.GetInfo(); |
| 967 | 946 |
| (...skipping 698 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1666 scope_info_length++; | 1645 scope_info_length++; |
| 1667 | 1646 |
| 1668 current_scope = current_scope->outer_scope(); | 1647 current_scope = current_scope->outer_scope(); |
| 1669 } | 1648 } |
| 1670 | 1649 |
| 1671 return scope_info_list; | 1650 return scope_info_list; |
| 1672 } | 1651 } |
| 1673 | 1652 |
| 1674 } // namespace internal | 1653 } // namespace internal |
| 1675 } // namespace v8 | 1654 } // namespace v8 |
| OLD | NEW |