Chromium Code Reviews| 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 |