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