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/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/compiler.h" | 7 #include "src/compiler.h" |
8 | 8 |
9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
(...skipping 29 matching lines...) Expand all Loading... |
40 CopyBytes(copy, data, length); | 40 CopyBytes(copy, data, length); |
41 data_ = copy; | 41 data_ = copy; |
42 AcquireDataOwnership(); | 42 AcquireDataOwnership(); |
43 } | 43 } |
44 } | 44 } |
45 | 45 |
46 | 46 |
47 CompilationInfo::CompilationInfo(Handle<Script> script, Zone* zone) | 47 CompilationInfo::CompilationInfo(Handle<Script> script, Zone* zone) |
48 : flags_(kThisHasUses), | 48 : flags_(kThisHasUses), |
49 script_(script), | 49 script_(script), |
| 50 source_stream_(NULL), |
50 osr_ast_id_(BailoutId::None()), | 51 osr_ast_id_(BailoutId::None()), |
51 parameter_count_(0), | 52 parameter_count_(0), |
52 optimization_id_(-1), | 53 optimization_id_(-1), |
53 ast_value_factory_(NULL), | 54 ast_value_factory_(NULL), |
54 ast_value_factory_owned_(false) { | 55 ast_value_factory_owned_(false) { |
55 Initialize(script->GetIsolate(), BASE, zone); | 56 Initialize(script->GetIsolate(), BASE, zone); |
56 } | 57 } |
57 | 58 |
58 | 59 |
59 CompilationInfo::CompilationInfo(Isolate* isolate, Zone* zone) | 60 CompilationInfo::CompilationInfo(Isolate* isolate, Zone* zone) |
60 : flags_(kThisHasUses), | 61 : flags_(kThisHasUses), |
61 script_(Handle<Script>::null()), | 62 script_(Handle<Script>::null()), |
| 63 source_stream_(NULL), |
62 osr_ast_id_(BailoutId::None()), | 64 osr_ast_id_(BailoutId::None()), |
63 parameter_count_(0), | 65 parameter_count_(0), |
64 optimization_id_(-1), | 66 optimization_id_(-1), |
65 ast_value_factory_(NULL), | 67 ast_value_factory_(NULL), |
66 ast_value_factory_owned_(false) { | 68 ast_value_factory_owned_(false) { |
67 Initialize(isolate, STUB, zone); | 69 Initialize(isolate, STUB, zone); |
68 } | 70 } |
69 | 71 |
70 | 72 |
71 CompilationInfo::CompilationInfo(Handle<SharedFunctionInfo> shared_info, | 73 CompilationInfo::CompilationInfo(Handle<SharedFunctionInfo> shared_info, |
72 Zone* zone) | 74 Zone* zone) |
73 : flags_(kLazy | kThisHasUses), | 75 : flags_(kLazy | kThisHasUses), |
74 shared_info_(shared_info), | 76 shared_info_(shared_info), |
75 script_(Handle<Script>(Script::cast(shared_info->script()))), | 77 script_(Handle<Script>(Script::cast(shared_info->script()))), |
| 78 source_stream_(NULL), |
76 osr_ast_id_(BailoutId::None()), | 79 osr_ast_id_(BailoutId::None()), |
77 parameter_count_(0), | 80 parameter_count_(0), |
78 optimization_id_(-1), | 81 optimization_id_(-1), |
79 ast_value_factory_(NULL), | 82 ast_value_factory_(NULL), |
80 ast_value_factory_owned_(false) { | 83 ast_value_factory_owned_(false) { |
81 Initialize(script_->GetIsolate(), BASE, zone); | 84 Initialize(script_->GetIsolate(), BASE, zone); |
82 } | 85 } |
83 | 86 |
84 | 87 |
85 CompilationInfo::CompilationInfo(Handle<JSFunction> closure, Zone* zone) | 88 CompilationInfo::CompilationInfo(Handle<JSFunction> closure, Zone* zone) |
86 : flags_(kLazy | kThisHasUses), | 89 : flags_(kLazy | kThisHasUses), |
87 closure_(closure), | 90 closure_(closure), |
88 shared_info_(Handle<SharedFunctionInfo>(closure->shared())), | 91 shared_info_(Handle<SharedFunctionInfo>(closure->shared())), |
89 script_(Handle<Script>(Script::cast(shared_info_->script()))), | 92 script_(Handle<Script>(Script::cast(shared_info_->script()))), |
| 93 source_stream_(NULL), |
90 context_(closure->context()), | 94 context_(closure->context()), |
91 osr_ast_id_(BailoutId::None()), | 95 osr_ast_id_(BailoutId::None()), |
92 parameter_count_(0), | 96 parameter_count_(0), |
93 optimization_id_(-1), | 97 optimization_id_(-1), |
94 ast_value_factory_(NULL), | 98 ast_value_factory_(NULL), |
95 ast_value_factory_owned_(false) { | 99 ast_value_factory_owned_(false) { |
96 Initialize(script_->GetIsolate(), BASE, zone); | 100 Initialize(script_->GetIsolate(), BASE, zone); |
97 } | 101 } |
98 | 102 |
99 | 103 |
100 CompilationInfo::CompilationInfo(HydrogenCodeStub* stub, Isolate* isolate, | 104 CompilationInfo::CompilationInfo(HydrogenCodeStub* stub, Isolate* isolate, |
101 Zone* zone) | 105 Zone* zone) |
102 : flags_(kLazy | kThisHasUses), | 106 : flags_(kLazy | kThisHasUses), |
| 107 source_stream_(NULL), |
103 osr_ast_id_(BailoutId::None()), | 108 osr_ast_id_(BailoutId::None()), |
104 parameter_count_(0), | 109 parameter_count_(0), |
105 optimization_id_(-1), | 110 optimization_id_(-1), |
106 ast_value_factory_(NULL), | 111 ast_value_factory_(NULL), |
107 ast_value_factory_owned_(false) { | 112 ast_value_factory_owned_(false) { |
108 Initialize(isolate, STUB, zone); | 113 Initialize(isolate, STUB, zone); |
109 code_stub_ = stub; | 114 code_stub_ = stub; |
110 } | 115 } |
111 | 116 |
112 | 117 |
| 118 CompilationInfo::CompilationInfo(ScriptCompiler::ExternalSourceStream* stream, |
| 119 Isolate* isolate, Zone* zone) |
| 120 : flags_(kThisHasUses), |
| 121 source_stream_(stream), |
| 122 osr_ast_id_(BailoutId::None()), |
| 123 parameter_count_(0), |
| 124 optimization_id_(-1), |
| 125 ast_value_factory_(NULL), |
| 126 ast_value_factory_owned_(false) { |
| 127 Initialize(isolate, BASE, zone); |
| 128 } |
| 129 |
| 130 |
113 void CompilationInfo::Initialize(Isolate* isolate, | 131 void CompilationInfo::Initialize(Isolate* isolate, |
114 Mode mode, | 132 Mode mode, |
115 Zone* zone) { | 133 Zone* zone) { |
116 isolate_ = isolate; | 134 isolate_ = isolate; |
117 function_ = NULL; | 135 function_ = NULL; |
118 scope_ = NULL; | 136 scope_ = NULL; |
119 global_scope_ = NULL; | 137 global_scope_ = NULL; |
120 extension_ = NULL; | 138 extension_ = NULL; |
121 cached_data_ = NULL; | 139 cached_data_ = NULL; |
122 compile_options_ = ScriptCompiler::kNoCompileOptions; | 140 compile_options_ = ScriptCompiler::kNoCompileOptions; |
123 zone_ = zone; | 141 zone_ = zone; |
124 deferred_handles_ = NULL; | 142 deferred_handles_ = NULL; |
125 code_stub_ = NULL; | 143 code_stub_ = NULL; |
126 prologue_offset_ = Code::kPrologueOffsetNotSet; | 144 prologue_offset_ = Code::kPrologueOffsetNotSet; |
127 opt_count_ = shared_info().is_null() ? 0 : shared_info()->opt_count(); | 145 opt_count_ = shared_info().is_null() ? 0 : shared_info()->opt_count(); |
128 no_frame_ranges_ = isolate->cpu_profiler()->is_profiling() | 146 no_frame_ranges_ = isolate->cpu_profiler()->is_profiling() |
129 ? new List<OffsetRange>(2) : NULL; | 147 ? new List<OffsetRange>(2) : NULL; |
130 for (int i = 0; i < DependentCode::kGroupCount; i++) { | 148 for (int i = 0; i < DependentCode::kGroupCount; i++) { |
131 dependencies_[i] = NULL; | 149 dependencies_[i] = NULL; |
132 } | 150 } |
133 if (mode == STUB) { | 151 if (mode == STUB) { |
134 mode_ = STUB; | 152 mode_ = STUB; |
135 return; | 153 return; |
136 } | 154 } |
137 mode_ = mode; | 155 mode_ = mode; |
138 abort_due_to_dependency_ = false; | 156 abort_due_to_dependency_ = false; |
139 if (script_->type()->value() == Script::TYPE_NATIVE) MarkAsNative(); | 157 if (!script_.is_null() && script_->type()->value() == Script::TYPE_NATIVE) { |
| 158 MarkAsNative(); |
| 159 } |
140 if (isolate_->debug()->is_active()) MarkAsDebug(); | 160 if (isolate_->debug()->is_active()) MarkAsDebug(); |
141 if (FLAG_context_specialization) MarkAsContextSpecializing(); | 161 if (FLAG_context_specialization) MarkAsContextSpecializing(); |
142 if (FLAG_turbo_types) MarkAsTypingEnabled(); | 162 if (FLAG_turbo_types) MarkAsTypingEnabled(); |
143 | 163 |
144 if (!shared_info_.is_null()) { | 164 if (!shared_info_.is_null()) { |
145 DCHECK(strict_mode() == SLOPPY); | 165 DCHECK(strict_mode() == SLOPPY); |
146 SetStrictMode(shared_info_->strict_mode()); | 166 SetStrictMode(shared_info_->strict_mode()); |
147 } | 167 } |
148 set_bailout_reason(kUnknown); | 168 set_bailout_reason(kUnknown); |
149 | 169 |
(...skipping 653 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
803 if (!CompileUnoptimizedCode(&info)) return; | 823 if (!CompileUnoptimizedCode(&info)) return; |
804 if (!info.shared_info().is_null()) { | 824 if (!info.shared_info().is_null()) { |
805 Handle<ScopeInfo> scope_info = ScopeInfo::Create(info.scope(), | 825 Handle<ScopeInfo> scope_info = ScopeInfo::Create(info.scope(), |
806 info.zone()); | 826 info.zone()); |
807 info.shared_info()->set_scope_info(*scope_info); | 827 info.shared_info()->set_scope_info(*scope_info); |
808 } | 828 } |
809 tracker.RecordRootFunctionInfo(info.code()); | 829 tracker.RecordRootFunctionInfo(info.code()); |
810 } | 830 } |
811 | 831 |
812 | 832 |
813 static bool DebuggerWantsEagerCompilation(CompilationInfo* info, | |
814 bool allow_lazy_without_ctx = false) { | |
815 return LiveEditFunctionTracker::IsActive(info->isolate()) || | |
816 (info->isolate()->DebuggerHasBreakPoints() && !allow_lazy_without_ctx); | |
817 } | |
818 | |
819 | |
820 static Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) { | 833 static Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) { |
821 Isolate* isolate = info->isolate(); | 834 Isolate* isolate = info->isolate(); |
822 PostponeInterruptsScope postpone(isolate); | 835 PostponeInterruptsScope postpone(isolate); |
823 DCHECK(!isolate->native_context().is_null()); | 836 DCHECK(!isolate->native_context().is_null()); |
824 Handle<Script> script = info->script(); | 837 Handle<Script> script = info->script(); |
825 | 838 |
826 // TODO(svenpanne) Obscure place for this, perhaps move to OnBeforeCompile? | 839 // TODO(svenpanne) Obscure place for this, perhaps move to OnBeforeCompile? |
827 FixedArray* array = isolate->native_context()->embedder_data(); | 840 FixedArray* array = isolate->native_context()->embedder_data(); |
828 script->set_context_data(array->get(0)); | 841 script->set_context_data(array->get(0)); |
829 | 842 |
830 isolate->debug()->OnBeforeCompile(script); | 843 isolate->debug()->OnBeforeCompile(script); |
831 | 844 |
832 DCHECK(info->is_eval() || info->is_global()); | 845 DCHECK(info->is_eval() || info->is_global()); |
833 | 846 |
834 bool parse_allow_lazy = | |
835 (info->compile_options() == ScriptCompiler::kConsumeParserCache || | |
836 String::cast(script->source())->length() > FLAG_min_preparse_length) && | |
837 !DebuggerWantsEagerCompilation(info); | |
838 | |
839 if (!parse_allow_lazy && | |
840 (info->compile_options() == ScriptCompiler::kProduceParserCache || | |
841 info->compile_options() == ScriptCompiler::kConsumeParserCache)) { | |
842 // We are going to parse eagerly, but we either 1) have cached data produced | |
843 // by lazy parsing or 2) are asked to generate cached data. We cannot use | |
844 // the existing data, since it won't contain all the symbols we need for | |
845 // eager parsing. In addition, it doesn't make sense to produce the data | |
846 // when parsing eagerly. That data would contain all symbols, but no | |
847 // functions, so it cannot be used to aid lazy parsing later. | |
848 info->SetCachedData(NULL, ScriptCompiler::kNoCompileOptions); | |
849 } | |
850 | |
851 Handle<SharedFunctionInfo> result; | 847 Handle<SharedFunctionInfo> result; |
852 | 848 |
853 { VMState<COMPILER> state(info->isolate()); | 849 { VMState<COMPILER> state(info->isolate()); |
854 if (!Parser::Parse(info, parse_allow_lazy)) { | 850 if (info->function() == NULL) { |
855 return Handle<SharedFunctionInfo>::null(); | 851 // Parse the script if needed (if it's already parsed, function() is |
| 852 // non-NULL). |
| 853 bool parse_allow_lazy = |
| 854 (info->compile_options() == ScriptCompiler::kConsumeParserCache || |
| 855 String::cast(script->source())->length() > |
| 856 FLAG_min_preparse_length) && |
| 857 !Compiler::DebuggerWantsEagerCompilation(info); |
| 858 |
| 859 if (!parse_allow_lazy && |
| 860 (info->compile_options() == ScriptCompiler::kProduceParserCache || |
| 861 info->compile_options() == ScriptCompiler::kConsumeParserCache)) { |
| 862 // We are going to parse eagerly, but we either 1) have cached data |
| 863 // produced by lazy parsing or 2) are asked to generate cached data. |
| 864 // Eager parsing cannot benefit from cached data, and producing cached |
| 865 // data while parsing eagerly is not implemented. |
| 866 info->SetCachedData(NULL, ScriptCompiler::kNoCompileOptions); |
| 867 } |
| 868 if (!Parser::Parse(info, parse_allow_lazy)) { |
| 869 return Handle<SharedFunctionInfo>::null(); |
| 870 } |
856 } | 871 } |
857 | 872 |
858 FunctionLiteral* lit = info->function(); | 873 FunctionLiteral* lit = info->function(); |
859 LiveEditFunctionTracker live_edit_tracker(isolate, lit); | 874 LiveEditFunctionTracker live_edit_tracker(isolate, lit); |
860 | 875 |
861 // Measure how long it takes to do the compilation; only take the | 876 // Measure how long it takes to do the compilation; only take the |
862 // rest of the function into account to avoid overlap with the | 877 // rest of the function into account to avoid overlap with the |
863 // parsing statistics. | 878 // parsing statistics. |
864 HistogramTimer* rate = info->is_eval() | 879 HistogramTimer* rate = info->is_eval() |
865 ? info->isolate()->counters()->compile_eval() | 880 ? info->isolate()->counters()->compile_eval() |
(...skipping 26 matching lines...) Expand all Loading... |
892 PROFILE(isolate, CodeCreateEvent( | 907 PROFILE(isolate, CodeCreateEvent( |
893 log_tag, *info->code(), *result, info, *script_name)); | 908 log_tag, *info->code(), *result, info, *script_name)); |
894 GDBJIT(AddCode(script_name, script, info->code(), info)); | 909 GDBJIT(AddCode(script_name, script, info->code(), info)); |
895 | 910 |
896 // Hint to the runtime system used when allocating space for initial | 911 // Hint to the runtime system used when allocating space for initial |
897 // property space by setting the expected number of properties for | 912 // property space by setting the expected number of properties for |
898 // the instances of the function. | 913 // the instances of the function. |
899 SetExpectedNofPropertiesFromEstimate(result, | 914 SetExpectedNofPropertiesFromEstimate(result, |
900 lit->expected_property_count()); | 915 lit->expected_property_count()); |
901 | 916 |
902 script->set_compilation_state(Script::COMPILATION_STATE_COMPILED); | 917 if (!script.is_null()) |
| 918 script->set_compilation_state(Script::COMPILATION_STATE_COMPILED); |
903 | 919 |
904 live_edit_tracker.RecordFunctionInfo(result, lit, info->zone()); | 920 live_edit_tracker.RecordFunctionInfo(result, lit, info->zone()); |
905 } | 921 } |
906 | 922 |
907 isolate->debug()->OnAfterCompile(script); | 923 isolate->debug()->OnAfterCompile(script); |
908 | 924 |
909 return result; | 925 return result; |
910 } | 926 } |
911 | 927 |
912 | 928 |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1049 } | 1065 } |
1050 | 1066 |
1051 if (result.is_null()) isolate->ReportPendingMessages(); | 1067 if (result.is_null()) isolate->ReportPendingMessages(); |
1052 } else if (result->ic_age() != isolate->heap()->global_ic_age()) { | 1068 } else if (result->ic_age() != isolate->heap()->global_ic_age()) { |
1053 result->ResetForNewContext(isolate->heap()->global_ic_age()); | 1069 result->ResetForNewContext(isolate->heap()->global_ic_age()); |
1054 } | 1070 } |
1055 return result; | 1071 return result; |
1056 } | 1072 } |
1057 | 1073 |
1058 | 1074 |
| 1075 Handle<SharedFunctionInfo> Compiler::CompileStreamedScript( |
| 1076 CompilationInfo* info, int source_length) { |
| 1077 Isolate* isolate = info->isolate(); |
| 1078 isolate->counters()->total_load_size()->Increment(source_length); |
| 1079 isolate->counters()->total_compile_size()->Increment(source_length); |
| 1080 |
| 1081 if (FLAG_use_strict) info->SetStrictMode(STRICT); |
| 1082 // TODO(marja): FLAG_serialize_toplevel is not honoured and won't be; when the |
| 1083 // real code caching lands, streaming needs to be adapted to use it. |
| 1084 return CompileToplevel(info); |
| 1085 } |
| 1086 |
| 1087 |
1059 Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo( | 1088 Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo( |
1060 FunctionLiteral* literal, Handle<Script> script, | 1089 FunctionLiteral* literal, Handle<Script> script, |
1061 CompilationInfo* outer_info) { | 1090 CompilationInfo* outer_info) { |
1062 // Precondition: code has been parsed and scopes have been analyzed. | 1091 // Precondition: code has been parsed and scopes have been analyzed. |
1063 CompilationInfoWithZone info(script); | 1092 CompilationInfoWithZone info(script); |
1064 info.SetFunction(literal); | 1093 info.SetFunction(literal); |
1065 info.PrepareForCompilation(literal->scope()); | 1094 info.PrepareForCompilation(literal->scope()); |
1066 info.SetStrictMode(literal->scope()->strict_mode()); | 1095 info.SetStrictMode(literal->scope()->strict_mode()); |
1067 if (outer_info->will_serialize()) info.PrepareForSerializing(); | 1096 if (outer_info->will_serialize()) info.PrepareForSerializing(); |
1068 | 1097 |
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1348 log_tag, *code, *shared, info, script_name, line_num, column_num)); | 1377 log_tag, *code, *shared, info, script_name, line_num, column_num)); |
1349 } | 1378 } |
1350 | 1379 |
1351 GDBJIT(AddCode(Handle<String>(shared->DebugName()), | 1380 GDBJIT(AddCode(Handle<String>(shared->DebugName()), |
1352 Handle<Script>(info->script()), | 1381 Handle<Script>(info->script()), |
1353 Handle<Code>(info->code()), | 1382 Handle<Code>(info->code()), |
1354 info)); | 1383 info)); |
1355 } | 1384 } |
1356 | 1385 |
1357 | 1386 |
| 1387 bool Compiler::DebuggerWantsEagerCompilation(CompilationInfo* info, |
| 1388 bool allow_lazy_without_ctx) { |
| 1389 return LiveEditFunctionTracker::IsActive(info->isolate()) || |
| 1390 (info->isolate()->DebuggerHasBreakPoints() && !allow_lazy_without_ctx); |
| 1391 } |
| 1392 |
| 1393 |
1358 CompilationPhase::CompilationPhase(const char* name, CompilationInfo* info) | 1394 CompilationPhase::CompilationPhase(const char* name, CompilationInfo* info) |
1359 : name_(name), info_(info), zone_(info->isolate()) { | 1395 : name_(name), info_(info), zone_(info->isolate()) { |
1360 if (FLAG_hydrogen_stats) { | 1396 if (FLAG_hydrogen_stats) { |
1361 info_zone_start_allocation_size_ = info->zone()->allocation_size(); | 1397 info_zone_start_allocation_size_ = info->zone()->allocation_size(); |
1362 timer_.Start(); | 1398 timer_.Start(); |
1363 } | 1399 } |
1364 } | 1400 } |
1365 | 1401 |
1366 | 1402 |
1367 CompilationPhase::~CompilationPhase() { | 1403 CompilationPhase::~CompilationPhase() { |
(...skipping 11 matching lines...) Expand all Loading... |
1379 AllowHandleDereference allow_deref; | 1415 AllowHandleDereference allow_deref; |
1380 bool tracing_on = info()->IsStub() | 1416 bool tracing_on = info()->IsStub() |
1381 ? FLAG_trace_hydrogen_stubs | 1417 ? FLAG_trace_hydrogen_stubs |
1382 : (FLAG_trace_hydrogen && | 1418 : (FLAG_trace_hydrogen && |
1383 info()->closure()->PassesFilter(FLAG_trace_hydrogen_filter)); | 1419 info()->closure()->PassesFilter(FLAG_trace_hydrogen_filter)); |
1384 return (tracing_on && | 1420 return (tracing_on && |
1385 base::OS::StrChr(const_cast<char*>(FLAG_trace_phase), name_[0]) != NULL); | 1421 base::OS::StrChr(const_cast<char*>(FLAG_trace_phase), name_[0]) != NULL); |
1386 } | 1422 } |
1387 | 1423 |
1388 } } // namespace v8::internal | 1424 } } // namespace v8::internal |
OLD | NEW |