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

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

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

Powered by Google App Engine
This is Rietveld 408576698