Index: src/compiler.h |
diff --git a/src/compiler.h b/src/compiler.h |
index 7599c13a0c48f98e2c545a049be02b2fba3c05a8..4d7c1a250547b4c1ad2ddf0640379f26e5f40eaa 100644 |
--- a/src/compiler.h |
+++ b/src/compiler.h |
@@ -84,8 +84,7 @@ class CompilationInfo { |
ScriptDataImpl* pre_parse_data() const { return pre_parse_data_; } |
Handle<Context> context() const { return context_; } |
BailoutId osr_ast_id() const { return osr_ast_id_; } |
- uint32_t osr_pc_offset() const { return osr_pc_offset_; } |
- Handle<Code> osr_patched_code() const { return osr_patched_code_; } |
+ Handle<Code> unoptimized_code() const { return unoptimized_code_; } |
int opt_count() const { return opt_count_; } |
int num_parameters() const; |
int num_heap_slots() const; |
@@ -189,19 +188,16 @@ class CompilationInfo { |
void SetContext(Handle<Context> context) { |
context_ = context; |
} |
- void MarkCompilingForDebugging(Handle<Code> current_code) { |
- ASSERT(mode_ != OPTIMIZE); |
- ASSERT(current_code->kind() == Code::FUNCTION); |
+ |
+ void MarkCompilingForDebugging() { |
flags_ |= IsCompilingForDebugging::encode(true); |
- if (current_code->is_compiled_optimizable()) { |
- EnableDeoptimizationSupport(); |
- } else { |
- mode_ = CompilationInfo::NONOPT; |
- } |
} |
bool IsCompilingForDebugging() { |
return IsCompilingForDebugging::decode(flags_); |
} |
+ void MarkNonOptimizable() { |
+ SetMode(CompilationInfo::NONOPT); |
+ } |
bool ShouldTrapOnDeopt() const { |
return (FLAG_trap_on_deopt && IsOptimizing()) || |
@@ -221,9 +217,11 @@ class CompilationInfo { |
bool IsOptimizing() const { return mode_ == OPTIMIZE; } |
bool IsOptimizable() const { return mode_ == BASE; } |
bool IsStub() const { return mode_ == STUB; } |
- void SetOptimizing(BailoutId osr_ast_id) { |
+ void SetOptimizing(BailoutId osr_ast_id, Handle<Code> unoptimized) { |
+ ASSERT(!shared_info_.is_null()); |
SetMode(OPTIMIZE); |
osr_ast_id_ = osr_ast_id; |
+ unoptimized_code_ = unoptimized; |
} |
void DisableOptimization(); |
@@ -239,11 +237,6 @@ class CompilationInfo { |
// Determines whether or not to insert a self-optimization header. |
bool ShouldSelfOptimize(); |
- // Reset code to the unoptimized version when optimization is aborted. |
- void AbortOptimization() { |
- SetCode(handle(shared_info()->code())); |
- } |
- |
void set_deferred_handles(DeferredHandles* deferred_handles) { |
ASSERT(deferred_handles_ == NULL); |
deferred_handles_ = deferred_handles; |
@@ -266,7 +259,7 @@ class CompilationInfo { |
SaveHandle(&shared_info_); |
SaveHandle(&context_); |
SaveHandle(&script_); |
- SaveHandle(&osr_patched_code_); |
+ SaveHandle(&unoptimized_code_); |
} |
BailoutReason bailout_reason() const { return bailout_reason_; } |
@@ -313,13 +306,8 @@ class CompilationInfo { |
return abort_due_to_dependency_; |
} |
- void SetOsrInfo(Handle<Code> code, uint32_t pc_offset) { |
- osr_patched_code_ = code; |
- osr_pc_offset_ = pc_offset; |
- } |
- |
- bool HasSameOsrEntry(Handle<JSFunction> function, uint32_t pc_offset) { |
- return osr_pc_offset_ == pc_offset && function.is_identical_to(closure_); |
+ bool HasSameOsrEntry(Handle<JSFunction> function, BailoutId osr_ast_id) { |
+ return osr_ast_id_ == osr_ast_id && function.is_identical_to(closure_); |
} |
protected: |
@@ -416,13 +404,10 @@ class CompilationInfo { |
// Compilation mode flag and whether deoptimization is allowed. |
Mode mode_; |
BailoutId osr_ast_id_; |
- // The pc_offset corresponding to osr_ast_id_ in unoptimized code. |
- // We can look this up in the back edge table, but cache it for quick access. |
- uint32_t osr_pc_offset_; |
// The unoptimized code we patched for OSR may not be the shared code |
// afterwards, since we may need to compile it again to include deoptimization |
// data. Keep track which code we patched. |
- Handle<Code> osr_patched_code_; |
+ Handle<Code> unoptimized_code_; |
// Flag whether compilation needs to be aborted due to dependency change. |
bool abort_due_to_dependency_; |
@@ -518,9 +503,9 @@ class LChunk; |
// fail, bail-out to the full code generator or succeed. Apart from |
// their return value, the status of the phase last run can be checked |
// using last_status(). |
-class RecompileJob: public ZoneObject { |
+class OptimizedCompileJob: public ZoneObject { |
public: |
- explicit RecompileJob(CompilationInfo* info) |
+ explicit OptimizedCompileJob(CompilationInfo* info) |
: info_(info), |
graph_builder_(NULL), |
graph_(NULL), |
@@ -534,14 +519,21 @@ class RecompileJob: public ZoneObject { |
MUST_USE_RESULT Status CreateGraph(); |
MUST_USE_RESULT Status OptimizeGraph(); |
- MUST_USE_RESULT Status GenerateAndInstallCode(); |
+ MUST_USE_RESULT Status GenerateCode(); |
Status last_status() const { return last_status_; } |
CompilationInfo* info() const { return info_; } |
Isolate* isolate() const { return info()->isolate(); } |
- MUST_USE_RESULT Status AbortOptimization() { |
- info_->AbortOptimization(); |
+ MUST_USE_RESULT Status AbortOptimization( |
+ BailoutReason reason = kNoReason) { |
+ if (reason != kNoReason) info_->set_bailout_reason(reason); |
+ return SetLastStatus(BAILED_OUT); |
+ } |
+ |
+ MUST_USE_RESULT Status AbortAndDisableOptimization( |
+ BailoutReason reason = kNoReason) { |
+ if (reason != kNoReason) info_->set_bailout_reason(reason); |
info_->shared_info()->DisableOptimization(info_->bailout_reason()); |
return SetLastStatus(BAILED_OUT); |
} |
@@ -571,7 +563,7 @@ class RecompileJob: public ZoneObject { |
void RecordOptimizationStats(); |
struct Timer { |
- Timer(RecompileJob* job, TimeDelta* location) |
+ Timer(OptimizedCompileJob* job, TimeDelta* location) |
: job_(job), location_(location) { |
ASSERT(location_ != NULL); |
timer_.Start(); |
@@ -581,7 +573,7 @@ class RecompileJob: public ZoneObject { |
*location_ += timer_.Elapsed(); |
} |
- RecompileJob* job_; |
+ OptimizedCompileJob* job_; |
ElapsedTimer timer_; |
TimeDelta* location_; |
}; |
@@ -601,57 +593,53 @@ class RecompileJob: public ZoneObject { |
class Compiler : public AllStatic { |
public: |
- // Call count before primitive functions trigger their own optimization. |
- static const int kCallsUntilPrimitiveOpt = 200; |
+ static Handle<Code> GetUnoptimizedCode(Handle<JSFunction> function); |
+ static Handle<Code> GetUnoptimizedCode(Handle<SharedFunctionInfo> shared); |
+ static bool EnsureCompiled(Handle<JSFunction> function, |
+ ClearExceptionFlag flag); |
+ static Handle<Code> GetCodeForDebugging(Handle<JSFunction> function); |
- // All routines return a SharedFunctionInfo. |
- // If an error occurs an exception is raised and the return handle |
- // contains NULL. |
+#ifdef ENABLE_DEBUGGER_SUPPORT |
+ static void CompileForLiveEdit(Handle<Script> script); |
+#endif |
- // Compile a String source within a context. |
- static Handle<SharedFunctionInfo> Compile(Handle<String> source, |
- Handle<Object> script_name, |
- int line_offset, |
- int column_offset, |
- bool is_shared_cross_origin, |
- Handle<Context> context, |
- v8::Extension* extension, |
- ScriptDataImpl* pre_data, |
- Handle<Object> script_data, |
- NativesFlag is_natives_code); |
- |
- // Compile a String source within a context for Eval. |
- static Handle<SharedFunctionInfo> CompileEval(Handle<String> source, |
+ // Compile a String source within a context for eval. |
+ static Handle<JSFunction> GetFunctionFromEval(Handle<String> source, |
Handle<Context> context, |
- bool is_global, |
LanguageMode language_mode, |
ParseRestriction restriction, |
int scope_position); |
- // Compile from function info (used for lazy compilation). Returns true on |
- // success and false if the compilation resulted in a stack overflow. |
- static bool CompileLazy(CompilationInfo* info); |
- |
- static bool RecompileConcurrent(Handle<JSFunction> function, |
- Handle<Code> unoptimized, |
- uint32_t osr_pc_offset = 0); |
- |
- // Compile a shared function info object (the function is possibly lazily |
- // compiled). |
+ // Compile a String source within a context. |
+ static Handle<SharedFunctionInfo> CompileScript(Handle<String> source, |
+ Handle<Object> script_name, |
+ int line_offset, |
+ int column_offset, |
+ bool is_shared_cross_origin, |
+ Handle<Context> context, |
+ v8::Extension* extension, |
+ ScriptDataImpl* pre_data, |
+ Handle<Object> script_data, |
+ NativesFlag is_natives_code); |
+ |
+ // Create a shared function info object (the code may be lazily compiled). |
static Handle<SharedFunctionInfo> BuildFunctionInfo(FunctionLiteral* node, |
Handle<Script> script); |
- // Set the function info for a newly compiled function. |
- static void SetFunctionInfo(Handle<SharedFunctionInfo> function_info, |
- FunctionLiteral* lit, |
- bool is_toplevel, |
- Handle<Script> script); |
+ enum ConcurrencyMode { NOT_CONCURRENT, CONCURRENT }; |
- static Handle<Code> InstallOptimizedCode(RecompileJob* job); |
+ // Generate and return optimized code or start a concurrent optimization job. |
+ // In the latter case, return the InOptimizationQueue builtin. On failure, |
+ // return the empty handle. |
+ static Handle<Code> GetOptimizedCode( |
+ Handle<JSFunction> function, |
+ Handle<Code> current_code, |
+ ConcurrencyMode mode, |
+ BailoutId osr_ast_id = BailoutId::None()); |
-#ifdef ENABLE_DEBUGGER_SUPPORT |
- static bool MakeCodeForLiveEdit(CompilationInfo* info); |
-#endif |
+ // Generate and return code from previously queued optimization job. |
+ // On failure, return the empty handle. |
+ static Handle<Code> GetConcurrentlyOptimizedCode(OptimizedCompileJob* job); |
static void RecordFunctionCompilation(Logger::LogEventsAndTags tag, |
CompilationInfo* info, |