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 #ifndef V8_COMPILER_H_ | 5 #ifndef V8_COMPILER_H_ |
6 #define V8_COMPILER_H_ | 6 #define V8_COMPILER_H_ |
7 | 7 |
8 #include "src/allocation.h" | 8 #include "src/allocation.h" |
9 #include "src/ast.h" | 9 #include "src/ast.h" |
10 #include "src/zone.h" | 10 #include "src/zone.h" |
(...skipping 22 matching lines...) Expand all Loading... |
33 public: | 33 public: |
34 ScriptData(const byte* data, int length); | 34 ScriptData(const byte* data, int length); |
35 ~ScriptData() { | 35 ~ScriptData() { |
36 if (owns_data_) DeleteArray(data_); | 36 if (owns_data_) DeleteArray(data_); |
37 } | 37 } |
38 | 38 |
39 const byte* data() const { return data_; } | 39 const byte* data() const { return data_; } |
40 int length() const { return length_; } | 40 int length() const { return length_; } |
41 | 41 |
42 void AcquireDataOwnership() { | 42 void AcquireDataOwnership() { |
43 ASSERT(!owns_data_); | 43 DCHECK(!owns_data_); |
44 owns_data_ = true; | 44 owns_data_ = true; |
45 } | 45 } |
46 | 46 |
47 void ReleaseDataOwnership() { | 47 void ReleaseDataOwnership() { |
48 ASSERT(owns_data_); | 48 DCHECK(owns_data_); |
49 owns_data_ = false; | 49 owns_data_ = false; |
50 } | 50 } |
51 | 51 |
52 private: | 52 private: |
53 bool owns_data_; | 53 bool owns_data_; |
54 const byte* data_; | 54 const byte* data_; |
55 int length_; | 55 int length_; |
56 | 56 |
57 DISALLOW_COPY_AND_ASSIGN(ScriptData); | 57 DISALLOW_COPY_AND_ASSIGN(ScriptData); |
58 }; | 58 }; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
90 } | 90 } |
91 Handle<Context> context() const { return context_; } | 91 Handle<Context> context() const { return context_; } |
92 BailoutId osr_ast_id() const { return osr_ast_id_; } | 92 BailoutId osr_ast_id() const { return osr_ast_id_; } |
93 Handle<Code> unoptimized_code() const { return unoptimized_code_; } | 93 Handle<Code> unoptimized_code() const { return unoptimized_code_; } |
94 int opt_count() const { return opt_count_; } | 94 int opt_count() const { return opt_count_; } |
95 int num_parameters() const; | 95 int num_parameters() const; |
96 int num_heap_slots() const; | 96 int num_heap_slots() const; |
97 Code::Flags flags() const; | 97 Code::Flags flags() const; |
98 | 98 |
99 void MarkAsEval() { | 99 void MarkAsEval() { |
100 ASSERT(!is_lazy()); | 100 DCHECK(!is_lazy()); |
101 flags_ |= IsEval::encode(true); | 101 flags_ |= IsEval::encode(true); |
102 } | 102 } |
103 | 103 |
104 void MarkAsGlobal() { | 104 void MarkAsGlobal() { |
105 ASSERT(!is_lazy()); | 105 DCHECK(!is_lazy()); |
106 flags_ |= IsGlobal::encode(true); | 106 flags_ |= IsGlobal::encode(true); |
107 } | 107 } |
108 | 108 |
109 void set_parameter_count(int parameter_count) { | 109 void set_parameter_count(int parameter_count) { |
110 ASSERT(IsStub()); | 110 DCHECK(IsStub()); |
111 parameter_count_ = parameter_count; | 111 parameter_count_ = parameter_count; |
112 } | 112 } |
113 | 113 |
114 void set_this_has_uses(bool has_no_uses) { | 114 void set_this_has_uses(bool has_no_uses) { |
115 this_has_uses_ = has_no_uses; | 115 this_has_uses_ = has_no_uses; |
116 } | 116 } |
117 | 117 |
118 bool this_has_uses() { | 118 bool this_has_uses() { |
119 return this_has_uses_; | 119 return this_has_uses_; |
120 } | 120 } |
121 | 121 |
122 void SetStrictMode(StrictMode strict_mode) { | 122 void SetStrictMode(StrictMode strict_mode) { |
123 ASSERT(this->strict_mode() == SLOPPY || this->strict_mode() == strict_mode); | 123 DCHECK(this->strict_mode() == SLOPPY || this->strict_mode() == strict_mode); |
124 flags_ = StrictModeField::update(flags_, strict_mode); | 124 flags_ = StrictModeField::update(flags_, strict_mode); |
125 } | 125 } |
126 | 126 |
127 void MarkAsNative() { | 127 void MarkAsNative() { |
128 flags_ |= IsNative::encode(true); | 128 flags_ |= IsNative::encode(true); |
129 } | 129 } |
130 | 130 |
131 bool is_native() const { | 131 bool is_native() const { |
132 return IsNative::decode(flags_); | 132 return IsNative::decode(flags_); |
133 } | 133 } |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
197 | 197 |
198 void SetParseRestriction(ParseRestriction restriction) { | 198 void SetParseRestriction(ParseRestriction restriction) { |
199 flags_ = ParseRestricitonField::update(flags_, restriction); | 199 flags_ = ParseRestricitonField::update(flags_, restriction); |
200 } | 200 } |
201 | 201 |
202 ParseRestriction parse_restriction() const { | 202 ParseRestriction parse_restriction() const { |
203 return ParseRestricitonField::decode(flags_); | 203 return ParseRestricitonField::decode(flags_); |
204 } | 204 } |
205 | 205 |
206 void SetFunction(FunctionLiteral* literal) { | 206 void SetFunction(FunctionLiteral* literal) { |
207 ASSERT(function_ == NULL); | 207 DCHECK(function_ == NULL); |
208 function_ = literal; | 208 function_ = literal; |
209 } | 209 } |
210 void PrepareForCompilation(Scope* scope); | 210 void PrepareForCompilation(Scope* scope); |
211 void SetGlobalScope(Scope* global_scope) { | 211 void SetGlobalScope(Scope* global_scope) { |
212 ASSERT(global_scope_ == NULL); | 212 DCHECK(global_scope_ == NULL); |
213 global_scope_ = global_scope; | 213 global_scope_ = global_scope; |
214 } | 214 } |
215 Handle<FixedArray> feedback_vector() const { | 215 Handle<FixedArray> feedback_vector() const { |
216 return feedback_vector_; | 216 return feedback_vector_; |
217 } | 217 } |
218 void SetCode(Handle<Code> code) { code_ = code; } | 218 void SetCode(Handle<Code> code) { code_ = code; } |
219 void SetExtension(v8::Extension* extension) { | 219 void SetExtension(v8::Extension* extension) { |
220 ASSERT(!is_lazy()); | 220 DCHECK(!is_lazy()); |
221 extension_ = extension; | 221 extension_ = extension; |
222 } | 222 } |
223 void SetCachedData(ScriptData** cached_data, | 223 void SetCachedData(ScriptData** cached_data, |
224 ScriptCompiler::CompileOptions compile_options) { | 224 ScriptCompiler::CompileOptions compile_options) { |
225 compile_options_ = compile_options; | 225 compile_options_ = compile_options; |
226 if (compile_options == ScriptCompiler::kNoCompileOptions) { | 226 if (compile_options == ScriptCompiler::kNoCompileOptions) { |
227 cached_data_ = NULL; | 227 cached_data_ = NULL; |
228 } else { | 228 } else { |
229 ASSERT(!is_lazy()); | 229 DCHECK(!is_lazy()); |
230 cached_data_ = cached_data; | 230 cached_data_ = cached_data; |
231 } | 231 } |
232 } | 232 } |
233 void SetContext(Handle<Context> context) { | 233 void SetContext(Handle<Context> context) { |
234 context_ = context; | 234 context_ = context; |
235 } | 235 } |
236 | 236 |
237 void MarkCompilingForDebugging() { | 237 void MarkCompilingForDebugging() { |
238 flags_ |= IsCompilingForDebugging::encode(true); | 238 flags_ |= IsCompilingForDebugging::encode(true); |
239 } | 239 } |
(...skipping 16 matching lines...) Expand all Loading... |
256 | 256 |
257 GlobalObject* global_object() const { | 257 GlobalObject* global_object() const { |
258 return has_global_object() ? closure()->context()->global_object() : NULL; | 258 return has_global_object() ? closure()->context()->global_object() : NULL; |
259 } | 259 } |
260 | 260 |
261 // Accessors for the different compilation modes. | 261 // Accessors for the different compilation modes. |
262 bool IsOptimizing() const { return mode_ == OPTIMIZE; } | 262 bool IsOptimizing() const { return mode_ == OPTIMIZE; } |
263 bool IsOptimizable() const { return mode_ == BASE; } | 263 bool IsOptimizable() const { return mode_ == BASE; } |
264 bool IsStub() const { return mode_ == STUB; } | 264 bool IsStub() const { return mode_ == STUB; } |
265 void SetOptimizing(BailoutId osr_ast_id, Handle<Code> unoptimized) { | 265 void SetOptimizing(BailoutId osr_ast_id, Handle<Code> unoptimized) { |
266 ASSERT(!shared_info_.is_null()); | 266 DCHECK(!shared_info_.is_null()); |
267 SetMode(OPTIMIZE); | 267 SetMode(OPTIMIZE); |
268 osr_ast_id_ = osr_ast_id; | 268 osr_ast_id_ = osr_ast_id; |
269 unoptimized_code_ = unoptimized; | 269 unoptimized_code_ = unoptimized; |
270 optimization_id_ = isolate()->NextOptimizationId(); | 270 optimization_id_ = isolate()->NextOptimizationId(); |
271 } | 271 } |
272 void DisableOptimization(); | 272 void DisableOptimization(); |
273 | 273 |
274 // Deoptimization support. | 274 // Deoptimization support. |
275 bool HasDeoptimizationSupport() const { | 275 bool HasDeoptimizationSupport() const { |
276 return SupportsDeoptimization::decode(flags_); | 276 return SupportsDeoptimization::decode(flags_); |
277 } | 277 } |
278 void EnableDeoptimizationSupport() { | 278 void EnableDeoptimizationSupport() { |
279 ASSERT(IsOptimizable()); | 279 DCHECK(IsOptimizable()); |
280 flags_ |= SupportsDeoptimization::encode(true); | 280 flags_ |= SupportsDeoptimization::encode(true); |
281 } | 281 } |
282 | 282 |
283 // Determines whether or not to insert a self-optimization header. | 283 // Determines whether or not to insert a self-optimization header. |
284 bool ShouldSelfOptimize(); | 284 bool ShouldSelfOptimize(); |
285 | 285 |
286 void set_deferred_handles(DeferredHandles* deferred_handles) { | 286 void set_deferred_handles(DeferredHandles* deferred_handles) { |
287 ASSERT(deferred_handles_ == NULL); | 287 DCHECK(deferred_handles_ == NULL); |
288 deferred_handles_ = deferred_handles; | 288 deferred_handles_ = deferred_handles; |
289 } | 289 } |
290 | 290 |
291 ZoneList<Handle<HeapObject> >* dependencies( | 291 ZoneList<Handle<HeapObject> >* dependencies( |
292 DependentCode::DependencyGroup group) { | 292 DependentCode::DependencyGroup group) { |
293 if (dependencies_[group] == NULL) { | 293 if (dependencies_[group] == NULL) { |
294 dependencies_[group] = new(zone_) ZoneList<Handle<HeapObject> >(2, zone_); | 294 dependencies_[group] = new(zone_) ZoneList<Handle<HeapObject> >(2, zone_); |
295 } | 295 } |
296 return dependencies_[group]; | 296 return dependencies_[group]; |
297 } | 297 } |
298 | 298 |
299 void CommitDependencies(Handle<Code> code); | 299 void CommitDependencies(Handle<Code> code); |
300 | 300 |
301 void RollbackDependencies(); | 301 void RollbackDependencies(); |
302 | 302 |
303 void SaveHandles() { | 303 void SaveHandles() { |
304 SaveHandle(&closure_); | 304 SaveHandle(&closure_); |
305 SaveHandle(&shared_info_); | 305 SaveHandle(&shared_info_); |
306 SaveHandle(&context_); | 306 SaveHandle(&context_); |
307 SaveHandle(&script_); | 307 SaveHandle(&script_); |
308 SaveHandle(&unoptimized_code_); | 308 SaveHandle(&unoptimized_code_); |
309 } | 309 } |
310 | 310 |
311 BailoutReason bailout_reason() const { return bailout_reason_; } | 311 BailoutReason bailout_reason() const { return bailout_reason_; } |
312 void set_bailout_reason(BailoutReason reason) { bailout_reason_ = reason; } | 312 void set_bailout_reason(BailoutReason reason) { bailout_reason_ = reason; } |
313 | 313 |
314 int prologue_offset() const { | 314 int prologue_offset() const { |
315 ASSERT_NE(Code::kPrologueOffsetNotSet, prologue_offset_); | 315 DCHECK_NE(Code::kPrologueOffsetNotSet, prologue_offset_); |
316 return prologue_offset_; | 316 return prologue_offset_; |
317 } | 317 } |
318 | 318 |
319 void set_prologue_offset(int prologue_offset) { | 319 void set_prologue_offset(int prologue_offset) { |
320 ASSERT_EQ(Code::kPrologueOffsetNotSet, prologue_offset_); | 320 DCHECK_EQ(Code::kPrologueOffsetNotSet, prologue_offset_); |
321 prologue_offset_ = prologue_offset; | 321 prologue_offset_ = prologue_offset; |
322 } | 322 } |
323 | 323 |
324 // Adds offset range [from, to) where fp register does not point | 324 // Adds offset range [from, to) where fp register does not point |
325 // to the current frame base. Used in CPU profiler to detect stack | 325 // to the current frame base. Used in CPU profiler to detect stack |
326 // samples where top frame is not set up. | 326 // samples where top frame is not set up. |
327 inline void AddNoFrameRange(int from, int to) { | 327 inline void AddNoFrameRange(int from, int to) { |
328 if (no_frame_ranges_) no_frame_ranges_->Add(OffsetRange(from, to)); | 328 if (no_frame_ranges_) no_frame_ranges_->Add(OffsetRange(from, to)); |
329 } | 329 } |
330 | 330 |
331 List<OffsetRange>* ReleaseNoFrameRanges() { | 331 List<OffsetRange>* ReleaseNoFrameRanges() { |
332 List<OffsetRange>* result = no_frame_ranges_; | 332 List<OffsetRange>* result = no_frame_ranges_; |
333 no_frame_ranges_ = NULL; | 333 no_frame_ranges_ = NULL; |
334 return result; | 334 return result; |
335 } | 335 } |
336 | 336 |
337 Handle<Foreign> object_wrapper() { | 337 Handle<Foreign> object_wrapper() { |
338 if (object_wrapper_.is_null()) { | 338 if (object_wrapper_.is_null()) { |
339 object_wrapper_ = | 339 object_wrapper_ = |
340 isolate()->factory()->NewForeign(reinterpret_cast<Address>(this)); | 340 isolate()->factory()->NewForeign(reinterpret_cast<Address>(this)); |
341 } | 341 } |
342 return object_wrapper_; | 342 return object_wrapper_; |
343 } | 343 } |
344 | 344 |
345 void AbortDueToDependencyChange() { | 345 void AbortDueToDependencyChange() { |
346 ASSERT(!OptimizingCompilerThread::IsOptimizerThread(isolate())); | 346 DCHECK(!OptimizingCompilerThread::IsOptimizerThread(isolate())); |
347 abort_due_to_dependency_ = true; | 347 abort_due_to_dependency_ = true; |
348 } | 348 } |
349 | 349 |
350 bool HasAbortedDueToDependencyChange() { | 350 bool HasAbortedDueToDependencyChange() { |
351 ASSERT(!OptimizingCompilerThread::IsOptimizerThread(isolate())); | 351 DCHECK(!OptimizingCompilerThread::IsOptimizerThread(isolate())); |
352 return abort_due_to_dependency_; | 352 return abort_due_to_dependency_; |
353 } | 353 } |
354 | 354 |
355 bool HasSameOsrEntry(Handle<JSFunction> function, BailoutId osr_ast_id) { | 355 bool HasSameOsrEntry(Handle<JSFunction> function, BailoutId osr_ast_id) { |
356 return osr_ast_id_ == osr_ast_id && function.is_identical_to(closure_); | 356 return osr_ast_id_ == osr_ast_id && function.is_identical_to(closure_); |
357 } | 357 } |
358 | 358 |
359 int optimization_id() const { return optimization_id_; } | 359 int optimization_id() const { return optimization_id_; } |
360 | 360 |
361 AstValueFactory* ast_value_factory() const { return ast_value_factory_; } | 361 AstValueFactory* ast_value_factory() const { return ast_value_factory_; } |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
603 MUST_USE_RESULT Status AbortAndDisableOptimization( | 603 MUST_USE_RESULT Status AbortAndDisableOptimization( |
604 BailoutReason reason = kNoReason) { | 604 BailoutReason reason = kNoReason) { |
605 if (reason != kNoReason) info_->set_bailout_reason(reason); | 605 if (reason != kNoReason) info_->set_bailout_reason(reason); |
606 // Reference to shared function info does not change between phases. | 606 // Reference to shared function info does not change between phases. |
607 AllowDeferredHandleDereference allow_handle_dereference; | 607 AllowDeferredHandleDereference allow_handle_dereference; |
608 info_->shared_info()->DisableOptimization(info_->bailout_reason()); | 608 info_->shared_info()->DisableOptimization(info_->bailout_reason()); |
609 return SetLastStatus(BAILED_OUT); | 609 return SetLastStatus(BAILED_OUT); |
610 } | 610 } |
611 | 611 |
612 void WaitForInstall() { | 612 void WaitForInstall() { |
613 ASSERT(info_->is_osr()); | 613 DCHECK(info_->is_osr()); |
614 awaiting_install_ = true; | 614 awaiting_install_ = true; |
615 } | 615 } |
616 | 616 |
617 bool IsWaitingForInstall() { return awaiting_install_; } | 617 bool IsWaitingForInstall() { return awaiting_install_; } |
618 | 618 |
619 private: | 619 private: |
620 CompilationInfo* info_; | 620 CompilationInfo* info_; |
621 HOptimizedGraphBuilder* graph_builder_; | 621 HOptimizedGraphBuilder* graph_builder_; |
622 HGraph* graph_; | 622 HGraph* graph_; |
623 LChunk* chunk_; | 623 LChunk* chunk_; |
624 base::TimeDelta time_taken_to_create_graph_; | 624 base::TimeDelta time_taken_to_create_graph_; |
625 base::TimeDelta time_taken_to_optimize_; | 625 base::TimeDelta time_taken_to_optimize_; |
626 base::TimeDelta time_taken_to_codegen_; | 626 base::TimeDelta time_taken_to_codegen_; |
627 Status last_status_; | 627 Status last_status_; |
628 bool awaiting_install_; | 628 bool awaiting_install_; |
629 | 629 |
630 MUST_USE_RESULT Status SetLastStatus(Status status) { | 630 MUST_USE_RESULT Status SetLastStatus(Status status) { |
631 last_status_ = status; | 631 last_status_ = status; |
632 return last_status_; | 632 return last_status_; |
633 } | 633 } |
634 void RecordOptimizationStats(); | 634 void RecordOptimizationStats(); |
635 | 635 |
636 struct Timer { | 636 struct Timer { |
637 Timer(OptimizedCompileJob* job, base::TimeDelta* location) | 637 Timer(OptimizedCompileJob* job, base::TimeDelta* location) |
638 : job_(job), location_(location) { | 638 : job_(job), location_(location) { |
639 ASSERT(location_ != NULL); | 639 DCHECK(location_ != NULL); |
640 timer_.Start(); | 640 timer_.Start(); |
641 } | 641 } |
642 | 642 |
643 ~Timer() { | 643 ~Timer() { |
644 *location_ += timer_.Elapsed(); | 644 *location_ += timer_.Elapsed(); |
645 } | 645 } |
646 | 646 |
647 OptimizedCompileJob* job_; | 647 OptimizedCompileJob* job_; |
648 base::ElapsedTimer timer_; | 648 base::ElapsedTimer timer_; |
649 base::TimeDelta* location_; | 649 base::TimeDelta* location_; |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
736 Zone zone_; | 736 Zone zone_; |
737 unsigned info_zone_start_allocation_size_; | 737 unsigned info_zone_start_allocation_size_; |
738 base::ElapsedTimer timer_; | 738 base::ElapsedTimer timer_; |
739 | 739 |
740 DISALLOW_COPY_AND_ASSIGN(CompilationPhase); | 740 DISALLOW_COPY_AND_ASSIGN(CompilationPhase); |
741 }; | 741 }; |
742 | 742 |
743 } } // namespace v8::internal | 743 } } // namespace v8::internal |
744 | 744 |
745 #endif // V8_COMPILER_H_ | 745 #endif // V8_COMPILER_H_ |
OLD | NEW |