Chromium Code Reviews| 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/ast-numbering.h" | 9 #include "src/ast-numbering.h" |
| 10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 27 #include "src/runtime-profiler.h" | 27 #include "src/runtime-profiler.h" |
| 28 #include "src/scanner-character-streams.h" | 28 #include "src/scanner-character-streams.h" |
| 29 #include "src/scopeinfo.h" | 29 #include "src/scopeinfo.h" |
| 30 #include "src/scopes.h" | 30 #include "src/scopes.h" |
| 31 #include "src/typing.h" | 31 #include "src/typing.h" |
| 32 #include "src/vm-state-inl.h" | 32 #include "src/vm-state-inl.h" |
| 33 | 33 |
| 34 namespace v8 { | 34 namespace v8 { |
| 35 namespace internal { | 35 namespace internal { |
| 36 | 36 |
| 37 | |
| 38 std::ostream& operator<<(std::ostream& os, const SourcePosition& p) { | 37 std::ostream& operator<<(std::ostream& os, const SourcePosition& p) { |
| 39 if (p.IsUnknown()) { | 38 if (p.IsUnknown()) { |
| 40 return os << "<?>"; | 39 return os << "<?>"; |
| 41 } else if (FLAG_hydrogen_track_positions) { | 40 } else if (FLAG_hydrogen_track_positions) { |
| 42 return os << "<" << p.inlining_id() << ":" << p.position() << ">"; | 41 return os << "<" << p.inlining_id() << ":" << p.position() << ">"; |
| 43 } else { | 42 } else { |
| 44 return os << "<0:" << p.raw() << ">"; | 43 return os << "<0:" << p.raw() << ">"; |
| 45 } | 44 } |
| 46 } | 45 } |
| 47 | 46 |
| 48 | 47 |
| 49 ScriptData::ScriptData(const byte* data, int length) | 48 #define PARSE_INFO_GETTER(type, name) \ |
| 50 : owns_data_(false), rejected_(false), data_(data), length_(length) { | 49 type CompilationInfo::name() const { \ |
| 51 if (!IsAligned(reinterpret_cast<intptr_t>(data), kPointerAlignment)) { | 50 CHECK(parse_info()); \ |
| 52 byte* copy = NewArray<byte>(length); | 51 return parse_info()->name(); \ |
| 53 DCHECK(IsAligned(reinterpret_cast<intptr_t>(copy), kPointerAlignment)); | |
| 54 CopyBytes(copy, data, length); | |
| 55 data_ = copy; | |
| 56 AcquireDataOwnership(); | |
| 57 } | 52 } |
| 53 | |
| 54 | |
| 55 #define PARSE_INFO_GETTER_WITH_DEFAULT(type, name, def) \ | |
| 56 type CompilationInfo::name() const { \ | |
| 57 return parse_info() ? parse_info()->name() : def; \ | |
| 58 } | |
| 59 | |
| 60 | |
| 61 PARSE_INFO_GETTER(Handle<Script>, script); | |
| 62 PARSE_INFO_GETTER(bool, is_eval); | |
| 63 PARSE_INFO_GETTER(bool, is_native); | |
| 64 PARSE_INFO_GETTER(bool, is_module); | |
| 65 PARSE_INFO_GETTER(bool, this_has_uses); | |
| 66 PARSE_INFO_GETTER(LanguageMode, language_mode); | |
| 67 PARSE_INFO_GETTER_WITH_DEFAULT(Handle<JSFunction>, closure, | |
| 68 Handle<JSFunction>::null()); | |
| 69 PARSE_INFO_GETTER(FunctionLiteral*, function); | |
| 70 PARSE_INFO_GETTER_WITH_DEFAULT(Scope*, scope, nullptr); | |
| 71 PARSE_INFO_GETTER(Handle<Context>, context); | |
| 72 PARSE_INFO_GETTER(Handle<SharedFunctionInfo>, shared_info); | |
| 73 | |
| 74 #undef PARSE_INFO_GETTER | |
| 75 #undef PARSE_INFO_GETTER_WITH_DEFAULT | |
| 76 | |
| 77 | |
| 78 bool CompilationInfo::has_shared_info() const { | |
| 79 return parse_info_ && !parse_info_->shared_info().is_null(); | |
| 58 } | 80 } |
| 59 | 81 |
| 60 | 82 |
| 61 CompilationInfo::CompilationInfo(Handle<Script> script, Zone* zone) | 83 CompilationInfo::CompilationInfo(ParseInfo* parse_info) |
| 62 : flags_(kThisHasUses), | 84 : parse_info_(parse_info), |
| 63 script_(script), | 85 flags_(0), |
| 64 source_stream_(NULL), | |
| 65 osr_ast_id_(BailoutId::None()), | 86 osr_ast_id_(BailoutId::None()), |
| 66 parameter_count_(0), | 87 parameter_count_(0), |
| 67 optimization_id_(-1), | 88 optimization_id_(-1), |
| 68 ast_value_factory_(NULL), | |
| 69 ast_value_factory_owned_(false), | |
| 70 aborted_due_to_dependency_change_(false), | 89 aborted_due_to_dependency_change_(false), |
| 71 osr_expr_stack_height_(0) { | 90 osr_expr_stack_height_(0) { |
| 72 Initialize(script->GetIsolate(), BASE, zone); | 91 Initialize(parse_info->isolate(), BASE, parse_info->zone()); |
| 73 } | |
| 74 | |
| 75 | |
| 76 CompilationInfo::CompilationInfo(Handle<SharedFunctionInfo> shared_info, | |
| 77 Zone* zone) | |
| 78 : flags_(kLazy | kThisHasUses), | |
| 79 shared_info_(shared_info), | |
| 80 script_(Handle<Script>(Script::cast(shared_info->script()))), | |
| 81 source_stream_(NULL), | |
| 82 osr_ast_id_(BailoutId::None()), | |
| 83 parameter_count_(0), | |
| 84 optimization_id_(-1), | |
| 85 ast_value_factory_(NULL), | |
| 86 ast_value_factory_owned_(false), | |
| 87 aborted_due_to_dependency_change_(false), | |
| 88 osr_expr_stack_height_(0) { | |
| 89 Initialize(script_->GetIsolate(), BASE, zone); | |
| 90 } | |
| 91 | |
| 92 | |
| 93 CompilationInfo::CompilationInfo(Handle<JSFunction> closure, Zone* zone) | |
| 94 : flags_(kLazy | kThisHasUses), | |
| 95 closure_(closure), | |
| 96 shared_info_(Handle<SharedFunctionInfo>(closure->shared())), | |
| 97 script_(Handle<Script>(Script::cast(shared_info_->script()))), | |
| 98 source_stream_(NULL), | |
| 99 context_(closure->context()), | |
| 100 osr_ast_id_(BailoutId::None()), | |
| 101 parameter_count_(0), | |
| 102 optimization_id_(-1), | |
| 103 ast_value_factory_(NULL), | |
| 104 ast_value_factory_owned_(false), | |
| 105 aborted_due_to_dependency_change_(false), | |
| 106 osr_expr_stack_height_(0) { | |
| 107 Initialize(script_->GetIsolate(), BASE, zone); | |
| 108 } | 92 } |
| 109 | 93 |
| 110 | 94 |
| 111 CompilationInfo::CompilationInfo(CodeStub* stub, Isolate* isolate, Zone* zone) | 95 CompilationInfo::CompilationInfo(CodeStub* stub, Isolate* isolate, Zone* zone) |
| 112 : flags_(kLazy | kThisHasUses), | 96 : parse_info_(nullptr), |
| 113 source_stream_(NULL), | 97 flags_(0), |
| 114 osr_ast_id_(BailoutId::None()), | 98 osr_ast_id_(BailoutId::None()), |
| 115 parameter_count_(0), | 99 parameter_count_(0), |
| 116 optimization_id_(-1), | 100 optimization_id_(-1), |
| 117 ast_value_factory_(NULL), | |
| 118 ast_value_factory_owned_(false), | |
| 119 aborted_due_to_dependency_change_(false), | 101 aborted_due_to_dependency_change_(false), |
| 120 osr_expr_stack_height_(0) { | 102 osr_expr_stack_height_(0) { |
| 121 Initialize(isolate, STUB, zone); | 103 Initialize(isolate, STUB, zone); |
| 122 code_stub_ = stub; | 104 code_stub_ = stub; |
| 123 } | 105 } |
| 124 | 106 |
| 125 | 107 |
| 126 CompilationInfo::CompilationInfo( | |
| 127 ScriptCompiler::ExternalSourceStream* stream, | |
| 128 ScriptCompiler::StreamedSource::Encoding encoding, Isolate* isolate, | |
| 129 Zone* zone) | |
| 130 : flags_(kThisHasUses), | |
| 131 source_stream_(stream), | |
| 132 source_stream_encoding_(encoding), | |
| 133 osr_ast_id_(BailoutId::None()), | |
| 134 parameter_count_(0), | |
| 135 optimization_id_(-1), | |
| 136 ast_value_factory_(NULL), | |
| 137 ast_value_factory_owned_(false), | |
| 138 aborted_due_to_dependency_change_(false), | |
| 139 osr_expr_stack_height_(0) { | |
| 140 Initialize(isolate, BASE, zone); | |
| 141 } | |
| 142 | |
| 143 | |
| 144 void CompilationInfo::Initialize(Isolate* isolate, | 108 void CompilationInfo::Initialize(Isolate* isolate, |
| 145 Mode mode, | 109 Mode mode, |
| 146 Zone* zone) { | 110 Zone* zone) { |
| 147 isolate_ = isolate; | 111 isolate_ = isolate; |
| 148 function_ = NULL; | |
| 149 scope_ = NULL; | |
| 150 script_scope_ = NULL; | |
| 151 extension_ = NULL; | |
| 152 cached_data_ = NULL; | |
| 153 compile_options_ = ScriptCompiler::kNoCompileOptions; | |
| 154 zone_ = zone; | 112 zone_ = zone; |
| 155 deferred_handles_ = NULL; | 113 deferred_handles_ = NULL; |
| 156 code_stub_ = NULL; | 114 code_stub_ = NULL; |
| 157 prologue_offset_ = Code::kPrologueOffsetNotSet; | 115 prologue_offset_ = Code::kPrologueOffsetNotSet; |
| 158 opt_count_ = shared_info().is_null() ? 0 : shared_info()->opt_count(); | 116 opt_count_ = has_shared_info() ? shared_info()->opt_count() : 0; |
| 159 no_frame_ranges_ = isolate->cpu_profiler()->is_profiling() | 117 no_frame_ranges_ = isolate->cpu_profiler()->is_profiling() |
| 160 ? new List<OffsetRange>(2) : NULL; | 118 ? new List<OffsetRange>(2) : NULL; |
| 161 if (FLAG_hydrogen_track_positions) { | 119 if (FLAG_hydrogen_track_positions) { |
| 162 inlined_function_infos_ = new List<InlinedFunctionInfo>(5); | 120 inlined_function_infos_ = new List<InlinedFunctionInfo>(5); |
| 163 inlining_id_to_function_id_ = new List<int>(5); | 121 inlining_id_to_function_id_ = new List<int>(5); |
| 164 } else { | 122 } else { |
| 165 inlined_function_infos_ = NULL; | 123 inlined_function_infos_ = NULL; |
| 166 inlining_id_to_function_id_ = NULL; | 124 inlining_id_to_function_id_ = NULL; |
| 167 } | 125 } |
| 168 | 126 |
| 169 for (int i = 0; i < DependentCode::kGroupCount; i++) { | 127 for (int i = 0; i < DependentCode::kGroupCount; i++) { |
| 170 dependencies_[i] = NULL; | 128 dependencies_[i] = NULL; |
| 171 } | 129 } |
| 172 if (mode == STUB) { | 130 if (mode == STUB) { |
| 173 mode_ = STUB; | 131 mode_ = STUB; |
| 174 return; | 132 return; |
| 175 } | 133 } |
| 176 mode_ = mode; | 134 mode_ = mode; |
| 177 if (!script_.is_null() && script_->type()->value() == Script::TYPE_NATIVE) { | |
| 178 MarkAsNative(); | |
| 179 } | |
| 180 // Compiling for the snapshot typically results in different code than | 135 // Compiling for the snapshot typically results in different code than |
| 181 // compiling later on. This means that code recompiled with deoptimization | 136 // compiling later on. This means that code recompiled with deoptimization |
| 182 // support won't be "equivalent" (as defined by SharedFunctionInfo:: | 137 // support won't be "equivalent" (as defined by SharedFunctionInfo:: |
| 183 // EnableDeoptimizationSupport), so it will replace the old code and all | 138 // EnableDeoptimizationSupport), so it will replace the old code and all |
| 184 // its type feedback. To avoid this, always compile functions in the snapshot | 139 // its type feedback. To avoid this, always compile functions in the snapshot |
| 185 // with deoptimization support. | 140 // with deoptimization support. |
| 186 if (isolate_->serializer_enabled()) EnableDeoptimizationSupport(); | 141 if (isolate_->serializer_enabled()) EnableDeoptimizationSupport(); |
| 187 | 142 |
| 188 if (isolate_->debug()->is_active()) MarkAsDebug(); | 143 if (isolate_->debug()->is_active()) MarkAsDebug(); |
| 189 if (FLAG_context_specialization) MarkAsContextSpecializing(); | 144 if (FLAG_context_specialization) MarkAsContextSpecializing(); |
| 190 if (FLAG_turbo_inlining) MarkAsInliningEnabled(); | 145 if (FLAG_turbo_inlining) MarkAsInliningEnabled(); |
| 191 if (FLAG_turbo_splitting) MarkAsSplittingEnabled(); | 146 if (FLAG_turbo_splitting) MarkAsSplittingEnabled(); |
| 192 if (FLAG_turbo_types) MarkAsTypingEnabled(); | 147 if (FLAG_turbo_types) MarkAsTypingEnabled(); |
| 193 | 148 |
| 194 if (!shared_info_.is_null()) { | |
| 195 DCHECK(is_sloppy(language_mode())); | |
| 196 SetLanguageMode(shared_info_->language_mode()); | |
| 197 } | |
| 198 bailout_reason_ = kNoReason; | 149 bailout_reason_ = kNoReason; |
| 199 | 150 |
| 200 if (!shared_info().is_null() && shared_info()->is_compiled()) { | 151 if (has_shared_info() && shared_info()->is_compiled()) { |
| 201 // We should initialize the CompilationInfo feedback vector from the | 152 // We should initialize the CompilationInfo feedback vector from the |
| 202 // passed in shared info, rather than creating a new one. | 153 // passed in shared info, rather than creating a new one. |
| 203 feedback_vector_ = | 154 feedback_vector_ = |
| 204 Handle<TypeFeedbackVector>(shared_info()->feedback_vector(), isolate); | 155 Handle<TypeFeedbackVector>(shared_info()->feedback_vector(), isolate); |
| 205 } | 156 } |
| 206 } | 157 } |
| 207 | 158 |
| 208 | 159 |
| 209 CompilationInfo::~CompilationInfo() { | 160 CompilationInfo::~CompilationInfo() { |
| 210 if (GetFlag(kDisableFutureOptimization)) { | 161 if (GetFlag(kDisableFutureOptimization)) { |
| 211 shared_info()->DisableOptimization(bailout_reason()); | 162 shared_info()->DisableOptimization(bailout_reason()); |
| 212 } | 163 } |
| 213 delete deferred_handles_; | 164 delete deferred_handles_; |
| 214 delete no_frame_ranges_; | 165 delete no_frame_ranges_; |
| 215 delete inlined_function_infos_; | 166 delete inlined_function_infos_; |
| 216 delete inlining_id_to_function_id_; | 167 delete inlining_id_to_function_id_; |
| 217 if (ast_value_factory_owned_) delete ast_value_factory_; | |
| 218 #ifdef DEBUG | 168 #ifdef DEBUG |
| 219 // Check that no dependent maps have been added or added dependent maps have | 169 // Check that no dependent maps have been added or added dependent maps have |
| 220 // been rolled back or committed. | 170 // been rolled back or committed. |
| 221 for (int i = 0; i < DependentCode::kGroupCount; i++) { | 171 for (int i = 0; i < DependentCode::kGroupCount; i++) { |
| 222 DCHECK(!dependencies_[i]); | 172 DCHECK(!dependencies_[i]); |
| 223 } | 173 } |
| 224 #endif // DEBUG | 174 #endif // DEBUG |
| 225 } | 175 } |
| 226 | 176 |
| 227 | 177 |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 300 } else { | 250 } else { |
| 301 return Code::ComputeFlags(Code::OPTIMIZED_FUNCTION); | 251 return Code::ComputeFlags(Code::OPTIMIZED_FUNCTION); |
| 302 } | 252 } |
| 303 } | 253 } |
| 304 | 254 |
| 305 | 255 |
| 306 // Primitive functions are unlikely to be picked up by the stack-walking | 256 // Primitive functions are unlikely to be picked up by the stack-walking |
| 307 // profiler, so they trigger their own optimization when they're called | 257 // profiler, so they trigger their own optimization when they're called |
| 308 // for the SharedFunctionInfo::kCallsUntilPrimitiveOptimization-th time. | 258 // for the SharedFunctionInfo::kCallsUntilPrimitiveOptimization-th time. |
| 309 bool CompilationInfo::ShouldSelfOptimize() { | 259 bool CompilationInfo::ShouldSelfOptimize() { |
| 310 return FLAG_crankshaft && | 260 return FLAG_crankshaft && !function()->flags()->Contains(kDontSelfOptimize) && |
| 311 !function()->flags()->Contains(kDontSelfOptimize) && | 261 !function()->dont_optimize() && |
| 312 !function()->dont_optimize() && | 262 function()->scope()->AllowsLazyCompilation() && |
| 313 function()->scope()->AllowsLazyCompilation() && | 263 (!has_shared_info() || !shared_info()->optimization_disabled()); |
| 314 (shared_info().is_null() || !shared_info()->optimization_disabled()); | |
| 315 } | 264 } |
| 316 | 265 |
| 317 | 266 |
| 318 void CompilationInfo::PrepareForCompilation(Scope* scope) { | |
| 319 DCHECK(scope_ == NULL); | |
| 320 scope_ = scope; | |
| 321 } | |
| 322 | |
| 323 | |
| 324 void CompilationInfo::EnsureFeedbackVector() { | 267 void CompilationInfo::EnsureFeedbackVector() { |
| 325 if (feedback_vector_.is_null()) { | 268 if (feedback_vector_.is_null()) { |
| 326 feedback_vector_ = isolate()->factory()->NewTypeFeedbackVector( | 269 feedback_vector_ = isolate()->factory()->NewTypeFeedbackVector( |
| 327 function()->feedback_vector_spec()); | 270 function()->feedback_vector_spec()); |
| 328 } | 271 } |
| 329 } | 272 } |
| 330 | 273 |
| 331 | 274 |
| 332 bool CompilationInfo::is_simple_parameter_list() { | 275 bool CompilationInfo::is_simple_parameter_list() { |
| 333 return scope_->is_simple_parameter_list(); | 276 return scope()->is_simple_parameter_list(); |
| 334 } | 277 } |
| 335 | 278 |
| 336 | 279 |
| 337 int CompilationInfo::TraceInlinedFunction(Handle<SharedFunctionInfo> shared, | 280 int CompilationInfo::TraceInlinedFunction(Handle<SharedFunctionInfo> shared, |
| 338 SourcePosition position) { | 281 SourcePosition position) { |
| 339 DCHECK(FLAG_hydrogen_track_positions); | 282 DCHECK(FLAG_hydrogen_track_positions); |
| 340 | 283 |
| 341 DCHECK(inlined_function_infos_); | 284 DCHECK(inlined_function_infos_); |
| 342 DCHECK(inlining_id_to_function_id_); | 285 DCHECK(inlining_id_to_function_id_); |
| 343 int id = 0; | 286 int id = 0; |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 542 if (info()->shared_info()->optimization_disabled()) { | 485 if (info()->shared_info()->optimization_disabled()) { |
| 543 return AbortOptimization( | 486 return AbortOptimization( |
| 544 info()->shared_info()->disable_optimization_reason()); | 487 info()->shared_info()->disable_optimization_reason()); |
| 545 } | 488 } |
| 546 | 489 |
| 547 graph_builder_ = (FLAG_hydrogen_track_positions || FLAG_trace_ic) | 490 graph_builder_ = (FLAG_hydrogen_track_positions || FLAG_trace_ic) |
| 548 ? new(info()->zone()) HOptimizedGraphBuilderWithPositions(info()) | 491 ? new(info()->zone()) HOptimizedGraphBuilderWithPositions(info()) |
| 549 : new(info()->zone()) HOptimizedGraphBuilder(info()); | 492 : new(info()->zone()) HOptimizedGraphBuilder(info()); |
| 550 | 493 |
| 551 Timer t(this, &time_taken_to_create_graph_); | 494 Timer t(this, &time_taken_to_create_graph_); |
| 552 info()->set_this_has_uses(false); | 495 // TODO(titzer): how is that possibly ok? |
|
Michael Starzinger
2015/03/04 22:50:46
I can shed light on that. IIRC, the "this_has_uses
| |
| 496 info()->parse_info()->set_this_has_uses(false); | |
| 553 graph_ = graph_builder_->CreateGraph(); | 497 graph_ = graph_builder_->CreateGraph(); |
| 554 | 498 |
| 555 if (isolate()->has_pending_exception()) { | 499 if (isolate()->has_pending_exception()) { |
| 556 return SetLastStatus(FAILED); | 500 return SetLastStatus(FAILED); |
| 557 } | 501 } |
| 558 | 502 |
| 559 if (graph_ == NULL) return SetLastStatus(BAILED_OUT); | 503 if (graph_ == NULL) return SetLastStatus(BAILED_OUT); |
| 560 | 504 |
| 561 if (info()->HasAbortedDueToDependencyChange()) { | 505 if (info()->HasAbortedDueToDependencyChange()) { |
| 562 // Dependency has changed during graph creation. Let's try again later. | 506 // Dependency has changed during graph creation. Let's try again later. |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 592 | 536 |
| 593 return SetLastStatus(BAILED_OUT); | 537 return SetLastStatus(BAILED_OUT); |
| 594 } | 538 } |
| 595 | 539 |
| 596 | 540 |
| 597 OptimizedCompileJob::Status OptimizedCompileJob::GenerateCode() { | 541 OptimizedCompileJob::Status OptimizedCompileJob::GenerateCode() { |
| 598 DCHECK(last_status() == SUCCEEDED); | 542 DCHECK(last_status() == SUCCEEDED); |
| 599 // TODO(turbofan): Currently everything is done in the first phase. | 543 // TODO(turbofan): Currently everything is done in the first phase. |
| 600 if (!info()->code().is_null()) { | 544 if (!info()->code().is_null()) { |
| 601 if (FLAG_turbo_deoptimization) { | 545 if (FLAG_turbo_deoptimization) { |
| 602 info()->context()->native_context()->AddOptimizedCode(*info()->code()); | 546 info()->parse_info()->context()->native_context()->AddOptimizedCode( |
| 547 *info()->code()); | |
| 603 } | 548 } |
| 604 RecordOptimizationStats(); | 549 RecordOptimizationStats(); |
| 605 return last_status(); | 550 return last_status(); |
| 606 } | 551 } |
| 607 | 552 |
| 608 DCHECK(!info()->HasAbortedDueToDependencyChange()); | 553 DCHECK(!info()->HasAbortedDueToDependencyChange()); |
| 609 DisallowCodeDependencyChange no_dependency_change; | 554 DisallowCodeDependencyChange no_dependency_change; |
| 610 DisallowJavascriptExecution no_js(isolate()); | 555 DisallowJavascriptExecution no_js(isolate()); |
| 611 { // Scope for timer. | 556 { // Scope for timer. |
| 612 Timer timer(this, &time_taken_to_codegen_); | 557 Timer timer(this, &time_taken_to_codegen_); |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 704 CompilationInfo* info, | 649 CompilationInfo* info, |
| 705 Handle<SharedFunctionInfo> shared) { | 650 Handle<SharedFunctionInfo> shared) { |
| 706 // SharedFunctionInfo is passed separately, because if CompilationInfo | 651 // SharedFunctionInfo is passed separately, because if CompilationInfo |
| 707 // was created using Script object, it will not have it. | 652 // was created using Script object, it will not have it. |
| 708 | 653 |
| 709 // Log the code generation. If source information is available include | 654 // Log the code generation. If source information is available include |
| 710 // script name and line number. Check explicitly whether logging is | 655 // script name and line number. Check explicitly whether logging is |
| 711 // enabled as finding the line number is not free. | 656 // enabled as finding the line number is not free. |
| 712 if (info->isolate()->logger()->is_logging_code_events() || | 657 if (info->isolate()->logger()->is_logging_code_events() || |
| 713 info->isolate()->cpu_profiler()->is_profiling()) { | 658 info->isolate()->cpu_profiler()->is_profiling()) { |
| 714 Handle<Script> script = info->script(); | 659 Handle<Script> script = info->parse_info()->script(); |
| 715 Handle<Code> code = info->code(); | 660 Handle<Code> code = info->code(); |
| 716 if (code.is_identical_to(info->isolate()->builtins()->CompileLazy())) { | 661 if (code.is_identical_to(info->isolate()->builtins()->CompileLazy())) { |
| 717 return; | 662 return; |
| 718 } | 663 } |
| 719 int line_num = Script::GetLineNumber(script, shared->start_position()) + 1; | 664 int line_num = Script::GetLineNumber(script, shared->start_position()) + 1; |
| 720 int column_num = | 665 int column_num = |
| 721 Script::GetColumnNumber(script, shared->start_position()) + 1; | 666 Script::GetColumnNumber(script, shared->start_position()) + 1; |
| 722 String* script_name = script->name()->IsString() | 667 String* script_name = script->name()->IsString() |
| 723 ? String::cast(script->name()) | 668 ? String::cast(script->name()) |
| 724 : info->isolate()->heap()->empty_string(); | 669 : info->isolate()->heap()->empty_string(); |
| 725 Logger::LogEventsAndTags log_tag = Logger::ToNativeByScript(tag, *script); | 670 Logger::LogEventsAndTags log_tag = Logger::ToNativeByScript(tag, *script); |
| 726 PROFILE(info->isolate(), | 671 PROFILE(info->isolate(), |
| 727 CodeCreateEvent(log_tag, *code, *shared, info, script_name, | 672 CodeCreateEvent(log_tag, *code, *shared, info, script_name, |
| 728 line_num, column_num)); | 673 line_num, column_num)); |
| 729 } | 674 } |
| 730 } | 675 } |
| 731 | 676 |
| 732 | 677 |
| 733 static bool CompileUnoptimizedCode(CompilationInfo* info) { | 678 static bool CompileUnoptimizedCode(CompilationInfo* info) { |
| 734 DCHECK(AllowCompilation::IsAllowed(info->isolate())); | 679 DCHECK(AllowCompilation::IsAllowed(info->isolate())); |
| 735 if (!Compiler::Analyze(info) || !FullCodeGenerator::MakeCode(info)) { | 680 if (!Compiler::Analyze(info->parse_info()) || |
| 681 !FullCodeGenerator::MakeCode(info)) { | |
| 736 Isolate* isolate = info->isolate(); | 682 Isolate* isolate = info->isolate(); |
| 737 if (!isolate->has_pending_exception()) isolate->StackOverflow(); | 683 if (!isolate->has_pending_exception()) isolate->StackOverflow(); |
| 738 return false; | 684 return false; |
| 739 } | 685 } |
| 740 return true; | 686 return true; |
| 741 } | 687 } |
| 742 | 688 |
| 743 | 689 |
| 744 MUST_USE_RESULT static MaybeHandle<Code> GetUnoptimizedCodeCommon( | 690 MUST_USE_RESULT static MaybeHandle<Code> GetUnoptimizedCodeCommon( |
| 745 CompilationInfo* info) { | 691 CompilationInfo* info) { |
| 746 VMState<COMPILER> state(info->isolate()); | 692 VMState<COMPILER> state(info->isolate()); |
| 747 PostponeInterruptsScope postpone(info->isolate()); | 693 PostponeInterruptsScope postpone(info->isolate()); |
| 748 | 694 |
| 749 // Parse and update CompilationInfo with the results. | 695 // Parse and update CompilationInfo with the results. |
| 750 if (!Parser::ParseStatic(info)) return MaybeHandle<Code>(); | 696 if (!Parser::ParseStatic(info->parse_info())) return MaybeHandle<Code>(); |
| 751 Handle<SharedFunctionInfo> shared = info->shared_info(); | 697 Handle<SharedFunctionInfo> shared = info->shared_info(); |
| 752 FunctionLiteral* lit = info->function(); | 698 FunctionLiteral* lit = info->function(); |
| 753 shared->set_language_mode(lit->language_mode()); | 699 shared->set_language_mode(lit->language_mode()); |
| 754 SetExpectedNofPropertiesFromEstimate(shared, lit->expected_property_count()); | 700 SetExpectedNofPropertiesFromEstimate(shared, lit->expected_property_count()); |
| 755 MaybeDisableOptimization(shared, lit->dont_optimize_reason()); | 701 MaybeDisableOptimization(shared, lit->dont_optimize_reason()); |
| 756 | 702 |
| 757 // Compile unoptimized code. | 703 // Compile unoptimized code. |
| 758 if (!CompileUnoptimizedCode(info)) return MaybeHandle<Code>(); | 704 if (!CompileUnoptimizedCode(info)) return MaybeHandle<Code>(); |
| 759 | 705 |
| 760 CHECK_EQ(Code::FUNCTION, info->code()->kind()); | 706 CHECK_EQ(Code::FUNCTION, info->code()->kind()); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 816 // Do not cache bound functions. | 762 // Do not cache bound functions. |
| 817 if (shared->bound()) return; | 763 if (shared->bound()) return; |
| 818 Handle<FixedArray> literals(function->literals()); | 764 Handle<FixedArray> literals(function->literals()); |
| 819 Handle<Context> native_context(function->context()->native_context()); | 765 Handle<Context> native_context(function->context()->native_context()); |
| 820 SharedFunctionInfo::AddToOptimizedCodeMap(shared, native_context, code, | 766 SharedFunctionInfo::AddToOptimizedCodeMap(shared, native_context, code, |
| 821 literals, info->osr_ast_id()); | 767 literals, info->osr_ast_id()); |
| 822 } | 768 } |
| 823 } | 769 } |
| 824 | 770 |
| 825 | 771 |
| 826 static bool Renumber(CompilationInfo* info) { | 772 static bool Renumber(ParseInfo* parse_info) { |
| 827 if (!AstNumbering::Renumber(info->isolate(), info->zone(), | 773 if (!AstNumbering::Renumber(parse_info->isolate(), parse_info->zone(), |
| 828 info->function())) { | 774 parse_info->function())) { |
| 829 return false; | 775 return false; |
| 830 } | 776 } |
| 831 if (!info->shared_info().is_null()) { | 777 Handle<SharedFunctionInfo> shared_info = parse_info->shared_info(); |
| 832 FunctionLiteral* lit = info->function(); | 778 if (!shared_info.is_null()) { |
| 833 info->shared_info()->set_ast_node_count(lit->ast_node_count()); | 779 FunctionLiteral* lit = parse_info->function(); |
| 834 MaybeDisableOptimization(info->shared_info(), lit->dont_optimize_reason()); | 780 shared_info->set_ast_node_count(lit->ast_node_count()); |
| 835 info->shared_info()->set_dont_cache(lit->flags()->Contains(kDontCache)); | 781 MaybeDisableOptimization(shared_info, lit->dont_optimize_reason()); |
| 782 shared_info->set_dont_cache(lit->flags()->Contains(kDontCache)); | |
| 836 } | 783 } |
| 837 return true; | 784 return true; |
| 838 } | 785 } |
| 839 | 786 |
| 840 | 787 |
| 841 bool Compiler::Analyze(CompilationInfo* info) { | 788 bool Compiler::Analyze(ParseInfo* info) { |
| 842 DCHECK(info->function() != NULL); | 789 DCHECK(info->function() != NULL); |
| 843 if (!Rewriter::Rewrite(info)) return false; | 790 if (!Rewriter::Rewrite(info)) return false; |
| 844 if (!Scope::Analyze(info)) return false; | 791 if (!Scope::Analyze(info)) return false; |
| 845 if (!Renumber(info)) return false; | 792 if (!Renumber(info)) return false; |
| 846 DCHECK(info->scope() != NULL); | 793 DCHECK(info->scope() != NULL); |
| 847 return true; | 794 return true; |
| 848 } | 795 } |
| 849 | 796 |
| 850 | 797 |
| 851 bool Compiler::ParseAndAnalyze(CompilationInfo* info) { | 798 bool Compiler::ParseAndAnalyze(ParseInfo* info) { |
| 852 if (!Parser::ParseStatic(info)) return false; | 799 if (!Parser::ParseStatic(info)) return false; |
| 853 return Compiler::Analyze(info); | 800 return Compiler::Analyze(info); |
| 854 } | 801 } |
| 855 | 802 |
| 856 | 803 |
| 857 static bool GetOptimizedCodeNow(CompilationInfo* info) { | 804 static bool GetOptimizedCodeNow(CompilationInfo* info) { |
| 858 if (!Compiler::ParseAndAnalyze(info)) return false; | 805 if (!Compiler::ParseAndAnalyze(info->parse_info())) return false; |
| 859 | 806 |
| 860 TimerEventScope<TimerEventRecompileSynchronous> timer(info->isolate()); | 807 TimerEventScope<TimerEventRecompileSynchronous> timer(info->isolate()); |
| 861 | 808 |
| 862 OptimizedCompileJob job(info); | 809 OptimizedCompileJob job(info); |
| 863 if (job.CreateGraph() != OptimizedCompileJob::SUCCEEDED || | 810 if (job.CreateGraph() != OptimizedCompileJob::SUCCEEDED || |
| 864 job.OptimizeGraph() != OptimizedCompileJob::SUCCEEDED || | 811 job.OptimizeGraph() != OptimizedCompileJob::SUCCEEDED || |
| 865 job.GenerateCode() != OptimizedCompileJob::SUCCEEDED) { | 812 job.GenerateCode() != OptimizedCompileJob::SUCCEEDED) { |
| 866 if (FLAG_trace_opt) { | 813 if (FLAG_trace_opt) { |
| 867 PrintF("[aborted optimizing "); | 814 PrintF("[aborted optimizing "); |
| 868 info->closure()->ShortPrint(); | 815 info->closure()->ShortPrint(); |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 885 if (!isolate->optimizing_compiler_thread()->IsQueueAvailable()) { | 832 if (!isolate->optimizing_compiler_thread()->IsQueueAvailable()) { |
| 886 if (FLAG_trace_concurrent_recompilation) { | 833 if (FLAG_trace_concurrent_recompilation) { |
| 887 PrintF(" ** Compilation queue full, will retry optimizing "); | 834 PrintF(" ** Compilation queue full, will retry optimizing "); |
| 888 info->closure()->ShortPrint(); | 835 info->closure()->ShortPrint(); |
| 889 PrintF(" later.\n"); | 836 PrintF(" later.\n"); |
| 890 } | 837 } |
| 891 return false; | 838 return false; |
| 892 } | 839 } |
| 893 | 840 |
| 894 CompilationHandleScope handle_scope(info); | 841 CompilationHandleScope handle_scope(info); |
| 895 if (!Compiler::ParseAndAnalyze(info)) return false; | 842 if (!Compiler::ParseAndAnalyze(info->parse_info())) return false; |
| 896 info->SaveHandles(); // Copy handles to the compilation handle scope. | 843 |
| 844 // Reopen handles in the new CompilationHandleScope. | |
| 845 info->ReopenHandlesInNewHandleScope(); | |
| 846 info->parse_info()->ReopenHandlesInNewHandleScope(); | |
| 897 | 847 |
| 898 TimerEventScope<TimerEventRecompileSynchronous> timer(info->isolate()); | 848 TimerEventScope<TimerEventRecompileSynchronous> timer(info->isolate()); |
| 899 | 849 |
| 900 OptimizedCompileJob* job = new (info->zone()) OptimizedCompileJob(info); | 850 OptimizedCompileJob* job = new (info->zone()) OptimizedCompileJob(info); |
| 901 OptimizedCompileJob::Status status = job->CreateGraph(); | 851 OptimizedCompileJob::Status status = job->CreateGraph(); |
| 902 if (status != OptimizedCompileJob::SUCCEEDED) return false; | 852 if (status != OptimizedCompileJob::SUCCEEDED) return false; |
| 903 isolate->optimizing_compiler_thread()->QueueForOptimization(job); | 853 isolate->optimizing_compiler_thread()->QueueForOptimization(job); |
| 904 | 854 |
| 905 if (FLAG_trace_concurrent_recompilation) { | 855 if (FLAG_trace_concurrent_recompilation) { |
| 906 PrintF(" ** Queued "); | 856 PrintF(" ** Queued "); |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1006 return true; | 956 return true; |
| 1007 } | 957 } |
| 1008 | 958 |
| 1009 | 959 |
| 1010 // TODO(turbofan): In the future, unoptimized code with deopt support could | 960 // TODO(turbofan): In the future, unoptimized code with deopt support could |
| 1011 // be generated lazily once deopt is triggered. | 961 // be generated lazily once deopt is triggered. |
| 1012 bool Compiler::EnsureDeoptimizationSupport(CompilationInfo* info) { | 962 bool Compiler::EnsureDeoptimizationSupport(CompilationInfo* info) { |
| 1013 DCHECK(info->function() != NULL); | 963 DCHECK(info->function() != NULL); |
| 1014 DCHECK(info->scope() != NULL); | 964 DCHECK(info->scope() != NULL); |
| 1015 if (!info->shared_info()->has_deoptimization_support()) { | 965 if (!info->shared_info()->has_deoptimization_support()) { |
| 966 // TODO(titzer): just reuse the ParseInfo for the unoptimized compile. | |
| 1016 Handle<SharedFunctionInfo> shared = info->shared_info(); | 967 Handle<SharedFunctionInfo> shared = info->shared_info(); |
| 1017 CompilationInfoWithZone unoptimized(shared); | 968 CompilationInfoWithZone unoptimized(shared); |
| 1018 // Note that we use the same AST that we will use for generating the | 969 // Note that we use the same AST that we will use for generating the |
| 1019 // optimized code. | 970 // optimized code. |
| 1020 unoptimized.SetFunction(info->function()); | 971 ParseInfo* parse_info = unoptimized.parse_info(); |
| 1021 unoptimized.PrepareForCompilation(info->scope()); | 972 parse_info->set_literal(info->function()); |
| 1022 unoptimized.SetContext(info->context()); | 973 parse_info->set_scope(info->scope()); |
| 974 parse_info->set_context(info->context()); | |
| 1023 unoptimized.EnableDeoptimizationSupport(); | 975 unoptimized.EnableDeoptimizationSupport(); |
| 1024 // If the current code has reloc info for serialization, also include | 976 // If the current code has reloc info for serialization, also include |
| 1025 // reloc info for serialization for the new code, so that deopt support | 977 // reloc info for serialization for the new code, so that deopt support |
| 1026 // can be added without losing IC state. | 978 // can be added without losing IC state. |
| 1027 if (shared->code()->kind() == Code::FUNCTION && | 979 if (shared->code()->kind() == Code::FUNCTION && |
| 1028 shared->code()->has_reloc_info_for_serialization()) { | 980 shared->code()->has_reloc_info_for_serialization()) { |
| 1029 unoptimized.PrepareForSerializing(); | 981 unoptimized.PrepareForSerializing(); |
| 1030 } | 982 } |
| 1031 if (!FullCodeGenerator::MakeCode(&unoptimized)) return false; | 983 if (!FullCodeGenerator::MakeCode(&unoptimized)) return false; |
| 1032 | 984 |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1086 return maybe_new_code; | 1038 return maybe_new_code; |
| 1087 } | 1039 } |
| 1088 | 1040 |
| 1089 | 1041 |
| 1090 void Compiler::CompileForLiveEdit(Handle<Script> script) { | 1042 void Compiler::CompileForLiveEdit(Handle<Script> script) { |
| 1091 // TODO(635): support extensions. | 1043 // TODO(635): support extensions. |
| 1092 CompilationInfoWithZone info(script); | 1044 CompilationInfoWithZone info(script); |
| 1093 PostponeInterruptsScope postpone(info.isolate()); | 1045 PostponeInterruptsScope postpone(info.isolate()); |
| 1094 VMState<COMPILER> state(info.isolate()); | 1046 VMState<COMPILER> state(info.isolate()); |
| 1095 | 1047 |
| 1096 info.MarkAsGlobal(); | 1048 info.parse_info()->set_global(); |
| 1097 if (!Parser::ParseStatic(&info)) return; | 1049 if (!Parser::ParseStatic(info.parse_info())) return; |
| 1098 | 1050 |
| 1099 LiveEditFunctionTracker tracker(info.isolate(), info.function()); | 1051 LiveEditFunctionTracker tracker(info.isolate(), info.function()); |
| 1100 if (!CompileUnoptimizedCode(&info)) return; | 1052 if (!CompileUnoptimizedCode(&info)) return; |
| 1101 if (!info.shared_info().is_null()) { | 1053 if (info.has_shared_info()) { |
| 1102 Handle<ScopeInfo> scope_info = | 1054 Handle<ScopeInfo> scope_info = |
| 1103 ScopeInfo::Create(info.isolate(), info.zone(), info.scope()); | 1055 ScopeInfo::Create(info.isolate(), info.zone(), info.scope()); |
| 1104 info.shared_info()->set_scope_info(*scope_info); | 1056 info.shared_info()->set_scope_info(*scope_info); |
| 1105 } | 1057 } |
| 1106 tracker.RecordRootFunctionInfo(info.code()); | 1058 tracker.RecordRootFunctionInfo(info.code()); |
| 1107 } | 1059 } |
| 1108 | 1060 |
| 1109 | 1061 |
| 1110 static Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) { | 1062 static Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) { |
| 1111 Isolate* isolate = info->isolate(); | 1063 Isolate* isolate = info->isolate(); |
| 1112 PostponeInterruptsScope postpone(isolate); | 1064 PostponeInterruptsScope postpone(isolate); |
| 1113 DCHECK(!isolate->native_context().is_null()); | 1065 DCHECK(!isolate->native_context().is_null()); |
| 1114 Handle<Script> script = info->script(); | 1066 ParseInfo* parse_info = info->parse_info(); |
| 1067 Handle<Script> script = parse_info->script(); | |
| 1115 | 1068 |
| 1116 // TODO(svenpanne) Obscure place for this, perhaps move to OnBeforeCompile? | 1069 // TODO(svenpanne) Obscure place for this, perhaps move to OnBeforeCompile? |
| 1117 FixedArray* array = isolate->native_context()->embedder_data(); | 1070 FixedArray* array = isolate->native_context()->embedder_data(); |
| 1118 script->set_context_data(array->get(0)); | 1071 script->set_context_data(array->get(0)); |
| 1119 | 1072 |
| 1120 isolate->debug()->OnBeforeCompile(script); | 1073 isolate->debug()->OnBeforeCompile(script); |
| 1121 | 1074 |
| 1122 DCHECK(info->is_eval() || info->is_global() || info->is_module()); | 1075 DCHECK(parse_info->is_eval() || parse_info->is_global() || |
| 1076 parse_info->is_module()); | |
| 1123 | 1077 |
| 1124 info->MarkAsToplevel(); | 1078 parse_info->set_toplevel(); |
| 1125 | 1079 |
| 1126 Handle<SharedFunctionInfo> result; | 1080 Handle<SharedFunctionInfo> result; |
| 1127 | 1081 |
| 1128 { VMState<COMPILER> state(info->isolate()); | 1082 { VMState<COMPILER> state(info->isolate()); |
| 1129 if (info->function() == NULL) { | 1083 if (info->function() == NULL) { |
| 1130 // Parse the script if needed (if it's already parsed, function() is | 1084 // Parse the script if needed (if it's already parsed, function() is |
| 1131 // non-NULL). | 1085 // non-NULL). |
| 1132 bool parse_allow_lazy = | 1086 ScriptCompiler::CompileOptions options = |
| 1133 (info->compile_options() == ScriptCompiler::kConsumeParserCache || | 1087 info->parse_info()->compile_options(); |
| 1134 String::cast(script->source())->length() > | 1088 bool parse_allow_lazy = (options == ScriptCompiler::kConsumeParserCache || |
| 1135 FLAG_min_preparse_length) && | 1089 String::cast(script->source())->length() > |
| 1136 !Compiler::DebuggerWantsEagerCompilation(info); | 1090 FLAG_min_preparse_length) && |
| 1091 !Compiler::DebuggerWantsEagerCompilation(isolate); | |
| 1137 | 1092 |
| 1138 if (!parse_allow_lazy && | 1093 if (!parse_allow_lazy && |
| 1139 (info->compile_options() == ScriptCompiler::kProduceParserCache || | 1094 (options == ScriptCompiler::kProduceParserCache || |
| 1140 info->compile_options() == ScriptCompiler::kConsumeParserCache)) { | 1095 options == ScriptCompiler::kConsumeParserCache)) { |
| 1141 // We are going to parse eagerly, but we either 1) have cached data | 1096 // We are going to parse eagerly, but we either 1) have cached data |
| 1142 // produced by lazy parsing or 2) are asked to generate cached data. | 1097 // produced by lazy parsing or 2) are asked to generate cached data. |
| 1143 // Eager parsing cannot benefit from cached data, and producing cached | 1098 // Eager parsing cannot benefit from cached data, and producing cached |
| 1144 // data while parsing eagerly is not implemented. | 1099 // data while parsing eagerly is not implemented. |
| 1145 info->SetCachedData(NULL, ScriptCompiler::kNoCompileOptions); | 1100 info->parse_info()->set_cached_data(nullptr); |
| 1101 info->parse_info()->set_compile_options( | |
| 1102 ScriptCompiler::kNoCompileOptions); | |
| 1146 } | 1103 } |
| 1147 if (!Parser::ParseStatic(info, parse_allow_lazy)) { | 1104 if (!Parser::ParseStatic(info->parse_info(), parse_allow_lazy)) { |
| 1148 return Handle<SharedFunctionInfo>::null(); | 1105 return Handle<SharedFunctionInfo>::null(); |
| 1149 } | 1106 } |
| 1150 } | 1107 } |
| 1151 | 1108 |
| 1152 FunctionLiteral* lit = info->function(); | 1109 FunctionLiteral* lit = info->function(); |
| 1153 LiveEditFunctionTracker live_edit_tracker(isolate, lit); | 1110 LiveEditFunctionTracker live_edit_tracker(isolate, lit); |
| 1154 | 1111 |
| 1155 // Measure how long it takes to do the compilation; only take the | 1112 // Measure how long it takes to do the compilation; only take the |
| 1156 // rest of the function into account to avoid overlap with the | 1113 // rest of the function into account to avoid overlap with the |
| 1157 // parsing statistics. | 1114 // parsing statistics. |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1217 | 1174 |
| 1218 CompilationCache* compilation_cache = isolate->compilation_cache(); | 1175 CompilationCache* compilation_cache = isolate->compilation_cache(); |
| 1219 MaybeHandle<SharedFunctionInfo> maybe_shared_info = | 1176 MaybeHandle<SharedFunctionInfo> maybe_shared_info = |
| 1220 compilation_cache->LookupEval(source, outer_info, context, language_mode, | 1177 compilation_cache->LookupEval(source, outer_info, context, language_mode, |
| 1221 scope_position); | 1178 scope_position); |
| 1222 Handle<SharedFunctionInfo> shared_info; | 1179 Handle<SharedFunctionInfo> shared_info; |
| 1223 | 1180 |
| 1224 if (!maybe_shared_info.ToHandle(&shared_info)) { | 1181 if (!maybe_shared_info.ToHandle(&shared_info)) { |
| 1225 Handle<Script> script = isolate->factory()->NewScript(source); | 1182 Handle<Script> script = isolate->factory()->NewScript(source); |
| 1226 CompilationInfoWithZone info(script); | 1183 CompilationInfoWithZone info(script); |
| 1227 info.MarkAsEval(); | 1184 ParseInfo* parse_info = info.parse_info(); |
| 1228 if (context->IsNativeContext()) info.MarkAsGlobal(); | 1185 parse_info->set_eval(); |
| 1229 info.SetLanguageMode(language_mode); | 1186 if (context->IsNativeContext()) parse_info->set_global(); |
| 1230 info.SetParseRestriction(restriction); | 1187 parse_info->set_language_mode(language_mode); |
| 1231 info.SetContext(context); | 1188 parse_info->set_parse_restriction(restriction); |
| 1189 parse_info->set_context(context); | |
| 1232 | 1190 |
| 1233 Debug::RecordEvalCaller(script); | 1191 Debug::RecordEvalCaller(script); |
| 1234 | 1192 |
| 1235 shared_info = CompileToplevel(&info); | 1193 shared_info = CompileToplevel(&info); |
| 1236 | 1194 |
| 1237 if (shared_info.is_null()) { | 1195 if (shared_info.is_null()) { |
| 1238 return MaybeHandle<JSFunction>(); | 1196 return MaybeHandle<JSFunction>(); |
| 1239 } else { | 1197 } else { |
| 1240 // Explicitly disable optimization for eval code. We're not yet prepared | 1198 // Explicitly disable optimization for eval code. We're not yet prepared |
| 1241 // to handle eval-code in the optimizing compiler. | 1199 // to handle eval-code in the optimizing compiler. |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1331 if (!script_name.is_null()) { | 1289 if (!script_name.is_null()) { |
| 1332 script->set_name(*script_name); | 1290 script->set_name(*script_name); |
| 1333 script->set_line_offset(Smi::FromInt(line_offset)); | 1291 script->set_line_offset(Smi::FromInt(line_offset)); |
| 1334 script->set_column_offset(Smi::FromInt(column_offset)); | 1292 script->set_column_offset(Smi::FromInt(column_offset)); |
| 1335 } | 1293 } |
| 1336 script->set_is_shared_cross_origin(is_shared_cross_origin); | 1294 script->set_is_shared_cross_origin(is_shared_cross_origin); |
| 1337 script->set_is_embedder_debug_script(is_embedder_debug_script); | 1295 script->set_is_embedder_debug_script(is_embedder_debug_script); |
| 1338 | 1296 |
| 1339 // Compile the function and add it to the cache. | 1297 // Compile the function and add it to the cache. |
| 1340 CompilationInfoWithZone info(script); | 1298 CompilationInfoWithZone info(script); |
| 1299 ParseInfo* parse_info = info.parse_info(); | |
| 1341 if (FLAG_harmony_modules && is_module) { | 1300 if (FLAG_harmony_modules && is_module) { |
| 1342 info.MarkAsModule(); | 1301 parse_info->set_module(); |
| 1343 } else { | 1302 } else { |
| 1344 info.MarkAsGlobal(); | 1303 parse_info->set_global(); |
| 1345 } | 1304 } |
| 1346 info.SetCachedData(cached_data, compile_options); | 1305 if (compile_options != ScriptCompiler::kNoCompileOptions) { |
| 1347 info.SetExtension(extension); | 1306 parse_info->set_cached_data(cached_data); |
| 1348 info.SetContext(context); | 1307 } |
| 1308 parse_info->set_compile_options(compile_options); | |
| 1309 parse_info->set_extension(extension); | |
| 1310 parse_info->set_context(context); | |
| 1349 if (FLAG_serialize_toplevel && | 1311 if (FLAG_serialize_toplevel && |
| 1350 compile_options == ScriptCompiler::kProduceCodeCache) { | 1312 compile_options == ScriptCompiler::kProduceCodeCache) { |
| 1351 info.PrepareForSerializing(); | 1313 info.PrepareForSerializing(); |
| 1352 } | 1314 } |
| 1353 | 1315 |
| 1354 info.SetLanguageMode( | 1316 parse_info->set_language_mode( |
| 1355 static_cast<LanguageMode>(info.language_mode() | language_mode)); | 1317 static_cast<LanguageMode>(info.language_mode() | language_mode)); |
| 1356 result = CompileToplevel(&info); | 1318 result = CompileToplevel(&info); |
| 1357 if (extension == NULL && !result.is_null() && !result->dont_cache()) { | 1319 if (extension == NULL && !result.is_null() && !result->dont_cache()) { |
| 1358 compilation_cache->PutScript(source, context, language_mode, result); | 1320 compilation_cache->PutScript(source, context, language_mode, result); |
| 1359 if (FLAG_serialize_toplevel && | 1321 if (FLAG_serialize_toplevel && |
| 1360 compile_options == ScriptCompiler::kProduceCodeCache) { | 1322 compile_options == ScriptCompiler::kProduceCodeCache) { |
| 1361 HistogramTimerScope histogram_timer( | 1323 HistogramTimerScope histogram_timer( |
| 1362 isolate->counters()->compile_serialize()); | 1324 isolate->counters()->compile_serialize()); |
| 1363 *cached_data = CodeSerializer::Serialize(isolate, result, source); | 1325 *cached_data = CodeSerializer::Serialize(isolate, result, source); |
| 1364 if (FLAG_profile_deserialization) { | 1326 if (FLAG_profile_deserialization) { |
| 1365 PrintF("[Compiling and serializing took %0.3f ms]\n", | 1327 PrintF("[Compiling and serializing took %0.3f ms]\n", |
| 1366 timer.Elapsed().InMillisecondsF()); | 1328 timer.Elapsed().InMillisecondsF()); |
| 1367 } | 1329 } |
| 1368 } | 1330 } |
| 1369 } | 1331 } |
| 1370 | 1332 |
| 1371 if (result.is_null()) isolate->ReportPendingMessages(); | 1333 if (result.is_null()) isolate->ReportPendingMessages(); |
| 1372 } else if (result->ic_age() != isolate->heap()->global_ic_age()) { | 1334 } else if (result->ic_age() != isolate->heap()->global_ic_age()) { |
| 1373 result->ResetForNewContext(isolate->heap()->global_ic_age()); | 1335 result->ResetForNewContext(isolate->heap()->global_ic_age()); |
| 1374 } | 1336 } |
| 1375 return result; | 1337 return result; |
| 1376 } | 1338 } |
| 1377 | 1339 |
| 1378 | 1340 |
| 1379 Handle<SharedFunctionInfo> Compiler::CompileStreamedScript( | 1341 Handle<SharedFunctionInfo> Compiler::CompileStreamedScript( |
| 1380 CompilationInfo* info, int source_length) { | 1342 Handle<Script> script, ParseInfo* parse_info, int source_length) { |
| 1381 Isolate* isolate = info->isolate(); | 1343 Isolate* isolate = script->GetIsolate(); |
| 1344 // TODO(titzer): increment the counters in caller. | |
| 1382 isolate->counters()->total_load_size()->Increment(source_length); | 1345 isolate->counters()->total_load_size()->Increment(source_length); |
| 1383 isolate->counters()->total_compile_size()->Increment(source_length); | 1346 isolate->counters()->total_compile_size()->Increment(source_length); |
| 1384 | 1347 |
| 1385 LanguageMode language_mode = | 1348 LanguageMode language_mode = |
| 1386 construct_language_mode(FLAG_use_strict, FLAG_use_strong); | 1349 construct_language_mode(FLAG_use_strict, FLAG_use_strong); |
| 1387 info->SetLanguageMode( | 1350 parse_info->set_language_mode( |
| 1388 static_cast<LanguageMode>(info->language_mode() | language_mode)); | 1351 static_cast<LanguageMode>(parse_info->language_mode() | language_mode)); |
| 1389 | 1352 |
| 1353 CompilationInfo compile_info(parse_info); | |
| 1390 // TODO(marja): FLAG_serialize_toplevel is not honoured and won't be; when the | 1354 // TODO(marja): FLAG_serialize_toplevel is not honoured and won't be; when the |
| 1391 // real code caching lands, streaming needs to be adapted to use it. | 1355 // real code caching lands, streaming needs to be adapted to use it. |
| 1392 return CompileToplevel(info); | 1356 return CompileToplevel(&compile_info); |
| 1393 } | 1357 } |
| 1394 | 1358 |
| 1395 | 1359 |
| 1396 Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo( | 1360 Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo( |
| 1397 FunctionLiteral* literal, Handle<Script> script, | 1361 FunctionLiteral* literal, Handle<Script> script, |
| 1398 CompilationInfo* outer_info) { | 1362 CompilationInfo* outer_info) { |
| 1399 // Precondition: code has been parsed and scopes have been analyzed. | 1363 // Precondition: code has been parsed and scopes have been analyzed. |
| 1400 CompilationInfoWithZone info(script); | 1364 CompilationInfoWithZone info(script); |
| 1401 info.SetFunction(literal); | 1365 ParseInfo* parse_info = info.parse_info(); |
| 1402 info.PrepareForCompilation(literal->scope()); | 1366 parse_info->set_literal(literal); |
| 1403 info.SetLanguageMode(literal->scope()->language_mode()); | 1367 parse_info->set_scope(literal->scope()); |
| 1368 parse_info->set_language_mode(literal->scope()->language_mode()); | |
| 1404 if (outer_info->will_serialize()) info.PrepareForSerializing(); | 1369 if (outer_info->will_serialize()) info.PrepareForSerializing(); |
| 1405 | 1370 |
| 1406 Isolate* isolate = info.isolate(); | 1371 Isolate* isolate = info.isolate(); |
| 1407 Factory* factory = isolate->factory(); | 1372 Factory* factory = isolate->factory(); |
| 1408 LiveEditFunctionTracker live_edit_tracker(isolate, literal); | 1373 LiveEditFunctionTracker live_edit_tracker(isolate, literal); |
| 1409 // Determine if the function can be lazily compiled. This is necessary to | 1374 // Determine if the function can be lazily compiled. This is necessary to |
| 1410 // allow some of our builtin JS files to be lazily compiled. These | 1375 // allow some of our builtin JS files to be lazily compiled. These |
| 1411 // builtins cannot be handled lazily by the parser, since we have to know | 1376 // builtins cannot be handled lazily by the parser, since we have to know |
| 1412 // if a function uses the special natives syntax, which is something the | 1377 // if a function uses the special natives syntax, which is something the |
| 1413 // parser records. | 1378 // parser records. |
| 1414 // If the debugger requests compilation for break points, we cannot be | 1379 // If the debugger requests compilation for break points, we cannot be |
| 1415 // aggressive about lazy compilation, because it might trigger compilation | 1380 // aggressive about lazy compilation, because it might trigger compilation |
| 1416 // of functions without an outer context when setting a breakpoint through | 1381 // of functions without an outer context when setting a breakpoint through |
| 1417 // Debug::FindSharedFunctionInfoInScript. | 1382 // Debug::FindSharedFunctionInfoInScript. |
| 1418 bool allow_lazy_without_ctx = literal->AllowsLazyCompilationWithoutContext(); | 1383 bool allow_lazy_without_ctx = literal->AllowsLazyCompilationWithoutContext(); |
| 1419 bool allow_lazy = literal->AllowsLazyCompilation() && | 1384 bool allow_lazy = |
| 1420 !DebuggerWantsEagerCompilation(&info, allow_lazy_without_ctx); | 1385 literal->AllowsLazyCompilation() && |
| 1386 !DebuggerWantsEagerCompilation(isolate, allow_lazy_without_ctx); | |
| 1421 | 1387 |
| 1422 if (outer_info->is_toplevel() && outer_info->will_serialize()) { | 1388 if (outer_info->parse_info()->is_toplevel() && outer_info->will_serialize()) { |
| 1423 // Make sure that if the toplevel code (possibly to be serialized), | 1389 // Make sure that if the toplevel code (possibly to be serialized), |
| 1424 // the inner function must be allowed to be compiled lazily. | 1390 // the inner function must be allowed to be compiled lazily. |
| 1425 // This is necessary to serialize toplevel code without inner functions. | 1391 // This is necessary to serialize toplevel code without inner functions. |
| 1426 DCHECK(allow_lazy); | 1392 DCHECK(allow_lazy); |
| 1427 } | 1393 } |
| 1428 | 1394 |
| 1429 // Generate code | 1395 // Generate code |
| 1430 Handle<ScopeInfo> scope_info; | 1396 Handle<ScopeInfo> scope_info; |
| 1431 if (FLAG_lazy && allow_lazy && !literal->is_parenthesized()) { | 1397 if (FLAG_lazy && allow_lazy && !literal->is_parenthesized()) { |
| 1432 Handle<Code> code = isolate->builtins()->CompileLazy(); | 1398 Handle<Code> code = isolate->builtins()->CompileLazy(); |
| 1433 info.SetCode(code); | 1399 info.SetCode(code); |
| 1434 // There's no need in theory for a lazy-compiled function to have a type | 1400 // There's no need in theory for a lazy-compiled function to have a type |
| 1435 // feedback vector, but some parts of the system expect all | 1401 // feedback vector, but some parts of the system expect all |
| 1436 // SharedFunctionInfo instances to have one. The size of the vector depends | 1402 // SharedFunctionInfo instances to have one. The size of the vector depends |
| 1437 // on how many feedback-needing nodes are in the tree, and when lazily | 1403 // on how many feedback-needing nodes are in the tree, and when lazily |
| 1438 // parsing we might not know that, if this function was never parsed before. | 1404 // parsing we might not know that, if this function was never parsed before. |
| 1439 // In that case the vector will be replaced the next time MakeCode is | 1405 // In that case the vector will be replaced the next time MakeCode is |
| 1440 // called. | 1406 // called. |
| 1441 info.EnsureFeedbackVector(); | 1407 info.EnsureFeedbackVector(); |
| 1442 scope_info = Handle<ScopeInfo>(ScopeInfo::Empty(isolate)); | 1408 scope_info = Handle<ScopeInfo>(ScopeInfo::Empty(isolate)); |
| 1443 } else if (Renumber(&info) && FullCodeGenerator::MakeCode(&info)) { | 1409 } else if (Renumber(info.parse_info()) && |
| 1410 FullCodeGenerator::MakeCode(&info)) { | |
| 1444 // MakeCode will ensure that the feedback vector is present and | 1411 // MakeCode will ensure that the feedback vector is present and |
| 1445 // appropriately sized. | 1412 // appropriately sized. |
| 1446 DCHECK(!info.code().is_null()); | 1413 DCHECK(!info.code().is_null()); |
| 1447 scope_info = ScopeInfo::Create(info.isolate(), info.zone(), info.scope()); | 1414 scope_info = ScopeInfo::Create(info.isolate(), info.zone(), info.scope()); |
| 1448 } else { | 1415 } else { |
| 1449 return Handle<SharedFunctionInfo>::null(); | 1416 return Handle<SharedFunctionInfo>::null(); |
| 1450 } | 1417 } |
| 1451 | 1418 |
| 1452 // Create a shared function info object. | 1419 // Create a shared function info object. |
| 1453 Handle<SharedFunctionInfo> result = factory->NewSharedFunctionInfo( | 1420 Handle<SharedFunctionInfo> result = factory->NewSharedFunctionInfo( |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1562 DCHECK(job->last_status() != OptimizedCompileJob::SUCCEEDED); | 1529 DCHECK(job->last_status() != OptimizedCompileJob::SUCCEEDED); |
| 1563 if (FLAG_trace_opt) { | 1530 if (FLAG_trace_opt) { |
| 1564 PrintF("[aborted optimizing "); | 1531 PrintF("[aborted optimizing "); |
| 1565 info->closure()->ShortPrint(); | 1532 info->closure()->ShortPrint(); |
| 1566 PrintF(" because: %s]\n", GetBailoutReason(info->bailout_reason())); | 1533 PrintF(" because: %s]\n", GetBailoutReason(info->bailout_reason())); |
| 1567 } | 1534 } |
| 1568 return Handle<Code>::null(); | 1535 return Handle<Code>::null(); |
| 1569 } | 1536 } |
| 1570 | 1537 |
| 1571 | 1538 |
| 1572 bool Compiler::DebuggerWantsEagerCompilation(CompilationInfo* info, | 1539 bool Compiler::DebuggerWantsEagerCompilation(Isolate* isolate, |
| 1573 bool allow_lazy_without_ctx) { | 1540 bool allow_lazy_without_ctx) { |
| 1574 if (LiveEditFunctionTracker::IsActive(info->isolate())) return true; | 1541 if (LiveEditFunctionTracker::IsActive(isolate)) return true; |
| 1575 Debug* debug = info->isolate()->debug(); | 1542 Debug* debug = isolate->debug(); |
| 1576 bool debugging = debug->is_active() || debug->has_break_points(); | 1543 bool debugging = debug->is_active() || debug->has_break_points(); |
| 1577 return debugging && !allow_lazy_without_ctx; | 1544 return debugging && !allow_lazy_without_ctx; |
| 1578 } | 1545 } |
| 1579 | 1546 |
| 1580 | 1547 |
| 1581 CompilationPhase::CompilationPhase(const char* name, CompilationInfo* info) | 1548 CompilationPhase::CompilationPhase(const char* name, CompilationInfo* info) |
| 1582 : name_(name), info_(info) { | 1549 : name_(name), info_(info) { |
| 1583 if (FLAG_hydrogen_stats) { | 1550 if (FLAG_hydrogen_stats) { |
| 1584 info_zone_start_allocation_size_ = info->zone()->allocation_size(); | 1551 info_zone_start_allocation_size_ = info->zone()->allocation_size(); |
| 1585 timer_.Start(); | 1552 timer_.Start(); |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 1602 AllowHandleDereference allow_deref; | 1569 AllowHandleDereference allow_deref; |
| 1603 bool tracing_on = info()->IsStub() | 1570 bool tracing_on = info()->IsStub() |
| 1604 ? FLAG_trace_hydrogen_stubs | 1571 ? FLAG_trace_hydrogen_stubs |
| 1605 : (FLAG_trace_hydrogen && | 1572 : (FLAG_trace_hydrogen && |
| 1606 info()->closure()->PassesFilter(FLAG_trace_hydrogen_filter)); | 1573 info()->closure()->PassesFilter(FLAG_trace_hydrogen_filter)); |
| 1607 return (tracing_on && | 1574 return (tracing_on && |
| 1608 base::OS::StrChr(const_cast<char*>(FLAG_trace_phase), name_[0]) != NULL); | 1575 base::OS::StrChr(const_cast<char*>(FLAG_trace_phase), name_[0]) != NULL); |
| 1609 } | 1576 } |
| 1610 | 1577 |
| 1611 | 1578 |
| 1579 CompilationInfoWithZone::CompilationInfoWithZone(Handle<Script> script) | |
| 1580 : CompilationInfo((new ParseInfo(&zone_))->InitializeFromScript(script)) {} | |
| 1581 | |
| 1582 CompilationInfoWithZone::CompilationInfoWithZone(Handle<JSFunction> function) | |
| 1583 : CompilationInfo( | |
| 1584 (new ParseInfo(&zone_))->InitializeFromJSFunction(function)) {} | |
| 1585 | |
| 1586 CompilationInfoWithZone::CompilationInfoWithZone( | |
| 1587 Handle<SharedFunctionInfo> shared_info) | |
| 1588 : CompilationInfo((new ParseInfo(&zone_)) | |
| 1589 ->InitializeFromSharedFunctionInfo(shared_info)) {} | |
| 1590 | |
| 1591 CompilationInfoWithZone::~CompilationInfoWithZone() { | |
| 1592 RollbackDependencies(); | |
| 1593 if (parse_info()) delete parse_info(); | |
| 1594 } | |
| 1595 | |
| 1612 #if DEBUG | 1596 #if DEBUG |
| 1613 void CompilationInfo::PrintAstForTesting() { | 1597 void CompilationInfo::PrintAstForTesting() { |
| 1614 PrintF("--- Source from AST ---\n%s\n", | 1598 PrintF("--- Source from AST ---\n%s\n", |
| 1615 PrettyPrinter(isolate(), zone()).PrintProgram(function())); | 1599 PrettyPrinter(isolate(), zone()).PrintProgram(function())); |
| 1616 } | 1600 } |
| 1617 #endif | 1601 #endif |
| 1618 } } // namespace v8::internal | 1602 } } // namespace v8::internal |
| OLD | NEW |