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 // Patch function literals. | |
1025 // Name 'literals' is a misnomer. Rather it's a cache for complex object | |
1026 // boilerplates and for a native context. We must clean cached values. | |
1027 // Additionally we may need to allocate a new array if number of literals | |
1028 // changed. | |
1029 class LiteralFixer { | |
1030 public: | |
1031 | |
1032 static void PatchLiterals(FunctionInfoWrapper* compile_info_wrapper, | |
1033 Handle<SharedFunctionInfo> shared_info, | |
1034 Isolate* isolate) { | |
1035 int new_literal_count = compile_info_wrapper->GetLiteralCount(); | |
1036 if (new_literal_count > 0) { | |
1037 new_literal_count += JSFunction::kLiteralsPrefixSize; | |
1038 } | |
1039 int old_literal_count = shared_info->num_literals(); | |
1040 | |
1041 if (old_literal_count == new_literal_count) { | |
1042 // If literal count didn't change, simply go over all functions | |
1043 // and clear literal arrays. | |
1044 ClearValuesProcessor processor; | |
1045 IterateJSFunctions(*shared_info, &processor); | |
Yang
2012/11/12 14:40:57
We usually call this kind of callback *Visitor, as
| |
1046 } else { | |
1047 // When literal count changes, we have to create new array instances. | |
1048 // Since we cannot create instances when iterating heap, we should first | |
1049 // collect all functions and fix their literal arrays. | |
1050 Handle<FixedArray> function_instances = | |
1051 CollectJSFunctions(shared_info, isolate); | |
1052 for (int i = 0; i < function_instances->length(); i++) { | |
1053 Handle<JSFunction> fun(JSFunction::cast(function_instances->get(i))); | |
1054 Handle<FixedArray> old_literals(fun->literals()); | |
1055 Handle<FixedArray> new_literals = | |
1056 isolate->factory()->NewFixedArray(new_literal_count); | |
1057 if (new_literal_count > 0) { | |
1058 Handle<Context> native_context; | |
1059 if (old_literals->length() > | |
1060 JSFunction::kLiteralNativeContextIndex) { | |
1061 native_context = Handle<Context>( | |
1062 JSFunction::NativeContextFromLiterals(fun->literals())); | |
1063 } else { | |
1064 native_context = Handle<Context>(fun->context()->native_context()); | |
1065 } | |
1066 new_literals->set(JSFunction::kLiteralNativeContextIndex, | |
1067 *native_context); | |
1068 } | |
1069 fun->set_literals(*new_literals); | |
1070 } | |
1071 | |
1072 shared_info->set_num_literals(new_literal_count); | |
1073 } | |
1074 } | |
1075 | |
1076 private: | |
1077 // Iterates all function instances in the HEAP that refers to the | |
1078 // provided shared_info. | |
1079 template<typename PROCESSOR> | |
Yang
2012/11/12 14:40:57
I think we usually use lowercase for typename. Als
| |
1080 static void IterateJSFunctions(SharedFunctionInfo* shared_info, | |
1081 PROCESSOR* processor) { | |
1082 AssertNoAllocation no_allocations_please; | |
1083 | |
1084 HeapIterator iterator; | |
1085 for (HeapObject* obj = iterator.next(); obj != NULL; | |
1086 obj = iterator.next()) { | |
1087 if (obj->IsJSFunction()) { | |
1088 JSFunction* function = JSFunction::cast(obj); | |
1089 if (function->shared() == shared_info) { | |
1090 processor->process(function); | |
1091 } | |
1092 } | |
1093 } | |
1094 } | |
1095 | |
1096 // Finds all instances of JSFunction that refers to the provided shared_info | |
1097 // and returns array with them. | |
1098 static Handle<FixedArray> CollectJSFunctions( | |
1099 Handle<SharedFunctionInfo> shared_info, Isolate* isolate) { | |
1100 CountProcessor count_processor; | |
1101 count_processor.count = 0; | |
1102 IterateJSFunctions(*shared_info, &count_processor); | |
1103 int size = count_processor.count; | |
1104 | |
1105 Handle<FixedArray> result = isolate->factory()->NewFixedArray(size); | |
1106 if (size > 0) { | |
1107 CollectProcessor collect_processor(result); | |
1108 IterateJSFunctions(*shared_info, &collect_processor); | |
1109 } | |
1110 return result; | |
1111 } | |
1112 | |
1113 class ClearValuesProcessor { | |
1114 public: | |
1115 void process(JSFunction* fun) { | |
1116 FixedArray* literals = fun->literals(); | |
1117 int len = literals->length(); | |
1118 for (int j = JSFunction::kLiteralsPrefixSize; j < len; j++) { | |
1119 literals->set_undefined(j); | |
1120 } | |
1121 } | |
1122 }; | |
1123 | |
1124 class CountProcessor { | |
1125 public: | |
1126 void process(JSFunction* fun) { | |
1127 count++; | |
1128 } | |
1129 int count; | |
1130 }; | |
1131 | |
1132 class CollectProcessor { | |
1133 public: | |
1134 CollectProcessor(Handle<FixedArray> output) : m_output(output), m_pos(0) {} | |
1135 | |
1136 void process(JSFunction* fun) { | |
1137 m_output->set(m_pos, fun); | |
1138 m_pos++; | |
1139 } | |
1140 private: | |
1141 Handle<FixedArray> m_output; | |
1142 int m_pos; | |
1143 }; | |
1144 }; | |
1145 | |
1146 | |
1017 // Check whether the code is natural function code (not a lazy-compile stub | 1147 // Check whether the code is natural function code (not a lazy-compile stub |
1018 // code). | 1148 // code). |
1019 static bool IsJSFunctionCode(Code* code) { | 1149 static bool IsJSFunctionCode(Code* code) { |
1020 return code->kind() == Code::FUNCTION; | 1150 return code->kind() == Code::FUNCTION; |
1021 } | 1151 } |
1022 | 1152 |
1023 | 1153 |
1024 // Returns true if an instance of candidate were inlined into function's code. | 1154 // Returns true if an instance of candidate were inlined into function's code. |
1025 static bool IsInlined(JSFunction* function, SharedFunctionInfo* candidate) { | 1155 static bool IsInlined(JSFunction* function, SharedFunctionInfo* candidate) { |
1026 AssertNoAllocation no_gc; | 1156 AssertNoAllocation no_gc; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1073 | 1203 |
1074 DependentFunctionsDeoptimizingVisitor visitor(function_info); | 1204 DependentFunctionsDeoptimizingVisitor visitor(function_info); |
1075 Deoptimizer::VisitAllOptimizedFunctions(&visitor); | 1205 Deoptimizer::VisitAllOptimizedFunctions(&visitor); |
1076 } | 1206 } |
1077 | 1207 |
1078 | 1208 |
1079 MaybeObject* LiveEdit::ReplaceFunctionCode( | 1209 MaybeObject* LiveEdit::ReplaceFunctionCode( |
1080 Handle<JSArray> new_compile_info_array, | 1210 Handle<JSArray> new_compile_info_array, |
1081 Handle<JSArray> shared_info_array) { | 1211 Handle<JSArray> shared_info_array) { |
1082 HandleScope scope; | 1212 HandleScope scope; |
1213 Isolate* isolate = Isolate::Current(); | |
1083 | 1214 |
1084 if (!SharedInfoWrapper::IsInstance(shared_info_array)) { | 1215 if (!SharedInfoWrapper::IsInstance(shared_info_array)) { |
1085 return Isolate::Current()->ThrowIllegalOperation(); | 1216 return isolate->ThrowIllegalOperation(); |
1086 } | 1217 } |
1087 | 1218 |
1088 FunctionInfoWrapper compile_info_wrapper(new_compile_info_array); | 1219 FunctionInfoWrapper compile_info_wrapper(new_compile_info_array); |
1089 SharedInfoWrapper shared_info_wrapper(shared_info_array); | 1220 SharedInfoWrapper shared_info_wrapper(shared_info_array); |
1090 | 1221 |
1091 Handle<SharedFunctionInfo> shared_info = shared_info_wrapper.GetInfo(); | 1222 Handle<SharedFunctionInfo> shared_info = shared_info_wrapper.GetInfo(); |
1092 | 1223 |
1093 HEAP->EnsureHeapIsIterable(); | 1224 HEAP->EnsureHeapIsIterable(); |
1094 | 1225 |
1095 if (IsJSFunctionCode(shared_info->code())) { | 1226 if (IsJSFunctionCode(shared_info->code())) { |
(...skipping 10 matching lines...) Expand all Loading... | |
1106 Handle<Code> new_original_code = | 1237 Handle<Code> new_original_code = |
1107 FACTORY->CopyCode(compile_info_wrapper.GetFunctionCode()); | 1238 FACTORY->CopyCode(compile_info_wrapper.GetFunctionCode()); |
1108 debug_info->set_original_code(*new_original_code); | 1239 debug_info->set_original_code(*new_original_code); |
1109 } | 1240 } |
1110 | 1241 |
1111 int start_position = compile_info_wrapper.GetStartPosition(); | 1242 int start_position = compile_info_wrapper.GetStartPosition(); |
1112 int end_position = compile_info_wrapper.GetEndPosition(); | 1243 int end_position = compile_info_wrapper.GetEndPosition(); |
1113 shared_info->set_start_position(start_position); | 1244 shared_info->set_start_position(start_position); |
1114 shared_info->set_end_position(end_position); | 1245 shared_info->set_end_position(end_position); |
1115 | 1246 |
1247 LiteralFixer::PatchLiterals(&compile_info_wrapper, shared_info, isolate); | |
1248 | |
1116 shared_info->set_construct_stub( | 1249 shared_info->set_construct_stub( |
1117 Isolate::Current()->builtins()->builtin( | 1250 Isolate::Current()->builtins()->builtin( |
1118 Builtins::kJSConstructStubGeneric)); | 1251 Builtins::kJSConstructStubGeneric)); |
1119 | 1252 |
1120 DeoptimizeDependentFunctions(*shared_info); | 1253 DeoptimizeDependentFunctions(*shared_info); |
1121 Isolate::Current()->compilation_cache()->Remove(shared_info); | 1254 Isolate::Current()->compilation_cache()->Remove(shared_info); |
1122 | 1255 |
1123 return HEAP->undefined_value(); | 1256 return HEAP->undefined_value(); |
1124 } | 1257 } |
1125 | 1258 |
(...skipping 797 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1923 | 2056 |
1924 bool LiveEditFunctionTracker::IsActive(Isolate* isolate) { | 2057 bool LiveEditFunctionTracker::IsActive(Isolate* isolate) { |
1925 return false; | 2058 return false; |
1926 } | 2059 } |
1927 | 2060 |
1928 #endif // ENABLE_DEBUGGER_SUPPORT | 2061 #endif // ENABLE_DEBUGGER_SUPPORT |
1929 | 2062 |
1930 | 2063 |
1931 | 2064 |
1932 } } // namespace v8::internal | 2065 } } // namespace v8::internal |
OLD | NEW |