OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium 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 #include "content/renderer/render_thread_impl.h" | 5 #include "content/renderer/render_thread_impl.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <limits> | 8 #include <limits> |
9 #include <map> | 9 #include <map> |
10 #include <vector> | 10 #include <vector> |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
94 using WebKit::WebNetworkStateNotifier; | 94 using WebKit::WebNetworkStateNotifier; |
95 using WebKit::WebRuntimeFeatures; | 95 using WebKit::WebRuntimeFeatures; |
96 using WebKit::WebScriptController; | 96 using WebKit::WebScriptController; |
97 using WebKit::WebString; | 97 using WebKit::WebString; |
98 using WebKit::WebStorageEventDispatcher; | 98 using WebKit::WebStorageEventDispatcher; |
99 using WebKit::WebView; | 99 using WebKit::WebView; |
100 using content::RenderProcessObserver; | 100 using content::RenderProcessObserver; |
101 | 101 |
102 namespace { | 102 namespace { |
103 static const int64 kInitialIdleHandlerDelayMs = 1000; | 103 static const int64 kInitialIdleHandlerDelayMs = 1000; |
104 static const int64 kShortIdleHandlerDelayMs = 1000; | |
105 static const int64 kLongIdleHandlerDelayMs = 30*1000; | |
106 static const int kIdleCPUUsageThresholdInPercents = 3; | |
104 | 107 |
105 #if defined(TOUCH_UI) | 108 #if defined(TOUCH_UI) |
106 static const int kPopupListBoxMinimumRowHeight = 60; | 109 static const int kPopupListBoxMinimumRowHeight = 60; |
107 #endif | 110 #endif |
108 | 111 |
109 // Keep the global RenderThreadImpl in a TLS slot so it is impossible to access | 112 // Keep the global RenderThreadImpl in a TLS slot so it is impossible to access |
110 // incorrectly from the wrong thread. | 113 // incorrectly from the wrong thread. |
111 static base::LazyInstance<base::ThreadLocalPointer<RenderThreadImpl> > | 114 static base::LazyInstance<base::ThreadLocalPointer<RenderThreadImpl> > |
112 lazy_tls = LAZY_INSTANCE_INITIALIZER; | 115 lazy_tls = LAZY_INSTANCE_INITIALIZER; |
113 | 116 |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
186 initialize_com_.reset(new base::win::ScopedCOMInitializer()); | 189 initialize_com_.reset(new base::win::ScopedCOMInitializer()); |
187 #endif | 190 #endif |
188 | 191 |
189 // In single process the single process is all there is. | 192 // In single process the single process is all there is. |
190 suspend_webkit_shared_timer_ = true; | 193 suspend_webkit_shared_timer_ = true; |
191 notify_webkit_of_modal_loop_ = true; | 194 notify_webkit_of_modal_loop_ = true; |
192 plugin_refresh_allowed_ = true; | 195 plugin_refresh_allowed_ = true; |
193 widget_count_ = 0; | 196 widget_count_ = 0; |
194 hidden_widget_count_ = 0; | 197 hidden_widget_count_ = 0; |
195 idle_notification_delay_in_ms_ = kInitialIdleHandlerDelayMs; | 198 idle_notification_delay_in_ms_ = kInitialIdleHandlerDelayMs; |
199 idle_notifications_to_skip_ = 0; | |
200 base::ProcessHandle handle = base::GetCurrentProcessHandle(); | |
201 #if defined(OS_MACOSX) | |
202 process_metrics_.reset(base::ProcessMetrics::CreateProcessMetrics(handle, | |
203 NULL)); | |
204 #else | |
205 process_metrics_.reset(base::ProcessMetrics::CreateProcessMetrics(handle)); | |
206 #endif | |
207 process_metrics_->GetCPUUsage(); // Initialize CPU usage counters. | |
196 task_factory_.reset(new ScopedRunnableMethodFactory<RenderThreadImpl>(this)); | 208 task_factory_.reset(new ScopedRunnableMethodFactory<RenderThreadImpl>(this)); |
197 | 209 |
198 appcache_dispatcher_.reset(new AppCacheDispatcher(Get())); | 210 appcache_dispatcher_.reset(new AppCacheDispatcher(Get())); |
199 indexed_db_dispatcher_.reset(new IndexedDBDispatcher()); | 211 indexed_db_dispatcher_.reset(new IndexedDBDispatcher()); |
200 | 212 |
201 db_message_filter_ = new DBMessageFilter(); | 213 db_message_filter_ = new DBMessageFilter(); |
202 AddFilter(db_message_filter_.get()); | 214 AddFilter(db_message_filter_.get()); |
203 | 215 |
204 vc_manager_ = new VideoCaptureImplManager(); | 216 vc_manager_ = new VideoCaptureImplManager(); |
205 AddFilter(vc_manager_->video_capture_message_filter()); | 217 AddFilter(vc_manager_->video_capture_message_filter()); |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
408 } | 420 } |
409 | 421 |
410 void RenderThreadImpl::WidgetRestored() { | 422 void RenderThreadImpl::WidgetRestored() { |
411 DCHECK_GT(hidden_widget_count_, 0); | 423 DCHECK_GT(hidden_widget_count_, 0); |
412 hidden_widget_count_--; | 424 hidden_widget_count_--; |
413 if (!content::GetContentClient()->renderer()-> | 425 if (!content::GetContentClient()->renderer()-> |
414 RunIdleHandlerWhenWidgetsHidden()) { | 426 RunIdleHandlerWhenWidgetsHidden()) { |
415 return; | 427 return; |
416 } | 428 } |
417 | 429 |
418 idle_timer_.Stop(); | 430 ScheduleIdleHandler(kLongIdleHandlerDelayMs); |
419 } | 431 } |
420 | 432 |
421 void RenderThreadImpl::EnsureWebKitInitialized() { | 433 void RenderThreadImpl::EnsureWebKitInitialized() { |
422 if (webkit_platform_support_.get()) | 434 if (webkit_platform_support_.get()) |
423 return; | 435 return; |
424 | 436 |
425 v8::V8::SetCounterFunction(base::StatsTable::FindLocation); | 437 v8::V8::SetCounterFunction(base::StatsTable::FindLocation); |
426 v8::V8::SetCreateHistogramFunction(CreateHistogram); | 438 v8::V8::SetCreateHistogramFunction(CreateHistogram); |
427 v8::V8::SetAddHistogramSampleFunction(AddHistogramSample); | 439 v8::V8::SetAddHistogramSampleFunction(AddHistogramSample); |
428 | 440 |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
517 | 529 |
518 WebRuntimeFeatures::enableFileSystem( | 530 WebRuntimeFeatures::enableFileSystem( |
519 !command_line.HasSwitch(switches::kDisableFileSystem)); | 531 !command_line.HasSwitch(switches::kDisableFileSystem)); |
520 | 532 |
521 WebRuntimeFeatures::enableJavaScriptI18NAPI( | 533 WebRuntimeFeatures::enableJavaScriptI18NAPI( |
522 !command_line.HasSwitch(switches::kDisableJavaScriptI18NAPI)); | 534 !command_line.HasSwitch(switches::kDisableJavaScriptI18NAPI)); |
523 | 535 |
524 WebRuntimeFeatures::enableQuota(true); | 536 WebRuntimeFeatures::enableQuota(true); |
525 | 537 |
526 FOR_EACH_OBSERVER(RenderProcessObserver, observers_, WebKitInitialized()); | 538 FOR_EACH_OBSERVER(RenderProcessObserver, observers_, WebKitInitialized()); |
539 | |
540 if (content::GetContentClient()->renderer()-> | |
541 RunIdleHandlerWhenWidgetsHidden()) { | |
542 ScheduleIdleHandler(kLongIdleHandlerDelayMs); | |
543 } | |
527 } | 544 } |
528 | 545 |
529 void RenderThreadImpl::RecordUserMetrics(const std::string& action) { | 546 void RenderThreadImpl::RecordUserMetrics(const std::string& action) { |
530 Send(new ViewHostMsg_UserMetricsRecordAction(action)); | 547 Send(new ViewHostMsg_UserMetricsRecordAction(action)); |
531 } | 548 } |
532 | 549 |
533 base::SharedMemoryHandle RenderThreadImpl::HostAllocateSharedMemoryBuffer( | 550 base::SharedMemoryHandle RenderThreadImpl::HostAllocateSharedMemoryBuffer( |
534 uint32 buffer_size) { | 551 uint32 buffer_size) { |
535 base::SharedMemoryHandle mem_handle; | 552 base::SharedMemoryHandle mem_handle; |
536 Send(new ChildProcessHostMsg_SyncAllocateSharedMemory( | 553 Send(new ChildProcessHostMsg_SyncAllocateSharedMemory( |
(...skipping 13 matching lines...) Expand all Loading... | |
550 | 567 |
551 void RenderThreadImpl::ScheduleIdleHandler(int64 initial_delay_ms) { | 568 void RenderThreadImpl::ScheduleIdleHandler(int64 initial_delay_ms) { |
552 idle_notification_delay_in_ms_ = initial_delay_ms; | 569 idle_notification_delay_in_ms_ = initial_delay_ms; |
553 idle_timer_.Stop(); | 570 idle_timer_.Stop(); |
554 idle_timer_.Start(FROM_HERE, | 571 idle_timer_.Start(FROM_HERE, |
555 base::TimeDelta::FromMilliseconds(initial_delay_ms), | 572 base::TimeDelta::FromMilliseconds(initial_delay_ms), |
556 this, &RenderThreadImpl::IdleHandler); | 573 this, &RenderThreadImpl::IdleHandler); |
557 } | 574 } |
558 | 575 |
559 void RenderThreadImpl::IdleHandler() { | 576 void RenderThreadImpl::IdleHandler() { |
560 #if !defined(OS_MACOSX) && defined(USE_TCMALLOC) | 577 bool is_extension = !content::GetContentClient()->renderer()-> |
Matt Perry
2011/11/16 19:23:52
extensions are a chrome concept, and this code liv
ulan
2011/11/16 20:13:22
Done.
| |
578 RunIdleHandlerWhenWidgetsHidden(); | |
579 bool foreground_tab = (widget_count_ > hidden_widget_count_) && !is_extension; | |
580 if (foreground_tab) { | |
581 IdleHandlerInForegroundTab(); | |
582 return; | |
583 } | |
584 #if !defined(OS_MACOSX) && defined(USE_TCMALLOC) | |
561 MallocExtension::instance()->ReleaseFreeMemory(); | 585 MallocExtension::instance()->ReleaseFreeMemory(); |
562 #endif | 586 #endif |
563 | 587 |
564 v8::V8::IdleNotification(); | 588 v8::V8::IdleNotification(); |
565 | 589 |
566 // Schedule next invocation. | 590 // Schedule next invocation. |
567 // Dampen the delay using the algorithm (if delay is in seconds): | 591 // Dampen the delay using the algorithm (if delay is in seconds): |
568 // delay = delay + 1 / (delay + 2) | 592 // delay = delay + 1 / (delay + 2) |
569 // Using floor(delay) has a dampening effect such as: | 593 // Using floor(delay) has a dampening effect such as: |
570 // 1s, 1, 1, 2, 2, 2, 2, 3, 3, ... | 594 // 1s, 1, 1, 2, 2, 2, 2, 3, 3, ... |
(...skipping 11 matching lines...) Expand all Loading... | |
582 | 606 |
583 int64 RenderThreadImpl::GetIdleNotificationDelayInMs() const { | 607 int64 RenderThreadImpl::GetIdleNotificationDelayInMs() const { |
584 return idle_notification_delay_in_ms_; | 608 return idle_notification_delay_in_ms_; |
585 } | 609 } |
586 | 610 |
587 void RenderThreadImpl::SetIdleNotificationDelayInMs( | 611 void RenderThreadImpl::SetIdleNotificationDelayInMs( |
588 int64 idle_notification_delay_in_ms) { | 612 int64 idle_notification_delay_in_ms) { |
589 idle_notification_delay_in_ms_ = idle_notification_delay_in_ms; | 613 idle_notification_delay_in_ms_ = idle_notification_delay_in_ms; |
590 } | 614 } |
591 | 615 |
616 void RenderThreadImpl::PostponeIdleNotification() { | |
617 idle_notifications_to_skip_ = 2; | |
618 } | |
619 | |
592 #if defined(OS_WIN) | 620 #if defined(OS_WIN) |
593 void RenderThreadImpl::PreCacheFont(const LOGFONT& log_font) { | 621 void RenderThreadImpl::PreCacheFont(const LOGFONT& log_font) { |
594 Send(new ChildProcessHostMsg_PreCacheFont(log_font)); | 622 Send(new ChildProcessHostMsg_PreCacheFont(log_font)); |
595 } | 623 } |
596 | 624 |
597 void RenderThreadImpl::ReleaseCachedFonts() { | 625 void RenderThreadImpl::ReleaseCachedFonts() { |
598 Send(new ChildProcessHostMsg_ReleaseCachedFonts()); | 626 Send(new ChildProcessHostMsg_ReleaseCachedFonts()); |
599 } | 627 } |
600 | 628 |
601 #endif // OS_WIN | 629 #endif // OS_WIN |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
776 void RenderThreadImpl::OnNetworkStateChanged(bool online) { | 804 void RenderThreadImpl::OnNetworkStateChanged(bool online) { |
777 EnsureWebKitInitialized(); | 805 EnsureWebKitInitialized(); |
778 WebNetworkStateNotifier::setOnLine(online); | 806 WebNetworkStateNotifier::setOnLine(online); |
779 } | 807 } |
780 | 808 |
781 void RenderThreadImpl::OnTempCrashWithData(const GURL& data) { | 809 void RenderThreadImpl::OnTempCrashWithData(const GURL& data) { |
782 content::GetContentClient()->SetActiveURL(data); | 810 content::GetContentClient()->SetActiveURL(data); |
783 CHECK(false); | 811 CHECK(false); |
784 } | 812 } |
785 | 813 |
814 void RenderThreadImpl::IdleHandlerInForegroundTab() { | |
Matt Perry
2011/11/16 19:23:52
could you move this next to the other IdleHandler,
ulan
2011/11/16 20:13:22
Done.
| |
815 // Increase the delay in the same way as in IdleHandler, | |
816 // but make it periodic by reseting it once it is too big. | |
817 int64 new_delay_ms = idle_notification_delay_in_ms_ + | |
818 1000000 / (idle_notification_delay_in_ms_ + 2000); | |
819 if (new_delay_ms >= kLongIdleHandlerDelayMs) | |
820 new_delay_ms = kShortIdleHandlerDelayMs; | |
821 | |
822 double cpu_usage = process_metrics_->GetCPUUsage(); | |
ulan
2011/11/16 14:14:46
I didn't place GetCPUUsage inside the "if" stateme
Matt Perry
2011/11/16 19:23:52
Add this as a comment in the code, so someone read
ulan
2011/11/16 20:13:22
Done.
| |
823 | |
824 if (idle_notifications_to_skip_ > 0) { | |
825 idle_notifications_to_skip_--; | |
826 } else if (cpu_usage < kIdleCPUUsageThresholdInPercents) { | |
827 if (v8::V8::IdleNotification()) { | |
828 // V8 finished collecting garbage. | |
829 new_delay_ms = kLongIdleHandlerDelayMs; | |
830 } | |
831 } | |
832 | |
833 ScheduleIdleHandler(new_delay_ms); | |
834 } | |
835 | |
786 scoped_refptr<base::MessageLoopProxy> | 836 scoped_refptr<base::MessageLoopProxy> |
787 RenderThreadImpl::GetFileThreadMessageLoopProxy() { | 837 RenderThreadImpl::GetFileThreadMessageLoopProxy() { |
788 DCHECK(message_loop() == MessageLoop::current()); | 838 DCHECK(message_loop() == MessageLoop::current()); |
789 if (!file_thread_.get()) { | 839 if (!file_thread_.get()) { |
790 file_thread_.reset(new base::Thread("Renderer::FILE")); | 840 file_thread_.reset(new base::Thread("Renderer::FILE")); |
791 file_thread_->Start(); | 841 file_thread_->Start(); |
792 } | 842 } |
793 return file_thread_->message_loop_proxy(); | 843 return file_thread_->message_loop_proxy(); |
794 } | 844 } |
OLD | NEW |