| Index: src/compiler.cc
|
| diff --git a/src/compiler.cc b/src/compiler.cc
|
| index 7f5c5975a841fb17a68fff6579a62ac3c861e027..e4eedf59e3124286dad244ea639a4a45e852a593 100644
|
| --- a/src/compiler.cc
|
| +++ b/src/compiler.cc
|
| @@ -240,11 +240,11 @@ bool CompilationInfo::ExpectsJSReceiverAsReceiver() {
|
| // ----------------------------------------------------------------------------
|
| // Implementation of CompilationJob
|
|
|
| -CompilationJob::Status CompilationJob::CreateGraph() {
|
| +CompilationJob::Status CompilationJob::PrepareJob() {
|
| + DCHECK(ThreadId::Current().Equals(info()->isolate()->thread_id()));
|
| DisallowJavascriptExecution no_js(isolate());
|
| - DCHECK(info()->IsOptimizing());
|
|
|
| - if (FLAG_trace_opt) {
|
| + if (FLAG_trace_opt && info()->IsOptimizing()) {
|
| OFStream os(stdout);
|
| os << "[compiling method " << Brief(*info()->closure()) << " using "
|
| << compiler_name_;
|
| @@ -253,103 +253,46 @@ CompilationJob::Status CompilationJob::CreateGraph() {
|
| }
|
|
|
| // Delegate to the underlying implementation.
|
| - DCHECK_EQ(SUCCEEDED, last_status());
|
| - ScopedTimer t(&time_taken_to_create_graph_);
|
| - return SetLastStatus(CreateGraphImpl());
|
| + DCHECK(state() == State::kReadyToPrepare);
|
| + ScopedTimer t(&time_taken_to_prepare_);
|
| + return UpdateState(PrepareJobImpl(), State::kReadyToExecute);
|
| }
|
|
|
| -CompilationJob::Status CompilationJob::OptimizeGraph() {
|
| +CompilationJob::Status CompilationJob::ExecuteJob() {
|
| DisallowHeapAllocation no_allocation;
|
| DisallowHandleAllocation no_handles;
|
| DisallowHandleDereference no_deref;
|
| DisallowCodeDependencyChange no_dependency_change;
|
|
|
| // Delegate to the underlying implementation.
|
| - DCHECK_EQ(SUCCEEDED, last_status());
|
| - ScopedTimer t(&time_taken_to_optimize_);
|
| - return SetLastStatus(OptimizeGraphImpl());
|
| + DCHECK(state() == State::kReadyToExecute);
|
| + ScopedTimer t(&time_taken_to_execute_);
|
| + return UpdateState(ExecuteJobImpl(), State::kReadyToFinalize);
|
| }
|
|
|
| -CompilationJob::Status CompilationJob::GenerateCode() {
|
| +CompilationJob::Status CompilationJob::FinalizeJob() {
|
| + DCHECK(ThreadId::Current().Equals(info()->isolate()->thread_id()));
|
| DisallowCodeDependencyChange no_dependency_change;
|
| DisallowJavascriptExecution no_js(isolate());
|
| DCHECK(!info()->dependencies()->HasAborted());
|
|
|
| // Delegate to the underlying implementation.
|
| - DCHECK_EQ(SUCCEEDED, last_status());
|
| - ScopedTimer t(&time_taken_to_codegen_);
|
| - return SetLastStatus(GenerateCodeImpl());
|
| -}
|
| -
|
| -
|
| -namespace {
|
| -
|
| -void AddWeakObjectToCodeDependency(Isolate* isolate, Handle<HeapObject> object,
|
| - Handle<Code> code) {
|
| - Handle<WeakCell> cell = Code::WeakCellFor(code);
|
| - Heap* heap = isolate->heap();
|
| - if (heap->InNewSpace(*object)) {
|
| - heap->AddWeakNewSpaceObjectToCodeDependency(object, cell);
|
| - } else {
|
| - Handle<DependentCode> dep(heap->LookupWeakObjectToCodeDependency(object));
|
| - dep =
|
| - DependentCode::InsertWeakCode(dep, DependentCode::kWeakCodeGroup, cell);
|
| - heap->AddWeakObjectToCodeDependency(object, dep);
|
| - }
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| -void CompilationJob::RegisterWeakObjectsInOptimizedCode(Handle<Code> code) {
|
| - // TODO(turbofan): Move this to pipeline.cc once Crankshaft dies.
|
| - Isolate* const isolate = code->GetIsolate();
|
| - DCHECK(code->is_optimized_code());
|
| - std::vector<Handle<Map>> maps;
|
| - std::vector<Handle<HeapObject>> objects;
|
| - {
|
| - DisallowHeapAllocation no_gc;
|
| - int const mode_mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |
|
| - RelocInfo::ModeMask(RelocInfo::CELL);
|
| - for (RelocIterator it(*code, mode_mask); !it.done(); it.next()) {
|
| - RelocInfo::Mode mode = it.rinfo()->rmode();
|
| - if (mode == RelocInfo::CELL &&
|
| - code->IsWeakObjectInOptimizedCode(it.rinfo()->target_cell())) {
|
| - objects.push_back(handle(it.rinfo()->target_cell(), isolate));
|
| - } else if (mode == RelocInfo::EMBEDDED_OBJECT &&
|
| - code->IsWeakObjectInOptimizedCode(
|
| - it.rinfo()->target_object())) {
|
| - Handle<HeapObject> object(HeapObject::cast(it.rinfo()->target_object()),
|
| - isolate);
|
| - if (object->IsMap()) {
|
| - maps.push_back(Handle<Map>::cast(object));
|
| - } else {
|
| - objects.push_back(object);
|
| - }
|
| - }
|
| - }
|
| - }
|
| - for (Handle<Map> map : maps) {
|
| - if (map->dependent_code()->IsEmpty(DependentCode::kWeakCodeGroup)) {
|
| - isolate->heap()->AddRetainedMap(map);
|
| - }
|
| - Map::AddDependentCode(map, DependentCode::kWeakCodeGroup, code);
|
| - }
|
| - for (Handle<HeapObject> object : objects) {
|
| - AddWeakObjectToCodeDependency(isolate, object, code);
|
| - }
|
| - code->set_can_have_weak_objects(true);
|
| + DCHECK(state() == State::kReadyToFinalize);
|
| + ScopedTimer t(&time_taken_to_finalize_);
|
| + return UpdateState(FinalizeJobImpl(), State::kSucceeded);
|
| }
|
|
|
| void CompilationJob::RecordOptimizationStats() {
|
| + DCHECK(info()->IsOptimizing());
|
| Handle<JSFunction> function = info()->closure();
|
| if (!function->IsOptimized()) {
|
| // Concurrent recompilation and OSR may race. Increment only once.
|
| int opt_count = function->shared()->opt_count();
|
| function->shared()->set_opt_count(opt_count + 1);
|
| }
|
| - double ms_creategraph = time_taken_to_create_graph_.InMillisecondsF();
|
| - double ms_optimize = time_taken_to_optimize_.InMillisecondsF();
|
| - double ms_codegen = time_taken_to_codegen_.InMillisecondsF();
|
| + double ms_creategraph = time_taken_to_prepare_.InMillisecondsF();
|
| + double ms_optimize = time_taken_to_execute_.InMillisecondsF();
|
| + double ms_codegen = time_taken_to_finalize_.InMillisecondsF();
|
| if (FLAG_trace_opt) {
|
| PrintF("[optimizing ");
|
| function->ShortPrint();
|
| @@ -370,9 +313,9 @@ void CompilationJob::RecordOptimizationStats() {
|
| compilation_time);
|
| }
|
| if (FLAG_hydrogen_stats) {
|
| - isolate()->GetHStatistics()->IncrementSubtotals(time_taken_to_create_graph_,
|
| - time_taken_to_optimize_,
|
| - time_taken_to_codegen_);
|
| + isolate()->GetHStatistics()->IncrementSubtotals(time_taken_to_prepare_,
|
| + time_taken_to_execute_,
|
| + time_taken_to_finalize_);
|
| }
|
| }
|
|
|
| @@ -672,9 +615,9 @@ bool GetOptimizedCodeNow(CompilationJob* job) {
|
| TRACE_EVENT_RUNTIME_CALL_STATS_TRACING_SCOPED(
|
| isolate, &tracing::TraceEventStatsTable::RecompileSynchronous);
|
|
|
| - if (job->CreateGraph() != CompilationJob::SUCCEEDED ||
|
| - job->OptimizeGraph() != CompilationJob::SUCCEEDED ||
|
| - job->GenerateCode() != CompilationJob::SUCCEEDED) {
|
| + if (job->PrepareJob() != CompilationJob::SUCCEEDED ||
|
| + job->ExecuteJob() != CompilationJob::SUCCEEDED ||
|
| + job->FinalizeJob() != CompilationJob::SUCCEEDED) {
|
| if (FLAG_trace_opt) {
|
| PrintF("[aborted optimizing ");
|
| info->closure()->ShortPrint();
|
| @@ -735,7 +678,7 @@ bool GetOptimizedCodeLater(CompilationJob* job) {
|
| TRACE_EVENT_RUNTIME_CALL_STATS_TRACING_SCOPED(
|
| isolate, &tracing::TraceEventStatsTable::RecompileSynchronous);
|
|
|
| - if (job->CreateGraph() != CompilationJob::SUCCEEDED) return false;
|
| + if (job->PrepareJob() != CompilationJob::SUCCEEDED) return false;
|
| isolate->optimizing_compile_dispatcher()->QueueForOptimization(job);
|
|
|
| if (FLAG_trace_concurrent_recompilation) {
|
| @@ -1901,12 +1844,12 @@ void Compiler::FinalizeCompilationJob(CompilationJob* raw_job) {
|
| // Except when OSR already disabled optimization for some reason.
|
| // 3) The code may have already been invalidated due to dependency change.
|
| // 4) Code generation may have failed.
|
| - if (job->last_status() == CompilationJob::SUCCEEDED) {
|
| + if (job->state() == CompilationJob::State::kReadyToFinalize) {
|
| if (shared->optimization_disabled()) {
|
| job->RetryOptimization(kOptimizationDisabled);
|
| } else if (info->dependencies()->HasAborted()) {
|
| job->RetryOptimization(kBailedOutDueToDependencyChange);
|
| - } else if (job->GenerateCode() == CompilationJob::SUCCEEDED) {
|
| + } else if (job->FinalizeJob() == CompilationJob::SUCCEEDED) {
|
| job->RecordOptimizationStats();
|
| RecordFunctionCompilation(CodeEventListener::LAZY_COMPILE_TAG, info);
|
| if (shared->SearchOptimizedCodeMap(info->context()->native_context(),
|
| @@ -1923,7 +1866,7 @@ void Compiler::FinalizeCompilationJob(CompilationJob* raw_job) {
|
| }
|
| }
|
|
|
| - DCHECK(job->last_status() != CompilationJob::SUCCEEDED);
|
| + DCHECK(job->state() == CompilationJob::State::kFailed);
|
| if (FLAG_trace_opt) {
|
| PrintF("[aborted optimizing ");
|
| info->closure()->ShortPrint();
|
| @@ -1958,5 +1901,64 @@ void Compiler::PostInstantiation(Handle<JSFunction> function,
|
| }
|
| }
|
|
|
| +namespace {
|
| +
|
| +void AddWeakObjectToCodeDependency(Isolate* isolate, Handle<HeapObject> object,
|
| + Handle<Code> code) {
|
| + Handle<WeakCell> cell = Code::WeakCellFor(code);
|
| + Heap* heap = isolate->heap();
|
| + if (heap->InNewSpace(*object)) {
|
| + heap->AddWeakNewSpaceObjectToCodeDependency(object, cell);
|
| + } else {
|
| + Handle<DependentCode> dep(heap->LookupWeakObjectToCodeDependency(object));
|
| + dep =
|
| + DependentCode::InsertWeakCode(dep, DependentCode::kWeakCodeGroup, cell);
|
| + heap->AddWeakObjectToCodeDependency(object, dep);
|
| + }
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +// static
|
| +void Compiler::RegisterWeakObjectsInOptimizedCode(Handle<Code> code) {
|
| + // TODO(turbofan): Move this to pipeline.cc once Crankshaft dies.
|
| + Isolate* const isolate = code->GetIsolate();
|
| + DCHECK(code->is_optimized_code());
|
| + std::vector<Handle<Map>> maps;
|
| + std::vector<Handle<HeapObject>> objects;
|
| + {
|
| + DisallowHeapAllocation no_gc;
|
| + int const mode_mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |
|
| + RelocInfo::ModeMask(RelocInfo::CELL);
|
| + for (RelocIterator it(*code, mode_mask); !it.done(); it.next()) {
|
| + RelocInfo::Mode mode = it.rinfo()->rmode();
|
| + if (mode == RelocInfo::CELL &&
|
| + code->IsWeakObjectInOptimizedCode(it.rinfo()->target_cell())) {
|
| + objects.push_back(handle(it.rinfo()->target_cell(), isolate));
|
| + } else if (mode == RelocInfo::EMBEDDED_OBJECT &&
|
| + code->IsWeakObjectInOptimizedCode(
|
| + it.rinfo()->target_object())) {
|
| + Handle<HeapObject> object(HeapObject::cast(it.rinfo()->target_object()),
|
| + isolate);
|
| + if (object->IsMap()) {
|
| + maps.push_back(Handle<Map>::cast(object));
|
| + } else {
|
| + objects.push_back(object);
|
| + }
|
| + }
|
| + }
|
| + }
|
| + for (Handle<Map> map : maps) {
|
| + if (map->dependent_code()->IsEmpty(DependentCode::kWeakCodeGroup)) {
|
| + isolate->heap()->AddRetainedMap(map);
|
| + }
|
| + Map::AddDependentCode(map, DependentCode::kWeakCodeGroup, code);
|
| + }
|
| + for (Handle<HeapObject> object : objects) {
|
| + AddWeakObjectToCodeDependency(isolate, object, code);
|
| + }
|
| + code->set_can_have_weak_objects(true);
|
| +}
|
| +
|
| } // namespace internal
|
| } // namespace v8
|
|
|