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