Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(143)

Side by Side Diff: src/debug/liveedit.cc

Issue 2504153002: [TypeFeedbackVector] Root literal arrays in function literals slots (Closed)
Patch Set: REBASE. Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 807 matching lines...) Expand 10 before | Expand all | Expand 10 after
818 818
819 // Patch function literals. 819 // Patch function literals.
820 // Name 'literals' is a misnomer. Rather it's a cache for complex object 820 // Name 'literals' is a misnomer. Rather it's a cache for complex object
821 // boilerplates and for a native context. We must clean cached values. 821 // boilerplates and for a native context. We must clean cached values.
822 // Additionally we may need to allocate a new array if number of literals 822 // Additionally we may need to allocate a new array if number of literals
823 // changed. 823 // changed.
824 class LiteralFixer { 824 class LiteralFixer {
825 public: 825 public:
826 static void PatchLiterals(FunctionInfoWrapper* compile_info_wrapper, 826 static void PatchLiterals(FunctionInfoWrapper* compile_info_wrapper,
827 Handle<SharedFunctionInfo> shared_info, 827 Handle<SharedFunctionInfo> shared_info,
828 bool feedback_metadata_changed, Isolate* isolate) { 828 Isolate* isolate) {
829 int new_literal_count = compile_info_wrapper->GetLiteralCount(); 829 int new_literal_count = compile_info_wrapper->GetLiteralCount();
830 int old_literal_count = shared_info->num_literals();
831 830
832 if (old_literal_count == new_literal_count && !feedback_metadata_changed) { 831 // Recreate the literal array and type feedback vector.
833 // If literal count didn't change, simply go over all functions 832 // Since the feedback vector roots literal arrays for nested functions,
834 // and clear literal arrays. 833 // we can't simply leave it in place because those nested literal
835 ClearValuesVisitor visitor; 834 // array and feedback vectors may have changed structure.
836 IterateJSFunctions(shared_info, &visitor); 835 Handle<FixedArray> function_instances =
837 } else { 836 CollectJSFunctions(shared_info, isolate);
838 // When literal count changes, we have to create new array instances. 837 Handle<TypeFeedbackMetadata> feedback_metadata(
839 // Since we cannot create instances when iterating heap, we should first 838 shared_info->feedback_metadata());
840 // collect all functions and fix their literal arrays.
841 Handle<FixedArray> function_instances =
842 CollectJSFunctions(shared_info, isolate);
843 Handle<TypeFeedbackMetadata> feedback_metadata(
844 shared_info->feedback_metadata());
845 839
846 for (int i = 0; i < function_instances->length(); i++) { 840 for (int i = 0; i < function_instances->length(); i++) {
847 Handle<JSFunction> fun(JSFunction::cast(function_instances->get(i))); 841 Handle<JSFunction> fun(JSFunction::cast(function_instances->get(i)));
848 Handle<TypeFeedbackVector> vector = 842 Handle<TypeFeedbackVector> vector =
849 TypeFeedbackVector::New(isolate, feedback_metadata); 843 TypeFeedbackVector::New(isolate, feedback_metadata);
850 Handle<LiteralsArray> new_literals = 844 Handle<LiteralsArray> new_literals =
851 LiteralsArray::New(isolate, vector, new_literal_count); 845 LiteralsArray::New(isolate, vector, new_literal_count);
852 fun->set_literals(*new_literals); 846 Handle<LiteralsArray> old_literals(fun->literals(), isolate);
853 } 847 fun->set_literals(*new_literals);
854 848
855 shared_info->set_num_literals(new_literal_count); 849 // The literals are rooted in a containing feedback vector.
850 // Replace them there, so new closures have the correct literals.
851 ReplaceRoots(old_literals, new_literals);
856 } 852 }
853
854 shared_info->set_num_literals(new_literal_count);
857 } 855 }
858 856
859 private: 857 private:
860 // Iterates all function instances in the HEAP that refers to the 858 // Iterates all function instances in the HEAP that refers to the
861 // provided shared_info. 859 // provided shared_info.
862 template<typename Visitor> 860 template<typename Visitor>
863 static void IterateJSFunctions(Handle<SharedFunctionInfo> shared_info, 861 static void IterateJSFunctions(Handle<SharedFunctionInfo> shared_info,
864 Visitor* visitor) { 862 Visitor* visitor) {
865 HeapIterator iterator(shared_info->GetHeap()); 863 HeapIterator iterator(shared_info->GetHeap());
866 for (HeapObject* obj = iterator.next(); obj != NULL; 864 for (HeapObject* obj = iterator.next(); obj != NULL;
867 obj = iterator.next()) { 865 obj = iterator.next()) {
868 if (obj->IsJSFunction()) { 866 if (obj->IsJSFunction()) {
869 JSFunction* function = JSFunction::cast(obj); 867 JSFunction* function = JSFunction::cast(obj);
870 if (function->shared() == *shared_info) { 868 if (function->shared() == *shared_info) {
871 visitor->visit(function); 869 visitor->visit(function);
872 } 870 }
873 } 871 }
874 } 872 }
875 } 873 }
876 874
875 template <typename Visitor>
876 static void IterateAllJSFunctions(Heap* heap, Visitor* visitor) {
877 HeapIterator iterator(heap);
878 for (HeapObject* obj = iterator.next(); obj != NULL;
879 obj = iterator.next()) {
880 if (obj->IsJSFunction()) {
881 JSFunction* function = JSFunction::cast(obj);
882 visitor->visit(function);
883 }
884 }
885 }
886
887 class ReplaceRootsVisitor {
888 public:
889 ReplaceRootsVisitor(Handle<LiteralsArray> old_literals,
890 Handle<LiteralsArray> new_literals)
891 : old_literals_(old_literals), new_literals_(new_literals) {}
892
893 void visit(JSFunction* fun) {
894 if (!fun->shared()->is_compiled()) return;
895
896 // Look in the type feedback vector for a copy of literals.
897 TypeFeedbackVector* vector = fun->feedback_vector();
898 // Note: it's important to get the feedback metadata from the
899 // type feedback vector, because there may be a new metadata
900 // object in the SharedFunctionInfo (with a different slot
901 // configuration).
902 TypeFeedbackMetadataIterator iter(vector->metadata());
903 while (iter.HasNext()) {
904 FeedbackVectorSlot slot = iter.Next();
905 FeedbackVectorSlotKind kind = iter.kind();
906 if (kind == FeedbackVectorSlotKind::CREATE_CLOSURE) {
907 Object* obj = vector->Get(slot);
908 if (obj == *old_literals_) {
909 vector->Set(slot, *new_literals_);
910 }
911 }
912 }
913 }
914
915 Handle<LiteralsArray> old_literals_;
916 Handle<LiteralsArray> new_literals_;
917 };
918
919 static void ReplaceRoots(Handle<LiteralsArray> old_literals,
920 Handle<LiteralsArray> new_literals) {
921 ReplaceRootsVisitor replace_visitor(old_literals, new_literals);
922 IterateAllJSFunctions(old_literals->GetHeap(), &replace_visitor);
923 }
924
877 // Finds all instances of JSFunction that refers to the provided shared_info 925 // Finds all instances of JSFunction that refers to the provided shared_info
878 // and returns array with them. 926 // and returns array with them.
879 static Handle<FixedArray> CollectJSFunctions( 927 static Handle<FixedArray> CollectJSFunctions(
880 Handle<SharedFunctionInfo> shared_info, Isolate* isolate) { 928 Handle<SharedFunctionInfo> shared_info, Isolate* isolate) {
881 CountVisitor count_visitor; 929 CountVisitor count_visitor;
882 count_visitor.count = 0; 930 count_visitor.count = 0;
883 IterateJSFunctions(shared_info, &count_visitor); 931 IterateJSFunctions(shared_info, &count_visitor);
884 int size = count_visitor.count; 932 int size = count_visitor.count;
885 933
886 Handle<FixedArray> result = isolate->factory()->NewFixedArray(size); 934 Handle<FixedArray> result = isolate->factory()->NewFixedArray(size);
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
967 Handle<JSArray> new_compile_info_array, 1015 Handle<JSArray> new_compile_info_array,
968 Handle<JSArray> shared_info_array) { 1016 Handle<JSArray> shared_info_array) {
969 Isolate* isolate = new_compile_info_array->GetIsolate(); 1017 Isolate* isolate = new_compile_info_array->GetIsolate();
970 1018
971 FunctionInfoWrapper compile_info_wrapper(new_compile_info_array); 1019 FunctionInfoWrapper compile_info_wrapper(new_compile_info_array);
972 SharedInfoWrapper shared_info_wrapper(shared_info_array); 1020 SharedInfoWrapper shared_info_wrapper(shared_info_array);
973 1021
974 Handle<SharedFunctionInfo> shared_info = shared_info_wrapper.GetInfo(); 1022 Handle<SharedFunctionInfo> shared_info = shared_info_wrapper.GetInfo();
975 Handle<SharedFunctionInfo> new_shared_info = 1023 Handle<SharedFunctionInfo> new_shared_info =
976 compile_info_wrapper.GetSharedFunctionInfo(); 1024 compile_info_wrapper.GetSharedFunctionInfo();
977 bool feedback_metadata_changed = false;
978 1025
979 if (shared_info->is_compiled()) { 1026 if (shared_info->is_compiled()) {
980 // Take whatever code we can get from the new shared function info. We 1027 // Take whatever code we can get from the new shared function info. We
981 // expect activations of neither the old bytecode nor old FCG code, since 1028 // expect activations of neither the old bytecode nor old FCG code, since
982 // the lowest activation is going to be restarted. 1029 // the lowest activation is going to be restarted.
983 Handle<Code> old_code(shared_info->code()); 1030 Handle<Code> old_code(shared_info->code());
984 Handle<Code> new_code(new_shared_info->code()); 1031 Handle<Code> new_code(new_shared_info->code());
985 // Clear old bytecode. This will trigger self-healing if we do not install 1032 // Clear old bytecode. This will trigger self-healing if we do not install
986 // new bytecode. 1033 // new bytecode.
987 shared_info->ClearBytecodeArray(); 1034 shared_info->ClearBytecodeArray();
(...skipping 26 matching lines...) Expand all
1014 // Existing break points will be re-applied. Reset the debug info here. 1061 // Existing break points will be re-applied. Reset the debug info here.
1015 isolate->debug()->RemoveDebugInfoAndClearFromShared( 1062 isolate->debug()->RemoveDebugInfoAndClearFromShared(
1016 handle(shared_info->GetDebugInfo())); 1063 handle(shared_info->GetDebugInfo()));
1017 } 1064 }
1018 shared_info->set_scope_info(new_shared_info->scope_info()); 1065 shared_info->set_scope_info(new_shared_info->scope_info());
1019 shared_info->set_outer_scope_info(new_shared_info->outer_scope_info()); 1066 shared_info->set_outer_scope_info(new_shared_info->outer_scope_info());
1020 shared_info->DisableOptimization(kLiveEdit); 1067 shared_info->DisableOptimization(kLiveEdit);
1021 // Update the type feedback vector, if needed. 1068 // Update the type feedback vector, if needed.
1022 Handle<TypeFeedbackMetadata> new_feedback_metadata( 1069 Handle<TypeFeedbackMetadata> new_feedback_metadata(
1023 new_shared_info->feedback_metadata()); 1070 new_shared_info->feedback_metadata());
1024 feedback_metadata_changed =
1025 new_feedback_metadata->DiffersFrom(shared_info->feedback_metadata());
1026 shared_info->set_feedback_metadata(*new_feedback_metadata); 1071 shared_info->set_feedback_metadata(*new_feedback_metadata);
1027 } 1072 }
1028 1073
1029 int start_position = compile_info_wrapper.GetStartPosition(); 1074 int start_position = compile_info_wrapper.GetStartPosition();
1030 int end_position = compile_info_wrapper.GetEndPosition(); 1075 int end_position = compile_info_wrapper.GetEndPosition();
1031 shared_info->set_start_position(start_position); 1076 shared_info->set_start_position(start_position);
1032 shared_info->set_end_position(end_position); 1077 shared_info->set_end_position(end_position);
1033 1078
1034 LiteralFixer::PatchLiterals(&compile_info_wrapper, shared_info, 1079 LiteralFixer::PatchLiterals(&compile_info_wrapper, shared_info, isolate);
1035 feedback_metadata_changed, isolate);
1036 1080
1037 DeoptimizeDependentFunctions(*shared_info); 1081 DeoptimizeDependentFunctions(*shared_info);
1038 isolate->compilation_cache()->Remove(shared_info); 1082 isolate->compilation_cache()->Remove(shared_info);
1039 } 1083 }
1040 1084
1041 1085
1042 void LiveEdit::FunctionSourceUpdated(Handle<JSArray> shared_info_array) { 1086 void LiveEdit::FunctionSourceUpdated(Handle<JSArray> shared_info_array) {
1043 SharedInfoWrapper shared_info_wrapper(shared_info_array); 1087 SharedInfoWrapper shared_info_wrapper(shared_info_array);
1044 Handle<SharedFunctionInfo> shared_info = shared_info_wrapper.GetInfo(); 1088 Handle<SharedFunctionInfo> shared_info = shared_info_wrapper.GetInfo();
1045 1089
(...skipping 869 matching lines...) Expand 10 before | Expand all | Expand 10 after
1915 scope_info_length++; 1959 scope_info_length++;
1916 1960
1917 current_scope = current_scope->outer_scope(); 1961 current_scope = current_scope->outer_scope();
1918 } 1962 }
1919 1963
1920 return scope_info_list; 1964 return scope_info_list;
1921 } 1965 }
1922 1966
1923 } // namespace internal 1967 } // namespace internal
1924 } // namespace v8 1968 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698