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 |