| 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/bailout-reason.h" | 10 #include "src/bailout-reason.h" |
| 11 #include "src/zone.h" | 11 #include "src/zone.h" |
| 12 | 12 |
| 13 namespace v8 { | 13 namespace v8 { |
| 14 namespace internal { | 14 namespace internal { |
| 15 | 15 |
| 16 class AstValueFactory; | 16 class AstValueFactory; |
| 17 class HydrogenCodeStub; | 17 class HydrogenCodeStub; |
| 18 | 18 class ParseInfo; |
| 19 // ParseRestriction is used to restrict the set of valid statements in a | 19 class ScriptData; |
| 20 // unit of compilation. Restriction violations cause a syntax error. | |
| 21 enum ParseRestriction { | |
| 22 NO_PARSE_RESTRICTION, // All expressions are allowed. | |
| 23 ONLY_SINGLE_FUNCTION_LITERAL // Only a single FunctionLiteral expression. | |
| 24 }; | |
| 25 | 20 |
| 26 struct OffsetRange { | 21 struct OffsetRange { |
| 27 OffsetRange(int from, int to) : from(from), to(to) {} | 22 OffsetRange(int from, int to) : from(from), to(to) {} |
| 28 int from; | 23 int from; |
| 29 int to; | 24 int to; |
| 30 }; | 25 }; |
| 31 | 26 |
| 32 | 27 |
| 33 // This class encapsulates encoding and decoding of sources positions from | 28 // This class encapsulates encoding and decoding of sources positions from |
| 34 // which hydrogen values originated. | 29 // which hydrogen values originated. |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 98 | 93 |
| 99 Handle<SharedFunctionInfo> shared() const { return shared_; } | 94 Handle<SharedFunctionInfo> shared() const { return shared_; } |
| 100 int start_position() const { return start_position_; } | 95 int start_position() const { return start_position_; } |
| 101 | 96 |
| 102 private: | 97 private: |
| 103 Handle<SharedFunctionInfo> shared_; | 98 Handle<SharedFunctionInfo> shared_; |
| 104 int start_position_; | 99 int start_position_; |
| 105 }; | 100 }; |
| 106 | 101 |
| 107 | 102 |
| 108 class ScriptData { | |
| 109 public: | |
| 110 ScriptData(const byte* data, int length); | |
| 111 ~ScriptData() { | |
| 112 if (owns_data_) DeleteArray(data_); | |
| 113 } | |
| 114 | |
| 115 const byte* data() const { return data_; } | |
| 116 int length() const { return length_; } | |
| 117 bool rejected() const { return rejected_; } | |
| 118 | |
| 119 void Reject() { rejected_ = true; } | |
| 120 | |
| 121 void AcquireDataOwnership() { | |
| 122 DCHECK(!owns_data_); | |
| 123 owns_data_ = true; | |
| 124 } | |
| 125 | |
| 126 void ReleaseDataOwnership() { | |
| 127 DCHECK(owns_data_); | |
| 128 owns_data_ = false; | |
| 129 } | |
| 130 | |
| 131 private: | |
| 132 bool owns_data_ : 1; | |
| 133 bool rejected_ : 1; | |
| 134 const byte* data_; | |
| 135 int length_; | |
| 136 | |
| 137 DISALLOW_COPY_AND_ASSIGN(ScriptData); | |
| 138 }; | |
| 139 | |
| 140 // CompilationInfo encapsulates some information known at compile time. It | 103 // CompilationInfo encapsulates some information known at compile time. It |
| 141 // is constructed based on the resources available at compile-time. | 104 // is constructed based on the resources available at compile-time. |
| 142 class CompilationInfo { | 105 class CompilationInfo { |
| 143 public: | 106 public: |
| 144 // Various configuration flags for a compilation, as well as some properties | 107 // Various configuration flags for a compilation, as well as some properties |
| 145 // of the compiled code produced by a compilation. | 108 // of the compiled code produced by a compilation. |
| 146 enum Flag { | 109 enum Flag { |
| 147 kLazy = 1 << 0, | |
| 148 kEval = 1 << 1, | |
| 149 kGlobal = 1 << 2, | |
| 150 kStrictMode = 1 << 3, | |
| 151 kStrongMode = 1 << 4, | |
| 152 kThisHasUses = 1 << 5, | |
| 153 kNative = 1 << 6, | |
| 154 kDeferredCalling = 1 << 7, | 110 kDeferredCalling = 1 << 7, |
| 155 kNonDeferredCalling = 1 << 8, | 111 kNonDeferredCalling = 1 << 8, |
| 156 kSavesCallerDoubles = 1 << 9, | 112 kSavesCallerDoubles = 1 << 9, |
| 157 kRequiresFrame = 1 << 10, | 113 kRequiresFrame = 1 << 10, |
| 158 kMustNotHaveEagerFrame = 1 << 11, | 114 kMustNotHaveEagerFrame = 1 << 11, |
| 159 kDeoptimizationSupport = 1 << 12, | 115 kDeoptimizationSupport = 1 << 12, |
| 160 kDebug = 1 << 13, | 116 kDebug = 1 << 13, |
| 161 kCompilingForDebugging = 1 << 14, | 117 kCompilingForDebugging = 1 << 14, |
| 162 kParseRestriction = 1 << 15, | |
| 163 kSerializing = 1 << 16, | 118 kSerializing = 1 << 16, |
| 164 kContextSpecializing = 1 << 17, | 119 kContextSpecializing = 1 << 17, |
| 165 kInliningEnabled = 1 << 18, | 120 kInliningEnabled = 1 << 18, |
| 166 kTypingEnabled = 1 << 19, | 121 kTypingEnabled = 1 << 19, |
| 167 kDisableFutureOptimization = 1 << 20, | 122 kDisableFutureOptimization = 1 << 20, |
| 168 kModule = 1 << 21, | |
| 169 kToplevel = 1 << 22, | |
| 170 kSplittingEnabled = 1 << 23 | 123 kSplittingEnabled = 1 << 23 |
| 171 }; | 124 }; |
| 172 | 125 |
| 173 CompilationInfo(Handle<JSFunction> closure, Zone* zone); | 126 explicit CompilationInfo(ParseInfo* parse_info); |
| 174 CompilationInfo(Handle<Script> script, Zone* zone); | |
| 175 CompilationInfo(CodeStub* stub, Isolate* isolate, Zone* zone); | 127 CompilationInfo(CodeStub* stub, Isolate* isolate, Zone* zone); |
| 176 virtual ~CompilationInfo(); | 128 virtual ~CompilationInfo(); |
| 177 | 129 |
| 130 ParseInfo* parse_info() const { return parse_info_; } |
| 131 |
| 132 // ----------------------------------------------------------- |
| 133 // TODO(titzer): inline and delete accessors of ParseInfo |
| 134 // ----------------------------------------------------------- |
| 135 Handle<Script> script() const; |
| 136 bool is_eval() const; |
| 137 bool is_native() const; |
| 138 bool is_module() const; |
| 139 bool this_has_uses() const; |
| 140 LanguageMode language_mode() const; |
| 141 Handle<JSFunction> closure() const; |
| 142 FunctionLiteral* function() const; |
| 143 Scope* scope() const; |
| 144 Handle<Context> context() const; |
| 145 Handle<SharedFunctionInfo> shared_info() const; |
| 146 bool has_shared_info() const; |
| 147 // ----------------------------------------------------------- |
| 148 |
| 178 Isolate* isolate() const { | 149 Isolate* isolate() const { |
| 179 return isolate_; | 150 return isolate_; |
| 180 } | 151 } |
| 181 Zone* zone() { return zone_; } | 152 Zone* zone() { return zone_; } |
| 182 bool is_osr() const { return !osr_ast_id_.IsNone(); } | 153 bool is_osr() const { return !osr_ast_id_.IsNone(); } |
| 183 bool is_lazy() const { return GetFlag(kLazy); } | |
| 184 bool is_eval() const { return GetFlag(kEval); } | |
| 185 bool is_global() const { return GetFlag(kGlobal); } | |
| 186 bool is_module() const { return GetFlag(kModule); } | |
| 187 LanguageMode language_mode() const { | |
| 188 STATIC_ASSERT(LANGUAGE_END == 3); | |
| 189 return construct_language_mode(GetFlag(kStrictMode), GetFlag(kStrongMode)); | |
| 190 } | |
| 191 FunctionLiteral* function() const { return function_; } | |
| 192 Scope* scope() const { return scope_; } | |
| 193 Scope* script_scope() const { return script_scope_; } | |
| 194 Handle<Code> code() const { return code_; } | 154 Handle<Code> code() const { return code_; } |
| 195 Handle<JSFunction> closure() const { return closure_; } | |
| 196 Handle<SharedFunctionInfo> shared_info() const { return shared_info_; } | |
| 197 Handle<Script> script() const { return script_; } | |
| 198 void set_script(Handle<Script> script) { script_ = script; } | |
| 199 CodeStub* code_stub() const { return code_stub_; } | 155 CodeStub* code_stub() const { return code_stub_; } |
| 200 v8::Extension* extension() const { return extension_; } | |
| 201 ScriptData** cached_data() const { return cached_data_; } | |
| 202 ScriptCompiler::CompileOptions compile_options() const { | |
| 203 return compile_options_; | |
| 204 } | |
| 205 ScriptCompiler::ExternalSourceStream* source_stream() const { | |
| 206 return source_stream_; | |
| 207 } | |
| 208 ScriptCompiler::StreamedSource::Encoding source_stream_encoding() const { | |
| 209 return source_stream_encoding_; | |
| 210 } | |
| 211 Handle<Context> context() const { return context_; } | |
| 212 BailoutId osr_ast_id() const { return osr_ast_id_; } | 156 BailoutId osr_ast_id() const { return osr_ast_id_; } |
| 213 Handle<Code> unoptimized_code() const { return unoptimized_code_; } | 157 Handle<Code> unoptimized_code() const { return unoptimized_code_; } |
| 214 int opt_count() const { return opt_count_; } | 158 int opt_count() const { return opt_count_; } |
| 215 int num_parameters() const; | 159 int num_parameters() const; |
| 216 int num_heap_slots() const; | 160 int num_heap_slots() const; |
| 217 Code::Flags flags() const; | 161 Code::Flags flags() const; |
| 218 | 162 |
| 219 void MarkAsEval() { | |
| 220 DCHECK(!is_lazy()); | |
| 221 SetFlag(kEval); | |
| 222 } | |
| 223 | |
| 224 void MarkAsGlobal() { | |
| 225 DCHECK(!is_lazy()); | |
| 226 SetFlag(kGlobal); | |
| 227 } | |
| 228 | |
| 229 void MarkAsModule() { | |
| 230 DCHECK(!is_lazy()); | |
| 231 SetFlag(kModule); | |
| 232 } | |
| 233 | |
| 234 void set_parameter_count(int parameter_count) { | 163 void set_parameter_count(int parameter_count) { |
| 235 DCHECK(IsStub()); | 164 DCHECK(IsStub()); |
| 236 parameter_count_ = parameter_count; | 165 parameter_count_ = parameter_count; |
| 237 } | 166 } |
| 238 | 167 |
| 239 void set_this_has_uses(bool has_no_uses) { | |
| 240 SetFlag(kThisHasUses, has_no_uses); | |
| 241 } | |
| 242 | |
| 243 bool this_has_uses() { return GetFlag(kThisHasUses); } | |
| 244 | |
| 245 void SetLanguageMode(LanguageMode language_mode) { | |
| 246 STATIC_ASSERT(LANGUAGE_END == 3); | |
| 247 SetFlag(kStrictMode, language_mode & STRICT_BIT); | |
| 248 SetFlag(kStrongMode, language_mode & STRONG_BIT); | |
| 249 } | |
| 250 | |
| 251 void MarkAsNative() { SetFlag(kNative); } | |
| 252 | |
| 253 bool is_native() const { return GetFlag(kNative); } | |
| 254 | |
| 255 bool is_calling() const { | 168 bool is_calling() const { |
| 256 return GetFlag(kDeferredCalling) || GetFlag(kNonDeferredCalling); | 169 return GetFlag(kDeferredCalling) || GetFlag(kNonDeferredCalling); |
| 257 } | 170 } |
| 258 | 171 |
| 259 void MarkAsDeferredCalling() { SetFlag(kDeferredCalling); } | 172 void MarkAsDeferredCalling() { SetFlag(kDeferredCalling); } |
| 260 | 173 |
| 261 bool is_deferred_calling() const { return GetFlag(kDeferredCalling); } | 174 bool is_deferred_calling() const { return GetFlag(kDeferredCalling); } |
| 262 | 175 |
| 263 void MarkAsNonDeferredCalling() { SetFlag(kNonDeferredCalling); } | 176 void MarkAsNonDeferredCalling() { SetFlag(kNonDeferredCalling); } |
| 264 | 177 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 291 bool is_context_specializing() const { return GetFlag(kContextSpecializing); } | 204 bool is_context_specializing() const { return GetFlag(kContextSpecializing); } |
| 292 | 205 |
| 293 void MarkAsInliningEnabled() { SetFlag(kInliningEnabled); } | 206 void MarkAsInliningEnabled() { SetFlag(kInliningEnabled); } |
| 294 | 207 |
| 295 bool is_inlining_enabled() const { return GetFlag(kInliningEnabled); } | 208 bool is_inlining_enabled() const { return GetFlag(kInliningEnabled); } |
| 296 | 209 |
| 297 void MarkAsTypingEnabled() { SetFlag(kTypingEnabled); } | 210 void MarkAsTypingEnabled() { SetFlag(kTypingEnabled); } |
| 298 | 211 |
| 299 bool is_typing_enabled() const { return GetFlag(kTypingEnabled); } | 212 bool is_typing_enabled() const { return GetFlag(kTypingEnabled); } |
| 300 | 213 |
| 301 void MarkAsToplevel() { SetFlag(kToplevel); } | |
| 302 | |
| 303 bool is_toplevel() const { return GetFlag(kToplevel); } | |
| 304 | |
| 305 void MarkAsSplittingEnabled() { SetFlag(kSplittingEnabled); } | 214 void MarkAsSplittingEnabled() { SetFlag(kSplittingEnabled); } |
| 306 | 215 |
| 307 bool is_splitting_enabled() const { return GetFlag(kSplittingEnabled); } | 216 bool is_splitting_enabled() const { return GetFlag(kSplittingEnabled); } |
| 308 | 217 |
| 309 bool IsCodePreAgingActive() const { | 218 bool IsCodePreAgingActive() const { |
| 310 return FLAG_optimize_for_size && FLAG_age_code && !will_serialize() && | 219 return FLAG_optimize_for_size && FLAG_age_code && !will_serialize() && |
| 311 !is_debug(); | 220 !is_debug(); |
| 312 } | 221 } |
| 313 | 222 |
| 314 void SetParseRestriction(ParseRestriction restriction) { | |
| 315 SetFlag(kParseRestriction, restriction != NO_PARSE_RESTRICTION); | |
| 316 } | |
| 317 | |
| 318 ParseRestriction parse_restriction() const { | |
| 319 return GetFlag(kParseRestriction) ? ONLY_SINGLE_FUNCTION_LITERAL | |
| 320 : NO_PARSE_RESTRICTION; | |
| 321 } | |
| 322 | |
| 323 void SetFunction(FunctionLiteral* literal) { | |
| 324 DCHECK(function_ == NULL); | |
| 325 function_ = literal; | |
| 326 } | |
| 327 void PrepareForCompilation(Scope* scope); | |
| 328 void SetScriptScope(Scope* script_scope) { | |
| 329 DCHECK(script_scope_ == NULL); | |
| 330 script_scope_ = script_scope; | |
| 331 } | |
| 332 void EnsureFeedbackVector(); | 223 void EnsureFeedbackVector(); |
| 333 Handle<TypeFeedbackVector> feedback_vector() const { | 224 Handle<TypeFeedbackVector> feedback_vector() const { |
| 334 return feedback_vector_; | 225 return feedback_vector_; |
| 335 } | 226 } |
| 336 void SetCode(Handle<Code> code) { code_ = code; } | 227 void SetCode(Handle<Code> code) { code_ = code; } |
| 337 void SetExtension(v8::Extension* extension) { | |
| 338 DCHECK(!is_lazy()); | |
| 339 extension_ = extension; | |
| 340 } | |
| 341 void SetCachedData(ScriptData** cached_data, | |
| 342 ScriptCompiler::CompileOptions compile_options) { | |
| 343 compile_options_ = compile_options; | |
| 344 if (compile_options == ScriptCompiler::kNoCompileOptions) { | |
| 345 cached_data_ = NULL; | |
| 346 } else { | |
| 347 DCHECK(!is_lazy()); | |
| 348 cached_data_ = cached_data; | |
| 349 } | |
| 350 } | |
| 351 void SetContext(Handle<Context> context) { | |
| 352 context_ = context; | |
| 353 } | |
| 354 | 228 |
| 355 void MarkCompilingForDebugging() { SetFlag(kCompilingForDebugging); } | 229 void MarkCompilingForDebugging() { SetFlag(kCompilingForDebugging); } |
| 356 bool IsCompilingForDebugging() { return GetFlag(kCompilingForDebugging); } | 230 bool IsCompilingForDebugging() { return GetFlag(kCompilingForDebugging); } |
| 357 void MarkNonOptimizable() { | 231 void MarkNonOptimizable() { |
| 358 SetMode(CompilationInfo::NONOPT); | 232 SetMode(CompilationInfo::NONOPT); |
| 359 } | 233 } |
| 360 | 234 |
| 361 bool ShouldTrapOnDeopt() const { | 235 bool ShouldTrapOnDeopt() const { |
| 362 return (FLAG_trap_on_deopt && IsOptimizing()) || | 236 return (FLAG_trap_on_deopt && IsOptimizing()) || |
| 363 (FLAG_trap_on_stub_deopt && IsStub()); | 237 (FLAG_trap_on_stub_deopt && IsStub()); |
| 364 } | 238 } |
| 365 | 239 |
| 366 bool has_global_object() const { | 240 bool has_global_object() const { |
| 367 return !closure().is_null() && | 241 return !closure().is_null() && |
| 368 (closure()->context()->global_object() != NULL); | 242 (closure()->context()->global_object() != NULL); |
| 369 } | 243 } |
| 370 | 244 |
| 371 GlobalObject* global_object() const { | 245 GlobalObject* global_object() const { |
| 372 return has_global_object() ? closure()->context()->global_object() : NULL; | 246 return has_global_object() ? closure()->context()->global_object() : NULL; |
| 373 } | 247 } |
| 374 | 248 |
| 375 // Accessors for the different compilation modes. | 249 // Accessors for the different compilation modes. |
| 376 bool IsOptimizing() const { return mode_ == OPTIMIZE; } | 250 bool IsOptimizing() const { return mode_ == OPTIMIZE; } |
| 377 bool IsOptimizable() const { return mode_ == BASE; } | 251 bool IsOptimizable() const { return mode_ == BASE; } |
| 378 bool IsStub() const { return mode_ == STUB; } | 252 bool IsStub() const { return mode_ == STUB; } |
| 379 void SetOptimizing(BailoutId osr_ast_id, Handle<Code> unoptimized) { | 253 void SetOptimizing(BailoutId osr_ast_id, Handle<Code> unoptimized) { |
| 380 DCHECK(!shared_info_.is_null()); | 254 DCHECK(!shared_info().is_null()); |
| 381 SetMode(OPTIMIZE); | 255 SetMode(OPTIMIZE); |
| 382 osr_ast_id_ = osr_ast_id; | 256 osr_ast_id_ = osr_ast_id; |
| 383 unoptimized_code_ = unoptimized; | 257 unoptimized_code_ = unoptimized; |
| 384 optimization_id_ = isolate()->NextOptimizationId(); | 258 optimization_id_ = isolate()->NextOptimizationId(); |
| 385 } | 259 } |
| 386 | 260 |
| 387 // Deoptimization support. | 261 // Deoptimization support. |
| 388 bool HasDeoptimizationSupport() const { | 262 bool HasDeoptimizationSupport() const { |
| 389 return GetFlag(kDeoptimizationSupport); | 263 return GetFlag(kDeoptimizationSupport); |
| 390 } | 264 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 406 if (dependencies_[group] == NULL) { | 280 if (dependencies_[group] == NULL) { |
| 407 dependencies_[group] = new(zone_) ZoneList<Handle<HeapObject> >(2, zone_); | 281 dependencies_[group] = new(zone_) ZoneList<Handle<HeapObject> >(2, zone_); |
| 408 } | 282 } |
| 409 return dependencies_[group]; | 283 return dependencies_[group]; |
| 410 } | 284 } |
| 411 | 285 |
| 412 void CommitDependencies(Handle<Code> code); | 286 void CommitDependencies(Handle<Code> code); |
| 413 | 287 |
| 414 void RollbackDependencies(); | 288 void RollbackDependencies(); |
| 415 | 289 |
| 416 void SaveHandles() { | 290 void ReopenHandlesInNewHandleScope() { |
| 417 SaveHandle(&closure_); | 291 unoptimized_code_ = Handle<Code>(*unoptimized_code_); |
| 418 SaveHandle(&shared_info_); | |
| 419 SaveHandle(&context_); | |
| 420 SaveHandle(&script_); | |
| 421 SaveHandle(&unoptimized_code_); | |
| 422 } | 292 } |
| 423 | 293 |
| 424 void AbortOptimization(BailoutReason reason) { | 294 void AbortOptimization(BailoutReason reason) { |
| 425 DCHECK(reason != kNoReason); | 295 DCHECK(reason != kNoReason); |
| 426 if (bailout_reason_ == kNoReason) bailout_reason_ = reason; | 296 if (bailout_reason_ == kNoReason) bailout_reason_ = reason; |
| 427 SetFlag(kDisableFutureOptimization); | 297 SetFlag(kDisableFutureOptimization); |
| 428 } | 298 } |
| 429 | 299 |
| 430 void RetryOptimization(BailoutReason reason) { | 300 void RetryOptimization(BailoutReason reason) { |
| 431 DCHECK(reason != kNoReason); | 301 DCHECK(reason != kNoReason); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 479 DCHECK(!OptimizingCompilerThread::IsOptimizerThread(isolate())); | 349 DCHECK(!OptimizingCompilerThread::IsOptimizerThread(isolate())); |
| 480 aborted_due_to_dependency_change_ = true; | 350 aborted_due_to_dependency_change_ = true; |
| 481 } | 351 } |
| 482 | 352 |
| 483 bool HasAbortedDueToDependencyChange() const { | 353 bool HasAbortedDueToDependencyChange() const { |
| 484 DCHECK(!OptimizingCompilerThread::IsOptimizerThread(isolate())); | 354 DCHECK(!OptimizingCompilerThread::IsOptimizerThread(isolate())); |
| 485 return aborted_due_to_dependency_change_; | 355 return aborted_due_to_dependency_change_; |
| 486 } | 356 } |
| 487 | 357 |
| 488 bool HasSameOsrEntry(Handle<JSFunction> function, BailoutId osr_ast_id) { | 358 bool HasSameOsrEntry(Handle<JSFunction> function, BailoutId osr_ast_id) { |
| 489 return osr_ast_id_ == osr_ast_id && function.is_identical_to(closure_); | 359 return osr_ast_id_ == osr_ast_id && function.is_identical_to(closure()); |
| 490 } | 360 } |
| 491 | 361 |
| 492 int optimization_id() const { return optimization_id_; } | 362 int optimization_id() const { return optimization_id_; } |
| 493 | 363 |
| 494 AstValueFactory* ast_value_factory() const { return ast_value_factory_; } | |
| 495 void SetAstValueFactory(AstValueFactory* ast_value_factory, | |
| 496 bool owned = true) { | |
| 497 ast_value_factory_ = ast_value_factory; | |
| 498 ast_value_factory_owned_ = owned; | |
| 499 } | |
| 500 | |
| 501 int osr_expr_stack_height() { return osr_expr_stack_height_; } | 364 int osr_expr_stack_height() { return osr_expr_stack_height_; } |
| 502 void set_osr_expr_stack_height(int height) { | 365 void set_osr_expr_stack_height(int height) { |
| 503 DCHECK(height >= 0); | 366 DCHECK(height >= 0); |
| 504 osr_expr_stack_height_ = height; | 367 osr_expr_stack_height_ = height; |
| 505 } | 368 } |
| 506 | 369 |
| 507 #if DEBUG | 370 #if DEBUG |
| 508 void PrintAstForTesting(); | 371 void PrintAstForTesting(); |
| 509 #endif | 372 #endif |
| 510 | 373 |
| 511 bool is_simple_parameter_list(); | 374 bool is_simple_parameter_list(); |
| 512 | 375 |
| 513 protected: | 376 protected: |
| 514 CompilationInfo(Handle<SharedFunctionInfo> shared_info, | 377 ParseInfo* parse_info_; |
| 515 Zone* zone); | |
| 516 CompilationInfo(ScriptCompiler::ExternalSourceStream* source_stream, | |
| 517 ScriptCompiler::StreamedSource::Encoding encoding, | |
| 518 Isolate* isolate, Zone* zone); | |
| 519 | 378 |
| 379 void DisableFutureOptimization() { |
| 380 if (GetFlag(kDisableFutureOptimization) && has_shared_info()) { |
| 381 shared_info()->DisableOptimization(bailout_reason()); |
| 382 } |
| 383 } |
| 520 | 384 |
| 521 private: | 385 private: |
| 522 Isolate* isolate_; | 386 Isolate* isolate_; |
| 523 | 387 |
| 524 // Compilation mode. | 388 // Compilation mode. |
| 525 // BASE is generated by the full codegen, optionally prepared for bailouts. | 389 // BASE is generated by the full codegen, optionally prepared for bailouts. |
| 526 // OPTIMIZE is optimized code generated by the Hydrogen-based backend. | 390 // OPTIMIZE is optimized code generated by the Hydrogen-based backend. |
| 527 // NONOPT is generated by the full codegen and is not prepared for | 391 // NONOPT is generated by the full codegen and is not prepared for |
| 528 // recompilation/bailouts. These functions are never recompiled. | 392 // recompilation/bailouts. These functions are never recompiled. |
| 529 enum Mode { | 393 enum Mode { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 542 void SetFlag(Flag flag) { flags_ |= flag; } | 406 void SetFlag(Flag flag) { flags_ |= flag; } |
| 543 | 407 |
| 544 void SetFlag(Flag flag, bool value) { | 408 void SetFlag(Flag flag, bool value) { |
| 545 flags_ = value ? flags_ | flag : flags_ & ~flag; | 409 flags_ = value ? flags_ | flag : flags_ & ~flag; |
| 546 } | 410 } |
| 547 | 411 |
| 548 bool GetFlag(Flag flag) const { return (flags_ & flag) != 0; } | 412 bool GetFlag(Flag flag) const { return (flags_ & flag) != 0; } |
| 549 | 413 |
| 550 unsigned flags_; | 414 unsigned flags_; |
| 551 | 415 |
| 552 // Fields filled in by the compilation pipeline. | |
| 553 // AST filled in by the parser. | |
| 554 FunctionLiteral* function_; | |
| 555 // The scope of the function literal as a convenience. Set to indicate | |
| 556 // that scopes have been analyzed. | |
| 557 Scope* scope_; | |
| 558 // The script scope provided as a convenience. | |
| 559 Scope* script_scope_; | |
| 560 // For compiled stubs, the stub object | 416 // For compiled stubs, the stub object |
| 561 CodeStub* code_stub_; | 417 CodeStub* code_stub_; |
| 562 // The compiled code. | 418 // The compiled code. |
| 563 Handle<Code> code_; | 419 Handle<Code> code_; |
| 564 | 420 |
| 565 // Possible initial inputs to the compilation process. | |
| 566 Handle<JSFunction> closure_; | |
| 567 Handle<SharedFunctionInfo> shared_info_; | |
| 568 Handle<Script> script_; | |
| 569 ScriptCompiler::ExternalSourceStream* source_stream_; // Not owned. | |
| 570 ScriptCompiler::StreamedSource::Encoding source_stream_encoding_; | |
| 571 | |
| 572 // Fields possibly needed for eager compilation, NULL by default. | |
| 573 v8::Extension* extension_; | |
| 574 ScriptData** cached_data_; | |
| 575 ScriptCompiler::CompileOptions compile_options_; | |
| 576 | |
| 577 // The context of the caller for eval code, and the script context for a | |
| 578 // global script. Will be a null handle otherwise. | |
| 579 Handle<Context> context_; | |
| 580 | |
| 581 // Used by codegen, ultimately kept rooted by the SharedFunctionInfo. | 421 // Used by codegen, ultimately kept rooted by the SharedFunctionInfo. |
| 582 Handle<TypeFeedbackVector> feedback_vector_; | 422 Handle<TypeFeedbackVector> feedback_vector_; |
| 583 | 423 |
| 584 // Compilation mode flag and whether deoptimization is allowed. | 424 // Compilation mode flag and whether deoptimization is allowed. |
| 585 Mode mode_; | 425 Mode mode_; |
| 586 BailoutId osr_ast_id_; | 426 BailoutId osr_ast_id_; |
| 587 // The unoptimized code we patched for OSR may not be the shared code | 427 // The unoptimized code we patched for OSR may not be the shared code |
| 588 // afterwards, since we may need to compile it again to include deoptimization | 428 // afterwards, since we may need to compile it again to include deoptimization |
| 589 // data. Keep track which code we patched. | 429 // data. Keep track which code we patched. |
| 590 Handle<Code> unoptimized_code_; | 430 Handle<Code> unoptimized_code_; |
| 591 | 431 |
| 592 // The zone from which the compilation pipeline working on this | 432 // The zone from which the compilation pipeline working on this |
| 593 // CompilationInfo allocates. | 433 // CompilationInfo allocates. |
| 594 Zone* zone_; | 434 Zone* zone_; |
| 595 | 435 |
| 596 DeferredHandles* deferred_handles_; | 436 DeferredHandles* deferred_handles_; |
| 597 | 437 |
| 598 ZoneList<Handle<HeapObject> >* dependencies_[DependentCode::kGroupCount]; | 438 ZoneList<Handle<HeapObject> >* dependencies_[DependentCode::kGroupCount]; |
| 599 | 439 |
| 600 template<typename T> | |
| 601 void SaveHandle(Handle<T> *object) { | |
| 602 if (!object->is_null()) { | |
| 603 Handle<T> handle(*(*object)); | |
| 604 *object = handle; | |
| 605 } | |
| 606 } | |
| 607 | |
| 608 BailoutReason bailout_reason_; | 440 BailoutReason bailout_reason_; |
| 609 | 441 |
| 610 int prologue_offset_; | 442 int prologue_offset_; |
| 611 | 443 |
| 612 List<OffsetRange>* no_frame_ranges_; | 444 List<OffsetRange>* no_frame_ranges_; |
| 613 List<InlinedFunctionInfo>* inlined_function_infos_; | 445 List<InlinedFunctionInfo>* inlined_function_infos_; |
| 614 List<int>* inlining_id_to_function_id_; | 446 List<int>* inlining_id_to_function_id_; |
| 615 | 447 |
| 616 // A copy of shared_info()->opt_count() to avoid handle deref | 448 // A copy of shared_info()->opt_count() to avoid handle deref |
| 617 // during graph optimization. | 449 // during graph optimization. |
| 618 int opt_count_; | 450 int opt_count_; |
| 619 | 451 |
| 620 // Number of parameters used for compilation of stubs that require arguments. | 452 // Number of parameters used for compilation of stubs that require arguments. |
| 621 int parameter_count_; | 453 int parameter_count_; |
| 622 | 454 |
| 623 Handle<Foreign> object_wrapper_; | 455 Handle<Foreign> object_wrapper_; |
| 624 | 456 |
| 625 int optimization_id_; | 457 int optimization_id_; |
| 626 | 458 |
| 627 AstValueFactory* ast_value_factory_; | |
| 628 bool ast_value_factory_owned_; | |
| 629 | |
| 630 // This flag is used by the main thread to track whether this compilation | 459 // This flag is used by the main thread to track whether this compilation |
| 631 // should be abandoned due to dependency change. | 460 // should be abandoned due to dependency change. |
| 632 bool aborted_due_to_dependency_change_; | 461 bool aborted_due_to_dependency_change_; |
| 633 | 462 |
| 634 int osr_expr_stack_height_; | 463 int osr_expr_stack_height_; |
| 635 | 464 |
| 636 DISALLOW_COPY_AND_ASSIGN(CompilationInfo); | 465 DISALLOW_COPY_AND_ASSIGN(CompilationInfo); |
| 637 }; | 466 }; |
| 638 | 467 |
| 639 | 468 |
| 640 // Exactly like a CompilationInfo, except also creates and enters a | 469 // Exactly like a CompilationInfo, except also creates and enters a |
| 641 // Zone on construction and deallocates it on exit. | 470 // Zone on construction and deallocates it on exit. |
| 642 class CompilationInfoWithZone: public CompilationInfo { | 471 class CompilationInfoWithZone: public CompilationInfo { |
| 643 public: | 472 public: |
| 644 explicit CompilationInfoWithZone(Handle<Script> script) | 473 explicit CompilationInfoWithZone(Handle<Script> script); |
| 645 : CompilationInfo(script, &zone_) {} | 474 explicit CompilationInfoWithZone(Handle<SharedFunctionInfo> shared_info); |
| 646 explicit CompilationInfoWithZone(Handle<SharedFunctionInfo> shared_info) | 475 explicit CompilationInfoWithZone(Handle<JSFunction> closure); |
| 647 : CompilationInfo(shared_info, &zone_) {} | |
| 648 explicit CompilationInfoWithZone(Handle<JSFunction> closure) | |
| 649 : CompilationInfo(closure, &zone_) {} | |
| 650 CompilationInfoWithZone(CodeStub* stub, Isolate* isolate) | 476 CompilationInfoWithZone(CodeStub* stub, Isolate* isolate) |
| 651 : CompilationInfo(stub, isolate, &zone_) {} | 477 : CompilationInfo(stub, isolate, &zone_) {} |
| 652 CompilationInfoWithZone(ScriptCompiler::ExternalSourceStream* stream, | |
| 653 ScriptCompiler::StreamedSource::Encoding encoding, | |
| 654 Isolate* isolate) | |
| 655 : CompilationInfo(stream, encoding, isolate, &zone_) {} | |
| 656 | 478 |
| 657 // Virtual destructor because a CompilationInfoWithZone has to exit the | 479 // Virtual destructor because a CompilationInfoWithZone has to exit the |
| 658 // zone scope and get rid of dependent maps even when the destructor is | 480 // zone scope and get rid of dependent maps even when the destructor is |
| 659 // called when cast as a CompilationInfo. | 481 // called when cast as a CompilationInfo. |
| 660 virtual ~CompilationInfoWithZone() { | 482 virtual ~CompilationInfoWithZone(); |
| 661 RollbackDependencies(); | |
| 662 } | |
| 663 | 483 |
| 664 private: | 484 private: |
| 665 Zone zone_; | 485 Zone zone_; |
| 666 }; | 486 }; |
| 667 | 487 |
| 668 | |
| 669 // A wrapper around a CompilationInfo that detaches the Handles from | 488 // A wrapper around a CompilationInfo that detaches the Handles from |
| 670 // the underlying DeferredHandleScope and stores them in info_ on | 489 // the underlying DeferredHandleScope and stores them in info_ on |
| 671 // destruction. | 490 // destruction. |
| 672 class CompilationHandleScope BASE_EMBEDDED { | 491 class CompilationHandleScope BASE_EMBEDDED { |
| 673 public: | 492 public: |
| 674 explicit CompilationHandleScope(CompilationInfo* info) | 493 explicit CompilationHandleScope(CompilationInfo* info) |
| 675 : deferred_(info->isolate()), info_(info) {} | 494 : deferred_(info->isolate()), info_(info) {} |
| 676 ~CompilationHandleScope() { | 495 ~CompilationHandleScope() { |
| 677 info_->set_deferred_handles(deferred_.Detach()); | 496 info_->set_deferred_handles(deferred_.Detach()); |
| 678 } | 497 } |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 783 MUST_USE_RESULT static MaybeHandle<Code> GetUnoptimizedCode( | 602 MUST_USE_RESULT static MaybeHandle<Code> GetUnoptimizedCode( |
| 784 Handle<JSFunction> function); | 603 Handle<JSFunction> function); |
| 785 MUST_USE_RESULT static MaybeHandle<Code> GetLazyCode( | 604 MUST_USE_RESULT static MaybeHandle<Code> GetLazyCode( |
| 786 Handle<JSFunction> function); | 605 Handle<JSFunction> function); |
| 787 MUST_USE_RESULT static MaybeHandle<Code> GetUnoptimizedCode( | 606 MUST_USE_RESULT static MaybeHandle<Code> GetUnoptimizedCode( |
| 788 Handle<SharedFunctionInfo> shared); | 607 Handle<SharedFunctionInfo> shared); |
| 789 MUST_USE_RESULT static MaybeHandle<Code> GetDebugCode( | 608 MUST_USE_RESULT static MaybeHandle<Code> GetDebugCode( |
| 790 Handle<JSFunction> function); | 609 Handle<JSFunction> function); |
| 791 | 610 |
| 792 // Parser::Parse, then Compiler::Analyze. | 611 // Parser::Parse, then Compiler::Analyze. |
| 793 static bool ParseAndAnalyze(CompilationInfo* info); | 612 static bool ParseAndAnalyze(ParseInfo* info); |
| 794 // Rewrite, analyze scopes, and renumber. | 613 // Rewrite, analyze scopes, and renumber. |
| 795 static bool Analyze(CompilationInfo* info); | 614 static bool Analyze(ParseInfo* info); |
| 796 // Adds deoptimization support, requires ParseAndAnalyze. | 615 // Adds deoptimization support, requires ParseAndAnalyze. |
| 797 static bool EnsureDeoptimizationSupport(CompilationInfo* info); | 616 static bool EnsureDeoptimizationSupport(CompilationInfo* info); |
| 798 | 617 |
| 799 static bool EnsureCompiled(Handle<JSFunction> function, | 618 static bool EnsureCompiled(Handle<JSFunction> function, |
| 800 ClearExceptionFlag flag); | 619 ClearExceptionFlag flag); |
| 801 | 620 |
| 802 static void CompileForLiveEdit(Handle<Script> script); | 621 static void CompileForLiveEdit(Handle<Script> script); |
| 803 | 622 |
| 804 // Compile a String source within a context for eval. | 623 // Compile a String source within a context for eval. |
| 805 MUST_USE_RESULT static MaybeHandle<JSFunction> GetFunctionFromEval( | 624 MUST_USE_RESULT static MaybeHandle<JSFunction> GetFunctionFromEval( |
| 806 Handle<String> source, Handle<SharedFunctionInfo> outer_info, | 625 Handle<String> source, Handle<SharedFunctionInfo> outer_info, |
| 807 Handle<Context> context, LanguageMode language_mode, | 626 Handle<Context> context, LanguageMode language_mode, |
| 808 ParseRestriction restriction, int scope_position); | 627 ParseRestriction restriction, int scope_position); |
| 809 | 628 |
| 810 // Compile a String source within a context. | 629 // Compile a String source within a context. |
| 811 static Handle<SharedFunctionInfo> CompileScript( | 630 static Handle<SharedFunctionInfo> CompileScript( |
| 812 Handle<String> source, Handle<Object> script_name, int line_offset, | 631 Handle<String> source, Handle<Object> script_name, int line_offset, |
| 813 int column_offset, bool is_debugger_script, bool is_shared_cross_origin, | 632 int column_offset, bool is_debugger_script, bool is_shared_cross_origin, |
| 814 Handle<Context> context, v8::Extension* extension, | 633 Handle<Context> context, v8::Extension* extension, |
| 815 ScriptData** cached_data, ScriptCompiler::CompileOptions compile_options, | 634 ScriptData** cached_data, ScriptCompiler::CompileOptions compile_options, |
| 816 NativesFlag is_natives_code, bool is_module); | 635 NativesFlag is_natives_code, bool is_module); |
| 817 | 636 |
| 818 static Handle<SharedFunctionInfo> CompileStreamedScript(CompilationInfo* info, | 637 static Handle<SharedFunctionInfo> CompileStreamedScript(Handle<Script> script, |
| 638 ParseInfo* info, |
| 819 int source_length); | 639 int source_length); |
| 820 | 640 |
| 821 // Create a shared function info object (the code may be lazily compiled). | 641 // Create a shared function info object (the code may be lazily compiled). |
| 822 static Handle<SharedFunctionInfo> BuildFunctionInfo(FunctionLiteral* node, | 642 static Handle<SharedFunctionInfo> BuildFunctionInfo(FunctionLiteral* node, |
| 823 Handle<Script> script, | 643 Handle<Script> script, |
| 824 CompilationInfo* outer); | 644 CompilationInfo* outer); |
| 825 | 645 |
| 826 enum ConcurrencyMode { NOT_CONCURRENT, CONCURRENT }; | 646 enum ConcurrencyMode { NOT_CONCURRENT, CONCURRENT }; |
| 827 | 647 |
| 828 // Generate and return optimized code or start a concurrent optimization job. | 648 // Generate and return optimized code or start a concurrent optimization job. |
| 829 // In the latter case, return the InOptimizationQueue builtin. On failure, | 649 // In the latter case, return the InOptimizationQueue builtin. On failure, |
| 830 // return the empty handle. | 650 // return the empty handle. |
| 831 MUST_USE_RESULT static MaybeHandle<Code> GetOptimizedCode( | 651 MUST_USE_RESULT static MaybeHandle<Code> GetOptimizedCode( |
| 832 Handle<JSFunction> function, | 652 Handle<JSFunction> function, |
| 833 Handle<Code> current_code, | 653 Handle<Code> current_code, |
| 834 ConcurrencyMode mode, | 654 ConcurrencyMode mode, |
| 835 BailoutId osr_ast_id = BailoutId::None()); | 655 BailoutId osr_ast_id = BailoutId::None()); |
| 836 | 656 |
| 837 // Generate and return code from previously queued optimization job. | 657 // Generate and return code from previously queued optimization job. |
| 838 // On failure, return the empty handle. | 658 // On failure, return the empty handle. |
| 839 static Handle<Code> GetConcurrentlyOptimizedCode(OptimizedCompileJob* job); | 659 static Handle<Code> GetConcurrentlyOptimizedCode(OptimizedCompileJob* job); |
| 840 | 660 |
| 661 // TODO(titzer): move this method out of the compiler. |
| 841 static bool DebuggerWantsEagerCompilation( | 662 static bool DebuggerWantsEagerCompilation( |
| 842 CompilationInfo* info, bool allow_lazy_without_ctx = false); | 663 Isolate* isolate, bool allow_lazy_without_ctx = false); |
| 843 }; | 664 }; |
| 844 | 665 |
| 845 | 666 |
| 846 class CompilationPhase BASE_EMBEDDED { | 667 class CompilationPhase BASE_EMBEDDED { |
| 847 public: | 668 public: |
| 848 CompilationPhase(const char* name, CompilationInfo* info); | 669 CompilationPhase(const char* name, CompilationInfo* info); |
| 849 ~CompilationPhase(); | 670 ~CompilationPhase(); |
| 850 | 671 |
| 851 protected: | 672 protected: |
| 852 bool ShouldProduceTraceOutput() const; | 673 bool ShouldProduceTraceOutput() const; |
| 853 | 674 |
| 854 const char* name() const { return name_; } | 675 const char* name() const { return name_; } |
| 855 CompilationInfo* info() const { return info_; } | 676 CompilationInfo* info() const { return info_; } |
| 856 Isolate* isolate() const { return info()->isolate(); } | 677 Isolate* isolate() const { return info()->isolate(); } |
| 857 Zone* zone() { return &zone_; } | 678 Zone* zone() { return &zone_; } |
| 858 | 679 |
| 859 private: | 680 private: |
| 860 const char* name_; | 681 const char* name_; |
| 861 CompilationInfo* info_; | 682 CompilationInfo* info_; |
| 862 Zone zone_; | 683 Zone zone_; |
| 863 size_t info_zone_start_allocation_size_; | 684 size_t info_zone_start_allocation_size_; |
| 864 base::ElapsedTimer timer_; | 685 base::ElapsedTimer timer_; |
| 865 | 686 |
| 866 DISALLOW_COPY_AND_ASSIGN(CompilationPhase); | 687 DISALLOW_COPY_AND_ASSIGN(CompilationPhase); |
| 867 }; | 688 }; |
| 868 | 689 |
| 869 } } // namespace v8::internal | 690 } } // namespace v8::internal |
| 870 | 691 |
| 871 #endif // V8_COMPILER_H_ | 692 #endif // V8_COMPILER_H_ |
| OLD | NEW |