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 bool feedback_metadata_changed, | |
754 Isolate* isolate) { | |
755 int new_literal_count = compile_info_wrapper->GetLiteralCount(); | |
745 | 756 |
746 // Patch function literals. | 757 if (!feedback_metadata_changed) { |
747 // Name 'literals' is a misnomer. Rather it's a cache for complex object | 758 // It's enough to clear the feedback vector in this case. |
748 // boilerplates and for a native context. We must clean cached values. | |
749 // Additionally we may need to allocate a new array if number of literals | |
750 // changed. | |
751 class LiteralFixer { | |
752 public: | |
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 | |
759 if (old_literal_count == new_literal_count && !feedback_metadata_changed) { | |
760 // If literal count didn't change, simply go over all functions | |
761 // and clear literal arrays. | |
762 ClearValuesVisitor visitor; | 759 ClearValuesVisitor visitor; |
763 IterateJSFunctions(shared_info, &visitor); | 760 IterateJSFunctions(shared_info, &visitor); |
764 } else { | 761 } else { |
765 // When literal count changes, we have to create new array instances. | 762 // When feedback metadata changes, we have to create new array instances. |
766 // Since we cannot create instances when iterating heap, we should first | 763 // Since we cannot create instances when iterating heap, we should first |
767 // collect all functions and fix their literal arrays. | 764 // collect all functions and fix their literal arrays. |
768 Handle<FixedArray> function_instances = | 765 Handle<FixedArray> function_instances = |
769 CollectJSFunctions(shared_info, isolate); | 766 CollectJSFunctions(shared_info, isolate); |
770 Handle<TypeFeedbackMetadata> feedback_metadata( | 767 Handle<TypeFeedbackMetadata> feedback_metadata( |
771 shared_info->feedback_metadata()); | 768 shared_info->feedback_metadata()); |
772 | 769 |
773 for (int i = 0; i < function_instances->length(); i++) { | 770 for (int i = 0; i < function_instances->length(); i++) { |
774 Handle<JSFunction> fun(JSFunction::cast(function_instances->get(i))); | 771 Handle<JSFunction> fun(JSFunction::cast(function_instances->get(i))); |
775 Handle<TypeFeedbackVector> vector = | 772 Handle<TypeFeedbackVector> vector = |
776 TypeFeedbackVector::New(isolate, feedback_metadata); | 773 TypeFeedbackVector::New(isolate, feedback_metadata); |
777 fun->set_feedback_vector(*vector); | 774 fun->feedback_vector_cell()->set_value(*vector); |
778 } | 775 } |
776 } | |
779 | 777 |
780 shared_info->set_num_literals(new_literal_count); | 778 shared_info->set_num_literals(new_literal_count); |
781 } | |
782 } | 779 } |
783 | 780 |
784 private: | 781 private: |
785 // Iterates all function instances in the HEAP that refers to the | 782 // Iterates all function instances in the HEAP that refers to the |
786 // provided shared_info. | 783 // provided shared_info. |
787 template<typename Visitor> | 784 template<typename Visitor> |
788 static void IterateJSFunctions(Handle<SharedFunctionInfo> shared_info, | 785 static void IterateJSFunctions(Handle<SharedFunctionInfo> shared_info, |
789 Visitor* visitor) { | 786 Visitor* visitor) { |
790 HeapIterator iterator(shared_info->GetHeap()); | 787 HeapIterator iterator(shared_info->GetHeap()); |
791 for (HeapObject* obj = iterator.next(); obj != NULL; | 788 for (HeapObject* obj = iterator.next(); obj != NULL; |
792 obj = iterator.next()) { | 789 obj = iterator.next()) { |
793 if (obj->IsJSFunction()) { | 790 if (obj->IsJSFunction()) { |
794 JSFunction* function = JSFunction::cast(obj); | 791 JSFunction* function = JSFunction::cast(obj); |
795 if (function->shared() == *shared_info) { | 792 if (function->shared() == *shared_info) { |
796 visitor->visit(function); | 793 visitor->visit(function); |
797 } | 794 } |
798 } | 795 } |
799 } | 796 } |
800 } | 797 } |
801 | 798 |
799 template <typename Visitor> | |
800 static void IterateAllJSFunctions(Heap* heap, Visitor* visitor) { | |
mvstanton
2017/02/03 12:16:37
dead code, remove.
| |
801 HeapIterator iterator(heap); | |
802 for (HeapObject* obj = iterator.next(); obj != NULL; | |
803 obj = iterator.next()) { | |
804 if (obj->IsJSFunction()) { | |
805 JSFunction* function = JSFunction::cast(obj); | |
806 visitor->visit(function); | |
807 } | |
808 } | |
809 } | |
810 | |
802 // Finds all instances of JSFunction that refers to the provided shared_info | 811 // Finds all instances of JSFunction that refers to the provided shared_info |
803 // and returns array with them. | 812 // and returns array with them. |
804 static Handle<FixedArray> CollectJSFunctions( | 813 static Handle<FixedArray> CollectJSFunctions( |
805 Handle<SharedFunctionInfo> shared_info, Isolate* isolate) { | 814 Handle<SharedFunctionInfo> shared_info, Isolate* isolate) { |
806 CountVisitor count_visitor; | 815 CountVisitor count_visitor; |
807 count_visitor.count = 0; | 816 count_visitor.count = 0; |
808 IterateJSFunctions(shared_info, &count_visitor); | 817 IterateJSFunctions(shared_info, &count_visitor); |
809 int size = count_visitor.count; | 818 int size = count_visitor.count; |
810 | 819 |
811 Handle<FixedArray> result = isolate->factory()->NewFixedArray(size); | 820 Handle<FixedArray> result = isolate->factory()->NewFixedArray(size); |
812 if (size > 0) { | 821 if (size > 0) { |
813 CollectVisitor collect_visitor(result); | 822 CollectVisitor collect_visitor(result); |
814 IterateJSFunctions(shared_info, &collect_visitor); | 823 IterateJSFunctions(shared_info, &collect_visitor); |
815 } | 824 } |
816 return result; | 825 return result; |
817 } | 826 } |
818 | 827 |
819 class ClearValuesVisitor { | 828 class ClearValuesVisitor { |
820 public: | 829 public: |
821 void visit(JSFunction* fun) { | 830 void visit(JSFunction* fun) { |
822 TypeFeedbackVector* vector = fun->feedback_vector(); | 831 if (fun->feedback_vector_cell()->value()->IsTypeFeedbackVector()) { |
823 vector->ClearSlots(fun->shared()); | 832 TypeFeedbackVector* vector = fun->feedback_vector(); |
833 vector->ClearSlots(fun->shared()); | |
834 } | |
824 } | 835 } |
825 }; | 836 }; |
826 | 837 |
827 class CountVisitor { | 838 class CountVisitor { |
828 public: | 839 public: |
829 void visit(JSFunction* fun) { | 840 void visit(JSFunction* fun) { |
830 count++; | 841 count++; |
831 } | 842 } |
832 int count; | 843 int count; |
833 }; | 844 }; |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
937 isolate->debug()->RemoveDebugInfoAndClearFromShared( | 948 isolate->debug()->RemoveDebugInfoAndClearFromShared( |
938 handle(shared_info->GetDebugInfo())); | 949 handle(shared_info->GetDebugInfo())); |
939 } | 950 } |
940 shared_info->set_scope_info(new_shared_info->scope_info()); | 951 shared_info->set_scope_info(new_shared_info->scope_info()); |
941 shared_info->set_outer_scope_info(new_shared_info->outer_scope_info()); | 952 shared_info->set_outer_scope_info(new_shared_info->outer_scope_info()); |
942 shared_info->DisableOptimization(kLiveEdit); | 953 shared_info->DisableOptimization(kLiveEdit); |
943 // Update the type feedback vector, if needed. | 954 // Update the type feedback vector, if needed. |
944 Handle<TypeFeedbackMetadata> new_feedback_metadata( | 955 Handle<TypeFeedbackMetadata> new_feedback_metadata( |
945 new_shared_info->feedback_metadata()); | 956 new_shared_info->feedback_metadata()); |
946 feedback_metadata_changed = | 957 feedback_metadata_changed = |
947 new_feedback_metadata->DiffersFrom(shared_info->feedback_metadata()); | 958 new_feedback_metadata->DiffersFrom(shared_info->feedback_metadata()) || |
959 new_feedback_metadata->HasFunctionLiteralSlots(); | |
948 shared_info->set_feedback_metadata(*new_feedback_metadata); | 960 shared_info->set_feedback_metadata(*new_feedback_metadata); |
949 } | 961 } |
950 | 962 |
951 int start_position = compile_info_wrapper.GetStartPosition(); | 963 int start_position = compile_info_wrapper.GetStartPosition(); |
952 int end_position = compile_info_wrapper.GetEndPosition(); | 964 int end_position = compile_info_wrapper.GetEndPosition(); |
953 shared_info->set_start_position(start_position); | 965 shared_info->set_start_position(start_position); |
954 shared_info->set_end_position(end_position); | 966 shared_info->set_end_position(end_position); |
955 | 967 |
956 LiteralFixer::PatchLiterals(&compile_info_wrapper, shared_info, | 968 FeedbackVectorFixer::PatchFeedbackVector(&compile_info_wrapper, shared_info, |
957 feedback_metadata_changed, isolate); | 969 feedback_metadata_changed, isolate); |
958 | 970 |
959 DeoptimizeDependentFunctions(*shared_info); | 971 DeoptimizeDependentFunctions(*shared_info); |
960 isolate->compilation_cache()->Remove(shared_info); | 972 isolate->compilation_cache()->Remove(shared_info); |
961 } | 973 } |
962 | 974 |
963 void LiveEdit::FunctionSourceUpdated(Handle<JSArray> shared_info_array, | 975 void LiveEdit::FunctionSourceUpdated(Handle<JSArray> shared_info_array, |
964 int new_function_literal_id) { | 976 int new_function_literal_id) { |
965 SharedInfoWrapper shared_info_wrapper(shared_info_array); | 977 SharedInfoWrapper shared_info_wrapper(shared_info_array); |
966 Handle<SharedFunctionInfo> shared_info = shared_info_wrapper.GetInfo(); | 978 Handle<SharedFunctionInfo> shared_info = shared_info_wrapper.GetInfo(); |
967 | 979 |
(...skipping 698 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1666 scope_info_length++; | 1678 scope_info_length++; |
1667 | 1679 |
1668 current_scope = current_scope->outer_scope(); | 1680 current_scope = current_scope->outer_scope(); |
1669 } | 1681 } |
1670 | 1682 |
1671 return scope_info_list; | 1683 return scope_info_list; |
1672 } | 1684 } |
1673 | 1685 |
1674 } // namespace internal | 1686 } // namespace internal |
1675 } // namespace v8 | 1687 } // namespace v8 |
OLD | NEW |