OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 685 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
696 | 696 |
697 // Represents some function compilation details. This structure will be used | 697 // Represents some function compilation details. This structure will be used |
698 // from JavaScript. It contains Code object, which is kept wrapped | 698 // from JavaScript. It contains Code object, which is kept wrapped |
699 // into a BlindReference for sanitizing reasons. | 699 // into a BlindReference for sanitizing reasons. |
700 class FunctionInfoWrapper : public JSArrayBasedStruct<FunctionInfoWrapper> { | 700 class FunctionInfoWrapper : public JSArrayBasedStruct<FunctionInfoWrapper> { |
701 public: | 701 public: |
702 explicit FunctionInfoWrapper(Handle<JSArray> array) | 702 explicit FunctionInfoWrapper(Handle<JSArray> array) |
703 : JSArrayBasedStruct<FunctionInfoWrapper>(array) { | 703 : JSArrayBasedStruct<FunctionInfoWrapper>(array) { |
704 } | 704 } |
705 void SetInitialProperties(Handle<String> name, int start_position, | 705 void SetInitialProperties(Handle<String> name, int start_position, |
706 int end_position, int param_num, int parent_index) { | 706 int end_position, int param_num, |
707 int literal_count, int parent_index) { | |
707 HandleScope scope; | 708 HandleScope scope; |
708 this->SetField(kFunctionNameOffset_, name); | 709 this->SetField(kFunctionNameOffset_, name); |
709 this->SetSmiValueField(kStartPositionOffset_, start_position); | 710 this->SetSmiValueField(kStartPositionOffset_, start_position); |
710 this->SetSmiValueField(kEndPositionOffset_, end_position); | 711 this->SetSmiValueField(kEndPositionOffset_, end_position); |
711 this->SetSmiValueField(kParamNumOffset_, param_num); | 712 this->SetSmiValueField(kParamNumOffset_, param_num); |
713 this->SetSmiValueField(kLiteralNumOffset_, literal_count); | |
712 this->SetSmiValueField(kParentIndexOffset_, parent_index); | 714 this->SetSmiValueField(kParentIndexOffset_, parent_index); |
713 } | 715 } |
714 void SetFunctionCode(Handle<Code> function_code, | 716 void SetFunctionCode(Handle<Code> function_code, |
715 Handle<Object> code_scope_info) { | 717 Handle<Object> code_scope_info) { |
716 Handle<JSValue> code_wrapper = WrapInJSValue(function_code); | 718 Handle<JSValue> code_wrapper = WrapInJSValue(function_code); |
717 this->SetField(kCodeOffset_, code_wrapper); | 719 this->SetField(kCodeOffset_, code_wrapper); |
718 | 720 |
719 Handle<JSValue> scope_wrapper = WrapInJSValue(code_scope_info); | 721 Handle<JSValue> scope_wrapper = WrapInJSValue(code_scope_info); |
720 this->SetField(kCodeScopeInfoOffset_, scope_wrapper); | 722 this->SetField(kCodeScopeInfoOffset_, scope_wrapper); |
721 } | 723 } |
722 void SetOuterScopeInfo(Handle<Object> scope_info_array) { | 724 void SetOuterScopeInfo(Handle<Object> scope_info_array) { |
723 this->SetField(kOuterScopeInfoOffset_, scope_info_array); | 725 this->SetField(kOuterScopeInfoOffset_, scope_info_array); |
724 } | 726 } |
725 void SetSharedFunctionInfo(Handle<SharedFunctionInfo> info) { | 727 void SetSharedFunctionInfo(Handle<SharedFunctionInfo> info) { |
726 Handle<JSValue> info_holder = WrapInJSValue(info); | 728 Handle<JSValue> info_holder = WrapInJSValue(info); |
727 this->SetField(kSharedFunctionInfoOffset_, info_holder); | 729 this->SetField(kSharedFunctionInfoOffset_, info_holder); |
728 } | 730 } |
731 int GetLiteralCount() { | |
732 return this->GetSmiValueField(kLiteralNumOffset_); | |
733 } | |
729 int GetParentIndex() { | 734 int GetParentIndex() { |
730 return this->GetSmiValueField(kParentIndexOffset_); | 735 return this->GetSmiValueField(kParentIndexOffset_); |
731 } | 736 } |
732 Handle<Code> GetFunctionCode() { | 737 Handle<Code> GetFunctionCode() { |
733 Object* element = this->GetField(kCodeOffset_); | 738 Object* element = this->GetField(kCodeOffset_); |
734 CHECK(element->IsJSValue()); | 739 CHECK(element->IsJSValue()); |
735 Handle<JSValue> value_wrapper(JSValue::cast(element)); | 740 Handle<JSValue> value_wrapper(JSValue::cast(element)); |
736 Handle<Object> raw_result = UnwrapJSValue(value_wrapper); | 741 Handle<Object> raw_result = UnwrapJSValue(value_wrapper); |
737 CHECK(raw_result->IsCode()); | 742 CHECK(raw_result->IsCode()); |
738 return Handle<Code>::cast(raw_result); | 743 return Handle<Code>::cast(raw_result); |
(...skipping 13 matching lines...) Expand all Loading... | |
752 private: | 757 private: |
753 static const int kFunctionNameOffset_ = 0; | 758 static const int kFunctionNameOffset_ = 0; |
754 static const int kStartPositionOffset_ = 1; | 759 static const int kStartPositionOffset_ = 1; |
755 static const int kEndPositionOffset_ = 2; | 760 static const int kEndPositionOffset_ = 2; |
756 static const int kParamNumOffset_ = 3; | 761 static const int kParamNumOffset_ = 3; |
757 static const int kCodeOffset_ = 4; | 762 static const int kCodeOffset_ = 4; |
758 static const int kCodeScopeInfoOffset_ = 5; | 763 static const int kCodeScopeInfoOffset_ = 5; |
759 static const int kOuterScopeInfoOffset_ = 6; | 764 static const int kOuterScopeInfoOffset_ = 6; |
760 static const int kParentIndexOffset_ = 7; | 765 static const int kParentIndexOffset_ = 7; |
761 static const int kSharedFunctionInfoOffset_ = 8; | 766 static const int kSharedFunctionInfoOffset_ = 8; |
762 static const int kSize_ = 9; | 767 static const int kLiteralNumOffset_ = 9; |
768 static const int kSize_ = 10; | |
763 | 769 |
764 friend class JSArrayBasedStruct<FunctionInfoWrapper>; | 770 friend class JSArrayBasedStruct<FunctionInfoWrapper>; |
765 }; | 771 }; |
766 | 772 |
767 | 773 |
768 // Wraps SharedFunctionInfo along with some of its fields for passing it | 774 // Wraps SharedFunctionInfo along with some of its fields for passing it |
769 // back to JavaScript. SharedFunctionInfo object itself is additionally | 775 // back to JavaScript. SharedFunctionInfo object itself is additionally |
770 // wrapped into BlindReference for sanitizing reasons. | 776 // wrapped into BlindReference for sanitizing reasons. |
771 class SharedInfoWrapper : public JSArrayBasedStruct<SharedInfoWrapper> { | 777 class SharedInfoWrapper : public JSArrayBasedStruct<SharedInfoWrapper> { |
772 public: | 778 public: |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
812 current_parent_index_ = -1; | 818 current_parent_index_ = -1; |
813 len_ = 0; | 819 len_ = 0; |
814 result_ = FACTORY->NewJSArray(10); | 820 result_ = FACTORY->NewJSArray(10); |
815 } | 821 } |
816 | 822 |
817 void FunctionStarted(FunctionLiteral* fun) { | 823 void FunctionStarted(FunctionLiteral* fun) { |
818 HandleScope scope; | 824 HandleScope scope; |
819 FunctionInfoWrapper info = FunctionInfoWrapper::Create(); | 825 FunctionInfoWrapper info = FunctionInfoWrapper::Create(); |
820 info.SetInitialProperties(fun->name(), fun->start_position(), | 826 info.SetInitialProperties(fun->name(), fun->start_position(), |
821 fun->end_position(), fun->parameter_count(), | 827 fun->end_position(), fun->parameter_count(), |
828 fun->materialized_literal_count(), | |
822 current_parent_index_); | 829 current_parent_index_); |
823 current_parent_index_ = len_; | 830 current_parent_index_ = len_; |
824 SetElementNonStrict(result_, len_, info.GetJSArray()); | 831 SetElementNonStrict(result_, len_, info.GetJSArray()); |
825 len_++; | 832 len_++; |
826 } | 833 } |
827 | 834 |
828 void FunctionDone() { | 835 void FunctionDone() { |
829 HandleScope scope; | 836 HandleScope scope; |
830 FunctionInfoWrapper info = | 837 FunctionInfoWrapper info = |
831 FunctionInfoWrapper::cast( | 838 FunctionInfoWrapper::cast( |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1007 | 1014 |
1008 // Now iterate over all pointers of all objects, including code_target | 1015 // Now iterate over all pointers of all objects, including code_target |
1009 // implicit pointers. | 1016 // implicit pointers. |
1010 HeapIterator iterator; | 1017 HeapIterator iterator; |
1011 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { | 1018 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { |
1012 obj->Iterate(&visitor); | 1019 obj->Iterate(&visitor); |
1013 } | 1020 } |
1014 } | 1021 } |
1015 | 1022 |
1016 | 1023 |
1024 // Finds all instances of JSFunction that refers to the provided shared_info. | |
1025 // Return their number and optionally writes them into output array. | |
1026 static int FindJSFunctions(Handle<SharedFunctionInfo> shared_info, | |
1027 Handle<FixedArray> output) { | |
1028 int pos = 0; | |
1029 | |
1030 AssertNoAllocation no_allocations_please; | |
1031 | |
1032 SharedFunctionInfo* shared_info_raw = *shared_info; | |
1033 HeapIterator iterator; | |
1034 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { | |
1035 if (obj->IsJSFunction()) { | |
1036 JSFunction* function = JSFunction::cast(obj); | |
1037 if (function->shared() == shared_info_raw) { | |
1038 if (!output.is_null()) { | |
1039 output->set(pos, function); | |
1040 } | |
1041 pos++; | |
1042 } | |
1043 } | |
1044 } | |
1045 return pos; | |
1046 } | |
1047 | |
1048 | |
1049 // Finds all instances of JSFunction that refers to the provided shared_info | |
1050 // and returns array with them. | |
1051 static Handle<FixedArray> CollectJSFunctions( | |
1052 Handle<SharedFunctionInfo> shared_info, Isolate* isolate) { | |
1053 int size = FindJSFunctions(shared_info, Handle<FixedArray>::null()); | |
1054 Handle<FixedArray> result = isolate->factory()->NewFixedArray(size); | |
1055 if (size > 0) { | |
1056 FindJSFunctions(shared_info, result); | |
Yang
2012/10/23 16:10:31
Running twice over the heap seems really inefficie
Peter Rybin
2012/11/11 03:28:47
In fact I only copy how Runtime_DebugReferencedBy
| |
1057 } | |
1058 return result; | |
1059 } | |
1060 | |
1061 | |
1017 // Check whether the code is natural function code (not a lazy-compile stub | 1062 // Check whether the code is natural function code (not a lazy-compile stub |
1018 // code). | 1063 // code). |
1019 static bool IsJSFunctionCode(Code* code) { | 1064 static bool IsJSFunctionCode(Code* code) { |
1020 return code->kind() == Code::FUNCTION; | 1065 return code->kind() == Code::FUNCTION; |
1021 } | 1066 } |
1022 | 1067 |
1023 | 1068 |
1024 // Returns true if an instance of candidate were inlined into function's code. | 1069 // Returns true if an instance of candidate were inlined into function's code. |
1025 static bool IsInlined(JSFunction* function, SharedFunctionInfo* candidate) { | 1070 static bool IsInlined(JSFunction* function, SharedFunctionInfo* candidate) { |
1026 AssertNoAllocation no_gc; | 1071 AssertNoAllocation no_gc; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1073 | 1118 |
1074 DependentFunctionsDeoptimizingVisitor visitor(function_info); | 1119 DependentFunctionsDeoptimizingVisitor visitor(function_info); |
1075 Deoptimizer::VisitAllOptimizedFunctions(&visitor); | 1120 Deoptimizer::VisitAllOptimizedFunctions(&visitor); |
1076 } | 1121 } |
1077 | 1122 |
1078 | 1123 |
1079 MaybeObject* LiveEdit::ReplaceFunctionCode( | 1124 MaybeObject* LiveEdit::ReplaceFunctionCode( |
1080 Handle<JSArray> new_compile_info_array, | 1125 Handle<JSArray> new_compile_info_array, |
1081 Handle<JSArray> shared_info_array) { | 1126 Handle<JSArray> shared_info_array) { |
1082 HandleScope scope; | 1127 HandleScope scope; |
1128 Isolate* isolate = Isolate::Current(); | |
1083 | 1129 |
1084 if (!SharedInfoWrapper::IsInstance(shared_info_array)) { | 1130 if (!SharedInfoWrapper::IsInstance(shared_info_array)) { |
1085 return Isolate::Current()->ThrowIllegalOperation(); | 1131 return isolate->ThrowIllegalOperation(); |
1086 } | 1132 } |
1087 | 1133 |
1088 FunctionInfoWrapper compile_info_wrapper(new_compile_info_array); | 1134 FunctionInfoWrapper compile_info_wrapper(new_compile_info_array); |
1089 SharedInfoWrapper shared_info_wrapper(shared_info_array); | 1135 SharedInfoWrapper shared_info_wrapper(shared_info_array); |
1090 | 1136 |
1091 Handle<SharedFunctionInfo> shared_info = shared_info_wrapper.GetInfo(); | 1137 Handle<SharedFunctionInfo> shared_info = shared_info_wrapper.GetInfo(); |
1092 | 1138 |
1093 HEAP->EnsureHeapIsIterable(); | 1139 HEAP->EnsureHeapIsIterable(); |
1094 | 1140 |
1095 if (IsJSFunctionCode(shared_info->code())) { | 1141 if (IsJSFunctionCode(shared_info->code())) { |
(...skipping 10 matching lines...) Expand all Loading... | |
1106 Handle<Code> new_original_code = | 1152 Handle<Code> new_original_code = |
1107 FACTORY->CopyCode(compile_info_wrapper.GetFunctionCode()); | 1153 FACTORY->CopyCode(compile_info_wrapper.GetFunctionCode()); |
1108 debug_info->set_original_code(*new_original_code); | 1154 debug_info->set_original_code(*new_original_code); |
1109 } | 1155 } |
1110 | 1156 |
1111 int start_position = compile_info_wrapper.GetStartPosition(); | 1157 int start_position = compile_info_wrapper.GetStartPosition(); |
1112 int end_position = compile_info_wrapper.GetEndPosition(); | 1158 int end_position = compile_info_wrapper.GetEndPosition(); |
1113 shared_info->set_start_position(start_position); | 1159 shared_info->set_start_position(start_position); |
1114 shared_info->set_end_position(end_position); | 1160 shared_info->set_end_position(end_position); |
1115 | 1161 |
1162 // Patch function literals. | |
1163 // TODO(prybin): is the following legit? | |
1164 // Name 'literals' is a misnomer. Rather it's a cache for complex object | |
1165 // boilerplates and for a native context. We must clean cached values or | |
1166 // adjust array size. | |
Yang
2012/10/23 16:10:31
Wouldn't adjusting array size imply cleaning cache
Peter Rybin
2012/11/11 03:28:47
Done.
| |
1167 { | |
1168 int new_literal_count = compile_info_wrapper.GetLiteralCount(); | |
1169 if (new_literal_count > 0) { | |
1170 new_literal_count += JSFunction::kLiteralsPrefixSize; | |
1171 } | |
1172 shared_info->set_num_literals(new_literal_count); | |
1173 | |
1174 Handle<FixedArray> function_instances = | |
1175 CollectJSFunctions(shared_info, isolate); | |
1176 for (int i = 0; i < function_instances->length(); i++) { | |
Yang
2012/10/23 16:10:31
Instead of looping over function instances that yo
Peter Rybin
2012/11/11 03:28:47
I have to update literal array, and possibly creat
| |
1177 Handle<JSFunction> fun(JSFunction::cast(function_instances->get(i))); | |
1178 Handle<FixedArray> old_literals(fun->literals()); | |
1179 if (old_literals->length() == new_literal_count) { | |
1180 for (int j = JSFunction::kLiteralsPrefixSize; | |
1181 j < new_literal_count; j++) { | |
1182 old_literals->set(j, isolate->heap()->undefined_value()); | |
Yang
2012/10/23 16:10:31
I guess you could use FixedArray->set_undefined he
Peter Rybin
2012/11/11 03:28:47
Done.
| |
1183 } | |
1184 } else { | |
1185 Handle<FixedArray> new_literals = | |
1186 isolate->factory()->NewFixedArray(new_literal_count); | |
1187 if (new_literal_count > 0) { | |
1188 Handle<Context> native_context; | |
1189 if (old_literals->length() > | |
1190 JSFunction::kLiteralNativeContextIndex) { | |
1191 native_context = Handle<Context>( | |
1192 JSFunction::NativeContextFromLiterals(fun->literals())); | |
1193 } else { | |
1194 native_context = Handle<Context>(fun->context()->native_context()); | |
1195 } | |
1196 new_literals->set(JSFunction::kLiteralNativeContextIndex, | |
1197 *native_context); | |
1198 } | |
1199 fun->set_literals(*new_literals); | |
1200 } | |
Yang
2012/10/23 16:10:31
I assume that we are not dealing with optimized co
Peter Rybin
2012/11/11 03:28:47
May be it more safe to always create an accurate l
| |
1201 } | |
1202 } | |
1203 | |
1116 shared_info->set_construct_stub( | 1204 shared_info->set_construct_stub( |
1117 Isolate::Current()->builtins()->builtin( | 1205 Isolate::Current()->builtins()->builtin( |
1118 Builtins::kJSConstructStubGeneric)); | 1206 Builtins::kJSConstructStubGeneric)); |
1119 | 1207 |
1120 DeoptimizeDependentFunctions(*shared_info); | 1208 DeoptimizeDependentFunctions(*shared_info); |
1121 Isolate::Current()->compilation_cache()->Remove(shared_info); | 1209 Isolate::Current()->compilation_cache()->Remove(shared_info); |
1122 | 1210 |
1123 return HEAP->undefined_value(); | 1211 return HEAP->undefined_value(); |
1124 } | 1212 } |
1125 | 1213 |
(...skipping 795 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1921 | 2009 |
1922 bool LiveEditFunctionTracker::IsActive(Isolate* isolate) { | 2010 bool LiveEditFunctionTracker::IsActive(Isolate* isolate) { |
1923 return false; | 2011 return false; |
1924 } | 2012 } |
1925 | 2013 |
1926 #endif // ENABLE_DEBUGGER_SUPPORT | 2014 #endif // ENABLE_DEBUGGER_SUPPORT |
1927 | 2015 |
1928 | 2016 |
1929 | 2017 |
1930 } } // namespace v8::internal | 2018 } } // namespace v8::internal |
OLD | NEW |